I wrote: > Ugh. I wonder if we can get away with declaring the walker arguments > as something like "bool (*walker) (Node *, void *)" without having > to change all the actual walkers to be exactly that signature. > Having to insert casts in the walkers would be a major pain-in-the-butt.
No joy on that: both gcc and clang want the walkers to be declared as taking exactly "void *". Attached is an incomplete POC patch that suppresses these warnings in nodeFuncs.c itself and in costsize.c, which I selected at random as a typical caller. I'll push forward with converting the other call sites if this way seems good to people. In nodeFuncs.c, we can hide the newly-required casts inside macros; indeed, the mutators barely need any changes because they already had MUTATE() macros that contained casts. So on that side, it feels to me that this is actually a bit nicer than before. For the callers, we can either do it as I did below: static bool -cost_qual_eval_walker(Node *node, cost_qual_eval_context *context) +cost_qual_eval_walker(Node *node, void *ctx) { + cost_qual_eval_context *context = (cost_qual_eval_context *) ctx; + if (node == NULL) return false; or perhaps like this: static bool -cost_qual_eval_walker(Node *node, cost_qual_eval_context *context) +cost_qual_eval_walker(Node *node, void *context) { + cost_qual_eval_context *cqctx = (cost_qual_eval_context *) context; + if (node == NULL) return false; but the latter would require changing references further down in the function, so I felt it more invasive. It's sad to note that this exercise in hoop-jumping actually leaves us with net LESS type safety, because the outside callers of cost_qual_eval_walker are no longer constrained to call it with the appropriate kind of context struct. Thanks, C committee. regards, tom lane
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index 3bac350bf5..1e2ae3a5a4 100644 --- a/src/backend/nodes/nodeFuncs.c +++ b/src/backend/nodes/nodeFuncs.c @@ -27,10 +27,10 @@ static bool expression_returns_set_walker(Node *node, void *context); static int leftmostLoc(int loc1, int loc2); static bool fix_opfuncids_walker(Node *node, void *context); -static bool planstate_walk_subplans(List *plans, bool (*walker) (), +static bool planstate_walk_subplans(List *plans, tree_walker_callback walker, void *context); static bool planstate_walk_members(PlanState **planstates, int nplans, - bool (*walker) (), void *context); + tree_walker_callback walker, void *context); /* @@ -1836,7 +1836,7 @@ check_functions_in_node(Node *node, check_function_callback checker, * that modify nodes in-place but never add/delete/replace nodes). * A walker routine should look like this: * - * bool my_walker (Node *node, my_struct *context) + * bool my_walker (Node *node, void *context) * { * if (node == NULL) * return false; @@ -1850,7 +1850,7 @@ check_functions_in_node(Node *node, check_function_callback checker, * ... do special actions for other node types * } * // for any node type not specially processed, do: - * return expression_tree_walker(node, my_walker, (void *) context); + * return expression_tree_walker(node, my_walker, context); * } * * The "context" argument points to a struct that holds whatever context @@ -1910,7 +1910,7 @@ check_functions_in_node(Node *node, check_function_callback checker, bool expression_tree_walker(Node *node, - bool (*walker) (), + tree_walker_callback walker, void *context) { ListCell *temp; @@ -1923,6 +1923,10 @@ expression_tree_walker(Node *node, * when we expect a List we just recurse directly to self without * bothering to call the walker. */ +#define WALK(n) walker((Node *) (n), context) + +#define LIST_WALK(l) expression_tree_walker((Node *) (l), walker, context) + if (node == NULL) return false; @@ -1946,25 +1950,21 @@ expression_tree_walker(Node *node, /* primitive node types with no expression subnodes */ break; case T_WithCheckOption: - return walker(((WithCheckOption *) node)->qual, context); + return WALK(((WithCheckOption *) node)->qual); case T_Aggref: { Aggref *expr = (Aggref *) node; - /* recurse directly on List */ - if (expression_tree_walker((Node *) expr->aggdirectargs, - walker, context)) + /* recurse directly on Lists */ + if (LIST_WALK(expr->aggdirectargs)) return true; - if (expression_tree_walker((Node *) expr->args, - walker, context)) + if (LIST_WALK(expr->args)) return true; - if (expression_tree_walker((Node *) expr->aggorder, - walker, context)) + if (LIST_WALK(expr->aggorder)) return true; - if (expression_tree_walker((Node *) expr->aggdistinct, - walker, context)) + if (LIST_WALK(expr->aggdistinct)) return true; - if (walker((Node *) expr->aggfilter, context)) + if (WALK(expr->aggfilter)) return true; } break; @@ -1972,8 +1972,7 @@ expression_tree_walker(Node *node, { GroupingFunc *grouping = (GroupingFunc *) node; - if (expression_tree_walker((Node *) grouping->args, - walker, context)) + if (LIST_WALK(grouping->args)) return true; } break; @@ -1982,10 +1981,9 @@ expression_tree_walker(Node *node, WindowFunc *expr = (WindowFunc *) node; /* recurse directly on List */ - if (expression_tree_walker((Node *) expr->args, - walker, context)) + if (LIST_WALK(expr->args)) return true; - if (walker((Node *) expr->aggfilter, context)) + if (WALK(expr->aggfilter)) return true; } break; @@ -1994,17 +1992,15 @@ expression_tree_walker(Node *node, SubscriptingRef *sbsref = (SubscriptingRef *) node; /* recurse directly for upper/lower container index lists */ - if (expression_tree_walker((Node *) sbsref->refupperindexpr, - walker, context)) + if (LIST_WALK(sbsref->refupperindexpr)) return true; - if (expression_tree_walker((Node *) sbsref->reflowerindexpr, - walker, context)) + if (LIST_WALK(sbsref->reflowerindexpr)) return true; /* walker must see the refexpr and refassgnexpr, however */ - if (walker(sbsref->refexpr, context)) + if (WALK(sbsref->refexpr)) return true; - if (walker(sbsref->refassgnexpr, context)) + if (WALK(sbsref->refassgnexpr)) return true; } break; @@ -2012,21 +2008,19 @@ expression_tree_walker(Node *node, { FuncExpr *expr = (FuncExpr *) node; - if (expression_tree_walker((Node *) expr->args, - walker, context)) + if (LIST_WALK(expr->args)) return true; } break; case T_NamedArgExpr: - return walker(((NamedArgExpr *) node)->arg, context); + return WALK(((NamedArgExpr *) node)->arg); case T_OpExpr: case T_DistinctExpr: /* struct-equivalent to OpExpr */ case T_NullIfExpr: /* struct-equivalent to OpExpr */ { OpExpr *expr = (OpExpr *) node; - if (expression_tree_walker((Node *) expr->args, - walker, context)) + if (LIST_WALK(expr->args)) return true; } break; @@ -2034,8 +2028,7 @@ expression_tree_walker(Node *node, { ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node; - if (expression_tree_walker((Node *) expr->args, - walker, context)) + if (LIST_WALK(expr->args)) return true; } break; @@ -2043,8 +2036,7 @@ expression_tree_walker(Node *node, { BoolExpr *expr = (BoolExpr *) node; - if (expression_tree_walker((Node *) expr->args, - walker, context)) + if (LIST_WALK(expr->args)) return true; } break; @@ -2052,14 +2044,14 @@ expression_tree_walker(Node *node, { SubLink *sublink = (SubLink *) node; - if (walker(sublink->testexpr, context)) + if (WALK(sublink->testexpr)) return true; /* * Also invoke the walker on the sublink's Query node, so it * can recurse into the sub-query if it wants to. */ - return walker(sublink->subselect, context); + return WALK(sublink->subselect); } break; case T_SubPlan: @@ -2067,104 +2059,103 @@ expression_tree_walker(Node *node, SubPlan *subplan = (SubPlan *) node; /* recurse into the testexpr, but not into the Plan */ - if (walker(subplan->testexpr, context)) + if (WALK(subplan->testexpr)) return true; /* also examine args list */ - if (expression_tree_walker((Node *) subplan->args, - walker, context)) + if (LIST_WALK(subplan->args)) return true; } break; case T_AlternativeSubPlan: - return walker(((AlternativeSubPlan *) node)->subplans, context); + return LIST_WALK(((AlternativeSubPlan *) node)->subplans); case T_FieldSelect: - return walker(((FieldSelect *) node)->arg, context); + return WALK(((FieldSelect *) node)->arg); case T_FieldStore: { FieldStore *fstore = (FieldStore *) node; - if (walker(fstore->arg, context)) + if (WALK(fstore->arg)) return true; - if (walker(fstore->newvals, context)) + if (WALK(fstore->newvals)) return true; } break; case T_RelabelType: - return walker(((RelabelType *) node)->arg, context); + return WALK(((RelabelType *) node)->arg); case T_CoerceViaIO: - return walker(((CoerceViaIO *) node)->arg, context); + return WALK(((CoerceViaIO *) node)->arg); case T_ArrayCoerceExpr: { ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; - if (walker(acoerce->arg, context)) + if (WALK(acoerce->arg)) return true; - if (walker(acoerce->elemexpr, context)) + if (WALK(acoerce->elemexpr)) return true; } break; case T_ConvertRowtypeExpr: - return walker(((ConvertRowtypeExpr *) node)->arg, context); + return WALK(((ConvertRowtypeExpr *) node)->arg); case T_CollateExpr: - return walker(((CollateExpr *) node)->arg, context); + return WALK(((CollateExpr *) node)->arg); case T_CaseExpr: { CaseExpr *caseexpr = (CaseExpr *) node; - if (walker(caseexpr->arg, context)) + if (WALK(caseexpr->arg)) return true; /* we assume walker doesn't care about CaseWhens, either */ foreach(temp, caseexpr->args) { CaseWhen *when = lfirst_node(CaseWhen, temp); - if (walker(when->expr, context)) + if (WALK(when->expr)) return true; - if (walker(when->result, context)) + if (WALK(when->result)) return true; } - if (walker(caseexpr->defresult, context)) + if (WALK(caseexpr->defresult)) return true; } break; case T_ArrayExpr: - return walker(((ArrayExpr *) node)->elements, context); + return WALK(((ArrayExpr *) node)->elements); case T_RowExpr: /* Assume colnames isn't interesting */ - return walker(((RowExpr *) node)->args, context); + return WALK(((RowExpr *) node)->args); case T_RowCompareExpr: { RowCompareExpr *rcexpr = (RowCompareExpr *) node; - if (walker(rcexpr->largs, context)) + if (WALK(rcexpr->largs)) return true; - if (walker(rcexpr->rargs, context)) + if (WALK(rcexpr->rargs)) return true; } break; case T_CoalesceExpr: - return walker(((CoalesceExpr *) node)->args, context); + return WALK(((CoalesceExpr *) node)->args); case T_MinMaxExpr: - return walker(((MinMaxExpr *) node)->args, context); + return WALK(((MinMaxExpr *) node)->args); case T_XmlExpr: { XmlExpr *xexpr = (XmlExpr *) node; - if (walker(xexpr->named_args, context)) + if (WALK(xexpr->named_args)) return true; /* we assume walker doesn't care about arg_names */ - if (walker(xexpr->args, context)) + if (WALK(xexpr->args)) return true; } break; case T_NullTest: - return walker(((NullTest *) node)->arg, context); + return WALK(((NullTest *) node)->arg); case T_BooleanTest: - return walker(((BooleanTest *) node)->arg, context); + return WALK(((BooleanTest *) node)->arg); case T_CoerceToDomain: - return walker(((CoerceToDomain *) node)->arg, context); + return WALK(((CoerceToDomain *) node)->arg); case T_TargetEntry: - return walker(((TargetEntry *) node)->expr, context); + return WALK(((TargetEntry *) node)->expr); case T_Query: /* Do nothing with a sub-Query, per discussion above */ break; @@ -2172,13 +2163,13 @@ expression_tree_walker(Node *node, { WindowClause *wc = (WindowClause *) node; - if (walker(wc->partitionClause, context)) + if (WALK(wc->partitionClause)) return true; - if (walker(wc->orderClause, context)) + if (WALK(wc->orderClause)) return true; - if (walker(wc->startOffset, context)) + if (WALK(wc->startOffset)) return true; - if (walker(wc->endOffset, context)) + if (WALK(wc->endOffset)) return true; } break; @@ -2186,9 +2177,9 @@ expression_tree_walker(Node *node, { CTECycleClause *cc = (CTECycleClause *) node; - if (walker(cc->cycle_mark_value, context)) + if (WALK(cc->cycle_mark_value)) return true; - if (walker(cc->cycle_mark_default, context)) + if (WALK(cc->cycle_mark_default)) return true; } break; @@ -2200,12 +2191,12 @@ expression_tree_walker(Node *node, * Invoke the walker on the CTE's Query node, so it can * recurse into the sub-query if it wants to. */ - if (walker(cte->ctequery, context)) + if (WALK(cte->ctequery)) return true; - if (walker(cte->search_clause, context)) + if (WALK(cte->search_clause)) return true; - if (walker(cte->cycle_clause, context)) + if (WALK(cte->cycle_clause)) return true; } break; @@ -2213,11 +2204,11 @@ expression_tree_walker(Node *node, { PartitionBoundSpec *pbs = (PartitionBoundSpec *) node; - if (walker(pbs->listdatums, context)) + if (WALK(pbs->listdatums)) return true; - if (walker(pbs->lowerdatums, context)) + if (WALK(pbs->lowerdatums)) return true; - if (walker(pbs->upperdatums, context)) + if (WALK(pbs->upperdatums)) return true; } break; @@ -2225,14 +2216,14 @@ expression_tree_walker(Node *node, { PartitionRangeDatum *prd = (PartitionRangeDatum *) node; - if (walker(prd->value, context)) + if (WALK(prd->value)) return true; } break; case T_List: foreach(temp, (List *) node) { - if (walker((Node *) lfirst(temp), context)) + if (WALK(lfirst(temp))) return true; } break; @@ -2240,9 +2231,9 @@ expression_tree_walker(Node *node, { FromExpr *from = (FromExpr *) node; - if (walker(from->fromlist, context)) + if (LIST_WALK(from->fromlist)) return true; - if (walker(from->quals, context)) + if (WALK(from->quals)) return true; } break; @@ -2250,15 +2241,15 @@ expression_tree_walker(Node *node, { OnConflictExpr *onconflict = (OnConflictExpr *) node; - if (walker((Node *) onconflict->arbiterElems, context)) + if (WALK(onconflict->arbiterElems)) return true; - if (walker(onconflict->arbiterWhere, context)) + if (WALK(onconflict->arbiterWhere)) return true; - if (walker(onconflict->onConflictSet, context)) + if (WALK(onconflict->onConflictSet)) return true; - if (walker(onconflict->onConflictWhere, context)) + if (WALK(onconflict->onConflictWhere)) return true; - if (walker(onconflict->exclRelTlist, context)) + if (WALK(onconflict->exclRelTlist)) return true; } break; @@ -2266,9 +2257,9 @@ expression_tree_walker(Node *node, { MergeAction *action = (MergeAction *) node; - if (walker(action->targetList, context)) + if (WALK(action->targetList)) return true; - if (walker(action->qual, context)) + if (WALK(action->qual)) return true; } break; @@ -2276,7 +2267,7 @@ expression_tree_walker(Node *node, { PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node; - if (walker((Node *) opstep->exprs, context)) + if (WALK(opstep->exprs)) return true; } break; @@ -2287,11 +2278,11 @@ expression_tree_walker(Node *node, { JoinExpr *join = (JoinExpr *) node; - if (walker(join->larg, context)) + if (WALK(join->larg)) return true; - if (walker(join->rarg, context)) + if (WALK(join->rarg)) return true; - if (walker(join->quals, context)) + if (WALK(join->quals)) return true; /* @@ -2303,9 +2294,9 @@ expression_tree_walker(Node *node, { SetOperationStmt *setop = (SetOperationStmt *) node; - if (walker(setop->larg, context)) + if (WALK(setop->larg)) return true; - if (walker(setop->rarg, context)) + if (WALK(setop->rarg)) return true; /* groupClauses are deemed uninteresting */ @@ -2315,38 +2306,35 @@ expression_tree_walker(Node *node, { IndexClause *iclause = (IndexClause *) node; - if (walker(iclause->rinfo, context)) + if (WALK(iclause->rinfo)) return true; - if (expression_tree_walker((Node *) iclause->indexquals, - walker, context)) + if (LIST_WALK(iclause->indexquals)) return true; } break; case T_PlaceHolderVar: - return walker(((PlaceHolderVar *) node)->phexpr, context); + return WALK(((PlaceHolderVar *) node)->phexpr); case T_InferenceElem: - return walker(((InferenceElem *) node)->expr, context); + return WALK(((InferenceElem *) node)->expr); case T_AppendRelInfo: { AppendRelInfo *appinfo = (AppendRelInfo *) node; - if (expression_tree_walker((Node *) appinfo->translated_vars, - walker, context)) + if (LIST_WALK(appinfo->translated_vars)) return true; } break; case T_PlaceHolderInfo: - return walker(((PlaceHolderInfo *) node)->ph_var, context); + return WALK(((PlaceHolderInfo *) node)->ph_var); case T_RangeTblFunction: - return walker(((RangeTblFunction *) node)->funcexpr, context); + return WALK(((RangeTblFunction *) node)->funcexpr); case T_TableSampleClause: { TableSampleClause *tsc = (TableSampleClause *) node; - if (expression_tree_walker((Node *) tsc->args, - walker, context)) + if (LIST_WALK(tsc->args)) return true; - if (walker((Node *) tsc->repeatable, context)) + if (WALK(tsc->repeatable)) return true; } break; @@ -2354,15 +2342,15 @@ expression_tree_walker(Node *node, { TableFunc *tf = (TableFunc *) node; - if (walker(tf->ns_uris, context)) + if (WALK(tf->ns_uris)) return true; - if (walker(tf->docexpr, context)) + if (WALK(tf->docexpr)) return true; - if (walker(tf->rowexpr, context)) + if (WALK(tf->rowexpr)) return true; - if (walker(tf->colexprs, context)) + if (WALK(tf->colexprs)) return true; - if (walker(tf->coldefexprs, context)) + if (WALK(tf->coldefexprs)) return true; } break; @@ -2372,6 +2360,9 @@ expression_tree_walker(Node *node, break; } return false; + + /* The WALK() macro can be re-used below, but LIST_WALK() not so much */ +#undef LIST_WALK } /* @@ -2391,7 +2382,7 @@ expression_tree_walker(Node *node, */ bool query_tree_walker(Query *query, - bool (*walker) (), + tree_walker_callback walker, void *context, int flags) { @@ -2404,25 +2395,25 @@ query_tree_walker(Query *query, * in a rule action. */ - if (walker((Node *) query->targetList, context)) + if (WALK(query->targetList)) return true; - if (walker((Node *) query->withCheckOptions, context)) + if (WALK(query->withCheckOptions)) return true; - if (walker((Node *) query->onConflict, context)) + if (WALK(query->onConflict)) return true; - if (walker((Node *) query->mergeActionList, context)) + if (WALK(query->mergeActionList)) return true; - if (walker((Node *) query->returningList, context)) + if (WALK(query->returningList)) return true; - if (walker((Node *) query->jointree, context)) + if (WALK(query->jointree)) return true; - if (walker(query->setOperations, context)) + if (WALK(query->setOperations)) return true; - if (walker(query->havingQual, context)) + if (WALK(query->havingQual)) return true; - if (walker(query->limitOffset, context)) + if (WALK(query->limitOffset)) return true; - if (walker(query->limitCount, context)) + if (WALK(query->limitCount)) return true; /* @@ -2432,13 +2423,13 @@ query_tree_walker(Query *query, */ if ((flags & QTW_EXAMINE_SORTGROUP)) { - if (walker((Node *) query->groupClause, context)) + if (WALK(query->groupClause)) return true; - if (walker((Node *) query->windowClause, context)) + if (WALK(query->windowClause)) return true; - if (walker((Node *) query->sortClause, context)) + if (WALK(query->sortClause)) return true; - if (walker((Node *) query->distinctClause, context)) + if (WALK(query->distinctClause)) return true; } else @@ -2453,9 +2444,9 @@ query_tree_walker(Query *query, { WindowClause *wc = lfirst_node(WindowClause, lc); - if (walker(wc->startOffset, context)) + if (WALK(wc->startOffset)) return true; - if (walker(wc->endOffset, context)) + if (WALK(wc->endOffset)) return true; } } @@ -2474,7 +2465,7 @@ query_tree_walker(Query *query, if (!(flags & QTW_IGNORE_CTE_SUBQUERIES)) { - if (walker((Node *) query->cteList, context)) + if (WALK(query->cteList)) return true; } if (!(flags & QTW_IGNORE_RANGE_TABLE)) @@ -2492,7 +2483,7 @@ query_tree_walker(Query *query, */ bool range_table_walker(List *rtable, - bool (*walker) (), + tree_walker_callback walker, void *context, int flags) { @@ -2513,7 +2504,7 @@ range_table_walker(List *rtable, */ bool range_table_entry_walker(RangeTblEntry *rte, - bool (*walker) (), + tree_walker_callback walker, void *context, int flags) { @@ -2523,35 +2514,35 @@ range_table_entry_walker(RangeTblEntry *rte, * specify neither flag, the walker won't be called on the RTE at all. */ if (flags & QTW_EXAMINE_RTES_BEFORE) - if (walker(rte, context)) + if (WALK(rte)) return true; switch (rte->rtekind) { case RTE_RELATION: - if (walker(rte->tablesample, context)) + if (WALK(rte->tablesample)) return true; break; case RTE_SUBQUERY: if (!(flags & QTW_IGNORE_RT_SUBQUERIES)) - if (walker(rte->subquery, context)) + if (WALK(rte->subquery)) return true; break; case RTE_JOIN: if (!(flags & QTW_IGNORE_JOINALIASES)) - if (walker(rte->joinaliasvars, context)) + if (WALK(rte->joinaliasvars)) return true; break; case RTE_FUNCTION: - if (walker(rte->functions, context)) + if (WALK(rte->functions)) return true; break; case RTE_TABLEFUNC: - if (walker(rte->tablefunc, context)) + if (WALK(rte->tablefunc)) return true; break; case RTE_VALUES: - if (walker(rte->values_lists, context)) + if (WALK(rte->values_lists)) return true; break; case RTE_CTE: @@ -2561,11 +2552,11 @@ range_table_entry_walker(RangeTblEntry *rte, break; } - if (walker(rte->securityQuals, context)) + if (WALK(rte->securityQuals)) return true; if (flags & QTW_EXAMINE_RTES_AFTER) - if (walker(rte, context)) + if (WALK(rte)) return true; return false; @@ -2580,7 +2571,7 @@ range_table_entry_walker(RangeTblEntry *rte, * (or appropriately modified substitute for) the subtree it is handed. * A mutator routine should look like this: * - * Node * my_mutator (Node *node, my_struct *context) + * Node * my_mutator (Node *node, void *context) * { * if (node == NULL) * return NULL; @@ -2594,7 +2585,7 @@ range_table_entry_walker(RangeTblEntry *rte, * ... do special transformations of other node types * } * // for any node type not specially processed, do: - * return expression_tree_mutator(node, my_mutator, (void *) context); + * return expression_tree_mutator(node, my_mutator, context); * } * * The "context" argument points to a struct that holds whatever context @@ -2636,7 +2627,7 @@ range_table_entry_walker(RangeTblEntry *rte, Node * expression_tree_mutator(Node *node, - Node *(*mutator) (), + tree_mutator_callback mutator, void *context) { /* @@ -3367,7 +3358,7 @@ expression_tree_mutator(Node *node, */ Query * query_tree_mutator(Query *query, - Node *(*mutator) (), + tree_mutator_callback mutator, void *context, int flags) { @@ -3457,7 +3448,7 @@ query_tree_mutator(Query *query, */ List * range_table_mutator(List *rtable, - Node *(*mutator) (), + tree_mutator_callback mutator, void *context, int flags) { @@ -3526,7 +3517,7 @@ range_table_mutator(List *rtable, */ bool query_or_expression_tree_walker(Node *node, - bool (*walker) (), + tree_walker_callback walker, void *context, int flags) { @@ -3536,7 +3527,7 @@ query_or_expression_tree_walker(Node *node, context, flags); else - return walker(node, context); + return WALK(node); } /* @@ -3549,7 +3540,7 @@ query_or_expression_tree_walker(Node *node, */ Node * query_or_expression_tree_mutator(Node *node, - Node *(*mutator) (), + tree_mutator_callback mutator, void *context, int flags) { @@ -3580,7 +3571,7 @@ query_or_expression_tree_mutator(Node *node, */ bool raw_expression_tree_walker(Node *node, - bool (*walker) (), + tree_walker_callback walker, void *context) { ListCell *temp; @@ -3614,17 +3605,17 @@ raw_expression_tree_walker(Node *node, /* we assume the colnames list isn't interesting */ break; case T_RangeVar: - return walker(((RangeVar *) node)->alias, context); + return WALK(((RangeVar *) node)->alias); case T_GroupingFunc: - return walker(((GroupingFunc *) node)->args, context); + return WALK(((GroupingFunc *) node)->args); case T_SubLink: { SubLink *sublink = (SubLink *) node; - if (walker(sublink->testexpr, context)) + if (WALK(sublink->testexpr)) return true; /* we assume the operName is not interesting */ - if (walker(sublink->subselect, context)) + if (WALK(sublink->subselect)) return true; } break; @@ -3632,55 +3623,55 @@ raw_expression_tree_walker(Node *node, { CaseExpr *caseexpr = (CaseExpr *) node; - if (walker(caseexpr->arg, context)) + if (WALK(caseexpr->arg)) return true; /* we assume walker doesn't care about CaseWhens, either */ foreach(temp, caseexpr->args) { CaseWhen *when = lfirst_node(CaseWhen, temp); - if (walker(when->expr, context)) + if (WALK(when->expr)) return true; - if (walker(when->result, context)) + if (WALK(when->result)) return true; } - if (walker(caseexpr->defresult, context)) + if (WALK(caseexpr->defresult)) return true; } break; case T_RowExpr: /* Assume colnames isn't interesting */ - return walker(((RowExpr *) node)->args, context); + return WALK(((RowExpr *) node)->args); case T_CoalesceExpr: - return walker(((CoalesceExpr *) node)->args, context); + return WALK(((CoalesceExpr *) node)->args); case T_MinMaxExpr: - return walker(((MinMaxExpr *) node)->args, context); + return WALK(((MinMaxExpr *) node)->args); case T_XmlExpr: { XmlExpr *xexpr = (XmlExpr *) node; - if (walker(xexpr->named_args, context)) + if (WALK(xexpr->named_args)) return true; /* we assume walker doesn't care about arg_names */ - if (walker(xexpr->args, context)) + if (WALK(xexpr->args)) return true; } break; case T_NullTest: - return walker(((NullTest *) node)->arg, context); + return WALK(((NullTest *) node)->arg); case T_BooleanTest: - return walker(((BooleanTest *) node)->arg, context); + return WALK(((BooleanTest *) node)->arg); case T_JoinExpr: { JoinExpr *join = (JoinExpr *) node; - if (walker(join->larg, context)) + if (WALK(join->larg)) return true; - if (walker(join->rarg, context)) + if (WALK(join->rarg)) return true; - if (walker(join->quals, context)) + if (WALK(join->quals)) return true; - if (walker(join->alias, context)) + if (WALK(join->alias)) return true; /* using list is deemed uninteresting */ } @@ -3689,18 +3680,18 @@ raw_expression_tree_walker(Node *node, { IntoClause *into = (IntoClause *) node; - if (walker(into->rel, context)) + if (WALK(into->rel)) return true; /* colNames, options are deemed uninteresting */ /* viewQuery should be null in raw parsetree, but check it */ - if (walker(into->viewQuery, context)) + if (WALK(into->viewQuery)) return true; } break; case T_List: foreach(temp, (List *) node) { - if (walker((Node *) lfirst(temp), context)) + if (WALK((Node *) lfirst(temp))) return true; } break; @@ -3708,17 +3699,17 @@ raw_expression_tree_walker(Node *node, { InsertStmt *stmt = (InsertStmt *) node; - if (walker(stmt->relation, context)) + if (WALK(stmt->relation)) return true; - if (walker(stmt->cols, context)) + if (WALK(stmt->cols)) return true; - if (walker(stmt->selectStmt, context)) + if (WALK(stmt->selectStmt)) return true; - if (walker(stmt->onConflictClause, context)) + if (WALK(stmt->onConflictClause)) return true; - if (walker(stmt->returningList, context)) + if (WALK(stmt->returningList)) return true; - if (walker(stmt->withClause, context)) + if (WALK(stmt->withClause)) return true; } break; @@ -3726,15 +3717,15 @@ raw_expression_tree_walker(Node *node, { DeleteStmt *stmt = (DeleteStmt *) node; - if (walker(stmt->relation, context)) + if (WALK(stmt->relation)) return true; - if (walker(stmt->usingClause, context)) + if (WALK(stmt->usingClause)) return true; - if (walker(stmt->whereClause, context)) + if (WALK(stmt->whereClause)) return true; - if (walker(stmt->returningList, context)) + if (WALK(stmt->returningList)) return true; - if (walker(stmt->withClause, context)) + if (WALK(stmt->withClause)) return true; } break; @@ -3742,17 +3733,17 @@ raw_expression_tree_walker(Node *node, { UpdateStmt *stmt = (UpdateStmt *) node; - if (walker(stmt->relation, context)) + if (WALK(stmt->relation)) return true; - if (walker(stmt->targetList, context)) + if (WALK(stmt->targetList)) return true; - if (walker(stmt->whereClause, context)) + if (WALK(stmt->whereClause)) return true; - if (walker(stmt->fromClause, context)) + if (WALK(stmt->fromClause)) return true; - if (walker(stmt->returningList, context)) + if (WALK(stmt->returningList)) return true; - if (walker(stmt->withClause, context)) + if (WALK(stmt->withClause)) return true; } break; @@ -3760,15 +3751,15 @@ raw_expression_tree_walker(Node *node, { MergeStmt *stmt = (MergeStmt *) node; - if (walker(stmt->relation, context)) + if (WALK(stmt->relation)) return true; - if (walker(stmt->sourceRelation, context)) + if (WALK(stmt->sourceRelation)) return true; - if (walker(stmt->joinCondition, context)) + if (WALK(stmt->joinCondition)) return true; - if (walker(stmt->mergeWhenClauses, context)) + if (WALK(stmt->mergeWhenClauses)) return true; - if (walker(stmt->withClause, context)) + if (WALK(stmt->withClause)) return true; } break; @@ -3776,11 +3767,11 @@ raw_expression_tree_walker(Node *node, { MergeWhenClause *mergeWhenClause = (MergeWhenClause *) node; - if (walker(mergeWhenClause->condition, context)) + if (WALK(mergeWhenClause->condition)) return true; - if (walker(mergeWhenClause->targetList, context)) + if (WALK(mergeWhenClause->targetList)) return true; - if (walker(mergeWhenClause->values, context)) + if (WALK(mergeWhenClause->values)) return true; } break; @@ -3788,37 +3779,37 @@ raw_expression_tree_walker(Node *node, { SelectStmt *stmt = (SelectStmt *) node; - if (walker(stmt->distinctClause, context)) + if (WALK(stmt->distinctClause)) return true; - if (walker(stmt->intoClause, context)) + if (WALK(stmt->intoClause)) return true; - if (walker(stmt->targetList, context)) + if (WALK(stmt->targetList)) return true; - if (walker(stmt->fromClause, context)) + if (WALK(stmt->fromClause)) return true; - if (walker(stmt->whereClause, context)) + if (WALK(stmt->whereClause)) return true; - if (walker(stmt->groupClause, context)) + if (WALK(stmt->groupClause)) return true; - if (walker(stmt->havingClause, context)) + if (WALK(stmt->havingClause)) return true; - if (walker(stmt->windowClause, context)) + if (WALK(stmt->windowClause)) return true; - if (walker(stmt->valuesLists, context)) + if (WALK(stmt->valuesLists)) return true; - if (walker(stmt->sortClause, context)) + if (WALK(stmt->sortClause)) return true; - if (walker(stmt->limitOffset, context)) + if (WALK(stmt->limitOffset)) return true; - if (walker(stmt->limitCount, context)) + if (WALK(stmt->limitCount)) return true; - if (walker(stmt->lockingClause, context)) + if (WALK(stmt->lockingClause)) return true; - if (walker(stmt->withClause, context)) + if (WALK(stmt->withClause)) return true; - if (walker(stmt->larg, context)) + if (WALK(stmt->larg)) return true; - if (walker(stmt->rarg, context)) + if (WALK(stmt->rarg)) return true; } break; @@ -3826,9 +3817,9 @@ raw_expression_tree_walker(Node *node, { PLAssignStmt *stmt = (PLAssignStmt *) node; - if (walker(stmt->indirection, context)) + if (WALK(stmt->indirection)) return true; - if (walker(stmt->val, context)) + if (WALK(stmt->val)) return true; } break; @@ -3836,9 +3827,9 @@ raw_expression_tree_walker(Node *node, { A_Expr *expr = (A_Expr *) node; - if (walker(expr->lexpr, context)) + if (WALK(expr->lexpr)) return true; - if (walker(expr->rexpr, context)) + if (WALK(expr->rexpr)) return true; /* operator name is deemed uninteresting */ } @@ -3847,7 +3838,7 @@ raw_expression_tree_walker(Node *node, { BoolExpr *expr = (BoolExpr *) node; - if (walker(expr->args, context)) + if (WALK(expr->args)) return true; } break; @@ -3858,26 +3849,26 @@ raw_expression_tree_walker(Node *node, { FuncCall *fcall = (FuncCall *) node; - if (walker(fcall->args, context)) + if (WALK(fcall->args)) return true; - if (walker(fcall->agg_order, context)) + if (WALK(fcall->agg_order)) return true; - if (walker(fcall->agg_filter, context)) + if (WALK(fcall->agg_filter)) return true; - if (walker(fcall->over, context)) + if (WALK(fcall->over)) return true; /* function name is deemed uninteresting */ } break; case T_NamedArgExpr: - return walker(((NamedArgExpr *) node)->arg, context); + return WALK(((NamedArgExpr *) node)->arg); case T_A_Indices: { A_Indices *indices = (A_Indices *) node; - if (walker(indices->lidx, context)) + if (WALK(indices->lidx)) return true; - if (walker(indices->uidx, context)) + if (WALK(indices->uidx)) return true; } break; @@ -3885,51 +3876,51 @@ raw_expression_tree_walker(Node *node, { A_Indirection *indir = (A_Indirection *) node; - if (walker(indir->arg, context)) + if (WALK(indir->arg)) return true; - if (walker(indir->indirection, context)) + if (WALK(indir->indirection)) return true; } break; case T_A_ArrayExpr: - return walker(((A_ArrayExpr *) node)->elements, context); + return WALK(((A_ArrayExpr *) node)->elements); case T_ResTarget: { ResTarget *rt = (ResTarget *) node; - if (walker(rt->indirection, context)) + if (WALK(rt->indirection)) return true; - if (walker(rt->val, context)) + if (WALK(rt->val)) return true; } break; case T_MultiAssignRef: - return walker(((MultiAssignRef *) node)->source, context); + return WALK(((MultiAssignRef *) node)->source); case T_TypeCast: { TypeCast *tc = (TypeCast *) node; - if (walker(tc->arg, context)) + if (WALK(tc->arg)) return true; - if (walker(tc->typeName, context)) + if (WALK(tc->typeName)) return true; } break; case T_CollateClause: - return walker(((CollateClause *) node)->arg, context); + return WALK(((CollateClause *) node)->arg); case T_SortBy: - return walker(((SortBy *) node)->node, context); + return WALK(((SortBy *) node)->node); case T_WindowDef: { WindowDef *wd = (WindowDef *) node; - if (walker(wd->partitionClause, context)) + if (WALK(wd->partitionClause)) return true; - if (walker(wd->orderClause, context)) + if (WALK(wd->orderClause)) return true; - if (walker(wd->startOffset, context)) + if (WALK(wd->startOffset)) return true; - if (walker(wd->endOffset, context)) + if (WALK(wd->endOffset)) return true; } break; @@ -3937,9 +3928,9 @@ raw_expression_tree_walker(Node *node, { RangeSubselect *rs = (RangeSubselect *) node; - if (walker(rs->subquery, context)) + if (WALK(rs->subquery)) return true; - if (walker(rs->alias, context)) + if (WALK(rs->alias)) return true; } break; @@ -3947,11 +3938,11 @@ raw_expression_tree_walker(Node *node, { RangeFunction *rf = (RangeFunction *) node; - if (walker(rf->functions, context)) + if (WALK(rf->functions)) return true; - if (walker(rf->alias, context)) + if (WALK(rf->alias)) return true; - if (walker(rf->coldeflist, context)) + if (WALK(rf->coldeflist)) return true; } break; @@ -3959,12 +3950,12 @@ raw_expression_tree_walker(Node *node, { RangeTableSample *rts = (RangeTableSample *) node; - if (walker(rts->relation, context)) + if (WALK(rts->relation)) return true; /* method name is deemed uninteresting */ - if (walker(rts->args, context)) + if (WALK(rts->args)) return true; - if (walker(rts->repeatable, context)) + if (WALK(rts->repeatable)) return true; } break; @@ -3972,15 +3963,15 @@ raw_expression_tree_walker(Node *node, { RangeTableFunc *rtf = (RangeTableFunc *) node; - if (walker(rtf->docexpr, context)) + if (WALK(rtf->docexpr)) return true; - if (walker(rtf->rowexpr, context)) + if (WALK(rtf->rowexpr)) return true; - if (walker(rtf->namespaces, context)) + if (WALK(rtf->namespaces)) return true; - if (walker(rtf->columns, context)) + if (WALK(rtf->columns)) return true; - if (walker(rtf->alias, context)) + if (WALK(rtf->alias)) return true; } break; @@ -3988,9 +3979,9 @@ raw_expression_tree_walker(Node *node, { RangeTableFuncCol *rtfc = (RangeTableFuncCol *) node; - if (walker(rtfc->colexpr, context)) + if (WALK(rtfc->colexpr)) return true; - if (walker(rtfc->coldefexpr, context)) + if (WALK(rtfc->coldefexpr)) return true; } break; @@ -3998,9 +3989,9 @@ raw_expression_tree_walker(Node *node, { TypeName *tn = (TypeName *) node; - if (walker(tn->typmods, context)) + if (WALK(tn->typmods)) return true; - if (walker(tn->arrayBounds, context)) + if (WALK(tn->arrayBounds)) return true; /* type name itself is deemed uninteresting */ } @@ -4009,13 +4000,13 @@ raw_expression_tree_walker(Node *node, { ColumnDef *coldef = (ColumnDef *) node; - if (walker(coldef->typeName, context)) + if (WALK(coldef->typeName)) return true; - if (walker(coldef->compression, context)) + if (WALK(coldef->compression)) return true; - if (walker(coldef->raw_default, context)) + if (WALK(coldef->raw_default)) return true; - if (walker(coldef->collClause, context)) + if (WALK(coldef->collClause)) return true; /* for now, constraints are ignored */ } @@ -4024,34 +4015,34 @@ raw_expression_tree_walker(Node *node, { IndexElem *indelem = (IndexElem *) node; - if (walker(indelem->expr, context)) + if (WALK(indelem->expr)) return true; /* collation and opclass names are deemed uninteresting */ } break; case T_GroupingSet: - return walker(((GroupingSet *) node)->content, context); + return WALK(((GroupingSet *) node)->content); case T_LockingClause: - return walker(((LockingClause *) node)->lockedRels, context); + return WALK(((LockingClause *) node)->lockedRels); case T_XmlSerialize: { XmlSerialize *xs = (XmlSerialize *) node; - if (walker(xs->expr, context)) + if (WALK(xs->expr)) return true; - if (walker(xs->typeName, context)) + if (WALK(xs->typeName)) return true; } break; case T_WithClause: - return walker(((WithClause *) node)->ctes, context); + return WALK(((WithClause *) node)->ctes); case T_InferClause: { InferClause *stmt = (InferClause *) node; - if (walker(stmt->indexElems, context)) + if (WALK(stmt->indexElems)) return true; - if (walker(stmt->whereClause, context)) + if (WALK(stmt->whereClause)) return true; } break; @@ -4059,17 +4050,17 @@ raw_expression_tree_walker(Node *node, { OnConflictClause *stmt = (OnConflictClause *) node; - if (walker(stmt->infer, context)) + if (WALK(stmt->infer)) return true; - if (walker(stmt->targetList, context)) + if (WALK(stmt->targetList)) return true; - if (walker(stmt->whereClause, context)) + if (WALK(stmt->whereClause)) return true; } break; case T_CommonTableExpr: /* search_clause and cycle_clause are not interesting here */ - return walker(((CommonTableExpr *) node)->ctequery, context); + return WALK(((CommonTableExpr *) node)->ctequery); default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node)); @@ -4086,7 +4077,7 @@ raw_expression_tree_walker(Node *node, */ bool planstate_tree_walker(PlanState *planstate, - bool (*walker) (), + tree_walker_callback walker, void *context) { Plan *plan = planstate->plan; @@ -4102,14 +4093,14 @@ planstate_tree_walker(PlanState *planstate, /* lefttree */ if (outerPlanState(planstate)) { - if (walker(outerPlanState(planstate), context)) + if (WALK(outerPlanState(planstate))) return true; } /* righttree */ if (innerPlanState(planstate)) { - if (walker(innerPlanState(planstate), context)) + if (WALK(innerPlanState(planstate))) return true; } @@ -4141,13 +4132,13 @@ planstate_tree_walker(PlanState *planstate, return true; break; case T_SubqueryScan: - if (walker(((SubqueryScanState *) planstate)->subplan, context)) + if (WALK(((SubqueryScanState *) planstate)->subplan)) return true; break; case T_CustomScan: foreach(lc, ((CustomScanState *) planstate)->custom_ps) { - if (walker((PlanState *) lfirst(lc), context)) + if (WALK(lfirst(lc))) return true; } break; @@ -4167,7 +4158,7 @@ planstate_tree_walker(PlanState *planstate, */ static bool planstate_walk_subplans(List *plans, - bool (*walker) (), + tree_walker_callback walker, void *context) { ListCell *lc; @@ -4176,7 +4167,7 @@ planstate_walk_subplans(List *plans, { SubPlanState *sps = lfirst_node(SubPlanState, lc); - if (walker(sps->planstate, context)) + if (WALK(sps->planstate)) return true; } @@ -4189,13 +4180,13 @@ planstate_walk_subplans(List *plans, */ static bool planstate_walk_members(PlanState **planstates, int nplans, - bool (*walker) (), void *context) + tree_walker_callback walker, void *context) { int j; for (j = 0; j < nplans; j++) { - if (walker(planstates[j], context)) + if (WALK(planstates[j])) return true; } diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index f486d42441..9ba3ad93b7 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -165,7 +165,7 @@ static MergeScanSelCache *cached_scansel(PlannerInfo *root, PathKey *pathkey); static void cost_rescan(PlannerInfo *root, Path *path, Cost *rescan_startup_cost, Cost *rescan_total_cost); -static bool cost_qual_eval_walker(Node *node, cost_qual_eval_context *context); +static bool cost_qual_eval_walker(Node *node, void *ctx); static void get_restriction_qual_cost(PlannerInfo *root, RelOptInfo *baserel, ParamPathInfo *param_info, QualCost *qpqual_cost); @@ -4722,8 +4722,10 @@ cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root) } static bool -cost_qual_eval_walker(Node *node, cost_qual_eval_context *context) +cost_qual_eval_walker(Node *node, void *ctx) { + cost_qual_eval_context *context = (cost_qual_eval_context *) ctx; + if (node == NULL) return false; diff --git a/src/include/nodes/nodeFuncs.h b/src/include/nodes/nodeFuncs.h index 93c60bde66..cb92a9de66 100644 --- a/src/include/nodes/nodeFuncs.h +++ b/src/include/nodes/nodeFuncs.h @@ -32,6 +32,12 @@ /* callback function for check_functions_in_node */ typedef bool (*check_function_callback) (Oid func_id, void *context); +/* callback functions for tree walkers */ +typedef bool (*tree_walker_callback) (Node *node, void *context); + +/* callback functions for tree mutators */ +typedef Node *(*tree_mutator_callback) (Node *node, void *context); + extern Oid exprType(const Node *expr); extern int32 exprTypmod(const Node *expr); @@ -129,34 +135,39 @@ get_notclausearg(const void *notclause) extern bool check_functions_in_node(Node *node, check_function_callback checker, void *context); -extern bool expression_tree_walker(Node *node, bool (*walker) (), +extern bool expression_tree_walker(Node *node, tree_walker_callback walker, void *context); -extern Node *expression_tree_mutator(Node *node, Node *(*mutator) (), +extern Node *expression_tree_mutator(Node *node, tree_mutator_callback mutator, void *context); -extern bool query_tree_walker(Query *query, bool (*walker) (), +extern bool query_tree_walker(Query *query, tree_walker_callback walker, void *context, int flags); -extern Query *query_tree_mutator(Query *query, Node *(*mutator) (), +extern Query *query_tree_mutator(Query *query, tree_mutator_callback mutator, void *context, int flags); -extern bool range_table_walker(List *rtable, bool (*walker) (), +extern bool range_table_walker(List *rtable, tree_walker_callback walker, void *context, int flags); -extern List *range_table_mutator(List *rtable, Node *(*mutator) (), +extern List *range_table_mutator(List *rtable, tree_mutator_callback mutator, void *context, int flags); -extern bool range_table_entry_walker(RangeTblEntry *rte, bool (*walker) (), +extern bool range_table_entry_walker(RangeTblEntry *rte, + tree_walker_callback walker, void *context, int flags); -extern bool query_or_expression_tree_walker(Node *node, bool (*walker) (), +extern bool query_or_expression_tree_walker(Node *node, + tree_walker_callback walker, void *context, int flags); -extern Node *query_or_expression_tree_mutator(Node *node, Node *(*mutator) (), +extern Node *query_or_expression_tree_mutator(Node *node, + tree_mutator_callback mutator, void *context, int flags); -extern bool raw_expression_tree_walker(Node *node, bool (*walker) (), +extern bool raw_expression_tree_walker(Node *node, + tree_walker_callback walker, void *context); struct PlanState; -extern bool planstate_tree_walker(struct PlanState *planstate, bool (*walker) (), +extern bool planstate_tree_walker(struct PlanState *planstate, + tree_walker_callback walker, void *context); #endif /* NODEFUNCS_H */