From 8a37951eebffd9bf528cb06d46127fb721d0e452 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 25 Jul 2020 12:54:58 -0400 Subject: [PATCH] Mark built-in coercion functions as leakproof where possible. Making these leakproof seems helpful since (for example) if you have a function f(int8) that is leakproof, you don't want it to effectively become non-leakproof when you apply it to an int4 or int2 column. But that's what happens today, since the implicit up-coercion will not be leakproof. Most of the coercion functions that visibly can't throw errors are functions that convert numeric datatypes to other, wider ones. Notable is that float4_numeric and float8_numeric can be marked leakproof; before commit a57d312a7 they could not have been. I also marked the functions that coerce strings to "name" as leakproof; that's okay today because they truncate silently, but if we ever reconsidered that behavior then they could no longer be leakproof. I desisted from marking rtrim1() as leakproof; it appears so right now, but the code seems a little too complex and perhaps subject to change, since it's shared with other SQL functions. Discussion: https://postgr.es/m/459322.1595607431@sss.pgh.pa.us --- src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_proc.dat | 103 ++++++++++++----------- src/test/regress/expected/opr_sanity.out | 25 ++++++ 3 files changed, 78 insertions(+), 52 deletions(-) diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index ed3aef93d04..92849511219 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202007202 +#define CATALOG_VERSION_NO 202007251 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4b5af32440f..082a11f2708 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -698,11 +698,11 @@ proname => 'dlog1', prorettype => 'float8', proargtypes => 'float8', prosrc => 'dlog1' }, { oid => '235', descr => 'convert int2 to float8', - proname => 'float8', prorettype => 'float8', proargtypes => 'int2', - prosrc => 'i2tod' }, + proname => 'float8', proleakproof => 't', prorettype => 'float8', + proargtypes => 'int2', prosrc => 'i2tod' }, { oid => '236', descr => 'convert int2 to float4', - proname => 'float4', prorettype => 'float4', proargtypes => 'int2', - prosrc => 'i2tof' }, + proname => 'float4', proleakproof => 't', prorettype => 'float4', + proargtypes => 'int2', prosrc => 'i2tof' }, { oid => '237', descr => 'convert float8 to int2', proname => 'int2', prorettype => 'int2', proargtypes => 'float8', prosrc => 'dtoi2' }, @@ -879,26 +879,26 @@ proargtypes => 'float8 float8 float8 int4', prosrc => 'width_bucket_float8' }, { oid => '311', descr => 'convert float4 to float8', - proname => 'float8', prorettype => 'float8', proargtypes => 'float4', - prosrc => 'ftod' }, + proname => 'float8', proleakproof => 't', prorettype => 'float8', + proargtypes => 'float4', prosrc => 'ftod' }, { oid => '312', descr => 'convert float8 to float4', proname => 'float4', prorettype => 'float4', proargtypes => 'float8', prosrc => 'dtof' }, { oid => '313', descr => 'convert int2 to int4', - proname => 'int4', prorettype => 'int4', proargtypes => 'int2', - prosrc => 'i2toi4' }, + proname => 'int4', proleakproof => 't', prorettype => 'int4', + proargtypes => 'int2', prosrc => 'i2toi4' }, { oid => '314', descr => 'convert int4 to int2', proname => 'int2', prorettype => 'int2', proargtypes => 'int4', prosrc => 'i4toi2' }, { oid => '316', descr => 'convert int4 to float8', - proname => 'float8', prorettype => 'float8', proargtypes => 'int4', - prosrc => 'i4tod' }, + proname => 'float8', proleakproof => 't', prorettype => 'float8', + proargtypes => 'int4', prosrc => 'i4tod' }, { oid => '317', descr => 'convert float8 to int4', proname => 'int4', prorettype => 'int4', proargtypes => 'float8', prosrc => 'dtoi4' }, { oid => '318', descr => 'convert int4 to float4', - proname => 'float4', prorettype => 'float4', proargtypes => 'int4', - prosrc => 'i4tof' }, + proname => 'float4', proleakproof => 't', prorettype => 'float4', + proargtypes => 'int4', prosrc => 'i4tof' }, { oid => '319', descr => 'convert float4 to int4', proname => 'int4', prorettype => 'int4', proargtypes => 'float4', prosrc => 'ftoi4' }, @@ -1150,17 +1150,17 @@ proname => 'text', prorettype => 'text', proargtypes => 'bpchar', prosrc => 'rtrim1' }, { oid => '406', descr => 'convert name to text', - proname => 'text', prorettype => 'text', proargtypes => 'name', - prosrc => 'name_text' }, + proname => 'text', proleakproof => 't', prorettype => 'text', + proargtypes => 'name', prosrc => 'name_text' }, { oid => '407', descr => 'convert text to name', - proname => 'name', prorettype => 'name', proargtypes => 'text', - prosrc => 'text_name' }, + proname => 'name', proleakproof => 't', prorettype => 'name', + proargtypes => 'text', prosrc => 'text_name' }, { oid => '408', descr => 'convert name to char(n)', proname => 'bpchar', prorettype => 'bpchar', proargtypes => 'name', prosrc => 'name_bpchar' }, { oid => '409', descr => 'convert char(n) to name', - proname => 'name', prorettype => 'name', proargtypes => 'bpchar', - prosrc => 'bpchar_name' }, + proname => 'name', proleakproof => 't', prorettype => 'name', + proargtypes => 'bpchar', prosrc => 'bpchar_name' }, { oid => '449', descr => 'hash', proname => 'hashint2', prorettype => 'int4', proargtypes => 'int2', @@ -1338,11 +1338,11 @@ proname => 'int4', prorettype => 'int4', proargtypes => 'int8', prosrc => 'int84' }, { oid => '481', descr => 'convert int4 to int8', - proname => 'int8', prorettype => 'int8', proargtypes => 'int4', - prosrc => 'int48' }, + proname => 'int8', proleakproof => 't', prorettype => 'int8', + proargtypes => 'int4', prosrc => 'int48' }, { oid => '482', descr => 'convert int8 to float8', - proname => 'float8', prorettype => 'float8', proargtypes => 'int8', - prosrc => 'i8tod' }, + proname => 'float8', proleakproof => 't', prorettype => 'float8', + proargtypes => 'int8', prosrc => 'i8tod' }, { oid => '483', descr => 'convert float8 to int8', proname => 'int8', prorettype => 'int8', proargtypes => 'float8', prosrc => 'dtoi8' }, @@ -1359,8 +1359,8 @@ proargtypes => 'anyarray int8', prosrc => 'hash_array_extended' }, { oid => '652', descr => 'convert int8 to float4', - proname => 'float4', prorettype => 'float4', proargtypes => 'int8', - prosrc => 'i8tof' }, + proname => 'float4', proleakproof => 't', prorettype => 'float4', + proargtypes => 'int8', prosrc => 'i8tof' }, { oid => '653', descr => 'convert float4 to int8', proname => 'int8', prorettype => 'int8', proargtypes => 'float4', prosrc => 'ftoi8' }, @@ -1369,8 +1369,8 @@ proname => 'int2', prorettype => 'int2', proargtypes => 'int8', prosrc => 'int82' }, { oid => '754', descr => 'convert int2 to int8', - proname => 'int8', prorettype => 'int8', proargtypes => 'int2', - prosrc => 'int28' }, + proname => 'int8', proleakproof => 't', prorettype => 'int8', + proargtypes => 'int2', prosrc => 'int28' }, { oid => '655', proname => 'namelt', proleakproof => 't', prorettype => 'bool', @@ -2521,8 +2521,8 @@ proname => 'oid', prorettype => 'oid', proargtypes => 'int8', prosrc => 'i8tooid' }, { oid => '1288', descr => 'convert oid to int8', - proname => 'int8', prorettype => 'int8', proargtypes => 'oid', - prosrc => 'oidtoi8' }, + proname => 'int8', proleakproof => 't', prorettype => 'int8', + proargtypes => 'oid', prosrc => 'oidtoi8' }, { oid => '1291', descr => 'trigger to suppress updates when new and old records match', @@ -2782,8 +2782,8 @@ prosrc => 'textlen' }, { oid => '1370', descr => 'convert time to interval', - proname => 'interval', prorettype => 'interval', proargtypes => 'time', - prosrc => 'time_interval' }, + proname => 'interval', proleakproof => 't', prorettype => 'interval', + proargtypes => 'time', prosrc => 'time_interval' }, { oid => '1372', descr => 'character length', proname => 'char_length', prorettype => 'int4', proargtypes => 'bpchar', prosrc => 'bpcharlen' }, @@ -2861,11 +2861,11 @@ # OIDS 1400 - 1499 { oid => '1400', descr => 'convert varchar to name', - proname => 'name', prorettype => 'name', proargtypes => 'varchar', - prosrc => 'text_name' }, + proname => 'name', proleakproof => 't', prorettype => 'name', + proargtypes => 'varchar', prosrc => 'text_name' }, { oid => '1401', descr => 'convert name to varchar', - proname => 'varchar', prorettype => 'varchar', proargtypes => 'name', - prosrc => 'name_text' }, + proname => 'varchar', proleakproof => 't', prorettype => 'varchar', + proargtypes => 'name', prosrc => 'name_text' }, { oid => '1402', descr => 'current schema name', proname => 'current_schema', provolatile => 's', proparallel => 'u', @@ -3941,8 +3941,8 @@ proname => 'macaddr8_or', prorettype => 'macaddr8', proargtypes => 'macaddr8 macaddr8', prosrc => 'macaddr8_or' }, { oid => '4123', descr => 'convert macaddr to macaddr8', - proname => 'macaddr8', prorettype => 'macaddr8', proargtypes => 'macaddr', - prosrc => 'macaddrtomacaddr8' }, + proname => 'macaddr8', proleakproof => 't', prorettype => 'macaddr8', + proargtypes => 'macaddr', prosrc => 'macaddrtomacaddr8' }, { oid => '4124', descr => 'convert macaddr8 to macaddr', proname => 'macaddr', prorettype => 'macaddr', proargtypes => 'macaddr8', prosrc => 'macaddr8tomacaddr' }, @@ -4321,8 +4321,8 @@ proname => 'trim_scale', prorettype => 'numeric', proargtypes => 'numeric', prosrc => 'numeric_trim_scale' }, { oid => '1740', descr => 'convert int4 to numeric', - proname => 'numeric', prorettype => 'numeric', proargtypes => 'int4', - prosrc => 'int4_numeric' }, + proname => 'numeric', proleakproof => 't', prorettype => 'numeric', + 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)' }, @@ -4330,11 +4330,11 @@ proname => 'log10', prolang => 'sql', prorettype => 'numeric', proargtypes => 'numeric', prosrc => 'select pg_catalog.log(10, $1)' }, { oid => '1742', descr => 'convert float4 to numeric', - proname => 'numeric', prorettype => 'numeric', proargtypes => 'float4', - prosrc => 'float4_numeric' }, + proname => 'numeric', proleakproof => 't', prorettype => 'numeric', + proargtypes => 'float4', prosrc => 'float4_numeric' }, { oid => '1743', descr => 'convert float8 to numeric', - proname => 'numeric', prorettype => 'numeric', proargtypes => 'float8', - prosrc => 'float8_numeric' }, + proname => 'numeric', proleakproof => 't', prorettype => 'numeric', + proargtypes => 'float8', prosrc => 'float8_numeric' }, { oid => '1744', descr => 'convert numeric to int4', proname => 'int4', prorettype => 'int4', proargtypes => 'numeric', prosrc => 'numeric_int4' }, @@ -4390,11 +4390,11 @@ proname => 'int8', prorettype => 'int8', proargtypes => 'numeric', prosrc => 'numeric_int8' }, { oid => '1781', descr => 'convert int8 to numeric', - proname => 'numeric', prorettype => 'numeric', proargtypes => 'int8', - prosrc => 'int8_numeric' }, + proname => 'numeric', proleakproof => 't', prorettype => 'numeric', + proargtypes => 'int8', prosrc => 'int8_numeric' }, { oid => '1782', descr => 'convert int2 to numeric', - proname => 'numeric', prorettype => 'numeric', proargtypes => 'int2', - prosrc => 'int2_numeric' }, + proname => 'numeric', proleakproof => 't', prorettype => 'numeric', + proargtypes => 'int2', prosrc => 'int2_numeric' }, { oid => '1783', descr => 'convert numeric to int2', proname => 'int2', prorettype => 'int2', proargtypes => 'numeric', prosrc => 'numeric_int2' }, @@ -7755,7 +7755,8 @@ { oid => '2510', descr => 'get the prepared statements for this session', proname => 'pg_prepared_statement', prorows => '1000', proretset => 't', provolatile => 's', proparallel => 'r', prorettype => 'record', - proargtypes => '', proallargtypes => '{text,text,timestamptz,_regtype,bool,int8,int8}', + proargtypes => '', + proallargtypes => '{text,text,timestamptz,_regtype,bool,int8,int8}', proargmodes => '{o,o,o,o,o,o,o}', proargnames => '{name,statement,prepare_time,parameter_types,from_sql,generic_plans,custom_plans}', prosrc => 'pg_prepared_statement' }, @@ -7933,11 +7934,11 @@ prosrc => 'pg_tablespace_databases' }, { oid => '2557', descr => 'convert int4 to boolean', - proname => 'bool', prorettype => 'bool', proargtypes => 'int4', - prosrc => 'int4_bool' }, + proname => 'bool', proleakproof => 't', prorettype => 'bool', + proargtypes => 'int4', prosrc => 'int4_bool' }, { oid => '2558', descr => 'convert boolean to int4', - proname => 'int4', prorettype => 'int4', proargtypes => 'bool', - prosrc => 'bool_int4' }, + proname => 'int4', proleakproof => 't', prorettype => 'int4', + proargtypes => 'bool', prosrc => 'bool_int4' }, { oid => '2559', descr => 'current value from last used sequence', proname => 'lastval', provolatile => 'v', proparallel => 'u', prorettype => 'int8', proargtypes => '', prosrc => 'lastval' }, diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out index 27056d70d36..1b3c146e4cc 100644 --- a/src/test/regress/expected/opr_sanity.out +++ b/src/test/regress/expected/opr_sanity.out @@ -572,6 +572,8 @@ int24ge(smallint,integer) int42ge(integer,smallint) oideq(oid,oid) oidne(oid,oid) +float8(smallint) +float4(smallint) nameeqtext(name,text) namelttext(name,text) nameletext(name,text) @@ -610,6 +612,10 @@ float84lt(double precision,real) float84le(double precision,real) float84gt(double precision,real) float84ge(double precision,real) +float8(real) +int4(smallint) +float8(integer) +float4(integer) btint2cmp(smallint,smallint) btint4cmp(integer,integer) btfloat4cmp(real,real) @@ -620,6 +626,9 @@ btnamecmp(name,name) bttextcmp(text,text) cash_cmp(money,money) btoidvectorcmp(oidvector,oidvector) +text(name) +name(text) +name(character) text_larger(text,text) text_smaller(text,text) int8eq(bigint,bigint) @@ -634,7 +643,10 @@ int84lt(bigint,integer) int84gt(bigint,integer) int84le(bigint,integer) int84ge(bigint,integer) +int8(integer) +float8(bigint) oidvectorne(oidvector,oidvector) +float4(bigint) namelt(name,name) namele(name,name) namegt(name,name) @@ -651,6 +663,7 @@ text_lt(text,text) text_le(text,text) text_gt(text,text) text_ge(text,text) +int8(smallint) macaddr_eq(macaddr,macaddr) macaddr_lt(macaddr,macaddr) macaddr_le(macaddr,macaddr) @@ -716,6 +729,7 @@ interval_ge(interval,interval) interval_gt(interval,interval) charlt("char","char") tidne(tid,tid) +int8(oid) tideq(tid,tid) timestamptz_cmp(timestamp with time zone,timestamp with time zone) interval_cmp(interval,interval) @@ -727,6 +741,9 @@ timetz_le(time with time zone,time with time zone) timetz_ge(time with time zone,time with time zone) timetz_gt(time with time zone,time with time zone) timetz_cmp(time with time zone,time with time zone) +"interval"(time without time zone) +name(character varying) +"varchar"(name) circle_eq(circle,circle) circle_ne(circle,circle) circle_lt(circle,circle) @@ -757,6 +774,11 @@ varbitcmp(bit varying,bit varying) boolle(boolean,boolean) boolge(boolean,boolean) btboolcmp(boolean,boolean) +"numeric"(integer) +"numeric"(real) +"numeric"(double precision) +"numeric"(bigint) +"numeric"(smallint) int28eq(smallint,bigint) int28ne(smallint,bigint) int28lt(smallint,bigint) @@ -803,6 +825,8 @@ btfloat48cmp(real,double precision) btfloat84cmp(double precision,real) md5(text) md5(bytea) +bool(integer) +int4(boolean) tidgt(tid,tid) tidlt(tid,tid) tidge(tid,tid) @@ -837,6 +861,7 @@ macaddr8_gt(macaddr8,macaddr8) macaddr8_ge(macaddr8,macaddr8) macaddr8_ne(macaddr8,macaddr8) macaddr8_cmp(macaddr8,macaddr8) +macaddr8(macaddr) xid8lt(xid8,xid8) xid8gt(xid8,xid8) xid8le(xid8,xid8) -- 2.30.2