Попробуйте:
date_part('year',age(coalesce(d1,current_date), d2))::int;
Функция age(d1,d2)
возвращает количество лет, месяцев и дней между двумя датами в следующем формате:
xxx year(s) xxx mon(s) xxx day(s).
с этого выхода, используя date_part()
, чтобы выбрать единственную разницу в году. а также не нужно приводить оператор if к NULL
, поскольку я добавил coalesece
, который возвращает первое значение NON Null
. Поэтому, если d1
есть NULL
, он возвращает cuurent_date
Функция Структура:
CREATE OR REPLACE FUNCTION diff(d1 date,d2 date) RETURNS int AS $$
BEGIN
RETURN date_part('year',age(coalesce(d1,current_date), d2))::int;
END
$$ language plpgsql;
Вызов функции:
select * from diff(null,'2010-04-01');
select * from diff('2012-10-01','2010-04-01');
Я думаю, прежде всего, что Вы запутываетесь между program's stack
и any old stack
.
Стопка А
Является структурой абстрактных данных, которая состоит из информации в системе Метода "последним пришел - первым вышел". Вы помещаете произвольные объекты на стек, и затем Вы снимаете их снова, во многом как в / лотке, главный объект всегда является тем, который снят, и Вы всегда ставите к вершине.
Стопка Программ А
Является стеком, это - раздел памяти, которая используется во время выполнения, он обычно имеет статический размер на программу и часто используемый для хранения параметров функции. Вы продвигаете параметры на стек, когда Вы вызываете функцию и функцию или обращаетесь к стеку непосредственно или появляетесь от переменных от стека.
стопка программ А не является обычно аппаратными средствами (хотя это сохранено в памяти, таким образом, это может быть обсуждено как таковое), но Указатель вершины стека, который указывает на текущую область Стека, обычно является регистром ЦП. Это делает это немного более гибким, чем стек LIFO, поскольку можно изменить точку, в которой стек обращается.
необходимо читать и удостовериться, что Вы понимаете Википедия статья, поскольку она дает хорошее описание Аппаратной Стопки, которая является тем, с чем Вы имеете дело.
существует также это учебное руководство , которое объясняет стек с точки зрения старых регистров на 16 битов, но могло быть полезным и другой конкретно о стеке.
От Nils Pipenbrinck:
Это достойно упоминания, что некоторые процессоры не реализуют все инструкции для доступа и управления стеком (нажатие, поп, указатель вершины стека, и т.д.), но x86 делает из-за, это - частота использования. В этих ситуациях, если бы Вы хотели стек, необходимо было бы реализовать его сами (некоторый MIPS, и некоторые процессоры ARM создаются без стеков).
, Например, в миллионе операций в секунду инструкция по нажатию была бы реализована как:
addi $sp, $sp, -4 # Decrement stack pointer by 4
sw $t0, ($sp) # Save $t0 to stack
и инструкция Pop был бы похож:
lw $t0, ($sp) # Copy from stack to $t0
addi $sp, $sp, 4 # Increment stack pointer by 4
Вы корректны, что стек является 'просто' структурой данных. Здесь, однако, это относится к реализованному стеку аппаратных средств, используемому для особых целей - "Стек".
Многие люди прокомментировали о реализованном стеке аппаратных средств по сравнению с (программное обеспечение) структура данных стека. Я хотел бы добавить, что существует три главных типа структуры стека -
первой вещью знать является архитектура, для которой Вы программируете, который книга объясняет (я просто искал ее - ссылка). Для реального понимания вещей я предлагаю, чтобы Вы узнали о памяти, обращении, регистрах и архитектуре x86 (я предполагаю, что это - то, что Вы узнаете - из книги).
Стек вызовов реализован x86 системой команд и операционной системой.
Инструкции как нажатие и поп корректируют указатель вершины стека, в то время как операционная система заботится о выделении памяти, когда стек растет для каждого потока.
то, что стопка x86 "углубляется" от выше для понижения адресов, делает эту архитектуру больше восприимчивый к атаке переполнения буфера.
Вы корректны, что стек является структурой данных. Часто, структуры данных (включенные стеки) Вы работаете с, абстрактны и существуют как представление в памяти.
стек Вы работаете с, в этом случае имеет больше материального существования - это отображается непосредственно на реальные физические регистры в процессоре. Как структура данных, стеки являются FILO (метод "первым пришел - последним вышел") структуры, которые гарантируют, что данные удалены в обратном порядке, это вводилось. Посмотрите логотип StackOverflow для визуального! ;)
Вы работаете с стопка инструкции . Это - стопка фактических инструкций, Вы подаете процессор.
Я не видел Газовый ассемблер а именно, но в целом стек "реализован" путем поддержания ссылки на местоположение в памяти, где вершина стека находится. Ячейка памяти хранится в регистре, который имеет различные названия различной архитектуры, но может считаться регистром указателя вершины стека.
поп и команды нажатия реализованы в большей части архитектуры для Вас путем здания на микро инструкциях. Однако некоторая "Образовательная Архитектура" требует, чтобы Вы реализовали их Ваш сам. Функционально, нажатие было бы реализовано несколько как это:
load the address in the stack pointer register to a gen. purpose register x
store data y at the location x
increment stack pointer register by size of y
кроме того, некоторая архитектура хранит последний используемый адрес памяти как Указатель вершины стека. Некоторое хранилище следующий доступный адрес.
Стек уже существует, таким образом, можно предположить это при написании кода. Стек содержит обратные адреса функций, локальных переменных и переменных, которые передаются между функциями. Существуют также регистры стека, такие как BP, SP (Указатель вершины стека), встроенный, который можно использовать, следовательно встроенные команды, которые Вы упомянули. Если бы стек не был уже реализован, то функции не могли бы работать и кодировать поток, не мог работать.
Вы путаете абстрактный стек, и аппаратные средства реализовали стек. Последний уже реализован.
Относительно того, реализован ли стек в аппаратных средствах, этот , статья Wikipedia могла бы помочь.
семейства процессоров Some, такие как x86, имеют специальные инструкции для управления стопкой в настоящее время выполняющегося потока. Другие семейства процессоров, включая PowerPC и MIPS, не имеют явной поддержки стека, но вместо этого полагаются на конвенцию и делегируют управление стеком к Двоичному интерфейсу приложений (ABI) операционной системы.
то, Что статья и другие это связывается с, могло бы быть полезно получить ощущение использования стека в процессорах.
Стек "реализован" посредством указателя вершины стека, который (принимающий x86 архитектура здесь) указывает в стек сегмент . Каждый раз что-то продвинуто на стеке (посредством pushl, звоните, или подобный код операции стека), он записан в адрес, на который указывает указатель вершины стека, и указатель вершины стека постепенно уменьшился (стек растет вниз , т.е. меньшие адреса). То, когда Вы выталкиваете что-то от стека (popl, мочите), указатель вершины стека , увеличило , и значение прочитало стек.
В приложении пространства пользователя, стек уже настраивается для Вас, когда Ваше приложение запускается. В космическом пространстве ядра необходимо настроить сегмент стека и указатель вершины стека сначала...
Я думаю, что на основной ответ, который Вы ищете, уже намекнули.
Когда x86 загрузки компьютера, стек не является установкой. Программист должен явно настроить его во время начальной загрузки. Однако, если Вы уже находитесь в операционной системе, это заботилось о. Ниже пример кода от простой программы самозагрузки.
Сначала регистры сегмента данных и сегмента стека установлены, и затем указатель вершины стека установлен 0x4000 кроме того.
movw $BOOT_SEGMENT, %ax
movw %ax, %ds
movw %ax, %ss
movw $0x4000, %ax
movw %ax, %sp
После этого кода может использоваться стек. Теперь я уверен, что это может быть сделано различными способами, но я думаю, что это должно проиллюстрировать идею.