aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/prep/prepunion.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/prep/prepunion.c')
-rw-r--r--src/backend/optimizer/prep/prepunion.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index f004fad1d92..2214920dea4 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -78,7 +78,8 @@ static List *generate_setop_tlist(List *colTypes, List *colCollations,
Index varno,
bool hack_constants,
List *input_tlist,
- List *refnames_tlist);
+ List *refnames_tlist,
+ bool *trivial_tlist);
static List *generate_append_tlist(List *colTypes, List *colCollations,
bool flag,
List *input_tlists,
@@ -226,6 +227,7 @@ recurse_set_operations(Node *setOp, PlannerInfo *root,
Path *subpath;
Path *path;
List *tlist;
+ bool trivial_tlist;
Assert(subquery != NULL);
@@ -254,7 +256,8 @@ recurse_set_operations(Node *setOp, PlannerInfo *root,
rtr->rtindex,
true,
subroot->processed_tlist,
- refnames_tlist);
+ refnames_tlist,
+ &trivial_tlist);
rel->reltarget = create_pathtarget(root, tlist);
/* Return the fully-fledged tlist to caller, too */
@@ -291,6 +294,7 @@ recurse_set_operations(Node *setOp, PlannerInfo *root,
* soon too, likely.)
*/
path = (Path *) create_subqueryscan_path(root, rel, subpath,
+ trivial_tlist,
NIL, NULL);
add_path(rel, path);
@@ -309,6 +313,7 @@ recurse_set_operations(Node *setOp, PlannerInfo *root,
partial_subpath = linitial(final_rel->partial_pathlist);
partial_path = (Path *)
create_subqueryscan_path(root, rel, partial_subpath,
+ trivial_tlist,
NIL, NULL);
add_partial_path(rel, partial_path);
}
@@ -376,6 +381,7 @@ recurse_set_operations(Node *setOp, PlannerInfo *root,
!tlist_same_collations(*pTargetList, colCollations, junkOK))
{
PathTarget *target;
+ bool trivial_tlist;
ListCell *lc;
*pTargetList = generate_setop_tlist(colTypes, colCollations,
@@ -383,7 +389,8 @@ recurse_set_operations(Node *setOp, PlannerInfo *root,
0,
false,
*pTargetList,
- refnames_tlist);
+ refnames_tlist,
+ &trivial_tlist);
target = create_pathtarget(root, *pTargetList);
/* Apply projection to each path */
@@ -1117,6 +1124,7 @@ choose_hashed_setop(PlannerInfo *root, List *groupClauses,
* hack_constants: true to copy up constants (see comments in code)
* input_tlist: targetlist of this node's input node
* refnames_tlist: targetlist to take column names from
+ * trivial_tlist: output parameter, set to true if targetlist is trivial
*/
static List *
generate_setop_tlist(List *colTypes, List *colCollations,
@@ -1124,7 +1132,8 @@ generate_setop_tlist(List *colTypes, List *colCollations,
Index varno,
bool hack_constants,
List *input_tlist,
- List *refnames_tlist)
+ List *refnames_tlist,
+ bool *trivial_tlist)
{
List *tlist = NIL;
int resno = 1;
@@ -1135,6 +1144,8 @@ generate_setop_tlist(List *colTypes, List *colCollations,
TargetEntry *tle;
Node *expr;
+ *trivial_tlist = true; /* until proven differently */
+
forfour(ctlc, colTypes, cclc, colCollations,
itlc, input_tlist, rtlc, refnames_tlist)
{
@@ -1160,6 +1171,9 @@ generate_setop_tlist(List *colTypes, List *colCollations,
* this only at the first level of subquery-scan plans; we don't want
* phony constants appearing in the output tlists of upper-level
* nodes!
+ *
+ * Note that copying a constant doesn't in itself require us to mark
+ * the tlist nontrivial; see trivial_subqueryscan() in setrefs.c.
*/
if (hack_constants && inputtle->expr && IsA(inputtle->expr, Const))
expr = (Node *) inputtle->expr;
@@ -1185,6 +1199,7 @@ generate_setop_tlist(List *colTypes, List *colCollations,
expr,
colType,
"UNION/INTERSECT/EXCEPT");
+ *trivial_tlist = false; /* the coercion makes it not trivial */
}
/*
@@ -1199,9 +1214,12 @@ generate_setop_tlist(List *colTypes, List *colCollations,
* will reach the executor without any further processing.
*/
if (exprCollation(expr) != colColl)
+ {
expr = applyRelabelType(expr,
exprType(expr), exprTypmod(expr), colColl,
COERCE_IMPLICIT_CAST, -1, false);
+ *trivial_tlist = false; /* the relabel makes it not trivial */
+ }
tle = makeTargetEntry((Expr *) expr,
(AttrNumber) resno++,
@@ -1234,6 +1252,7 @@ generate_setop_tlist(List *colTypes, List *colCollations,
pstrdup("flag"),
true);
tlist = lappend(tlist, tle);
+ *trivial_tlist = false; /* the extra entry makes it not trivial */
}
return tlist;