mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Fix no-longer-valid shortcuts in expression_returns_set().
expression_returns_set() used to short-circuit its recursion upon seeing certain node types, such as DistinctExpr, that it knew the executor did not support set-valued arguments for. That was never inherent, though, just a reflection of laziness in execQual.c. With the new implementation of SRFs there is no reason to think that any scalar-valued expression node could not have a set-valued subexpression, except for AggRefs and WindowFuncs where we know there is a parser check rejecting it. And indeed, the shortcut causes unexpected failures for cases such as a SRF underneath DistinctExpr, because the planner stops looking for SRFs too soon. Discussion: https://postgr.es/m/5259.1497044025@sss.pgh.pa.us
This commit is contained in:
@ -694,39 +694,11 @@ expression_returns_set_walker(Node *node, void *context)
|
|||||||
/* else fall through to check args */
|
/* else fall through to check args */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Avoid recursion for some cases that can't return a set */
|
/* Avoid recursion for some cases that parser checks not to return a set */
|
||||||
if (IsA(node, Aggref))
|
if (IsA(node, Aggref))
|
||||||
return false;
|
return false;
|
||||||
if (IsA(node, WindowFunc))
|
if (IsA(node, WindowFunc))
|
||||||
return false;
|
return false;
|
||||||
if (IsA(node, DistinctExpr))
|
|
||||||
return false;
|
|
||||||
if (IsA(node, NullIfExpr))
|
|
||||||
return false;
|
|
||||||
if (IsA(node, ScalarArrayOpExpr))
|
|
||||||
return false;
|
|
||||||
if (IsA(node, BoolExpr))
|
|
||||||
return false;
|
|
||||||
if (IsA(node, SubLink))
|
|
||||||
return false;
|
|
||||||
if (IsA(node, SubPlan))
|
|
||||||
return false;
|
|
||||||
if (IsA(node, AlternativeSubPlan))
|
|
||||||
return false;
|
|
||||||
if (IsA(node, ArrayExpr))
|
|
||||||
return false;
|
|
||||||
if (IsA(node, RowExpr))
|
|
||||||
return false;
|
|
||||||
if (IsA(node, RowCompareExpr))
|
|
||||||
return false;
|
|
||||||
if (IsA(node, CoalesceExpr))
|
|
||||||
return false;
|
|
||||||
if (IsA(node, MinMaxExpr))
|
|
||||||
return false;
|
|
||||||
if (IsA(node, SQLValueFunction))
|
|
||||||
return false;
|
|
||||||
if (IsA(node, XmlExpr))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return expression_tree_walker(node, expression_returns_set_walker,
|
return expression_tree_walker(node, expression_returns_set_walker,
|
||||||
context);
|
context);
|
||||||
|
@ -443,6 +443,14 @@ SELECT int4mul(generate_series(1,2), 10);
|
|||||||
20
|
20
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT generate_series(1,3) IS DISTINCT FROM 2;
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
f
|
||||||
|
t
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
-- but SRFs in function RTEs must be at top level (annoying restriction)
|
-- but SRFs in function RTEs must be at top level (annoying restriction)
|
||||||
SELECT * FROM int4mul(generate_series(1,2), 10);
|
SELECT * FROM int4mul(generate_series(1,2), 10);
|
||||||
ERROR: set-returning functions must appear at top level of FROM
|
ERROR: set-returning functions must appear at top level of FROM
|
||||||
|
@ -98,6 +98,7 @@ VALUES(1, generate_series(1,2));
|
|||||||
|
|
||||||
-- We allow tSRFs that are not at top level
|
-- We allow tSRFs that are not at top level
|
||||||
SELECT int4mul(generate_series(1,2), 10);
|
SELECT int4mul(generate_series(1,2), 10);
|
||||||
|
SELECT generate_series(1,3) IS DISTINCT FROM 2;
|
||||||
|
|
||||||
-- but SRFs in function RTEs must be at top level (annoying restriction)
|
-- but SRFs in function RTEs must be at top level (annoying restriction)
|
||||||
SELECT * FROM int4mul(generate_series(1,2), 10);
|
SELECT * FROM int4mul(generate_series(1,2), 10);
|
||||||
|
Reference in New Issue
Block a user