summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2017-06-14 15:10:05 +0000
committerTom Lane2017-06-14 15:10:05 +0000
commit8e72239e9d961c27f02b242e33fa832c364c7a4b (patch)
tree5060415d99b58597c4b1282b3f9226d9be83aec8
parenta571c7f661a7b601aafcb12196d004cdb8b8cb23 (diff)
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/[email protected]
-rw-r--r--src/backend/nodes/nodeFuncs.c30
-rw-r--r--src/test/regress/expected/tsrf.out8
-rw-r--r--src/test/regress/sql/tsrf.sql1
3 files changed, 10 insertions, 29 deletions
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index 41f3408cfc..5af37a9388 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -694,39 +694,11 @@ expression_returns_set_walker(Node *node, void *context)
/* 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))
return false;
if (IsA(node, WindowFunc))
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,
context);
diff --git a/src/test/regress/expected/tsrf.out b/src/test/regress/expected/tsrf.out
index ef02ba7465..b691abe714 100644
--- a/src/test/regress/expected/tsrf.out
+++ b/src/test/regress/expected/tsrf.out
@@ -443,6 +443,14 @@ SELECT int4mul(generate_series(1,2), 10);
20
(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)
SELECT * FROM int4mul(generate_series(1,2), 10);
ERROR: set-returning functions must appear at top level of FROM
diff --git a/src/test/regress/sql/tsrf.sql b/src/test/regress/sql/tsrf.sql
index 45de099e4d..0be7530beb 100644
--- a/src/test/regress/sql/tsrf.sql
+++ b/src/test/regress/sql/tsrf.sql
@@ -98,6 +98,7 @@ VALUES(1, generate_series(1,2));
-- We allow tSRFs that are not at top level
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)
SELECT * FROM int4mul(generate_series(1,2), 10);