Commit 39a96512 authored by Tom Lane's avatar Tom Lane

Mark built-in btree comparison functions as leakproof where it's safe.

Generally, if the comparison operators for a datatype or pair of datatypes
are leakproof, the corresponding btree comparison support function can be
considered so as well.  But we had not originally worried about marking
support functions as leakproof, reasoning that they'd not likely be used in
queries so the marking wouldn't matter.  It turns out there's at least one
place where it does matter: calc_arraycontsel() finds the target datatype's
default btree comparison function and tries to use that to estimate
selectivity, but it will be blocked in some cases if the function isn't
leakproof.  This leads to unnecessarily poor selectivity estimates and bad
plans, as seen in bug #15251.

Hence, run around and apply proleakproof markings where the corresponding
btree comparison operators are leakproof.  (I did eyeball each function
to verify that it wasn't doing anything surprising, too.)

This isn't a full solution to bug #15251, and it's not back-patchable
because of the need for a catversion bump.  A more useful response probably
is to consider whether we can check permissions on the parent table instead
of the child.  However, this change will help in some cases where that
won't, and it's easy enough to do in HEAD, so let's do so.

Discussion: https://postgr.es/m/3876.1531261875@sss.pgh.pa.us
parent 57cd2b6e
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201806231
#define CATALOG_VERSION_NO 201807111
#endif
This diff is collapsed.
......@@ -563,6 +563,17 @@ float84lt(double precision,real)
float84le(double precision,real)
float84gt(double precision,real)
float84ge(double precision,real)
btint2cmp(smallint,smallint)
btint4cmp(integer,integer)
btfloat4cmp(real,real)
btfloat8cmp(double precision,double precision)
btoidcmp(oid,oid)
btabstimecmp(abstime,abstime)
btcharcmp("char","char")
btnamecmp(name,name)
cash_cmp(money,money)
btreltimecmp(reltime,reltime)
bttintervalcmp(tinterval,tinterval)
int8eq(bigint,bigint)
int8ne(bigint,bigint)
int8lt(bigint,bigint)
......@@ -594,6 +605,8 @@ macaddr_le(macaddr,macaddr)
macaddr_gt(macaddr,macaddr)
macaddr_ge(macaddr,macaddr)
macaddr_ne(macaddr,macaddr)
macaddr_cmp(macaddr,macaddr)
btint8cmp(bigint,bigint)
int48eq(integer,bigint)
int48ne(integer,bigint)
int48lt(integer,bigint)
......@@ -612,6 +625,7 @@ network_le(inet,inet)
network_gt(inet,inet)
network_ge(inet,inet)
network_ne(inet,inet)
network_cmp(inet,inet)
lseg_eq(lseg,lseg)
bpchareq(character,character)
bpcharne(character,character)
......@@ -621,11 +635,13 @@ date_le(date,date)
date_gt(date,date)
date_ge(date,date)
date_ne(date,date)
date_cmp(date,date)
time_lt(time without time zone,time without time zone)
time_le(time without time zone,time without time zone)
time_gt(time without time zone,time without time zone)
time_ge(time without time zone,time without time zone)
time_ne(time without time zone,time without time zone)
time_cmp(time without time zone,time without time zone)
time_eq(time without time zone,time without time zone)
timestamptz_eq(timestamp with time zone,timestamp with time zone)
timestamptz_ne(timestamp with time zone,timestamp with time zone)
......@@ -642,6 +658,8 @@ interval_gt(interval,interval)
charlt("char","char")
tidne(tid,tid)
tideq(tid,tid)
timestamptz_cmp(timestamp with time zone,timestamp with time zone)
interval_cmp(interval,interval)
xideqint4(xid,integer)
timetz_eq(time with time zone,time with time zone)
timetz_ne(time with time zone,time with time zone)
......@@ -649,6 +667,7 @@ timetz_lt(time with time zone,time with time zone)
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)
circle_eq(circle,circle)
circle_ne(circle,circle)
circle_lt(circle,circle)
......@@ -666,6 +685,7 @@ bitge(bit,bit)
bitgt(bit,bit)
bitle(bit,bit)
bitlt(bit,bit)
bitcmp(bit,bit)
oidgt(oid,oid)
oidge(oid,oid)
varbiteq(bit varying,bit varying)
......@@ -674,8 +694,10 @@ varbitge(bit varying,bit varying)
varbitgt(bit varying,bit varying)
varbitle(bit varying,bit varying)
varbitlt(bit varying,bit varying)
varbitcmp(bit varying,bit varying)
boolle(boolean,boolean)
boolge(boolean,boolean)
btboolcmp(boolean,boolean)
int28eq(smallint,bigint)
int28ne(smallint,bigint)
int28lt(smallint,bigint)
......@@ -694,24 +716,36 @@ byteale(bytea,bytea)
byteagt(bytea,bytea)
byteage(bytea,bytea)
byteane(bytea,bytea)
byteacmp(bytea,bytea)
timestamp_cmp(timestamp without time zone,timestamp without time zone)
timestamp_eq(timestamp without time zone,timestamp without time zone)
timestamp_ne(timestamp without time zone,timestamp without time zone)
timestamp_lt(timestamp without time zone,timestamp without time zone)
timestamp_le(timestamp without time zone,timestamp without time zone)
timestamp_ge(timestamp without time zone,timestamp without time zone)
timestamp_gt(timestamp without time zone,timestamp without time zone)
btint48cmp(integer,bigint)
btint84cmp(bigint,integer)
btint24cmp(smallint,integer)
btint42cmp(integer,smallint)
btint28cmp(smallint,bigint)
btint82cmp(bigint,smallint)
btfloat48cmp(real,double precision)
btfloat84cmp(double precision,real)
md5(text)
md5(bytea)
tidgt(tid,tid)
tidlt(tid,tid)
tidge(tid,tid)
tidle(tid,tid)
bttidcmp(tid,tid)
uuid_lt(uuid,uuid)
uuid_le(uuid,uuid)
uuid_eq(uuid,uuid)
uuid_ge(uuid,uuid)
uuid_gt(uuid,uuid)
uuid_ne(uuid,uuid)
uuid_cmp(uuid,uuid)
xidneq(xid,xid)
xidneqint4(xid,integer)
sha224(bytea)
......@@ -725,6 +759,7 @@ macaddr8_le(macaddr8,macaddr8)
macaddr8_gt(macaddr8,macaddr8)
macaddr8_ge(macaddr8,macaddr8)
macaddr8_ne(macaddr8,macaddr8)
macaddr8_cmp(macaddr8,macaddr8)
-- restore normal output mode
\a\t
-- List of functions used by libpq's fe-lobj.c
......
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