Commit 5c292e6b authored by Tom Lane's avatar Tom Lane

Declare lead() and lag() using anycompatible not anyelement.

This allows use of a "default" expression that doesn't slavishly
match the data column's type.  Formerly you got something like
"function lag(numeric, integer, integer) does not exist", which
is not just unhelpful but actively misleading.

The SQL spec suggests that the default should be coerced to the data
column's type, but this implementation instead chooses the common
supertype, which seems at least as reasonable.

(Note: I took the opportunity to run "make reformat-dat-files" on
pg_proc.dat, so this commit includes some cosmetic changes to
recently-added entries that aren't related to lead/lag.)

Vik Fearing

Discussion: https://postgr.es/m/77675130-89da-dab1-51dd-492c93dcf5d1@postgresfriends.org
parent 40c24bfe
...@@ -19594,17 +19594,17 @@ SELECT count(*) FROM sometable; ...@@ -19594,17 +19594,17 @@ SELECT count(*) FROM sometable;
<indexterm> <indexterm>
<primary>lag</primary> <primary>lag</primary>
</indexterm> </indexterm>
<function>lag</function> ( <parameter>value</parameter> <type>anyelement</type> <function>lag</function> ( <parameter>value</parameter> <type>anycompatible</type>
<optional>, <parameter>offset</parameter> <type>integer</type> <optional>, <parameter>offset</parameter> <type>integer</type>
<optional>, <parameter>default</parameter> <type>anyelement</type> </optional></optional> ) <optional>, <parameter>default</parameter> <type>anycompatible</type> </optional></optional> )
<returnvalue>anyelement</returnvalue> <returnvalue>anycompatible</returnvalue>
</para> </para>
<para> <para>
Returns <parameter>value</parameter> evaluated at Returns <parameter>value</parameter> evaluated at
the row that is <parameter>offset</parameter> the row that is <parameter>offset</parameter>
rows before the current row within the partition; if there is no such rows before the current row within the partition; if there is no such
row, instead returns <parameter>default</parameter> row, instead returns <parameter>default</parameter>
(which must be of the same type as (which must be of a type compatible with
<parameter>value</parameter>). <parameter>value</parameter>).
Both <parameter>offset</parameter> and Both <parameter>offset</parameter> and
<parameter>default</parameter> are evaluated <parameter>default</parameter> are evaluated
...@@ -19619,17 +19619,17 @@ SELECT count(*) FROM sometable; ...@@ -19619,17 +19619,17 @@ SELECT count(*) FROM sometable;
<indexterm> <indexterm>
<primary>lead</primary> <primary>lead</primary>
</indexterm> </indexterm>
<function>lead</function> ( <parameter>value</parameter> <type>anyelement</type> <function>lead</function> ( <parameter>value</parameter> <type>anycompatible</type>
<optional>, <parameter>offset</parameter> <type>integer</type> <optional>, <parameter>offset</parameter> <type>integer</type>
<optional>, <parameter>default</parameter> <type>anyelement</type> </optional></optional> ) <optional>, <parameter>default</parameter> <type>anycompatible</type> </optional></optional> )
<returnvalue>anyelement</returnvalue> <returnvalue>anycompatible</returnvalue>
</para> </para>
<para> <para>
Returns <parameter>value</parameter> evaluated at Returns <parameter>value</parameter> evaluated at
the row that is <parameter>offset</parameter> the row that is <parameter>offset</parameter>
rows after the current row within the partition; if there is no such rows after the current row within the partition; if there is no such
row, instead returns <parameter>default</parameter> row, instead returns <parameter>default</parameter>
(which must be of the same type as (which must be of a type compatible with
<parameter>value</parameter>). <parameter>value</parameter>).
Both <parameter>offset</parameter> and Both <parameter>offset</parameter> and
<parameter>default</parameter> are evaluated <parameter>default</parameter> are evaluated
......
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 202011042 #define CATALOG_VERSION_NO 202011043
#endif #endif
...@@ -1563,11 +1563,11 @@ ...@@ -1563,11 +1563,11 @@
proname => 'string_to_array', proisstrict => 'f', prorettype => '_text', proname => 'string_to_array', proisstrict => 'f', prorettype => '_text',
proargtypes => 'text text text', prosrc => 'text_to_array_null' }, proargtypes => 'text text text', prosrc => 'text_to_array_null' },
{ oid => '8432', descr => 'split delimited text', { oid => '8432', descr => 'split delimited text',
proname => 'string_to_table', proisstrict => 'f', prorows => '1000', proname => 'string_to_table', prorows => '1000', proisstrict => 'f',
proretset => 't', prorettype => 'text', proargtypes => 'text text', proretset => 't', prorettype => 'text', proargtypes => 'text text',
prosrc => 'text_to_table' }, prosrc => 'text_to_table' },
{ oid => '8433', descr => 'split delimited text, with null string', { oid => '8433', descr => 'split delimited text, with null string',
proname => 'string_to_table', proisstrict => 'f', prorows => '1000', proname => 'string_to_table', prorows => '1000', proisstrict => 'f',
proretset => 't', prorettype => 'text', proargtypes => 'text text text', proretset => 't', prorettype => 'text', proargtypes => 'text text text',
prosrc => 'text_to_table_null' }, prosrc => 'text_to_table_null' },
{ oid => '395', { oid => '395',
...@@ -5257,8 +5257,8 @@ ...@@ -5257,8 +5257,8 @@
proargnames => '{pid,status,receive_start_lsn,receive_start_tli,written_lsn,flushed_lsn,received_tli,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time,slot_name,sender_host,sender_port,conninfo}', proargnames => '{pid,status,receive_start_lsn,receive_start_tli,written_lsn,flushed_lsn,received_tli,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time,slot_name,sender_host,sender_port,conninfo}',
prosrc => 'pg_stat_get_wal_receiver' }, prosrc => 'pg_stat_get_wal_receiver' },
{ oid => '8595', descr => 'statistics: information about replication slots', { oid => '8595', descr => 'statistics: information about replication slots',
proname => 'pg_stat_get_replication_slots', prorows => '10', proisstrict => 'f', proname => 'pg_stat_get_replication_slots', prorows => '10',
proretset => 't', provolatile => 's', proparallel => 'r', proisstrict => 'f', proretset => 't', provolatile => 's', proparallel => 'r',
prorettype => 'record', proargtypes => '', prorettype => 'record', proargtypes => '',
proallargtypes => '{text,int8,int8,int8,int8,int8,int8,timestamptz}', proallargtypes => '{text,int8,int8,int8,int8,int8,int8,timestamptz}',
proargmodes => '{o,o,o,o,o,o,o,o}', proargmodes => '{o,o,o,o,o,o,o,o}',
...@@ -5491,8 +5491,7 @@ ...@@ -5491,8 +5491,7 @@
{ oid => '1136', descr => 'statistics: information about WAL activity', { oid => '1136', descr => 'statistics: information about WAL activity',
proname => 'pg_stat_get_wal', proisstrict => 'f', provolatile => 's', proname => 'pg_stat_get_wal', proisstrict => 'f', provolatile => 's',
proparallel => 'r', prorettype => 'record', proargtypes => '', proparallel => 'r', prorettype => 'record', proargtypes => '',
proallargtypes => '{int8,timestamptz}', proallargtypes => '{int8,timestamptz}', proargmodes => '{o,o}',
proargmodes => '{o,o}',
proargnames => '{wal_buffers_full,stats_reset}', proargnames => '{wal_buffers_full,stats_reset}',
prosrc => 'pg_stat_get_wal' }, prosrc => 'pg_stat_get_wal' },
...@@ -5615,8 +5614,9 @@ ...@@ -5615,8 +5614,9 @@
prorettype => 'void', proargtypes => 'text', prosrc => 'pg_stat_reset_slru' }, prorettype => 'void', proargtypes => 'text', prosrc => 'pg_stat_reset_slru' },
{ oid => '8596', { oid => '8596',
descr => 'statistics: reset collected statistics for a single replication slot', descr => 'statistics: reset collected statistics for a single replication slot',
proname => 'pg_stat_reset_replication_slot', proisstrict => 'f', provolatile => 'v', proname => 'pg_stat_reset_replication_slot', proisstrict => 'f',
prorettype => 'void', proargtypes => 'text', prosrc => 'pg_stat_reset_replication_slot' }, provolatile => 'v', prorettype => 'void', proargtypes => 'text',
prosrc => 'pg_stat_reset_replication_slot' },
{ oid => '3163', descr => 'current trigger depth', { oid => '3163', descr => 'current trigger depth',
proname => 'pg_trigger_depth', provolatile => 's', proparallel => 'r', proname => 'pg_trigger_depth', provolatile => 's', proparallel => 'r',
...@@ -7833,9 +7833,11 @@ ...@@ -7833,9 +7833,11 @@
prosrc => 'pg_get_shmem_allocations' }, prosrc => 'pg_get_shmem_allocations' },
# memory context of local backend # memory context of local backend
{ oid => '2282', descr => 'information about all memory contexts of local backend', { oid => '2282',
proname => 'pg_get_backend_memory_contexts', prorows => '100', proretset => 't', descr => 'information about all memory contexts of local backend',
provolatile => 'v', proparallel => 'r', prorettype => 'record', proargtypes => '', proname => 'pg_get_backend_memory_contexts', prorows => '100',
proretset => 't', provolatile => 'v', proparallel => 'r',
prorettype => 'record', proargtypes => '',
proallargtypes => '{text,text,text,int4,int8,int8,int8,int8,int8}', proallargtypes => '{text,text,text,int4,int8,int8,int8,int8,int8}',
proargmodes => '{o,o,o,o,o,o,o,o,o}', proargmodes => '{o,o,o,o,o,o,o,o,o}',
proargnames => '{name, ident, parent, level, total_bytes, total_nblocks, free_bytes, free_chunks, used_bytes}', proargnames => '{name, ident, parent, level, total_bytes, total_nblocks, free_bytes, free_chunks, used_bytes}',
...@@ -9748,8 +9750,8 @@ ...@@ -9748,8 +9750,8 @@
proname => 'lag', prokind => 'w', prorettype => 'anyelement', proname => 'lag', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_lag_with_offset' }, proargtypes => 'anyelement int4', prosrc => 'window_lag_with_offset' },
{ oid => '3108', descr => 'fetch the Nth preceding row value with default', { oid => '3108', descr => 'fetch the Nth preceding row value with default',
proname => 'lag', prokind => 'w', prorettype => 'anyelement', proname => 'lag', prokind => 'w', prorettype => 'anycompatible',
proargtypes => 'anyelement int4 anyelement', proargtypes => 'anycompatible int4 anycompatible',
prosrc => 'window_lag_with_offset_and_default' }, prosrc => 'window_lag_with_offset_and_default' },
{ oid => '3109', descr => 'fetch the following row value', { oid => '3109', descr => 'fetch the following row value',
proname => 'lead', prokind => 'w', prorettype => 'anyelement', proname => 'lead', prokind => 'w', prorettype => 'anyelement',
...@@ -9758,8 +9760,8 @@ ...@@ -9758,8 +9760,8 @@
proname => 'lead', prokind => 'w', prorettype => 'anyelement', proname => 'lead', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_lead_with_offset' }, proargtypes => 'anyelement int4', prosrc => 'window_lead_with_offset' },
{ oid => '3111', descr => 'fetch the Nth following row value with default', { oid => '3111', descr => 'fetch the Nth following row value with default',
proname => 'lead', prokind => 'w', prorettype => 'anyelement', proname => 'lead', prokind => 'w', prorettype => 'anycompatible',
proargtypes => 'anyelement int4 anyelement', proargtypes => 'anycompatible int4 anycompatible',
prosrc => 'window_lead_with_offset_and_default' }, prosrc => 'window_lead_with_offset_and_default' },
{ oid => '3112', descr => 'fetch the first row value', { oid => '3112', descr => 'fetch the first row value',
proname => 'first_value', prokind => 'w', prorettype => 'anyelement', proname => 'first_value', prokind => 'w', prorettype => 'anyelement',
......
...@@ -300,6 +300,21 @@ SELECT lag(ten, four, 0) OVER (PARTITION BY four ORDER BY ten), ten, four FROM t ...@@ -300,6 +300,21 @@ SELECT lag(ten, four, 0) OVER (PARTITION BY four ORDER BY ten), ten, four FROM t
0 | 3 | 3 0 | 3 | 3
(10 rows) (10 rows)
SELECT lag(ten, four, 0.7) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten;
lag | ten | four
-----+-----+------
0 | 0 | 0
0 | 0 | 0
4 | 4 | 0
0.7 | 1 | 1
1 | 1 | 1
1 | 7 | 1
7 | 9 | 1
0.7 | 0 | 2
0.7 | 1 | 3
0.7 | 3 | 3
(10 rows)
SELECT lead(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; SELECT lead(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
lead | ten | four lead | ten | four
------+-----+------ ------+-----+------
...@@ -345,6 +360,21 @@ SELECT lead(ten * 2, 1, -1) OVER (PARTITION BY four ORDER BY ten), ten, four FRO ...@@ -345,6 +360,21 @@ SELECT lead(ten * 2, 1, -1) OVER (PARTITION BY four ORDER BY ten), ten, four FRO
-1 | 3 | 3 -1 | 3 | 3
(10 rows) (10 rows)
SELECT lead(ten * 2, 1, -1.4) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten;
lead | ten | four
------+-----+------
0 | 0 | 0
8 | 0 | 0
-1.4 | 4 | 0
2 | 1 | 1
14 | 1 | 1
18 | 7 | 1
-1.4 | 9 | 1
-1.4 | 0 | 2
6 | 1 | 3
-1.4 | 3 | 3
(10 rows)
SELECT first_value(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; SELECT first_value(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
first_value | ten | four first_value | ten | four
-------------+-----+------ -------------+-----+------
......
...@@ -63,12 +63,14 @@ SELECT lag(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHER ...@@ -63,12 +63,14 @@ SELECT lag(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHER
SELECT lag(ten, four) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; SELECT lag(ten, four) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
SELECT lag(ten, four, 0) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; SELECT lag(ten, four, 0) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
SELECT lag(ten, four, 0.7) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten;
SELECT lead(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; SELECT lead(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
SELECT lead(ten * 2, 1) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; SELECT lead(ten * 2, 1) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
SELECT lead(ten * 2, 1, -1) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; SELECT lead(ten * 2, 1, -1) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
SELECT lead(ten * 2, 1, -1.4) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten;
SELECT first_value(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; SELECT first_value(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment