#include "postgres.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "nodes/execnodes.h"
#include "nodes/nodeFuncs.h"
#include "nodes/pathnodes.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
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,
planstate_tree_walker_callback walker,
void *context);
static bool planstate_walk_members(PlanState **planstates, int nplans,
planstate_tree_walker_callback walker,
void *context);
#ifdef USE_ASSERT_CHECKING
#endif
int
exprLocation(const Node *expr)
{
int loc;
if (expr == NULL)
return -1;
switch (nodeTag(expr))
{
case T_RangeVar:
loc = ((const RangeVar *) expr)->location;
break;
case T_TableFunc:
loc = ((const TableFunc *) expr)->location;
break;
case T_Var:
loc = ((const Var *) expr)->location;
break;
case T_Const:
loc = ((const Const *) expr)->location;
break;
case T_Param:
loc = ((const Param *) expr)->location;
break;
case T_Aggref:
loc = ((const Aggref *) expr)->location;
break;
case T_GroupingFunc:
loc = ((const GroupingFunc *) expr)->location;
break;
case T_WindowFunc:
loc = ((const WindowFunc *) expr)->location;
break;
case T_MergeSupportFunc:
loc = ((const MergeSupportFunc *) expr)->location;
break;
case T_SubscriptingRef:
loc = exprLocation((Node *) ((const SubscriptingRef *) expr)->refexpr);
break;
case T_FuncExpr:
{
const FuncExpr *fexpr = (const FuncExpr *) expr;
loc = leftmostLoc(fexpr->location,
exprLocation((Node *) fexpr->args));
}
break;
case T_NamedArgExpr:
{
const NamedArgExpr *na = (const NamedArgExpr *) expr;
loc = leftmostLoc(na->location,
exprLocation((Node *) na->arg));
}
break;
case T_OpExpr:
case T_DistinctExpr:
case T_NullIfExpr:
{
const OpExpr *opexpr = (const OpExpr *) expr;
loc = leftmostLoc(opexpr->location,
exprLocation((Node *) opexpr->args));
}
break;
case T_ScalarArrayOpExpr:
{
const ScalarArrayOpExpr *saopexpr = (const ScalarArrayOpExpr *) expr;
loc = leftmostLoc(saopexpr->location,
exprLocation((Node *) saopexpr->args));
}
break;
case T_BoolExpr:
{
const BoolExpr *bexpr = (const BoolExpr *) expr;
loc = leftmostLoc(bexpr->location,
exprLocation((Node *) bexpr->args));
}
break;
case T_SubLink:
{
const SubLink *sublink = (const SubLink *) expr;
loc = leftmostLoc(exprLocation(sublink->testexpr),
sublink->location);
}
break;
case T_FieldSelect:
loc = exprLocation((Node *) ((const FieldSelect *) expr)->arg);
break;
case T_FieldStore:
loc = exprLocation((Node *) ((const FieldStore *) expr)->arg);
break;
case T_RelabelType:
{
const RelabelType *rexpr = (const RelabelType *) expr;
loc = leftmostLoc(rexpr->location,
exprLocation((Node *) rexpr->arg));
}
break;
case T_CoerceViaIO:
{
const CoerceViaIO *cexpr = (const CoerceViaIO *) expr;
loc = leftmostLoc(cexpr->location,
exprLocation((Node *) cexpr->arg));
}
break;
case T_ArrayCoerceExpr:
{
const ArrayCoerceExpr *cexpr = (const ArrayCoerceExpr *) expr;
loc = leftmostLoc(cexpr->location,
exprLocation((Node *) cexpr->arg));
}
break;
case T_ConvertRowtypeExpr:
{
const ConvertRowtypeExpr *cexpr = (const ConvertRowtypeExpr *) expr;
loc = leftmostLoc(cexpr->location,
exprLocation((Node *) cexpr->arg));
}
break;
case T_CollateExpr:
loc = exprLocation((Node *) ((const CollateExpr *) expr)->arg);
break;
case T_CaseExpr:
loc = ((const CaseExpr *) expr)->location;
break;
case T_CaseWhen:
loc = ((const CaseWhen *) expr)->location;
break;
case T_ArrayExpr:
loc = ((const ArrayExpr *) expr)->location;
break;
case T_RowExpr:
loc = ((const RowExpr *) expr)->location;
break;
case T_RowCompareExpr:
loc = exprLocation((Node *) ((const RowCompareExpr *) expr)->largs);
break;
case T_CoalesceExpr:
loc = ((const CoalesceExpr *) expr)->location;
break;
case T_MinMaxExpr:
loc = ((const MinMaxExpr *) expr)->location;
break;
case T_SQLValueFunction:
loc = ((const SQLValueFunction *) expr)->location;
break;
case T_XmlExpr:
{
const XmlExpr *xexpr = (const XmlExpr *) expr;
loc = leftmostLoc(xexpr->location,
exprLocation((Node *) xexpr->args));
}
break;
case T_JsonFormat:
loc = ((const JsonFormat *) expr)->location;
break;
case T_JsonValueExpr:
loc = exprLocation((Node *) ((const JsonValueExpr *) expr)->raw_expr);
break;
case T_JsonConstructorExpr:
loc = ((const JsonConstructorExpr *) expr)->location;
break;
case T_JsonIsPredicate:
loc = ((const JsonIsPredicate *) expr)->location;
break;
case T_JsonExpr:
{
const JsonExpr *jsexpr = (const JsonExpr *) expr;
loc = leftmostLoc(jsexpr->location,
exprLocation(jsexpr->formatted_expr));
}
break;
case T_JsonBehavior:
loc = exprLocation(((JsonBehavior *) expr)->expr);
break;
case T_NullTest:
{
const NullTest *nexpr = (const NullTest *) expr;
loc = leftmostLoc(nexpr->location,
exprLocation((Node *) nexpr->arg));
}
break;
case T_BooleanTest:
{
const BooleanTest *bexpr = (const BooleanTest *) expr;
loc = leftmostLoc(bexpr->location,
exprLocation((Node *) bexpr->arg));
}
break;
case T_CoerceToDomain:
{
const CoerceToDomain *cexpr = (const CoerceToDomain *) expr;
loc = leftmostLoc(cexpr->location,
exprLocation((Node *) cexpr->arg));
}
break;
case T_CoerceToDomainValue:
loc = ((const CoerceToDomainValue *) expr)->location;
break;
case T_SetToDefault:
loc = ((const SetToDefault *) expr)->location;
break;
case T_TargetEntry:
loc = exprLocation((Node *) ((const TargetEntry *) expr)->expr);
break;
case T_IntoClause:
loc = exprLocation((Node *) ((const IntoClause *) expr)->rel);
break;
case T_List:
{
ListCell *lc;
loc = -1;
foreach(lc, (const List *) expr)
{
loc = exprLocation((Node *) lfirst(lc));
if (loc >= 0)
break;
}
}
break;
case T_A_Expr:
{
const A_Expr *aexpr = (const A_Expr *) expr;
loc = leftmostLoc(aexpr->location,
exprLocation(aexpr->lexpr));
}
break;
case T_ColumnRef:
loc = ((const ColumnRef *) expr)->location;
break;
case T_ParamRef:
loc = ((const ParamRef *) expr)->location;
break;
case T_A_Const:
loc = ((const A_Const *) expr)->location;
break;
case T_FuncCall:
{
const FuncCall *fc = (const FuncCall *) expr;
loc = leftmostLoc(fc->location,
exprLocation((Node *) fc->args));
}
break;
case T_A_ArrayExpr:
loc = ((const A_ArrayExpr *) expr)->location;
break;
case T_ResTarget:
loc = ((const ResTarget *) expr)->location;
break;
case T_MultiAssignRef:
loc = exprLocation(((const MultiAssignRef *) expr)->source);
break;
case T_TypeCast:
{
const TypeCast *tc = (const TypeCast *) expr;
loc = exprLocation(tc->arg);
loc = leftmostLoc(loc, tc->typeName->location);
loc = leftmostLoc(loc, tc->location);
}
break;
case T_CollateClause:
loc = exprLocation(((const CollateClause *) expr)->arg);
break;
case T_SortBy:
loc = exprLocation(((const SortBy *) expr)->node);
break;
case T_WindowDef:
loc = ((const WindowDef *) expr)->location;
break;
case T_RangeTableSample:
loc = ((const RangeTableSample *) expr)->location;
break;
case T_TypeName:
loc = ((const TypeName *) expr)->location;
break;
case T_ColumnDef:
loc = ((const ColumnDef *) expr)->location;
break;
case T_Constraint:
loc = ((const Constraint *) expr)->location;
break;
case T_FunctionParameter:
loc = exprLocation((Node *) ((const FunctionParameter *) expr)->argType);
break;
case T_XmlSerialize:
loc = ((const XmlSerialize *) expr)->location;
break;
case T_GroupingSet:
loc = ((const GroupingSet *) expr)->location;
break;
case T_WithClause:
loc = ((const WithClause *) expr)->location;
break;
case T_InferClause:
loc = ((const InferClause *) expr)->location;
break;
case T_OnConflictClause:
loc = ((const OnConflictClause *) expr)->location;
break;
case T_CTESearchClause:
loc = ((const CTESearchClause *) expr)->location;
break;
case T_CTECycleClause:
loc = ((const CTECycleClause *) expr)->location;
break;
case T_CommonTableExpr:
loc = ((const CommonTableExpr *) expr)->location;
break;
case T_JsonKeyValue:
loc = exprLocation((Node *) ((const JsonKeyValue *) expr)->key);
break;
case T_JsonObjectConstructor:
loc = ((const JsonObjectConstructor *) expr)->location;
break;
case T_JsonArrayConstructor:
loc = ((const JsonArrayConstructor *) expr)->location;
break;
case T_JsonArrayQueryConstructor:
loc = ((const JsonArrayQueryConstructor *) expr)->location;
break;
case T_JsonAggConstructor:
loc = ((const JsonAggConstructor *) expr)->location;
break;
case T_JsonObjectAgg:
loc = exprLocation((Node *) ((const JsonObjectAgg *) expr)->constructor);
break;
case T_JsonArrayAgg:
loc = exprLocation((Node *) ((const JsonArrayAgg *) expr)->constructor);
break;
case T_PlaceHolderVar:
loc = exprLocation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
break;
case T_InferenceElem:
loc = exprLocation((Node *) ((const InferenceElem *) expr)->expr);
break;
case T_PartitionElem:
loc = ((const PartitionElem *) expr)->location;
break;
case T_PartitionSpec:
loc = ((const PartitionSpec *) expr)->location;
break;
case T_PartitionBoundSpec:
loc = ((const PartitionBoundSpec *) expr)->location;
break;
case T_PartitionRangeDatum:
loc = ((const PartitionRangeDatum *) expr)->location;
break;
default:
loc = -1;
break;
}
return loc;
}
static int
leftmostLoc(int loc1, int loc2)
{
if (loc1 < 0)
return loc2;
else if (loc2 < 0)
return loc1;
else
return Min(loc1, loc2);
}
#define WALK(n) walker((Node *) (n), context)
#define LIST_WALK(l) expression_tree_walker_impl((Node *) (l), walker, context)
#undef LIST_WALK
#define FLATCOPY(newnode, node, nodetype) \
( (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
memcpy((newnode), (node), sizeof(nodetype)) )
#define MUTATE(newfield, oldfield, fieldtype) \
( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )
bool
raw_expression_tree_walker_impl(Node *node,
tree_walker_callback walker,
void *context)
{
ListCell *temp;
if (node == NULL)
return false;
check_stack_depth();
switch (nodeTag(node))
{
case T_JsonFormat:
case T_SetToDefault:
case T_CurrentOfExpr:
case T_SQLValueFunction:
case T_Integer:
case T_Float:
case T_Boolean:
case T_String:
case T_BitString:
case T_ParamRef:
case T_A_Const:
case T_A_Star:
case T_MergeSupportFunc:
break;
case T_Alias:
break;
case T_RangeVar:
return WALK(((RangeVar *) node)->alias);
case T_GroupingFunc:
return WALK(((GroupingFunc *) node)->args);
case T_SubLink:
{
SubLink *sublink = (SubLink *) node;
if (WALK(sublink->testexpr))
return true;
if (WALK(sublink->subselect))
return true;
}
break;
case T_CaseExpr:
{
CaseExpr *caseexpr = (CaseExpr *) node;
if (WALK(caseexpr->arg))
return true;
foreach(temp, caseexpr->args)
{
CaseWhen *when = lfirst_node(CaseWhen, temp);
if (WALK(when->expr))
return true;
if (WALK(when->result))
return true;
}
if (WALK(caseexpr->defresult))
return true;
}
break;
case T_RowExpr:
return WALK(((RowExpr *) node)->args);
case T_CoalesceExpr:
return WALK(((CoalesceExpr *) node)->args);
case T_MinMaxExpr:
return WALK(((MinMaxExpr *) node)->args);
case T_XmlExpr:
{
XmlExpr *xexpr = (XmlExpr *) node;
if (WALK(xexpr->named_args))
return true;
if (WALK(xexpr->args))
return true;
}
break;
case T_JsonReturning:
return WALK(((JsonReturning *) node)->format);
case T_JsonValueExpr:
{
JsonValueExpr *jve = (JsonValueExpr *) node;
if (WALK(jve->raw_expr))
return true;
if (WALK(jve->formatted_expr))
return true;
if (WALK(jve->format))
return true;
}
break;
case T_JsonParseExpr:
{
JsonParseExpr *jpe = (JsonParseExpr *) node;
if (WALK(jpe->expr))
return true;
if (WALK(jpe->output))
return true;
}
break;
case T_JsonScalarExpr:
{
JsonScalarExpr *jse = (JsonScalarExpr *) node;
if (WALK(jse->expr))
return true;
if (WALK(jse->output))
return true;
}
break;
case T_JsonSerializeExpr:
{
JsonSerializeExpr *jse = (JsonSerializeExpr *) node;
if (WALK(jse->expr))
return true;
if (WALK(jse->output))
return true;
}
break;
case T_JsonConstructorExpr:
{
JsonConstructorExpr *ctor = (JsonConstructorExpr *) node;
if (WALK(ctor->args))
return true;
if (WALK(ctor->func))
return true;
if (WALK(ctor->coercion))
return true;
if (WALK(ctor->returning))
return true;
}
break;
case T_JsonIsPredicate:
return WALK(((JsonIsPredicate *) node)->expr);
case T_JsonArgument:
return WALK(((JsonArgument *) node)->val);
case T_JsonFuncExpr:
{
JsonFuncExpr *jfe = (JsonFuncExpr *) node;
if (WALK(jfe->context_item))
return true;
if (WALK(jfe->pathspec))
return true;
if (WALK(jfe->passing))
return true;
if (WALK(jfe->output))
return true;
if (WALK(jfe->on_empty))
return true;
if (WALK(jfe->on_error))
return true;
}
break;
case T_JsonBehavior:
{
JsonBehavior *jb = (JsonBehavior *) node;
if (WALK(jb->expr))
return true;
}
break;
case T_JsonTable:
{
JsonTable *jt = (JsonTable *) node;
if (WALK(jt->context_item))
return true;
if (WALK(jt->pathspec))
return true;
if (WALK(jt->passing))
return true;
if (WALK(jt->columns))
return true;
if (WALK(jt->on_error))
return true;
}
break;
case T_JsonTableColumn:
{
JsonTableColumn *jtc = (JsonTableColumn *) node;
if (WALK(jtc->typeName))
return true;
if (WALK(jtc->on_empty))
return true;
if (WALK(jtc->on_error))
return true;
if (WALK(jtc->columns))
return true;
}
break;
case T_JsonTablePathSpec:
return WALK(((JsonTablePathSpec *) node)->string);
case T_NullTest:
return WALK(((NullTest *) node)->arg);
case T_BooleanTest:
return WALK(((BooleanTest *) node)->arg);
case T_JoinExpr:
{
JoinExpr *join = (JoinExpr *) node;
if (WALK(join->larg))
return true;
if (WALK(join->rarg))
return true;
if (WALK(join->quals))
return true;
if (WALK(join->alias))
return true;
}
break;
case T_IntoClause:
{
IntoClause *into = (IntoClause *) node;
if (WALK(into->rel))
return true;
if (WALK(into->viewQuery))
return true;
}
break;
case T_List:
foreach(temp, (List *) node)
{
if (WALK((Node *) lfirst(temp)))
return true;
}
break;
case T_InsertStmt:
{
InsertStmt *stmt = (InsertStmt *) node;
if (WALK(stmt->relation))
return true;
if (WALK(stmt->cols))
return true;
if (WALK(stmt->selectStmt))
return true;
if (WALK(stmt->onConflictClause))
return true;
if (WALK(stmt->returningList))
return true;
if (WALK(stmt->withClause))
return true;
}
break;
case T_DeleteStmt:
{
DeleteStmt *stmt = (DeleteStmt *) node;
if (WALK(stmt->relation))
return true;
if (WALK(stmt->usingClause))
return true;
if (WALK(stmt->whereClause))
return true;
if (WALK(stmt->returningList))
return true;
if (WALK(stmt->withClause))
return true;
}
break;
case T_UpdateStmt:
{
UpdateStmt *stmt = (UpdateStmt *) node;
if (WALK(stmt->relation))
return true;
if (WALK(stmt->targetList))
return true;
if (WALK(stmt->whereClause))
return true;
if (WALK(stmt->fromClause))
return true;
if (WALK(stmt->returningList))
return true;
if (WALK(stmt->withClause))
return true;
}
break;
case T_MergeStmt:
{
MergeStmt *stmt = (MergeStmt *) node;
if (WALK(stmt->relation))
return true;
if (WALK(stmt->sourceRelation))
return true;
if (WALK(stmt->joinCondition))
return true;
if (WALK(stmt->mergeWhenClauses))
return true;
if (WALK(stmt->returningList))
return true;
if (WALK(stmt->withClause))
return true;
}
break;
case T_MergeWhenClause:
{
MergeWhenClause *mergeWhenClause = (MergeWhenClause *) node;
if (WALK(mergeWhenClause->condition))
return true;
if (WALK(mergeWhenClause->targetList))
return true;
if (WALK(mergeWhenClause->values))
return true;
}
break;
case T_SelectStmt:
{
SelectStmt *stmt = (SelectStmt *) node;
if (WALK(stmt->distinctClause))
return true;
if (WALK(stmt->intoClause))
return true;
if (WALK(stmt->targetList))
return true;
if (WALK(stmt->fromClause))
return true;
if (WALK(stmt->whereClause))
return true;
if (WALK(stmt->groupClause))
return true;
if (WALK(stmt->havingClause))
return true;
if (WALK(stmt->windowClause))
return true;
if (WALK(stmt->valuesLists))
return true;
if (WALK(stmt->sortClause))
return true;
if (WALK(stmt->limitOffset))
return true;
if (WALK(stmt->limitCount))
return true;
if (WALK(stmt->lockingClause))
return true;
if (WALK(stmt->withClause))
return true;
if (WALK(stmt->larg))
return true;
if (WALK(stmt->rarg))
return true;
}
break;
case T_PLAssignStmt:
{
PLAssignStmt *stmt = (PLAssignStmt *) node;
if (WALK(stmt->indirection))
return true;
if (WALK(stmt->val))
return true;
}
break;
case T_A_Expr:
{
A_Expr *expr = (A_Expr *) node;
if (WALK(expr->lexpr))
return true;
if (WALK(expr->rexpr))
return true;
}
break;
case T_BoolExpr:
{
BoolExpr *expr = (BoolExpr *) node;
if (WALK(expr->args))
return true;
}
break;
case T_ColumnRef:
break;
case T_FuncCall:
{
FuncCall *fcall = (FuncCall *) node;
if (WALK(fcall->args))
return true;
if (WALK(fcall->agg_order))
return true;
if (WALK(fcall->agg_filter))
return true;
if (WALK(fcall->over))
return true;
}
break;
case T_NamedArgExpr:
return WALK(((NamedArgExpr *) node)->arg);
case T_A_Indices:
{
A_Indices *indices = (A_Indices *) node;
if (WALK(indices->lidx))
return true;
if (WALK(indices->uidx))
return true;
}
break;
case T_A_Indirection:
{
A_Indirection *indir = (A_Indirection *) node;
if (WALK(indir->arg))
return true;
if (WALK(indir->indirection))
return true;
}
break;
case T_A_ArrayExpr:
return WALK(((A_ArrayExpr *) node)->elements);
case T_ResTarget:
{
ResTarget *rt = (ResTarget *) node;
if (WALK(rt->indirection))
return true;
if (WALK(rt->val))
return true;
}
break;
case T_MultiAssignRef:
return WALK(((MultiAssignRef *) node)->source);
case T_TypeCast:
{
TypeCast *tc = (TypeCast *) node;
if (WALK(tc->arg))
return true;
if (WALK(tc->typeName))
return true;
}
break;
case T_CollateClause:
return WALK(((CollateClause *) node)->arg);
case T_SortBy:
return WALK(((SortBy *) node)->node);
case T_WindowDef:
{
WindowDef *wd = (WindowDef *) node;
if (WALK(wd->partitionClause))
return true;
if (WALK(wd->orderClause))
return true;
if (WALK(wd->startOffset))
return true;
if (WALK(wd->endOffset))
return true;
}
break;
case T_RangeSubselect:
{
RangeSubselect *rs = (RangeSubselect *) node;
if (WALK(rs->subquery))
return true;
if (WALK(rs->alias))
return true;
}
break;
case T_RangeFunction:
{
RangeFunction *rf = (RangeFunction *) node;
if (WALK(rf->functions))
return true;
if (WALK(rf->alias))
return true;
if (WALK(rf->coldeflist))
return true;
}
break;
case T_RangeTableSample:
{
RangeTableSample *rts = (RangeTableSample *) node;
if (WALK(rts->relation))
return true;
if (WALK(rts->args))
return true;
if (WALK(rts->repeatable))
return true;
}
break;
case T_RangeTableFunc:
{
RangeTableFunc *rtf = (RangeTableFunc *) node;
if (WALK(rtf->docexpr))
return true;
if (WALK(rtf->rowexpr))
return true;
if (WALK(rtf->namespaces))
return true;
if (WALK(rtf->columns))
return true;
if (WALK(rtf->alias))
return true;
}
break;
case T_RangeTableFuncCol:
{
RangeTableFuncCol *rtfc = (RangeTableFuncCol *) node;
if (WALK(rtfc->colexpr))
return true;
if (WALK(rtfc->coldefexpr))
return true;
}
break;
case T_TypeName:
{
TypeName *tn = (TypeName *) node;
if (WALK(tn->typmods))
return true;
if (WALK(tn->arrayBounds))
return true;
}
break;
case T_ColumnDef:
{
ColumnDef *coldef = (ColumnDef *) node;
if (WALK(coldef->typeName))
return true;
if (WALK(coldef->raw_default))
return true;
if (WALK(coldef->collClause))
return true;
}
break;
case T_IndexElem:
{
IndexElem *indelem = (IndexElem *) node;
if (WALK(indelem->expr))
return true;
}
break;
case T_GroupingSet:
return WALK(((GroupingSet *) node)->content);
case T_LockingClause:
return WALK(((LockingClause *) node)->lockedRels);
case T_XmlSerialize:
{
XmlSerialize *xs = (XmlSerialize *) node;
if (WALK(xs->expr))
return true;
if (WALK(xs->typeName))
return true;
}
break;
case T_WithClause:
return WALK(((WithClause *) node)->ctes);
case T_InferClause:
{
InferClause *stmt = (InferClause *) node;
if (WALK(stmt->indexElems))
return true;
if (WALK(stmt->whereClause))
return true;
}
break;
case T_OnConflictClause:
{
OnConflictClause *stmt = (OnConflictClause *) node;
if (WALK(stmt->infer))
return true;
if (WALK(stmt->targetList))
return true;
if (WALK(stmt->whereClause))
return true;
}
break;
case T_CommonTableExpr:
return WALK(((CommonTableExpr *) node)->ctequery);
case T_JsonOutput:
{
JsonOutput *out = (JsonOutput *) node;
if (WALK(out->typeName))
return true;
if (WALK(out->returning))
return true;
}
break;
case T_JsonKeyValue:
{
JsonKeyValue *jkv = (JsonKeyValue *) node;
if (WALK(jkv->key))
return true;
if (WALK(jkv->value))
return true;
}
break;
case T_JsonObjectConstructor:
{
JsonObjectConstructor *joc = (JsonObjectConstructor *) node;
if (WALK(joc->output))
return true;
if (WALK(joc->exprs))
return true;
}
break;
case T_JsonArrayConstructor:
{
JsonArrayConstructor *jac = (JsonArrayConstructor *) node;
if (WALK(jac->output))
return true;
if (WALK(jac->exprs))
return true;
}
break;
case T_JsonAggConstructor:
{
JsonAggConstructor *ctor = (JsonAggConstructor *) node;
if (WALK(ctor->output))
return true;
if (WALK(ctor->agg_order))
return true;
if (WALK(ctor->agg_filter))
return true;
if (WALK(ctor->over))
return true;
}
break;
case T_JsonObjectAgg:
{
JsonObjectAgg *joa = (JsonObjectAgg *) node;
if (WALK(joa->constructor))
return true;
if (WALK(joa->arg))
return true;
}
break;
case T_JsonArrayAgg:
{
JsonArrayAgg *jaa = (JsonArrayAgg *) node;
if (WALK(jaa->constructor))
return true;
if (WALK(jaa->arg))
return true;
}
break;
case T_JsonArrayQueryConstructor:
{
JsonArrayQueryConstructor *jaqc = (JsonArrayQueryConstructor *) node;
if (WALK(jaqc->output))
return true;
if (WALK(jaqc->query))
return true;
}
break;
default:
elog(ERROR, "unrecognized node type: %d",
(int) nodeTag(node));
break;
}
return false;
}
#define PSWALK(n) walker(n, context)