aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2019-01-02 16:33:48 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2019-01-02 16:34:04 -0500
commit68a13f28bebc9eb70cc6988bfa2daaf4500f519f (patch)
tree63d86e437f42f3fe400da41b7f2018e5dcb99986 /src
parentacfe1392eff2f96ef7931068b11b2d58196f4d95 (diff)
downloadpostgresql-68a13f28bebc9eb70cc6988bfa2daaf4500f519f.tar.gz
postgresql-68a13f28bebc9eb70cc6988bfa2daaf4500f519f.zip
Don't believe MinMaxExpr is leakproof without checking.
MinMaxExpr invokes the btree comparison function for its input datatype, so it's only leakproof if that function is. Many such functions are indeed leakproof, but others are not, and we should not just assume that they are. Hence, adjust contain_leaked_vars to verify the leakproofness of the referenced function explicitly. I didn't add a regression test because it would need to depend on some particular comparison function being leaky, and that's a moving target, per discussion. This has been wrong all along, so back-patch to supported branches. Discussion: https://postgr.es/m/31042.1546194242@sss.pgh.pa.us
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/util/clauses.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 60e31279ecc..f0ef1029d10 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -1579,7 +1579,6 @@ contain_leaked_vars_walker(Node *node, void *context)
case T_CaseExpr:
case T_CaseTestExpr:
case T_RowExpr:
- case T_MinMaxExpr:
case T_SQLValueFunction:
case T_NullTest:
case T_BooleanTest:
@@ -1636,6 +1635,36 @@ contain_leaked_vars_walker(Node *node, void *context)
}
break;
+ case T_MinMaxExpr:
+ {
+ /*
+ * MinMaxExpr is leakproof if the comparison function it calls
+ * is leakproof.
+ */
+ MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
+ TypeCacheEntry *typentry;
+ bool leakproof;
+
+ /* Look up the btree comparison function for the datatype */
+ typentry = lookup_type_cache(minmaxexpr->minmaxtype,
+ TYPECACHE_CMP_PROC);
+ if (OidIsValid(typentry->cmp_proc))
+ leakproof = get_func_leakproof(typentry->cmp_proc);
+ else
+ {
+ /*
+ * The executor will throw an error, but here we just
+ * treat the missing function as leaky.
+ */
+ leakproof = false;
+ }
+
+ if (!leakproof &&
+ contain_var_clause((Node *) minmaxexpr->args))
+ return true;
+ }
+ break;
+
case T_CurrentOfExpr:
/*