From 767982e36298be4da44a063e36261e9cfdc0bf49 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 16 Apr 2021 18:36:45 -0400 Subject: [PATCH] Convert built-in SQL-language functions to SQL-standard-body style. Adopt the new pre-parsed representation for all built-in and information_schema SQL-language functions, except for a small number that can't presently be converted because they have polymorphic arguments. This eliminates residual hazards around search-path safety of these functions, and might provide some small performance benefits by reducing parsing costs. It seems useful also to provide more test coverage for the SQL-standard-body feature. Discussion: https://postgr.es/m/3956760.1618529139@sss.pgh.pa.us --- src/backend/catalog/information_schema.sql | 48 ++- src/backend/catalog/system_functions.sql | 350 +++++++++++++++++++-- src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_proc.dat | 115 ++++--- 4 files changed, 402 insertions(+), 113 deletions(-) diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql index 941a9f664c..0f2c1833e9 100644 --- a/src/backend/catalog/information_schema.sql +++ b/src/backend/catalog/information_schema.sql @@ -43,7 +43,8 @@ SET search_path TO information_schema; CREATE FUNCTION _pg_expandarray(IN anyarray, OUT x anyelement, OUT n int) RETURNS SETOF RECORD LANGUAGE sql STRICT IMMUTABLE PARALLEL SAFE - AS 'select $1[s], s - pg_catalog.array_lower($1,1) + 1 + AS 'select $1[s], + s operator(pg_catalog.-) pg_catalog.array_lower($1,1) operator(pg_catalog.+) 1 from pg_catalog.generate_series(pg_catalog.array_lower($1,1), pg_catalog.array_upper($1,1), 1) as g(s)'; @@ -52,28 +53,26 @@ CREATE FUNCTION _pg_expandarray(IN anyarray, OUT x anyelement, OUT n int) * column's position in the index (NULL if not there) */ CREATE FUNCTION _pg_index_position(oid, smallint) RETURNS int LANGUAGE sql STRICT STABLE - AS $$ +BEGIN ATOMIC SELECT (ss.a).n FROM (SELECT information_schema._pg_expandarray(indkey) AS a FROM pg_catalog.pg_index WHERE indexrelid = $1) ss WHERE (ss.a).x = $2; -$$; +END; CREATE FUNCTION _pg_truetypid(pg_attribute, pg_type) RETURNS oid LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT CASE WHEN $2.typtype = 'd' THEN $2.typbasetype ELSE $1.atttypid END$$; +RETURN CASE WHEN $2.typtype = 'd' THEN $2.typbasetype ELSE $1.atttypid END; CREATE FUNCTION _pg_truetypmod(pg_attribute, pg_type) RETURNS int4 LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT CASE WHEN $2.typtype = 'd' THEN $2.typtypmod ELSE $1.atttypmod END$$; +RETURN CASE WHEN $2.typtype = 'd' THEN $2.typtypmod ELSE $1.atttypmod END; -- these functions encapsulate knowledge about the encoding of typmod: @@ -82,8 +81,7 @@ CREATE FUNCTION _pg_char_max_length(typid oid, typmod int4) RETURNS integer IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT +RETURN CASE WHEN $2 = -1 /* default typmod */ THEN null WHEN $1 IN (1042, 1043) /* char, varchar */ @@ -91,15 +89,14 @@ $$SELECT WHEN $1 IN (1560, 1562) /* bit, varbit */ THEN $2 ELSE null - END$$; + END; CREATE FUNCTION _pg_char_octet_length(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT +RETURN CASE WHEN $1 IN (25, 1042, 1043) /* text, char, varchar */ THEN CASE WHEN $2 = -1 /* default typmod */ THEN CAST(2^30 AS integer) @@ -107,15 +104,14 @@ $$SELECT pg_catalog.pg_encoding_max_length((SELECT encoding FROM pg_catalog.pg_database WHERE datname = pg_catalog.current_database())) END ELSE null - END$$; + END; CREATE FUNCTION _pg_numeric_precision(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT +RETURN CASE $1 WHEN 21 /*int2*/ THEN 16 WHEN 23 /*int4*/ THEN 32 @@ -128,27 +124,25 @@ $$SELECT WHEN 700 /*float4*/ THEN 24 /*FLT_MANT_DIG*/ WHEN 701 /*float8*/ THEN 53 /*DBL_MANT_DIG*/ ELSE null - END$$; + END; CREATE FUNCTION _pg_numeric_precision_radix(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT +RETURN CASE WHEN $1 IN (21, 23, 20, 700, 701) THEN 2 WHEN $1 IN (1700) THEN 10 ELSE null - END$$; + END; CREATE FUNCTION _pg_numeric_scale(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT +RETURN CASE WHEN $1 IN (21, 23, 20) THEN 0 WHEN $1 IN (1700) THEN CASE WHEN $2 = -1 @@ -156,15 +150,14 @@ $$SELECT ELSE ($2 - 4) & 65535 END ELSE null - END$$; + END; CREATE FUNCTION _pg_datetime_precision(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT +RETURN CASE WHEN $1 IN (1082) /* date */ THEN 0 WHEN $1 IN (1083, 1114, 1184, 1266) /* time, timestamp, same + tz */ @@ -172,19 +165,18 @@ $$SELECT WHEN $1 IN (1186) /* interval */ THEN CASE WHEN $2 < 0 OR $2 & 65535 = 65535 THEN 6 ELSE $2 & 65535 END ELSE null - END$$; + END; CREATE FUNCTION _pg_interval_type(typid oid, mod int4) RETURNS text LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT +RETURN CASE WHEN $1 IN (1186) /* interval */ THEN pg_catalog.upper(substring(pg_catalog.format_type($1, $2) similar 'interval[()0-9]* #"%#"' escape '#')) ELSE null - END$$; + END; -- 5.2 INFORMATION_SCHEMA_CATALOG_NAME view appears later. diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index d7ac7a926e..1b2b37c1bf 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -30,65 +30,351 @@ */ -CREATE FUNCTION ts_debug(IN config regconfig, IN document text, +CREATE OR REPLACE FUNCTION lpad(text, integer) + RETURNS text + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN lpad($1, $2, ' '); + +CREATE OR REPLACE FUNCTION rpad(text, integer) + RETURNS text + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN rpad($1, $2, ' '); + +CREATE OR REPLACE FUNCTION "substring"(text, text, text) + RETURNS text + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN substring($1, similar_to_escape($2, $3)); + +CREATE OR REPLACE FUNCTION bit_length(bit) + RETURNS integer + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN length($1); + +CREATE OR REPLACE FUNCTION bit_length(bytea) + RETURNS integer + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN octet_length($1) * 8; + +CREATE OR REPLACE FUNCTION bit_length(text) + RETURNS integer + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN octet_length($1) * 8; + +CREATE OR REPLACE FUNCTION log(numeric) + RETURNS numeric + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN log(10, $1); + +CREATE OR REPLACE FUNCTION log10(numeric) + RETURNS numeric + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN log(10, $1); + +CREATE OR REPLACE FUNCTION round(numeric) + RETURNS numeric + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN round($1, 0); + +CREATE OR REPLACE FUNCTION trunc(numeric) + RETURNS numeric + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN trunc($1, 0); + +CREATE OR REPLACE FUNCTION numeric_pl_pg_lsn(numeric, pg_lsn) + RETURNS pg_lsn + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION path_contain_pt(path, point) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN on_ppath($2, $1); + +CREATE OR REPLACE FUNCTION polygon(circle) + RETURNS polygon + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN polygon(12, $1); + +CREATE OR REPLACE FUNCTION age(timestamptz) + RETURNS interval + LANGUAGE sql + STABLE PARALLEL SAFE STRICT COST 1 +RETURN age(cast(current_date as timestamptz), $1); + +CREATE OR REPLACE FUNCTION age(timestamp) + RETURNS interval + LANGUAGE sql + STABLE PARALLEL SAFE STRICT COST 1 +RETURN age(cast(current_date as timestamp), $1); + +CREATE OR REPLACE FUNCTION date_part(text, date) + RETURNS double precision + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN date_part($1, cast($2 as timestamp)); + +CREATE OR REPLACE FUNCTION timestamptz(date, time) + RETURNS timestamptz + LANGUAGE sql + STABLE PARALLEL SAFE STRICT COST 1 +RETURN cast(($1 + $2) as timestamptz); + +CREATE OR REPLACE FUNCTION timedate_pl(time, date) + RETURNS timestamp + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION timetzdate_pl(timetz, date) + RETURNS timestamptz + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION interval_pl_time(interval, time) + RETURNS time + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION interval_pl_date(interval, date) + RETURNS timestamp + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION interval_pl_timetz(interval, timetz) + RETURNS timetz + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION interval_pl_timestamp(interval, timestamp) + RETURNS timestamp + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION interval_pl_timestamptz(interval, timestamptz) + RETURNS timestamptz + LANGUAGE sql + STABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION integer_pl_date(integer, date) + RETURNS date + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION "overlaps"(timestamptz, timestamptz, + timestamptz, interval) + RETURNS boolean + LANGUAGE sql + STABLE PARALLEL SAFE COST 1 +RETURN ($1, $2) overlaps ($3, ($3 + $4)); + +CREATE OR REPLACE FUNCTION "overlaps"(timestamptz, interval, + timestamptz, interval) + RETURNS boolean + LANGUAGE sql + STABLE PARALLEL SAFE COST 1 +RETURN ($1, ($1 + $2)) overlaps ($3, ($3 + $4)); + +CREATE OR REPLACE FUNCTION "overlaps"(timestamptz, interval, + timestamptz, timestamptz) + RETURNS boolean + LANGUAGE sql + STABLE PARALLEL SAFE COST 1 +RETURN ($1, ($1 + $2)) overlaps ($3, $4); + +CREATE OR REPLACE FUNCTION "overlaps"(timestamp, timestamp, + timestamp, interval) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE COST 1 +RETURN ($1, $2) overlaps ($3, ($3 + $4)); + +CREATE OR REPLACE FUNCTION "overlaps"(timestamp, interval, + timestamp, timestamp) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE COST 1 +RETURN ($1, ($1 + $2)) overlaps ($3, $4); + +CREATE OR REPLACE FUNCTION "overlaps"(timestamp, interval, + timestamp, interval) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE COST 1 +RETURN ($1, ($1 + $2)) overlaps ($3, ($3 + $4)); + +CREATE OR REPLACE FUNCTION "overlaps"(time, interval, + time, interval) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE COST 1 +RETURN ($1, ($1 + $2)) overlaps ($3, ($3 + $4)); + +CREATE OR REPLACE FUNCTION "overlaps"(time, time, + time, interval) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE COST 1 +RETURN ($1, $2) overlaps ($3, ($3 + $4)); + +CREATE OR REPLACE FUNCTION "overlaps"(time, interval, + time, time) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE COST 1 +RETURN ($1, ($1 + $2)) overlaps ($3, $4); + +CREATE OR REPLACE FUNCTION int8pl_inet(bigint, inet) + RETURNS inet + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION xpath(text, xml) + RETURNS xml[] + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN xpath($1, $2, '{}'::text[]); + +CREATE OR REPLACE FUNCTION xpath_exists(text, xml) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN xpath_exists($1, $2, '{}'::text[]); + +CREATE OR REPLACE FUNCTION pg_sleep_for(interval) + RETURNS void + LANGUAGE sql + PARALLEL SAFE STRICT COST 1 +RETURN pg_sleep(extract(epoch from clock_timestamp() + $1) - + extract(epoch from clock_timestamp())); + +CREATE OR REPLACE FUNCTION pg_sleep_until(timestamptz) + RETURNS void + LANGUAGE sql + PARALLEL SAFE STRICT COST 1 +RETURN pg_sleep(extract(epoch from $1) - + extract(epoch from clock_timestamp())); + +CREATE OR REPLACE FUNCTION pg_relation_size(regclass) + RETURNS bigint + LANGUAGE sql + PARALLEL SAFE STRICT COST 1 +RETURN pg_relation_size($1, 'main'); + +CREATE OR REPLACE FUNCTION obj_description(oid, name) + RETURNS text + LANGUAGE sql + STABLE PARALLEL SAFE STRICT +BEGIN ATOMIC +select description from pg_description + where objoid = $1 and + classoid = (select oid from pg_class where relname = $2 and + relnamespace = 'pg_catalog'::regnamespace) and + objsubid = 0; +END; + +CREATE OR REPLACE FUNCTION shobj_description(oid, name) + RETURNS text + LANGUAGE sql + STABLE PARALLEL SAFE STRICT +BEGIN ATOMIC +select description from pg_shdescription + where objoid = $1 and + classoid = (select oid from pg_class where relname = $2 and + relnamespace = 'pg_catalog'::regnamespace); +END; + +CREATE OR REPLACE FUNCTION obj_description(oid) + RETURNS text + LANGUAGE sql + STABLE PARALLEL SAFE STRICT +BEGIN ATOMIC +select description from pg_description where objoid = $1 and objsubid = 0; +END; + +CREATE OR REPLACE FUNCTION col_description(oid, integer) + RETURNS text + LANGUAGE sql + STABLE PARALLEL SAFE STRICT +BEGIN ATOMIC +select description from pg_description + where objoid = $1 and classoid = 'pg_class'::regclass and objsubid = $2; +END; + +CREATE OR REPLACE FUNCTION ts_debug(config regconfig, document text, OUT alias text, OUT description text, OUT token text, OUT dictionaries regdictionary[], OUT dictionary regdictionary, OUT lexemes text[]) -RETURNS SETOF record AS -$$ -SELECT + RETURNS SETOF record + LANGUAGE sql + STABLE PARALLEL SAFE STRICT +BEGIN ATOMIC +select tt.alias AS alias, tt.description AS description, parse.token AS token, - ARRAY ( SELECT m.mapdict::pg_catalog.regdictionary - FROM pg_catalog.pg_ts_config_map AS m + ARRAY ( SELECT m.mapdict::regdictionary + FROM pg_ts_config_map AS m WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid ORDER BY m.mapseqno ) AS dictionaries, - ( SELECT mapdict::pg_catalog.regdictionary - FROM pg_catalog.pg_ts_config_map AS m + ( SELECT mapdict::regdictionary + FROM pg_ts_config_map AS m WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid - ORDER BY pg_catalog.ts_lexize(mapdict, parse.token) IS NULL, m.mapseqno + ORDER BY ts_lexize(mapdict, parse.token) IS NULL, m.mapseqno LIMIT 1 ) AS dictionary, - ( SELECT pg_catalog.ts_lexize(mapdict, parse.token) - FROM pg_catalog.pg_ts_config_map AS m + ( SELECT ts_lexize(mapdict, parse.token) + FROM pg_ts_config_map AS m WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid - ORDER BY pg_catalog.ts_lexize(mapdict, parse.token) IS NULL, m.mapseqno + ORDER BY ts_lexize(mapdict, parse.token) IS NULL, m.mapseqno LIMIT 1 ) AS lexemes -FROM pg_catalog.ts_parse( - (SELECT cfgparser FROM pg_catalog.pg_ts_config WHERE oid = $1 ), $2 +FROM ts_parse( + (SELECT cfgparser FROM pg_ts_config WHERE oid = $1 ), $2 ) AS parse, - pg_catalog.ts_token_type( - (SELECT cfgparser FROM pg_catalog.pg_ts_config WHERE oid = $1 ) + ts_token_type( + (SELECT cfgparser FROM pg_ts_config WHERE oid = $1 ) ) AS tt -WHERE tt.tokid = parse.tokid -$$ -LANGUAGE SQL STRICT STABLE PARALLEL SAFE; +WHERE tt.tokid = parse.tokid; +END; -COMMENT ON FUNCTION ts_debug(regconfig,text) IS - 'debug function for text search configuration'; - -CREATE FUNCTION ts_debug(IN document text, +CREATE OR REPLACE FUNCTION ts_debug(document text, OUT alias text, OUT description text, OUT token text, OUT dictionaries regdictionary[], OUT dictionary regdictionary, OUT lexemes text[]) -RETURNS SETOF record AS -$$ - SELECT * FROM pg_catalog.ts_debug( pg_catalog.get_current_ts_config(), $1); -$$ -LANGUAGE SQL STRICT STABLE PARALLEL SAFE; - -COMMENT ON FUNCTION ts_debug(text) IS - 'debug function for current text search configuration'; - + RETURNS SETOF record + LANGUAGE sql + STABLE PARALLEL SAFE STRICT +BEGIN ATOMIC + SELECT * FROM ts_debug(get_current_ts_config(), $1); +END; CREATE OR REPLACE FUNCTION pg_start_backup(label text, fast boolean DEFAULT false, exclusive boolean DEFAULT true) diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 904b0c97ec..1c60d1a699 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202104161 +#define CATALOG_VERSION_NO 202104162 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 591753fe81..14aba6e39b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -2364,7 +2364,7 @@ { oid => '1176', descr => 'convert date and time to timestamp with time zone', proname => 'timestamptz', prolang => 'sql', provolatile => 's', prorettype => 'timestamptz', proargtypes => 'date time', - prosrc => 'select cast(($1 + $2) as timestamp with time zone)' }, + prosrc => 'see system_views.sql' }, { oid => '1178', descr => 'convert timestamp with time zone to date', proname => 'date', provolatile => 's', prorettype => 'date', proargtypes => 'timestamptz', prosrc => 'timestamptz_date' }, @@ -2417,16 +2417,16 @@ { oid => '1215', descr => 'get description for object id and catalog name', proname => 'obj_description', prolang => 'sql', procost => '100', provolatile => 's', prorettype => 'text', proargtypes => 'oid name', - prosrc => 'select description from pg_catalog.pg_description where objoid = $1 and classoid = (select oid from pg_catalog.pg_class where relname = $2 and relnamespace = \'pg_catalog\'::pg_catalog.regnamespace) and objsubid = 0' }, + prosrc => 'see system_views.sql' }, { oid => '1216', descr => 'get description for table column', proname => 'col_description', prolang => 'sql', procost => '100', provolatile => 's', prorettype => 'text', proargtypes => 'oid int4', - prosrc => 'select description from pg_catalog.pg_description where objoid = $1 and classoid = \'pg_catalog.pg_class\'::pg_catalog.regclass and objsubid = $2' }, + prosrc => 'see system_views.sql' }, { oid => '1993', descr => 'get description for object id and shared catalog name', proname => 'shobj_description', prolang => 'sql', procost => '100', provolatile => 's', prorettype => 'text', proargtypes => 'oid name', - prosrc => 'select description from pg_catalog.pg_shdescription where objoid = $1 and classoid = (select oid from pg_catalog.pg_class where relname = $2 and relnamespace = \'pg_catalog\'::pg_catalog.regnamespace)' }, + prosrc => 'see system_views.sql' }, { oid => '1217', descr => 'truncate timestamp with time zone to specified units', @@ -2601,13 +2601,13 @@ { oid => '1296', proname => 'timedate_pl', prolang => 'sql', prorettype => 'timestamp', - proargtypes => 'time date', prosrc => 'select ($2 + $1)' }, + proargtypes => 'time date', prosrc => 'see system_views.sql' }, { oid => '1297', proname => 'datetimetz_pl', prorettype => 'timestamptz', proargtypes => 'date timetz', prosrc => 'datetimetz_timestamptz' }, { oid => '1298', proname => 'timetzdate_pl', prolang => 'sql', prorettype => 'timestamptz', - proargtypes => 'timetz date', prosrc => 'select ($2 + $1)' }, + proargtypes => 'timetz date', prosrc => 'see system_views.sql' }, { oid => '1299', descr => 'current transaction time', proname => 'now', provolatile => 's', prorettype => 'timestamptz', proargtypes => '', prosrc => 'now' }, @@ -2651,17 +2651,17 @@ proname => 'overlaps', prolang => 'sql', proisstrict => 'f', provolatile => 's', prorettype => 'bool', proargtypes => 'timestamptz interval timestamptz interval', - prosrc => 'select ($1, ($1 + $2)) overlaps ($3, ($3 + $4))' }, + prosrc => 'see system_views.sql' }, { oid => '1306', descr => 'intervals overlap?', proname => 'overlaps', prolang => 'sql', proisstrict => 'f', provolatile => 's', prorettype => 'bool', proargtypes => 'timestamptz timestamptz timestamptz interval', - prosrc => 'select ($1, $2) overlaps ($3, ($3 + $4))' }, + prosrc => 'see system_views.sql' }, { oid => '1307', descr => 'intervals overlap?', proname => 'overlaps', prolang => 'sql', proisstrict => 'f', provolatile => 's', prorettype => 'bool', proargtypes => 'timestamptz interval timestamptz timestamptz', - prosrc => 'select ($1, ($1 + $2)) overlaps ($3, $4)' }, + prosrc => 'see system_views.sql' }, { oid => '1308', descr => 'intervals overlap?', proname => 'overlaps', proisstrict => 'f', prorettype => 'bool', @@ -2669,15 +2669,15 @@ { oid => '1309', descr => 'intervals overlap?', proname => 'overlaps', prolang => 'sql', proisstrict => 'f', prorettype => 'bool', proargtypes => 'time interval time interval', - prosrc => 'select ($1, ($1 + $2)) overlaps ($3, ($3 + $4))' }, + prosrc => 'see system_views.sql' }, { oid => '1310', descr => 'intervals overlap?', proname => 'overlaps', prolang => 'sql', proisstrict => 'f', prorettype => 'bool', proargtypes => 'time time time interval', - prosrc => 'select ($1, $2) overlaps ($3, ($3 + $4))' }, + prosrc => 'see system_views.sql' }, { oid => '1311', descr => 'intervals overlap?', proname => 'overlaps', prolang => 'sql', proisstrict => 'f', prorettype => 'bool', proargtypes => 'time interval time time', - prosrc => 'select ($1, ($1 + $2)) overlaps ($3, $4)' }, + prosrc => 'see system_views.sql' }, { oid => '1312', descr => 'I/O', proname => 'timestamp_in', provolatile => 's', prorettype => 'timestamp', @@ -2758,7 +2758,7 @@ { oid => '1348', descr => 'deprecated, use two-argument form instead', proname => 'obj_description', prolang => 'sql', procost => '100', provolatile => 's', prorettype => 'text', proargtypes => 'oid', - prosrc => 'select description from pg_catalog.pg_description where objoid = $1 and objsubid = 0' }, + prosrc => 'see system_views.sql' }, { oid => '1349', descr => 'print type names of oidvector field', proname => 'oidvectortypes', provolatile => 's', prorettype => 'text', @@ -2841,8 +2841,7 @@ { oid => '1384', descr => 'extract field from date', proname => 'date_part', prolang => 'sql', prorettype => 'float8', - proargtypes => 'text date', - prosrc => 'select pg_catalog.date_part($1, cast($2 as timestamp without time zone))' }, + proargtypes => 'text date', prosrc => 'see system_views.sql' }, { oid => '9979', descr => 'extract field from date', proname => 'extract', prorettype => 'numeric', proargtypes => 'text date', prosrc => 'extract_date' }, @@ -2856,7 +2855,7 @@ descr => 'date difference from today preserving months and years', proname => 'age', prolang => 'sql', provolatile => 's', prorettype => 'interval', proargtypes => 'timestamptz', - prosrc => 'select pg_catalog.age(cast(current_date as timestamp with time zone), $1)' }, + prosrc => 'see system_views.sql' }, { oid => '1388', descr => 'convert timestamp with time zone to time with time zone', @@ -2970,7 +2969,7 @@ prosrc => 'box_div' }, { oid => '1426', proname => 'path_contain_pt', prolang => 'sql', prorettype => 'bool', - proargtypes => 'path point', prosrc => 'select pg_catalog.on_ppath($2, $1)' }, + proargtypes => 'path point', prosrc => 'see system_views.sql' }, { oid => '1428', proname => 'poly_contain_pt', prorettype => 'bool', proargtypes => 'polygon point', prosrc => 'poly_contain_pt' }, @@ -3230,7 +3229,7 @@ prosrc => 'circle_center' }, { oid => '1544', descr => 'convert circle to 12-vertex polygon', proname => 'polygon', prolang => 'sql', prorettype => 'polygon', - proargtypes => 'circle', prosrc => 'select pg_catalog.polygon(12, $1)' }, + proargtypes => 'circle', prosrc => 'see system_views.sql' }, { oid => '1545', descr => 'number of points', proname => 'npoints', prorettype => 'int4', proargtypes => 'path', prosrc => 'path_npoints' }, @@ -3526,12 +3525,10 @@ prosrc => 'translate' }, { oid => '879', descr => 'left-pad string to length', proname => 'lpad', prolang => 'sql', prorettype => 'text', - proargtypes => 'text int4', - prosrc => 'select pg_catalog.lpad($1, $2, \' \')' }, + proargtypes => 'text int4', prosrc => 'see system_views.sql' }, { oid => '880', descr => 'right-pad string to length', proname => 'rpad', prolang => 'sql', prorettype => 'text', - proargtypes => 'text int4', - prosrc => 'select pg_catalog.rpad($1, $2, \' \')' }, + proargtypes => 'text int4', prosrc => 'see system_views.sql' }, { oid => '881', descr => 'trim spaces from left end of string', proname => 'ltrim', prorettype => 'text', proargtypes => 'text', prosrc => 'ltrim1' }, @@ -4147,7 +4144,7 @@ prosrc => 'inetpl' }, { oid => '2631', proname => 'int8pl_inet', prolang => 'sql', prorettype => 'inet', - proargtypes => 'int8 inet', prosrc => 'select $2 + $1' }, + proargtypes => 'int8 inet', prosrc => 'see system_views.sql' }, { oid => '2632', proname => 'inetmi_int8', prorettype => 'inet', proargtypes => 'inet int8', prosrc => 'inetmi_int8' }, @@ -4279,13 +4276,13 @@ prosrc => 'numeric_round' }, { oid => '1708', descr => 'value rounded to \'scale\' of zero', proname => 'round', prolang => 'sql', prorettype => 'numeric', - proargtypes => 'numeric', prosrc => 'select pg_catalog.round($1,0)' }, + proargtypes => 'numeric', prosrc => 'see system_views.sql' }, { oid => '1709', descr => 'value truncated to \'scale\'', proname => 'trunc', prorettype => 'numeric', proargtypes => 'numeric int4', prosrc => 'numeric_trunc' }, { oid => '1710', descr => 'value truncated to \'scale\' of zero', proname => 'trunc', prolang => 'sql', prorettype => 'numeric', - proargtypes => 'numeric', prosrc => 'select pg_catalog.trunc($1,0)' }, + proargtypes => 'numeric', prosrc => 'see system_views.sql' }, { oid => '1711', descr => 'nearest integer >= value', proname => 'ceil', prorettype => 'numeric', proargtypes => 'numeric', prosrc => 'numeric_ceil' }, @@ -4385,10 +4382,10 @@ proargtypes => 'int4', prosrc => 'int4_numeric' }, { oid => '1741', descr => 'base 10 logarithm', proname => 'log', prolang => 'sql', prorettype => 'numeric', - proargtypes => 'numeric', prosrc => 'select pg_catalog.log(10, $1)' }, + proargtypes => 'numeric', prosrc => 'see system_views.sql' }, { oid => '1481', descr => 'base 10 logarithm', proname => 'log10', prolang => 'sql', prorettype => 'numeric', - proargtypes => 'numeric', prosrc => 'select pg_catalog.log(10, $1)' }, + proargtypes => 'numeric', prosrc => 'see system_views.sql' }, { oid => '1742', descr => 'convert float4 to numeric', proname => 'numeric', proleakproof => 't', prorettype => 'numeric', proargtypes => 'float4', prosrc => 'float4_numeric' }, @@ -4572,13 +4569,13 @@ { oid => '1810', descr => 'length in bits', proname => 'bit_length', prolang => 'sql', prorettype => 'int4', - proargtypes => 'bytea', prosrc => 'select pg_catalog.octet_length($1) * 8' }, + proargtypes => 'bytea', prosrc => 'see system_views.sql' }, { oid => '1811', descr => 'length in bits', proname => 'bit_length', prolang => 'sql', prorettype => 'int4', - proargtypes => 'text', prosrc => 'select pg_catalog.octet_length($1) * 8' }, + proargtypes => 'text', prosrc => 'see system_views.sql' }, { oid => '1812', descr => 'length in bits', proname => 'bit_length', prolang => 'sql', prorettype => 'int4', - proargtypes => 'bit', prosrc => 'select pg_catalog.length($1)' }, + proargtypes => 'bit', prosrc => 'see system_views.sql' }, # Selectivity estimators for LIKE and related operators { oid => '1814', descr => 'restriction selectivity of ILIKE', @@ -4897,7 +4894,7 @@ { oid => '1848', proname => 'interval_pl_time', prolang => 'sql', prorettype => 'time', - proargtypes => 'interval time', prosrc => 'select $2 + $1' }, + proargtypes => 'interval time', prosrc => 'see system_views.sql' }, { oid => '1850', proname => 'int28eq', proleakproof => 't', prorettype => 'bool', @@ -5782,11 +5779,11 @@ { oid => '2003', proname => 'textanycat', prolang => 'sql', provolatile => 's', prorettype => 'text', proargtypes => 'text anynonarray', - prosrc => 'select $1 || $2::pg_catalog.text' }, + prosrc => 'select $1 operator(pg_catalog.||) $2::pg_catalog.text' }, { oid => '2004', proname => 'anytextcat', prolang => 'sql', provolatile => 's', prorettype => 'text', proargtypes => 'anynonarray text', - prosrc => 'select $1::pg_catalog.text || $2' }, + prosrc => 'select $1::pg_catalog.text operator(pg_catalog.||) $2' }, { oid => '2005', proname => 'bytealike', prosupport => 'textlike_support', @@ -5906,15 +5903,15 @@ { oid => '2042', descr => 'intervals overlap?', proname => 'overlaps', prolang => 'sql', proisstrict => 'f', prorettype => 'bool', proargtypes => 'timestamp interval timestamp interval', - prosrc => 'select ($1, ($1 + $2)) overlaps ($3, ($3 + $4))' }, + prosrc => 'see system_views.sql' }, { oid => '2043', descr => 'intervals overlap?', proname => 'overlaps', prolang => 'sql', proisstrict => 'f', prorettype => 'bool', proargtypes => 'timestamp timestamp timestamp interval', - prosrc => 'select ($1, $2) overlaps ($3, ($3 + $4))' }, + prosrc => 'see system_views.sql' }, { oid => '2044', descr => 'intervals overlap?', proname => 'overlaps', prolang => 'sql', proisstrict => 'f', prorettype => 'bool', proargtypes => 'timestamp interval timestamp timestamp', - prosrc => 'select ($1, ($1 + $2)) overlaps ($3, $4)' }, + prosrc => 'see system_views.sql' }, { oid => '2045', descr => 'less-equal-greater', proname => 'timestamp_cmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'timestamp timestamp', prosrc => 'timestamp_cmp' }, @@ -5980,7 +5977,7 @@ descr => 'date difference from today preserving months and years', proname => 'age', prolang => 'sql', provolatile => 's', prorettype => 'interval', proargtypes => 'timestamp', - prosrc => 'select pg_catalog.age(cast(current_date as timestamp without time zone), $1)' }, + prosrc => 'see system_views.sql' }, { oid => '2069', descr => 'adjust timestamp to new time zone', proname => 'timezone', prorettype => 'timestamptz', @@ -6000,8 +5997,7 @@ prosrc => 'textregexsubstr' }, { oid => '2074', descr => 'extract text matching SQL regular expression', proname => 'substring', prolang => 'sql', prorettype => 'text', - proargtypes => 'text text text', - prosrc => 'select pg_catalog.substring($1, pg_catalog.similar_to_escape($2, $3))' }, + proargtypes => 'text text text', prosrc => 'see system_views.sql' }, { oid => '2075', descr => 'convert int8 to bitstring', proname => 'bit', prorettype => 'bit', proargtypes => 'int8 int4', @@ -6366,11 +6362,11 @@ { oid => '3935', descr => 'sleep for the specified interval', proname => 'pg_sleep_for', prolang => 'sql', provolatile => 'v', prorettype => 'void', proargtypes => 'interval', - prosrc => 'select pg_catalog.pg_sleep(extract(epoch from pg_catalog.clock_timestamp() operator(pg_catalog.+) $1) operator(pg_catalog.-) extract(epoch from pg_catalog.clock_timestamp()))' }, + prosrc => 'see system_views.sql' }, { oid => '3936', descr => 'sleep until the specified time', proname => 'pg_sleep_until', prolang => 'sql', provolatile => 'v', prorettype => 'void', proargtypes => 'timestamptz', - prosrc => 'select pg_catalog.pg_sleep(extract(epoch from $1) operator(pg_catalog.-) extract(epoch from pg_catalog.clock_timestamp()))' }, + prosrc => 'see system_views.sql' }, { oid => '315', descr => 'Is JIT compilation available in this session?', proname => 'pg_jit_available', provolatile => 'v', prorettype => 'bool', proargtypes => '', prosrc => 'pg_jit_available' }, @@ -7185,7 +7181,7 @@ descr => 'disk space usage for the main fork of the specified table or index', proname => 'pg_relation_size', prolang => 'sql', provolatile => 'v', prorettype => 'int8', proargtypes => 'regclass', - prosrc => 'select pg_catalog.pg_relation_size($1, \'main\')' }, + prosrc => 'see system_views.sql' }, { oid => '2332', descr => 'disk space usage for the specified fork of a table or index', proname => 'pg_relation_size', provolatile => 'v', prorettype => 'int8', @@ -8104,21 +8100,21 @@ # formerly-missing interval + datetime operators { oid => '2546', proname => 'interval_pl_date', prolang => 'sql', prorettype => 'timestamp', - proargtypes => 'interval date', prosrc => 'select $2 + $1' }, + proargtypes => 'interval date', prosrc => 'see system_views.sql' }, { oid => '2547', proname => 'interval_pl_timetz', prolang => 'sql', prorettype => 'timetz', - proargtypes => 'interval timetz', prosrc => 'select $2 + $1' }, + proargtypes => 'interval timetz', prosrc => 'see system_views.sql' }, { oid => '2548', proname => 'interval_pl_timestamp', prolang => 'sql', prorettype => 'timestamp', proargtypes => 'interval timestamp', - prosrc => 'select $2 + $1' }, + prosrc => 'see system_views.sql' }, { oid => '2549', proname => 'interval_pl_timestamptz', prolang => 'sql', provolatile => 's', prorettype => 'timestamptz', proargtypes => 'interval timestamptz', - prosrc => 'select $2 + $1' }, + prosrc => 'see system_views.sql' }, { oid => '2550', proname => 'integer_pl_date', prolang => 'sql', prorettype => 'date', - proargtypes => 'int4 date', prosrc => 'select $2 + $1' }, + proargtypes => 'int4 date', prosrc => 'see system_views.sql' }, { oid => '2556', descr => 'get OIDs of databases in a tablespace', proname => 'pg_tablespace_databases', prorows => '1000', proretset => 't', @@ -8601,8 +8597,7 @@ prosrc => 'xpath' }, { oid => '2932', descr => 'evaluate XPath expression', proname => 'xpath', prolang => 'sql', prorettype => '_xml', - proargtypes => 'text xml', - prosrc => 'select pg_catalog.xpath($1, $2, \'{}\'::pg_catalog.text[])' }, + proargtypes => 'text xml', prosrc => 'see system_views.sql' }, { oid => '2614', descr => 'test XML value against XPath expression', proname => 'xmlexists', prorettype => 'bool', proargtypes => 'text xml', @@ -8614,8 +8609,7 @@ proargtypes => 'text xml _text', prosrc => 'xpath_exists' }, { oid => '3050', descr => 'test XML value against XPath expression', proname => 'xpath_exists', prolang => 'sql', prorettype => 'bool', - proargtypes => 'text xml', - prosrc => 'select pg_catalog.xpath_exists($1, $2, \'{}\'::pg_catalog.text[])' }, + proargtypes => 'text xml', prosrc => 'see system_views.sql' }, { oid => '3051', descr => 'determine if a string is well formed XML', proname => 'xml_is_well_formed', provolatile => 's', prorettype => 'bool', proargtypes => 'text', prosrc => 'xml_is_well_formed' }, @@ -8880,7 +8874,7 @@ proargtypes => 'pg_lsn numeric', prosrc => 'pg_lsn_pli' }, { oid => '5023', proname => 'numeric_pl_pg_lsn', prolang => 'sql', prorettype => 'pg_lsn', - proargtypes => 'numeric pg_lsn', prosrc => 'select $2 + $1' }, + proargtypes => 'numeric pg_lsn', prosrc => 'see system_views.sql' }, { oid => '5024', proname => 'pg_lsn_mii', prorettype => 'pg_lsn', proargtypes => 'pg_lsn numeric', prosrc => 'pg_lsn_mii' }, @@ -9319,6 +9313,23 @@ proname => 'ts_lexize', prorettype => '_text', proargtypes => 'regdictionary text', prosrc => 'ts_lexize' }, +{ oid => '9531', descr => 'debug function for text search configuration', + proname => 'ts_debug', prolang => 'sql', prorows => '1000', proretset => 't', + provolatile => 's', prorettype => 'record', proargtypes => 'regconfig text', + proallargtypes => '{regconfig,text,text,text,text,_regdictionary,regdictionary,_text}', + proargmodes => '{i,i,o,o,o,o,o,o}', + proargnames => '{config,document,alias,description,token,dictionaries,dictionary,lexemes}', + prosrc => 'see system_views.sql' }, + +{ oid => '9532', + descr => 'debug function for current text search configuration', + proname => 'ts_debug', prolang => 'sql', prorows => '1000', proretset => 't', + provolatile => 's', prorettype => 'record', proargtypes => 'text', + proallargtypes => '{text,text,text,text,_regdictionary,regdictionary,_text}', + proargmodes => '{i,o,o,o,o,o,o}', + proargnames => '{document,alias,description,token,dictionaries,dictionary,lexemes}', + prosrc => 'see system_views.sql' }, + { oid => '3725', descr => '(internal)', proname => 'dsimple_init', prorettype => 'internal', proargtypes => 'internal', prosrc => 'dsimple_init' },