summaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2019-09-24 12:11:32 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2019-09-24 12:11:32 -0400
commita9ae99d0190960ce2d3dd3e5f10e7f4adc3cf203 (patch)
tree39d15b08493f95a414acab4d3282275e5364c368 /src/backend/optimizer
parent6d05086c0a79e50d8e91ed953626ec7280cd2481 (diff)
Prevent bogus pullup of constant-valued functions returning composite.
Fix an oversight in commit 7266d0997: as it stood, the code failed when a function-in-FROM returns composite and can be simplified to a composite constant. For the moment, just test for composite result and abandon pullup if we see one. To make it actually work, we'd have to decompose the composite constant into per-column constants; which is surely do-able, but I'm not convinced it's worth the code space. Per report from Raúl Marín Rodríguez. Discussion: https://postgr.es/m/CAM6_UM4isP+buRA5sWodO_MUEgutms-KDfnkwGmryc5DGj9XuQ@mail.gmail.com
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/prep/prepjointree.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index d13cb582272..f489f140e37 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -26,6 +26,7 @@
#include "postgres.h"
#include "catalog/pg_type.h"
+#include "funcapi.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
@@ -1683,6 +1684,9 @@ pull_up_constant_function(PlannerInfo *root, Node *jtnode,
{
Query *parse = root->parse;
RangeTblFunction *rtf;
+ TypeFuncClass functypclass;
+ Oid funcrettype;
+ TupleDesc tupdesc;
pullup_replace_vars_context rvcontext;
/* Fail if the RTE has ORDINALITY - we don't implement that here. */
@@ -1696,6 +1700,20 @@ pull_up_constant_function(PlannerInfo *root, Node *jtnode,
if (!IsA(rtf->funcexpr, Const))
return jtnode;
+ /*
+ * If the function's result is not a scalar, we punt. In principle we
+ * could break the composite constant value apart into per-column
+ * constants, but for now it seems not worth the work.
+ */
+ if (rtf->funccolcount != 1)
+ return jtnode; /* definitely composite */
+
+ functypclass = get_expr_result_type(rtf->funcexpr,
+ &funcrettype,
+ &tupdesc);
+ if (functypclass != TYPEFUNC_SCALAR)
+ return jtnode; /* must be a one-column composite type */
+
/* Create context for applying pullup_replace_vars */
rvcontext.root = root;
rvcontext.targetlist = list_make1(makeTargetEntry((Expr *) rtf->funcexpr,