diff --git a/src/backend/nodes/nodeFuncs.c src/backend/nodes/nodeFuncs.c index 54b3dcff3ec..0435d666cbf 100644 --- a/src/backend/nodes/nodeFuncs.c +++ src/backend/nodes/nodeFuncs.c @@ -2419,21 +2419,40 @@ range_table_walker(List *rtable, Node * expression_tree_mutator(Node *node, Node *(*mutator) (), - void *context) + void *context, + int flags) { /* * The mutator has already decided not to modify the current node, but we * must call the mutator for any sub-nodes. */ -#define FLATCOPY(newnode, node, nodetype) \ - ( (newnode) = (nodetype *) palloc(sizeof(nodetype)), \ - memcpy((newnode), (node), sizeof(nodetype)) ) - -#define CHECKFLATCOPY(newnode, node, nodetype) \ - ( AssertMacro(IsA((node), nodetype)), \ - (newnode) = (nodetype *) palloc(sizeof(nodetype)), \ - memcpy((newnode), (node), sizeof(nodetype)) ) +#define FLATCOPY(newnode, node, nodetype, flags) \ + do { \ + if ((flags) & QTW_DONT_COPY_DEFAULT) \ + { \ + (newnode) = (node); \ + } \ + else \ + { \ + (newnode) = (nodetype *) palloc(sizeof(nodetype)); \ + memcpy((newnode), (node), sizeof(nodetype)); \ + } \ + } while(0) + +#define CHECKFLATCOPY(newnode, node, nodetype, flags) \ + do { \ + AssertMacro(IsA((node), nodetype)); \ + if ((flags) & QTW_DONT_COPY_DEFAULT) \ + { \ + (newnode) = (node); \ + } \ + else \ + { \ + (newnode) = (nodetype *) palloc(sizeof(nodetype)); \ + memcpy((newnode), (node), sizeof(nodetype)); \ + } \ + } while(0) #define MUTATE(newfield, oldfield, fieldtype) \ ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) ) @@ -2456,7 +2475,7 @@ expression_tree_mutator(Node *node, Var *var = (Var *) node; Var *newnode; - FLATCOPY(newnode, var, Var); + FLATCOPY(newnode, var, Var, flags); return (Node *) newnode; } break; @@ -2465,7 +2484,7 @@ expression_tree_mutator(Node *node, Const *oldnode = (Const *) node; Const *newnode; - FLATCOPY(newnode, oldnode, Const); + FLATCOPY(newnode, oldnode, Const, flags); /* XXX we don't bother with datumCopy; should we? */ return (Node *) newnode; } @@ -2485,7 +2504,7 @@ expression_tree_mutator(Node *node, WithCheckOption *wco = (WithCheckOption *) node; WithCheckOption *newnode; - FLATCOPY(newnode, wco, WithCheckOption); + FLATCOPY(newnode, wco, WithCheckOption, flags); MUTATE(newnode->qual, wco->qual, Node *); return (Node *) newnode; } @@ -2494,7 +2513,7 @@ expression_tree_mutator(Node *node, Aggref *aggref = (Aggref *) node; Aggref *newnode; - FLATCOPY(newnode, aggref, Aggref); + FLATCOPY(newnode, aggref, Aggref, flags); /* assume mutation doesn't change types of arguments */ newnode->aggargtypes = list_copy(aggref->aggargtypes); MUTATE(newnode->aggdirectargs, aggref->aggdirectargs, List *); @@ -2510,7 +2529,7 @@ expression_tree_mutator(Node *node, GroupingFunc *grouping = (GroupingFunc *) node; GroupingFunc *newnode; - FLATCOPY(newnode, grouping, GroupingFunc); + FLATCOPY(newnode, grouping, GroupingFunc, flags); MUTATE(newnode->args, grouping->args, List *); /* @@ -2533,7 +2552,7 @@ expression_tree_mutator(Node *node, WindowFunc *wfunc = (WindowFunc *) node; WindowFunc *newnode; - FLATCOPY(newnode, wfunc, WindowFunc); + FLATCOPY(newnode, wfunc, WindowFunc, flags); MUTATE(newnode->args, wfunc->args, List *); MUTATE(newnode->aggfilter, wfunc->aggfilter, Expr *); return (Node *) newnode; @@ -2544,7 +2563,7 @@ expression_tree_mutator(Node *node, ArrayRef *arrayref = (ArrayRef *) node; ArrayRef *newnode; - FLATCOPY(newnode, arrayref, ArrayRef); + FLATCOPY(newnode, arrayref, ArrayRef, flags); MUTATE(newnode->refupperindexpr, arrayref->refupperindexpr, List *); MUTATE(newnode->reflowerindexpr, arrayref->reflowerindexpr, @@ -2561,7 +2580,7 @@ expression_tree_mutator(Node *node, FuncExpr *expr = (FuncExpr *) node; FuncExpr *newnode; - FLATCOPY(newnode, expr, FuncExpr); + FLATCOPY(newnode, expr, FuncExpr, flags); MUTATE(newnode->args, expr->args, List *); return (Node *) newnode; } @@ -2571,7 +2590,7 @@ expression_tree_mutator(Node *node, NamedArgExpr *nexpr = (NamedArgExpr *) node; NamedArgExpr *newnode; - FLATCOPY(newnode, nexpr, NamedArgExpr); + FLATCOPY(newnode, nexpr, NamedArgExpr, flags); MUTATE(newnode->arg, nexpr->arg, Expr *); return (Node *) newnode; } @@ -2581,7 +2600,7 @@ expression_tree_mutator(Node *node, OpExpr *expr = (OpExpr *) node; OpExpr *newnode; - FLATCOPY(newnode, expr, OpExpr); + FLATCOPY(newnode, expr, OpExpr, flags & ~QTW_DONT_COPY_DEFAULT); MUTATE(newnode->args, expr->args, List *); return (Node *) newnode; } @@ -2591,7 +2610,7 @@ expression_tree_mutator(Node *node, DistinctExpr *expr = (DistinctExpr *) node; DistinctExpr *newnode; - FLATCOPY(newnode, expr, DistinctExpr); + FLATCOPY(newnode, expr, DistinctExpr, flags); MUTATE(newnode->args, expr->args, List *); return (Node *) newnode; } @@ -2601,7 +2620,7 @@ expression_tree_mutator(Node *node, NullIfExpr *expr = (NullIfExpr *) node; NullIfExpr *newnode; - FLATCOPY(newnode, expr, NullIfExpr); + FLATCOPY(newnode, expr, NullIfExpr, flags); MUTATE(newnode->args, expr->args, List *); return (Node *) newnode; } @@ -2611,7 +2630,7 @@ expression_tree_mutator(Node *node, ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node; ScalarArrayOpExpr *newnode; - FLATCOPY(newnode, expr, ScalarArrayOpExpr); + FLATCOPY(newnode, expr, ScalarArrayOpExpr, flags); MUTATE(newnode->args, expr->args, List *); return (Node *) newnode; } @@ -2621,7 +2640,7 @@ expression_tree_mutator(Node *node, BoolExpr *expr = (BoolExpr *) node; BoolExpr *newnode; - FLATCOPY(newnode, expr, BoolExpr); + FLATCOPY(newnode, expr, BoolExpr, flags); MUTATE(newnode->args, expr->args, List *); return (Node *) newnode; } @@ -2631,7 +2650,7 @@ expression_tree_mutator(Node *node, SubLink *sublink = (SubLink *) node; SubLink *newnode; - FLATCOPY(newnode, sublink, SubLink); + FLATCOPY(newnode, sublink, SubLink, flags); MUTATE(newnode->testexpr, sublink->testexpr, Node *); /* @@ -2647,7 +2666,7 @@ expression_tree_mutator(Node *node, SubPlan *subplan = (SubPlan *) node; SubPlan *newnode; - FLATCOPY(newnode, subplan, SubPlan); + FLATCOPY(newnode, subplan, SubPlan, flags); /* transform testexpr */ MUTATE(newnode->testexpr, subplan->testexpr, Node *); /* transform args list (params to be passed to subplan) */ @@ -2661,7 +2680,7 @@ expression_tree_mutator(Node *node, AlternativeSubPlan *asplan = (AlternativeSubPlan *) node; AlternativeSubPlan *newnode; - FLATCOPY(newnode, asplan, AlternativeSubPlan); + FLATCOPY(newnode, asplan, AlternativeSubPlan, flags); MUTATE(newnode->subplans, asplan->subplans, List *); return (Node *) newnode; } @@ -2671,7 +2690,7 @@ expression_tree_mutator(Node *node, FieldSelect *fselect = (FieldSelect *) node; FieldSelect *newnode; - FLATCOPY(newnode, fselect, FieldSelect); + FLATCOPY(newnode, fselect, FieldSelect, flags); MUTATE(newnode->arg, fselect->arg, Expr *); return (Node *) newnode; } @@ -2681,7 +2700,7 @@ expression_tree_mutator(Node *node, FieldStore *fstore = (FieldStore *) node; FieldStore *newnode; - FLATCOPY(newnode, fstore, FieldStore); + FLATCOPY(newnode, fstore, FieldStore, flags); MUTATE(newnode->arg, fstore->arg, Expr *); MUTATE(newnode->newvals, fstore->newvals, List *); newnode->fieldnums = list_copy(fstore->fieldnums); @@ -2693,7 +2712,7 @@ expression_tree_mutator(Node *node, RelabelType *relabel = (RelabelType *) node; RelabelType *newnode; - FLATCOPY(newnode, relabel, RelabelType); + FLATCOPY(newnode, relabel, RelabelType, flags); MUTATE(newnode->arg, relabel->arg, Expr *); return (Node *) newnode; } @@ -2703,7 +2722,7 @@ expression_tree_mutator(Node *node, CoerceViaIO *iocoerce = (CoerceViaIO *) node; CoerceViaIO *newnode; - FLATCOPY(newnode, iocoerce, CoerceViaIO); + FLATCOPY(newnode, iocoerce, CoerceViaIO, flags); MUTATE(newnode->arg, iocoerce->arg, Expr *); return (Node *) newnode; } @@ -2713,7 +2732,7 @@ expression_tree_mutator(Node *node, ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; ArrayCoerceExpr *newnode; - FLATCOPY(newnode, acoerce, ArrayCoerceExpr); + FLATCOPY(newnode, acoerce, ArrayCoerceExpr, flags); MUTATE(newnode->arg, acoerce->arg, Expr *); MUTATE(newnode->elemexpr, acoerce->elemexpr, Expr *); return (Node *) newnode; @@ -2724,7 +2743,7 @@ expression_tree_mutator(Node *node, ConvertRowtypeExpr *convexpr = (ConvertRowtypeExpr *) node; ConvertRowtypeExpr *newnode; - FLATCOPY(newnode, convexpr, ConvertRowtypeExpr); + FLATCOPY(newnode, convexpr, ConvertRowtypeExpr, flags); MUTATE(newnode->arg, convexpr->arg, Expr *); return (Node *) newnode; } @@ -2734,7 +2753,7 @@ expression_tree_mutator(Node *node, CollateExpr *collate = (CollateExpr *) node; CollateExpr *newnode; - FLATCOPY(newnode, collate, CollateExpr); + FLATCOPY(newnode, collate, CollateExpr, flags); MUTATE(newnode->arg, collate->arg, Expr *); return (Node *) newnode; } @@ -2744,7 +2763,7 @@ expression_tree_mutator(Node *node, CaseExpr *caseexpr = (CaseExpr *) node; CaseExpr *newnode; - FLATCOPY(newnode, caseexpr, CaseExpr); + FLATCOPY(newnode, caseexpr, CaseExpr, flags); MUTATE(newnode->arg, caseexpr->arg, Expr *); MUTATE(newnode->args, caseexpr->args, List *); MUTATE(newnode->defresult, caseexpr->defresult, Expr *); @@ -2756,7 +2775,7 @@ expression_tree_mutator(Node *node, CaseWhen *casewhen = (CaseWhen *) node; CaseWhen *newnode; - FLATCOPY(newnode, casewhen, CaseWhen); + FLATCOPY(newnode, casewhen, CaseWhen, flags); MUTATE(newnode->expr, casewhen->expr, Expr *); MUTATE(newnode->result, casewhen->result, Expr *); return (Node *) newnode; @@ -2767,7 +2786,7 @@ expression_tree_mutator(Node *node, ArrayExpr *arrayexpr = (ArrayExpr *) node; ArrayExpr *newnode; - FLATCOPY(newnode, arrayexpr, ArrayExpr); + FLATCOPY(newnode, arrayexpr, ArrayExpr, flags); MUTATE(newnode->elements, arrayexpr->elements, List *); return (Node *) newnode; } @@ -2777,7 +2796,7 @@ expression_tree_mutator(Node *node, RowExpr *rowexpr = (RowExpr *) node; RowExpr *newnode; - FLATCOPY(newnode, rowexpr, RowExpr); + FLATCOPY(newnode, rowexpr, RowExpr, flags); MUTATE(newnode->args, rowexpr->args, List *); /* Assume colnames needn't be duplicated */ return (Node *) newnode; @@ -2788,7 +2807,7 @@ expression_tree_mutator(Node *node, RowCompareExpr *rcexpr = (RowCompareExpr *) node; RowCompareExpr *newnode; - FLATCOPY(newnode, rcexpr, RowCompareExpr); + FLATCOPY(newnode, rcexpr, RowCompareExpr, flags); MUTATE(newnode->largs, rcexpr->largs, List *); MUTATE(newnode->rargs, rcexpr->rargs, List *); return (Node *) newnode; @@ -2799,7 +2818,7 @@ expression_tree_mutator(Node *node, CoalesceExpr *coalesceexpr = (CoalesceExpr *) node; CoalesceExpr *newnode; - FLATCOPY(newnode, coalesceexpr, CoalesceExpr); + FLATCOPY(newnode, coalesceexpr, CoalesceExpr, flags); MUTATE(newnode->args, coalesceexpr->args, List *); return (Node *) newnode; } @@ -2809,7 +2828,7 @@ expression_tree_mutator(Node *node, MinMaxExpr *minmaxexpr = (MinMaxExpr *) node; MinMaxExpr *newnode; - FLATCOPY(newnode, minmaxexpr, MinMaxExpr); + FLATCOPY(newnode, minmaxexpr, MinMaxExpr, flags); MUTATE(newnode->args, minmaxexpr->args, List *); return (Node *) newnode; } @@ -2819,7 +2838,7 @@ expression_tree_mutator(Node *node, XmlExpr *xexpr = (XmlExpr *) node; XmlExpr *newnode; - FLATCOPY(newnode, xexpr, XmlExpr); + FLATCOPY(newnode, xexpr, XmlExpr, flags); MUTATE(newnode->named_args, xexpr->named_args, List *); /* assume mutator does not care about arg_names */ MUTATE(newnode->args, xexpr->args, List *); @@ -2831,7 +2850,7 @@ expression_tree_mutator(Node *node, NullTest *ntest = (NullTest *) node; NullTest *newnode; - FLATCOPY(newnode, ntest, NullTest); + FLATCOPY(newnode, ntest, NullTest, flags); MUTATE(newnode->arg, ntest->arg, Expr *); return (Node *) newnode; } @@ -2841,7 +2860,7 @@ expression_tree_mutator(Node *node, BooleanTest *btest = (BooleanTest *) node; BooleanTest *newnode; - FLATCOPY(newnode, btest, BooleanTest); + FLATCOPY(newnode, btest, BooleanTest, flags); MUTATE(newnode->arg, btest->arg, Expr *); return (Node *) newnode; } @@ -2851,7 +2870,7 @@ expression_tree_mutator(Node *node, CoerceToDomain *ctest = (CoerceToDomain *) node; CoerceToDomain *newnode; - FLATCOPY(newnode, ctest, CoerceToDomain); + FLATCOPY(newnode, ctest, CoerceToDomain, flags); MUTATE(newnode->arg, ctest->arg, Expr *); return (Node *) newnode; } @@ -2861,7 +2880,7 @@ expression_tree_mutator(Node *node, TargetEntry *targetentry = (TargetEntry *) node; TargetEntry *newnode; - FLATCOPY(newnode, targetentry, TargetEntry); + FLATCOPY(newnode, targetentry, TargetEntry, flags & ~QTW_DONT_COPY_DEFAULT); MUTATE(newnode->expr, targetentry->expr, Expr *); return (Node *) newnode; } @@ -2874,7 +2893,7 @@ expression_tree_mutator(Node *node, WindowClause *wc = (WindowClause *) node; WindowClause *newnode; - FLATCOPY(newnode, wc, WindowClause); + FLATCOPY(newnode, wc, WindowClause, flags); MUTATE(newnode->partitionClause, wc->partitionClause, List *); MUTATE(newnode->orderClause, wc->orderClause, List *); MUTATE(newnode->startOffset, wc->startOffset, Node *); @@ -2887,7 +2906,7 @@ expression_tree_mutator(Node *node, CommonTableExpr *cte = (CommonTableExpr *) node; CommonTableExpr *newnode; - FLATCOPY(newnode, cte, CommonTableExpr); + FLATCOPY(newnode, cte, CommonTableExpr, flags); /* * Also invoke the mutator on the CTE's Query node, so it can @@ -2922,7 +2941,7 @@ expression_tree_mutator(Node *node, FromExpr *from = (FromExpr *) node; FromExpr *newnode; - FLATCOPY(newnode, from, FromExpr); + FLATCOPY(newnode, from, FromExpr, flags); MUTATE(newnode->fromlist, from->fromlist, List *); MUTATE(newnode->quals, from->quals, Node *); return (Node *) newnode; @@ -2933,7 +2952,7 @@ expression_tree_mutator(Node *node, OnConflictExpr *oc = (OnConflictExpr *) node; OnConflictExpr *newnode; - FLATCOPY(newnode, oc, OnConflictExpr); + FLATCOPY(newnode, oc, OnConflictExpr, flags); MUTATE(newnode->arbiterElems, oc->arbiterElems, List *); MUTATE(newnode->arbiterWhere, oc->arbiterWhere, Node *); MUTATE(newnode->onConflictSet, oc->onConflictSet, List *); @@ -2948,7 +2967,7 @@ expression_tree_mutator(Node *node, PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node; PartitionPruneStepOp *newnode; - FLATCOPY(newnode, opstep, PartitionPruneStepOp); + FLATCOPY(newnode, opstep, PartitionPruneStepOp, flags); MUTATE(newnode->exprs, opstep->exprs, List *); return (Node *) newnode; @@ -2962,7 +2981,7 @@ expression_tree_mutator(Node *node, JoinExpr *join = (JoinExpr *) node; JoinExpr *newnode; - FLATCOPY(newnode, join, JoinExpr); + FLATCOPY(newnode, join, JoinExpr, flags); MUTATE(newnode->larg, join->larg, Node *); MUTATE(newnode->rarg, join->rarg, Node *); MUTATE(newnode->quals, join->quals, Node *); @@ -2975,7 +2994,7 @@ expression_tree_mutator(Node *node, SetOperationStmt *setop = (SetOperationStmt *) node; SetOperationStmt *newnode; - FLATCOPY(newnode, setop, SetOperationStmt); + FLATCOPY(newnode, setop, SetOperationStmt, flags); MUTATE(newnode->larg, setop->larg, Node *); MUTATE(newnode->rarg, setop->rarg, Node *); /* We do not mutate groupClauses by default */ @@ -2987,7 +3006,7 @@ expression_tree_mutator(Node *node, PlaceHolderVar *phv = (PlaceHolderVar *) node; PlaceHolderVar *newnode; - FLATCOPY(newnode, phv, PlaceHolderVar); + FLATCOPY(newnode, phv, PlaceHolderVar, flags); MUTATE(newnode->phexpr, phv->phexpr, Expr *); /* Assume we need not copy the relids bitmapset */ return (Node *) newnode; @@ -2998,7 +3017,7 @@ expression_tree_mutator(Node *node, InferenceElem *inferenceelemdexpr = (InferenceElem *) node; InferenceElem *newnode; - FLATCOPY(newnode, inferenceelemdexpr, InferenceElem); + FLATCOPY(newnode, inferenceelemdexpr, InferenceElem, flags); MUTATE(newnode->expr, newnode->expr, Node *); return (Node *) newnode; } @@ -3008,7 +3027,7 @@ expression_tree_mutator(Node *node, AppendRelInfo *appinfo = (AppendRelInfo *) node; AppendRelInfo *newnode; - FLATCOPY(newnode, appinfo, AppendRelInfo); + FLATCOPY(newnode, appinfo, AppendRelInfo, flags); MUTATE(newnode->translated_vars, appinfo->translated_vars, List *); return (Node *) newnode; } @@ -3018,7 +3037,7 @@ expression_tree_mutator(Node *node, PlaceHolderInfo *phinfo = (PlaceHolderInfo *) node; PlaceHolderInfo *newnode; - FLATCOPY(newnode, phinfo, PlaceHolderInfo); + FLATCOPY(newnode, phinfo, PlaceHolderInfo, flags); MUTATE(newnode->ph_var, phinfo->ph_var, PlaceHolderVar *); /* Assume we need not copy the relids bitmapsets */ return (Node *) newnode; @@ -3029,7 +3048,7 @@ expression_tree_mutator(Node *node, RangeTblFunction *rtfunc = (RangeTblFunction *) node; RangeTblFunction *newnode; - FLATCOPY(newnode, rtfunc, RangeTblFunction); + FLATCOPY(newnode, rtfunc, RangeTblFunction, flags); MUTATE(newnode->funcexpr, rtfunc->funcexpr, Node *); /* Assume we need not copy the coldef info lists */ return (Node *) newnode; @@ -3040,7 +3059,7 @@ expression_tree_mutator(Node *node, TableSampleClause *tsc = (TableSampleClause *) node; TableSampleClause *newnode; - FLATCOPY(newnode, tsc, TableSampleClause); + FLATCOPY(newnode, tsc, TableSampleClause, flags); MUTATE(newnode->args, tsc->args, List *); MUTATE(newnode->repeatable, tsc->repeatable, Expr *); return (Node *) newnode; @@ -3051,7 +3070,7 @@ expression_tree_mutator(Node *node, TableFunc *tf = (TableFunc *) node; TableFunc *newnode; - FLATCOPY(newnode, tf, TableFunc); + FLATCOPY(newnode, tf, TableFunc, flags); MUTATE(newnode->ns_uris, tf->ns_uris, List *); MUTATE(newnode->docexpr, tf->docexpr, Node *); MUTATE(newnode->rowexpr, tf->rowexpr, Node *); @@ -3101,7 +3120,7 @@ query_tree_mutator(Query *query, { Query *newquery; - FLATCOPY(newquery, query, Query); + FLATCOPY(newquery, query, Query, flags); query = newquery; } @@ -3142,7 +3161,7 @@ range_table_mutator(List *rtable, RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt); RangeTblEntry *newrte; - FLATCOPY(newrte, rte, RangeTblEntry); + FLATCOPY(newrte, rte, RangeTblEntry, flags); switch (rte->rtekind) { case RTE_RELATION: @@ -3157,7 +3176,7 @@ range_table_mutator(List *rtable, case RTE_SUBQUERY: if (!(flags & QTW_IGNORE_RT_SUBQUERIES)) { - CHECKFLATCOPY(newrte->subquery, rte->subquery, Query); + CHECKFLATCOPY(newrte->subquery, rte->subquery, Query, flags); MUTATE(newrte->subquery, newrte->subquery, Query *); } else diff --git a/src/backend/optimizer/plan/createplan.c src/backend/optimizer/plan/createplan.c index b6dd080565c..5ac54b3d014 100644 --- a/src/backend/optimizer/plan/createplan.c +++ src/backend/optimizer/plan/createplan.c @@ -4329,7 +4329,8 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root) } return expression_tree_mutator(node, replace_nestloop_params_mutator, - (void *) root); + (void *) root, + 0); } /* diff --git a/src/backend/optimizer/plan/setrefs.c src/backend/optimizer/plan/setrefs.c index ea7b1ca1d7c..3fd4035a654 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ src/backend/optimizer/plan/setrefs.c @@ -1572,7 +1572,7 @@ fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context) } fix_expr_common(context->root, node); return expression_tree_mutator(node, fix_scan_expr_mutator, - (void *) context); + (void *) context, 0); } static bool @@ -1896,7 +1896,7 @@ convert_combining_aggrefs(Node *node, void *context) return (Node *) parent_agg; } return expression_tree_mutator(node, convert_combining_aggrefs, - (void *) context); + (void *) context, 0); } /* @@ -2342,7 +2342,7 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context) fix_expr_common(context->root, node); return expression_tree_mutator(node, fix_join_expr_mutator, - (void *) context); + (void *) context, 0); } /* @@ -2463,7 +2463,7 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context) fix_expr_common(context->root, node); return expression_tree_mutator(node, fix_upper_expr_mutator, - (void *) context); + (void *) context, 0); } /* diff --git a/src/backend/optimizer/plan/subselect.c src/backend/optimizer/plan/subselect.c index d28323f03c3..541b56c7460 100644 --- a/src/backend/optimizer/plan/subselect.c +++ src/backend/optimizer/plan/subselect.c @@ -709,7 +709,7 @@ convert_testexpr_mutator(Node *node, } return expression_tree_mutator(node, convert_testexpr_mutator, - (void *) context); + (void *) context, 0); } /* @@ -1619,7 +1619,7 @@ replace_correlation_vars_mutator(Node *node, PlannerInfo *root) } return expression_tree_mutator(node, replace_correlation_vars_mutator, - (void *) root); + (void *) root, 0); } /* @@ -1761,7 +1761,7 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context) return expression_tree_mutator(node, process_sublinks_mutator, - (void *) &locContext); + (void *) &locContext, 0); } /* diff --git a/src/backend/optimizer/prep/prepunion.c src/backend/optimizer/prep/prepunion.c index 59cce11b7f0..6ac20826865 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ src/backend/optimizer/prep/prepunion.c @@ -2238,7 +2238,7 @@ adjust_appendrel_attrs_mutator(Node *node, j = (JoinExpr *) expression_tree_mutator(node, adjust_appendrel_attrs_mutator, - (void *) context); + (void *) context, 0); /* now fix JoinExpr's rtindex (probably never happens) */ for (cnt = 0; cnt < nappinfos; cnt++) { @@ -2259,7 +2259,7 @@ adjust_appendrel_attrs_mutator(Node *node, phv = (PlaceHolderVar *) expression_tree_mutator(node, adjust_appendrel_attrs_mutator, - (void *) context); + (void *) context, 0); /* now fix PlaceHolderVar's relid sets */ if (phv->phlevelsup == 0) phv->phrels = adjust_child_relids(phv->phrels, context->nappinfos, @@ -2341,7 +2341,7 @@ adjust_appendrel_attrs_mutator(Node *node, Assert(!IsA(node, Query)); return expression_tree_mutator(node, adjust_appendrel_attrs_mutator, - (void *) context); + (void *) context, 0); } /* diff --git a/src/backend/optimizer/util/clauses.c src/backend/optimizer/util/clauses.c index 1daafe1ea72..a7471d61b1f 100644 --- a/src/backend/optimizer/util/clauses.c +++ src/backend/optimizer/util/clauses.c @@ -2575,7 +2575,7 @@ estimate_expression_value(PlannerInfo *root, Node *node) */ #define ece_generic_processing(node) \ expression_tree_mutator((Node *) (node), eval_const_expressions_mutator, \ - (void *) context) + (void *) context, 0) /* * Check whether all arguments of the given node were reduced to Consts. @@ -2703,7 +2703,7 @@ eval_const_expressions_mutator(Node *node, args = (List *) expression_tree_mutator((Node *) args, eval_const_expressions_mutator, - (void *) context); + (void *) context, 0); /* ... and the filter expression, which isn't */ aggfilter = (Expr *) eval_const_expressions_mutator((Node *) expr->aggfilter, @@ -2847,7 +2847,7 @@ eval_const_expressions_mutator(Node *node, */ args = (List *) expression_tree_mutator((Node *) expr->args, eval_const_expressions_mutator, - (void *) context); + (void *) context, 0); /* * We must do our own check for NULLs because DistinctExpr has @@ -4141,7 +4141,7 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod, args = expand_function_arguments(args, result_type, func_tuple); args = (List *) expression_tree_mutator((Node *) args, eval_const_expressions_mutator, - (void *) context); + (void *) context, 0); /* Argument processing done, give it back to the caller */ *args_p = args; } @@ -4899,7 +4899,7 @@ substitute_actual_parameters_mutator(Node *node, return list_nth(context->args, param->paramid - 1); } return expression_tree_mutator(node, substitute_actual_parameters_mutator, - (void *) context); + (void *) context, 0); } /* @@ -5363,7 +5363,7 @@ substitute_actual_srf_parameters_mutator(Node *node, } return expression_tree_mutator(node, substitute_actual_srf_parameters_mutator, - (void *) context); + (void *) context, 0); } /* diff --git a/src/backend/optimizer/util/var.c src/backend/optimizer/util/var.c index b16b1e46562..ba42bed6363 100644 --- a/src/backend/optimizer/util/var.c +++ src/backend/optimizer/util/var.c @@ -779,7 +779,7 @@ flatten_join_alias_vars_mutator(Node *node, phv = (PlaceHolderVar *) expression_tree_mutator(node, flatten_join_alias_vars_mutator, - (void *) context); + (void *) context, 0); /* now fix PlaceHolderVar's relid sets */ if (phv->phlevelsup == context->sublevels_up) { @@ -815,7 +815,7 @@ flatten_join_alias_vars_mutator(Node *node, Assert(!IsA(node, MinMaxAggInfo)); return expression_tree_mutator(node, flatten_join_alias_vars_mutator, - (void *) context); + (void *) context, 0); } /* diff --git a/src/backend/parser/parse_clause.c src/backend/parser/parse_clause.c index d6b93f55dfd..f47baa09149 100644 --- a/src/backend/parser/parse_clause.c +++ src/backend/parser/parse_clause.c @@ -327,6 +327,9 @@ extractRemainingColumns(List *common_colnames, } } + list_free(*res_colnames); + list_free(*res_colvars); + *res_colnames = new_colnames; *res_colvars = new_colvars; } @@ -1271,6 +1274,7 @@ transformFromClauseItem(ParseState *pstate, Node *n, &r_namespace); /* Remove the left-side RTEs from the namespace list again */ + pstate->p_namespace = list_truncate(pstate->p_namespace, sv_namespace_length); diff --git a/src/backend/parser/parse_relation.c src/backend/parser/parse_relation.c index bf5df26009a..b3d8356191e 100644 --- a/src/backend/parser/parse_relation.c +++ src/backend/parser/parse_relation.c @@ -1805,7 +1805,6 @@ addRangeTableEntryForJoin(ParseState *pstate, { RangeTblEntry *rte = makeNode(RangeTblEntry); Alias *eref; - int numaliases; Assert(pstate != NULL); @@ -1826,13 +1825,31 @@ addRangeTableEntryForJoin(ParseState *pstate, rte->joinaliasvars = aliasvars; rte->alias = alias; - eref = alias ? copyObject(alias) : makeAlias("unnamed_join", NIL); - numaliases = list_length(eref->colnames); - /* fill in any unspecified alias columns */ - if (numaliases < list_length(colnames)) - eref->colnames = list_concat(eref->colnames, - list_copy_tail(colnames, numaliases)); + if (alias) + { + int numaliases; + + eref = copyObject(alias); + + numaliases = list_length(eref->colnames); + + if (numaliases == 0) + { + eref->colnames = colnames; + } + else if (numaliases > 0 && numaliases < list_length(colnames)) + { + eref->colnames = list_concat(eref->colnames, + list_copy_tail(colnames, numaliases)); + list_free(colnames); + } + } + else + { + eref = makeAlias("unnamed_join", NIL); + eref->colnames = colnames; + } rte->eref = eref; @@ -2408,8 +2425,11 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up, { char *label = strVal(lfirst(colname)); - *colnames = lappend(*colnames, - makeString(pstrdup(label))); + /* + * Assume label is already pstrdup'ed somewhere, so + * don't duplicate it again + */ + *colnames = lappend(*colnames, makeString(label)); } if (colvars) diff --git a/src/backend/rewrite/rewriteManip.c src/backend/rewrite/rewriteManip.c index f1f4212b5df..af1d5689d47 100644 --- a/src/backend/rewrite/rewriteManip.c +++ src/backend/rewrite/rewriteManip.c @@ -1112,7 +1112,7 @@ replace_rte_variables(Node *node, int target_varno, int sublevels_up, result = query_or_expression_tree_mutator(node, replace_rte_variables_mutator, (void *) &context, - 0); + QTW_DONT_COPY_DEFAULT); if (context.inserted_sublink) { @@ -1182,14 +1182,15 @@ replace_rte_variables_mutator(Node *node, newnode = query_tree_mutator((Query *) node, replace_rte_variables_mutator, (void *) context, - 0); + QTW_DONT_COPY_DEFAULT); newnode->hasSubLinks |= context->inserted_sublink; context->inserted_sublink = save_inserted_sublink; context->sublevels_up--; return (Node *) newnode; } - return expression_tree_mutator(node, replace_rte_variables_mutator, - (void *) context); + + return expression_tree_mutator(node, replace_rte_variables_mutator, + (void *) context, QTW_DONT_COPY_DEFAULT); } @@ -1344,7 +1345,7 @@ map_variable_attnos_mutator(Node *node, return (Node *) newnode; } return expression_tree_mutator(node, map_variable_attnos_mutator, - (void *) context); + (void *) context, 0); } Node * diff --git a/src/include/nodes/nodeFuncs.h src/include/nodes/nodeFuncs.h index 849f34d2a8e..37e0dc4b180 100644 --- a/src/include/nodes/nodeFuncs.h +++ src/include/nodes/nodeFuncs.h @@ -24,6 +24,7 @@ #define QTW_IGNORE_RANGE_TABLE 0x08 /* skip rangetable entirely */ #define QTW_EXAMINE_RTES 0x10 /* examine RTEs */ #define QTW_DONT_COPY_QUERY 0x20 /* do not copy top Query */ +#define QTW_DONT_COPY_DEFAULT 0x40 /* only custom mutator will copy */ /* callback function for check_functions_in_node */ typedef bool (*check_function_callback) (Oid func_id, void *context); @@ -53,7 +54,7 @@ extern bool check_functions_in_node(Node *node, check_function_callback checker, extern bool expression_tree_walker(Node *node, bool (*walker) (), void *context); extern Node *expression_tree_mutator(Node *node, Node *(*mutator) (), - void *context); + void *context, int flags); extern bool query_tree_walker(Query *query, bool (*walker) (), void *context, int flags);