/*------------------------------------------------------------------------- * * outfuncs.c * Output functions for Postgres tree nodes. * * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.389 2010/08/18 15:21:54 tgl Exp $ * * NOTES * Every node type that can appear in stored rules' parsetrees *must* * have an output function defined here (as well as an input function * in readfuncs.c). For use in debugging, we also provide output * functions for nodes that appear in raw parsetrees, path, and plan trees. * These nodes however need not have input functions. * *------------------------------------------------------------------------- */ #include "postgres.h" #include #include "lib/stringinfo.h" #include "nodes/plannodes.h" #include "nodes/relation.h" #include "utils/datum.h" /* * Macros to simplify output of different kinds of fields. Use these * wherever possible to reduce the chance for silly typos. Note that these * hard-wire conventions about the names of the local variables in an Out * routine. */ /* Write the label for the node type */ #define WRITE_NODE_TYPE(nodelabel) \ appendStringInfoString(str, nodelabel) /* Write an integer field (anything written as ":fldname %d") */ #define WRITE_INT_FIELD(fldname) \ appendStringInfo(str, " :" CppAsString(fldname) " %d", node->fldname) /* Write an unsigned integer field (anything written as ":fldname %u") */ #define WRITE_UINT_FIELD(fldname) \ appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname) /* Write an OID field (don't hard-wire assumption that OID is same as uint) */ #define WRITE_OID_FIELD(fldname) \ appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname) /* Write a long-integer field */ #define WRITE_LONG_FIELD(fldname) \ appendStringInfo(str, " :" CppAsString(fldname) " %ld", node->fldname) /* Write a char field (ie, one ascii character) */ #define WRITE_CHAR_FIELD(fldname) \ appendStringInfo(str, " :" CppAsString(fldname) " %c", node->fldname) /* Write an enumerated-type field as an integer code */ #define WRITE_ENUM_FIELD(fldname, enumtype) \ appendStringInfo(str, " :" CppAsString(fldname) " %d", \ (int) node->fldname) /* Write a float field --- caller must give format to define precision */ #define WRITE_FLOAT_FIELD(fldname,format) \ appendStringInfo(str, " :" CppAsString(fldname) " " format, node->fldname) /* Write a boolean field */ #define WRITE_BOOL_FIELD(fldname) \ appendStringInfo(str, " :" CppAsString(fldname) " %s", \ booltostr(node->fldname)) /* Write a character-string (possibly NULL) field */ #define WRITE_STRING_FIELD(fldname) \ (appendStringInfo(str, " :" CppAsString(fldname) " "), \ _outToken(str, node->fldname)) /* Write a parse location field (actually same as INT case) */ #define WRITE_LOCATION_FIELD(fldname) \ appendStringInfo(str, " :" CppAsString(fldname) " %d", node->fldname) /* Write a Node field */ #define WRITE_NODE_FIELD(fldname) \ (appendStringInfo(str, " :" CppAsString(fldname) " "), \ _outNode(str, node->fldname)) /* Write a bitmapset field */ #define WRITE_BITMAPSET_FIELD(fldname) \ (appendStringInfo(str, " :" CppAsString(fldname) " "), \ _outBitmapset(str, node->fldname)) #define booltostr(x) ((x) ? "true" : "false") static void _outNode(StringInfo str, void *obj); /* * _outToken * Convert an ordinary string (eg, an identifier) into a form that * will be decoded back to a plain token by read.c's functions. * * If a null or empty string is given, it is encoded as "<>". */ static void _outToken(StringInfo str, char *s) { if (s == NULL || *s == '\0') { appendStringInfo(str, "<>"); return; } /* * Look for characters or patterns that are treated specially by read.c * (either in pg_strtok() or in nodeRead()), and therefore need a * protective backslash. */ /* These characters only need to be quoted at the start of the string */ if (*s == '<' || *s == '\"' || isdigit((unsigned char) *s) || ((*s == '+' || *s == '-') && (isdigit((unsigned char) s[1]) || s[1] == '.'))) appendStringInfoChar(str, '\\'); while (*s) { /* These chars must be backslashed anywhere in the string */ if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '(' || *s == ')' || *s == '{' || *s == '}' || *s == '\\') appendStringInfoChar(str, '\\'); appendStringInfoChar(str, *s++); } } static void _outList(StringInfo str, List *node) { ListCell *lc; appendStringInfoChar(str, '('); if (IsA(node, IntList)) appendStringInfoChar(str, 'i'); else if (IsA(node, OidList)) appendStringInfoChar(str, 'o'); foreach(lc, node) { /* * For the sake of backward compatibility, we emit a slightly * different whitespace format for lists of nodes vs. other types of * lists. XXX: is this necessary? */ if (IsA(node, List)) { _outNode(str, lfirst(lc)); if (lnext(lc)) appendStringInfoChar(str, ' '); } else if (IsA(node, IntList)) appendStringInfo(str, " %d", lfirst_int(lc)); else if (IsA(node, OidList)) appendStringInfo(str, " %u", lfirst_oid(lc)); else elog(ERROR, "unrecognized list node type: %d", (int) node->type); } appendStringInfoChar(str, ')'); } /* * _outBitmapset - * converts a bitmap set of integers * * Note: the output format is "(b int int ...)", similar to an integer List. */ static void _outBitmapset(StringInfo str, Bitmapset *bms) { Bitmapset *tmpset; int x; appendStringInfoChar(str, '('); appendStringInfoChar(str, 'b'); tmpset = bms_copy(bms); while ((x = bms_first_member(tmpset)) >= 0) appendStringInfo(str, " %d", x); bms_free(tmpset); appendStringInfoChar(str, ')'); } /* * Print the value of a Datum given its type. */ static void _outDatum(StringInfo str, Datum value, int typlen, bool typbyval) { Size length, i; char *s; length = datumGetSize(value, typbyval, typlen); if (typbyval) { s = (char *) (&value); appendStringInfo(str, "%u [ ", (unsigned int) length); for (i = 0; i < (Size) sizeof(Datum); i++) appendStringInfo(str, "%d ", (int) (s[i])); appendStringInfo(str, "]"); } else { s = (char *) DatumGetPointer(value); if (!PointerIsValid(s)) appendStringInfo(str, "0 [ ]"); else { appendStringInfo(str, "%u [ ", (unsigned int) length); for (i = 0; i < length; i++) appendStringInfo(str, "%d ", (int) (s[i])); appendStringInfo(str, "]"); } } } /* * Stuff from plannodes.h */ static void _outPlannedStmt(StringInfo str, PlannedStmt *node) { WRITE_NODE_TYPE("PLANNEDSTMT"); WRITE_ENUM_FIELD(commandType, CmdType); WRITE_BOOL_FIELD(hasReturning); WRITE_BOOL_FIELD(canSetTag); WRITE_BOOL_FIELD(transientPlan); WRITE_NODE_FIELD(planTree); WRITE_NODE_FIELD(rtable); WRITE_NODE_FIELD(resultRelations); WRITE_NODE_FIELD(utilityStmt); WRITE_NODE_FIELD(intoClause); WRITE_NODE_FIELD(subplans); WRITE_BITMAPSET_FIELD(rewindPlanIDs); WRITE_NODE_FIELD(rowMarks); WRITE_NODE_FIELD(relationOids); WRITE_NODE_FIELD(invalItems); WRITE_INT_FIELD(nParamExec); } /* * print the basic stuff of all nodes that inherit from Plan */ static void _outPlanInfo(StringInfo str, Plan *node) { WRITE_FLOAT_FIELD(startup_cost, "%.2f"); WRITE_FLOAT_FIELD(total_cost, "%.2f"); WRITE_FLOAT_FIELD(plan_rows, "%.0f"); WRITE_INT_FIELD(plan_width); WRITE_NODE_FIELD(targetlist); WRITE_NODE_FIELD(qual); WRITE_NODE_FIELD(lefttree); WRITE_NODE_FIELD(righttree); WRITE_NODE_FIELD(initPlan); WRITE_BITMAPSET_FIELD(extParam); WRITE_BITMAPSET_FIELD(allParam); } /* * print the basic stuff of all nodes that inherit from Scan */ static void _outScanInfo(StringInfo str, Scan *node) { _outPlanInfo(str, (Plan *) node); WRITE_UINT_FIELD(scanrelid); } /* * print the basic stuff of all nodes that inherit from Join */ static void _outJoinPlanInfo(StringInfo str, Join *node) { _outPlanInfo(str, (Plan *) node); WRITE_ENUM_FIELD(jointype, JoinType); WRITE_NODE_FIELD(joinqual); } static void _outPlan(StringInfo str, Plan *node) { WRITE_NODE_TYPE("PLAN"); _outPlanInfo(str, (Plan *) node); } static void _outResult(StringInfo str, Result *node) { WRITE_NODE_TYPE("RESULT"); _outPlanInfo(str, (Plan *) node); WRITE_NODE_FIELD(resconstantqual); } static void _outModifyTable(StringInfo str, ModifyTable *node) { WRITE_NODE_TYPE("MODIFYTABLE"); _outPlanInfo(str, (Plan *) node); WRITE_ENUM_FIELD(operation, CmdType); WRITE_NODE_FIELD(resultRelations); WRITE_NODE_FIELD(plans); WRITE_NODE_FIELD(returningLists); WRITE_NODE_FIELD(rowMarks); WRITE_INT_FIELD(epqParam); } static void _outAppend(StringInfo str, Append *node) { WRITE_NODE_TYPE("APPEND"); _outPlanInfo(str, (Plan *) node); WRITE_NODE_FIELD(appendplans); } static void _outRecursiveUnion(StringInfo str, RecursiveUnion *node) { int i; WRITE_NODE_TYPE("RECURSIVEUNION"); _outPlanInfo(str, (Plan *) node); WRITE_INT_FIELD(wtParam); WRITE_INT_FIELD(numCols); appendStringInfo(str, " :dupColIdx"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %d", node->dupColIdx[i]); appendStringInfo(str, " :dupOperators"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %u", node->dupOperators[i]); WRITE_LONG_FIELD(numGroups); } static void _outBitmapAnd(StringInfo str, BitmapAnd *node) { WRITE_NODE_TYPE("BITMAPAND"); _outPlanInfo(str, (Plan *) node); WRITE_NODE_FIELD(bitmapplans); } static void _outBitmapOr(StringInfo str, BitmapOr *node) { WRITE_NODE_TYPE("BITMAPOR"); _outPlanInfo(str, (Plan *) node); WRITE_NODE_FIELD(bitmapplans); } static void _outScan(StringInfo str, Scan *node) { WRITE_NODE_TYPE("SCAN"); _outScanInfo(str, (Scan *) node); } static void _outSeqScan(StringInfo str, SeqScan *node) { WRITE_NODE_TYPE("SEQSCAN"); _outScanInfo(str, (Scan *) node); } static void _outIndexScan(StringInfo str, IndexScan *node) { WRITE_NODE_TYPE("INDEXSCAN"); _outScanInfo(str, (Scan *) node); WRITE_OID_FIELD(indexid); WRITE_NODE_FIELD(indexqual); WRITE_NODE_FIELD(indexqualorig); WRITE_ENUM_FIELD(indexorderdir, ScanDirection); } static void _outBitmapIndexScan(StringInfo str, BitmapIndexScan *node) { WRITE_NODE_TYPE("BITMAPINDEXSCAN"); _outScanInfo(str, (Scan *) node); WRITE_OID_FIELD(indexid); WRITE_NODE_FIELD(indexqual); WRITE_NODE_FIELD(indexqualorig); } static void _outBitmapHeapScan(StringInfo str, BitmapHeapScan *node) { WRITE_NODE_TYPE("BITMAPHEAPSCAN"); _outScanInfo(str, (Scan *) node); WRITE_NODE_FIELD(bitmapqualorig); } static void _outTidScan(StringInfo str, TidScan *node) { WRITE_NODE_TYPE("TIDSCAN"); _outScanInfo(str, (Scan *) node); WRITE_NODE_FIELD(tidquals); } static void _outSubqueryScan(StringInfo str, SubqueryScan *node) { WRITE_NODE_TYPE("SUBQUERYSCAN"); _outScanInfo(str, (Scan *) node); WRITE_NODE_FIELD(subplan); WRITE_NODE_FIELD(subrtable); WRITE_NODE_FIELD(subrowmark); } static void _outFunctionScan(StringInfo str, FunctionScan *node) { WRITE_NODE_TYPE("FUNCTIONSCAN"); _outScanInfo(str, (Scan *) node); WRITE_NODE_FIELD(funcexpr); WRITE_NODE_FIELD(funccolnames); WRITE_NODE_FIELD(funccoltypes); WRITE_NODE_FIELD(funccoltypmods); } static void _outValuesScan(StringInfo str, ValuesScan *node) { WRITE_NODE_TYPE("VALUESSCAN"); _outScanInfo(str, (Scan *) node); WRITE_NODE_FIELD(values_lists); } static void _outCteScan(StringInfo str, CteScan *node) { WRITE_NODE_TYPE("CTESCAN"); _outScanInfo(str, (Scan *) node); WRITE_INT_FIELD(ctePlanId); WRITE_INT_FIELD(cteParam); } static void _outWorkTableScan(StringInfo str, WorkTableScan *node) { WRITE_NODE_TYPE("WORKTABLESCAN"); _outScanInfo(str, (Scan *) node); WRITE_INT_FIELD(wtParam); } static void _outJoin(StringInfo str, Join *node) { WRITE_NODE_TYPE("JOIN"); _outJoinPlanInfo(str, (Join *) node); } static void _outNestLoop(StringInfo str, NestLoop *node) { WRITE_NODE_TYPE("NESTLOOP"); _outJoinPlanInfo(str, (Join *) node); WRITE_NODE_FIELD(nestParams); } static void _outMergeJoin(StringInfo str, MergeJoin *node) { int numCols; int i; WRITE_NODE_TYPE("MERGEJOIN"); _outJoinPlanInfo(str, (Join *) node); WRITE_NODE_FIELD(mergeclauses); numCols = list_length(node->mergeclauses); appendStringInfo(str, " :mergeFamilies"); for (i = 0; i < numCols; i++) appendStringInfo(str, " %u", node->mergeFamilies[i]); appendStringInfo(str, " :mergeStrategies"); for (i = 0; i < numCols; i++) appendStringInfo(str, " %d", node->mergeStrategies[i]); appendStringInfo(str, " :mergeNullsFirst"); for (i = 0; i < numCols; i++) appendStringInfo(str, " %d", (int) node->mergeNullsFirst[i]); } static void _outHashJoin(StringInfo str, HashJoin *node) { WRITE_NODE_TYPE("HASHJOIN"); _outJoinPlanInfo(str, (Join *) node); WRITE_NODE_FIELD(hashclauses); } static void _outAgg(StringInfo str, Agg *node) { int i; WRITE_NODE_TYPE("AGG"); _outPlanInfo(str, (Plan *) node); WRITE_ENUM_FIELD(aggstrategy, AggStrategy); WRITE_INT_FIELD(numCols); appendStringInfo(str, " :grpColIdx"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %d", node->grpColIdx[i]); appendStringInfo(str, " :grpOperators"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %u", node->grpOperators[i]); WRITE_LONG_FIELD(numGroups); } static void _outWindowAgg(StringInfo str, WindowAgg *node) { int i; WRITE_NODE_TYPE("WINDOWAGG"); _outPlanInfo(str, (Plan *) node); WRITE_UINT_FIELD(winref); WRITE_INT_FIELD(partNumCols); appendStringInfo(str, " :partColIdx"); for (i = 0; i < node->partNumCols; i++) appendStringInfo(str, " %d", node->partColIdx[i]); appendStringInfo(str, " :partOperations"); for (i = 0; i < node->partNumCols; i++) appendStringInfo(str, " %u", node->partOperators[i]); WRITE_INT_FIELD(ordNumCols); appendStringInfo(str, " :ordColIdx"); for (i = 0; i < node->ordNumCols; i++) appendStringInfo(str, " %d", node->ordColIdx[i]); appendStringInfo(str, " :ordOperations"); for (i = 0; i < node->ordNumCols; i++) appendStringInfo(str, " %u", node->ordOperators[i]); WRITE_INT_FIELD(frameOptions); WRITE_NODE_FIELD(startOffset); WRITE_NODE_FIELD(endOffset); } static void _outGroup(StringInfo str, Group *node) { int i; WRITE_NODE_TYPE("GROUP"); _outPlanInfo(str, (Plan *) node); WRITE_INT_FIELD(numCols); appendStringInfo(str, " :grpColIdx"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %d", node->grpColIdx[i]); appendStringInfo(str, " :grpOperators"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %u", node->grpOperators[i]); } static void _outMaterial(StringInfo str, Material *node) { WRITE_NODE_TYPE("MATERIAL"); _outPlanInfo(str, (Plan *) node); } static void _outSort(StringInfo str, Sort *node) { int i; WRITE_NODE_TYPE("SORT"); _outPlanInfo(str, (Plan *) node); WRITE_INT_FIELD(numCols); appendStringInfo(str, " :sortColIdx"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %d", node->sortColIdx[i]); appendStringInfo(str, " :sortOperators"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %u", node->sortOperators[i]); appendStringInfo(str, " :nullsFirst"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %s", booltostr(node->nullsFirst[i])); } static void _outUnique(StringInfo str, Unique *node) { int i; WRITE_NODE_TYPE("UNIQUE"); _outPlanInfo(str, (Plan *) node); WRITE_INT_FIELD(numCols); appendStringInfo(str, " :uniqColIdx"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %d", node->uniqColIdx[i]); appendStringInfo(str, " :uniqOperators"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %u", node->uniqOperators[i]); } static void _outHash(StringInfo str, Hash *node) { WRITE_NODE_TYPE("HASH"); _outPlanInfo(str, (Plan *) node); WRITE_OID_FIELD(skewTable); WRITE_INT_FIELD(skewColumn); WRITE_BOOL_FIELD(skewInherit); WRITE_OID_FIELD(skewColType); WRITE_INT_FIELD(skewColTypmod); } static void _outSetOp(StringInfo str, SetOp *node) { int i; WRITE_NODE_TYPE("SETOP"); _outPlanInfo(str, (Plan *) node); WRITE_ENUM_FIELD(cmd, SetOpCmd); WRITE_ENUM_FIELD(strategy, SetOpStrategy); WRITE_INT_FIELD(numCols); appendStringInfo(str, " :dupColIdx"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %d", node->dupColIdx[i]); appendStringInfo(str, " :dupOperators"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %u", node->dupOperators[i]); WRITE_INT_FIELD(flagColIdx); WRITE_INT_FIELD(firstFlag); WRITE_LONG_FIELD(numGroups); } static void _outLockRows(StringInfo str, LockRows *node) { WRITE_NODE_TYPE("LOCKROWS"); _outPlanInfo(str, (Plan *) node); WRITE_NODE_FIELD(rowMarks); WRITE_INT_FIELD(epqParam); } static void _outLimit(StringInfo str, Limit *node) { WRITE_NODE_TYPE("LIMIT"); _outPlanInfo(str, (Plan *) node); WRITE_NODE_FIELD(limitOffset); WRITE_NODE_FIELD(limitCount); } static void _outNestLoopParam(StringInfo str, NestLoopParam *node) { WRITE_NODE_TYPE("NESTLOOPPARAM"); WRITE_INT_FIELD(paramno); WRITE_NODE_FIELD(paramval); } static void _outPlanRowMark(StringInfo str, PlanRowMark *node) { WRITE_NODE_TYPE("PLANROWMARK"); WRITE_UINT_FIELD(rti); WRITE_UINT_FIELD(prti); WRITE_ENUM_FIELD(markType, RowMarkType); WRITE_BOOL_FIELD(noWait); WRITE_BOOL_FIELD(isParent); WRITE_INT_FIELD(ctidAttNo); WRITE_INT_FIELD(toidAttNo); WRITE_INT_FIELD(wholeAttNo); } static void _outPlanInvalItem(StringInfo str, PlanInvalItem *node) { WRITE_NODE_TYPE("PLANINVALITEM"); WRITE_INT_FIELD(cacheId); appendStringInfo(str, " :tupleId (%u,%u)", ItemPointerGetBlockNumber(&node->tupleId), ItemPointerGetOffsetNumber(&node->tupleId)); } /***************************************************************************** * * Stuff from primnodes.h. * *****************************************************************************/ static void _outAlias(StringInfo str, Alias *node) { WRITE_NODE_TYPE("ALIAS"); WRITE_STRING_FIELD(aliasname); WRITE_NODE_FIELD(colnames); } static void _outRangeVar(StringInfo str, RangeVar *node) { WRITE_NODE_TYPE("RANGEVAR"); /* * we deliberately ignore catalogname here, since it is presently not * semantically meaningful */ WRITE_STRING_FIELD(schemaname); WRITE_STRING_FIELD(relname); WRITE_ENUM_FIELD(inhOpt, InhOption); WRITE_BOOL_FIELD(istemp); WRITE_NODE_FIELD(alias); WRITE_LOCATION_FIELD(location); } static void _outIntoClause(StringInfo str, IntoClause *node) { WRITE_NODE_TYPE("INTOCLAUSE"); WRITE_NODE_FIELD(rel); WRITE_NODE_FIELD(colNames); WRITE_NODE_FIELD(options); WRITE_ENUM_FIELD(onCommit, OnCommitAction); WRITE_STRING_FIELD(tableSpaceName); } static void _outVar(StringInfo str, Var *node) { WRITE_NODE_TYPE("VAR"); WRITE_UINT_FIELD(varno); WRITE_INT_FIELD(varattno); WRITE_OID_FIELD(vartype); WRITE_INT_FIELD(vartypmod); WRITE_UINT_FIELD(varlevelsup); WRITE_UINT_FIELD(varnoold); WRITE_INT_FIELD(varoattno); WRITE_LOCATION_FIELD(location); } static void _outConst(StringInfo str, Const *node) { WRITE_NODE_TYPE("CONST"); WRITE_OID_FIELD(consttype); WRITE_INT_FIELD(consttypmod); WRITE_INT_FIELD(constlen); WRITE_BOOL_FIELD(constbyval); WRITE_BOOL_FIELD(constisnull); WRITE_LOCATION_FIELD(location); appendStringInfo(str, " :constvalue "); if (node->constisnull) appendStringInfo(str, "<>"); else _outDatum(str, node->constvalue, node->constlen, node->constbyval); } static void _outParam(StringInfo str, Param *node) { WRITE_NODE_TYPE("PARAM"); WRITE_ENUM_FIELD(paramkind, ParamKind); WRITE_INT_FIELD(paramid); WRITE_OID_FIELD(paramtype); WRITE_INT_FIELD(paramtypmod); WRITE_LOCATION_FIELD(location); } static void _outAggref(StringInfo str, Aggref *node) { WRITE_NODE_TYPE("AGGREF"); WRITE_OID_FIELD(aggfnoid); WRITE_OID_FIELD(aggtype); WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(aggorder); WRITE_NODE_FIELD(aggdistinct); WRITE_BOOL_FIELD(aggstar); WRITE_UINT_FIELD(agglevelsup); WRITE_LOCATION_FIELD(location); } static void _outWindowFunc(StringInfo str, WindowFunc *node) { WRITE_NODE_TYPE("WINDOWFUNC"); WRITE_OID_FIELD(winfnoid); WRITE_OID_FIELD(wintype); WRITE_NODE_FIELD(args); WRITE_UINT_FIELD(winref); WRITE_BOOL_FIELD(winstar); WRITE_BOOL_FIELD(winagg); WRITE_LOCATION_FIELD(location); } static void _outArrayRef(StringInfo str, ArrayRef *node) { WRITE_NODE_TYPE("ARRAYREF"); WRITE_OID_FIELD(refarraytype); WRITE_OID_FIELD(refelemtype); WRITE_INT_FIELD(reftypmod); WRITE_NODE_FIELD(refupperindexpr); WRITE_NODE_FIELD(reflowerindexpr); WRITE_NODE_FIELD(refexpr); WRITE_NODE_FIELD(refassgnexpr); } static void _outFuncExpr(StringInfo str, FuncExpr *node) { WRITE_NODE_TYPE("FUNCEXPR"); WRITE_OID_FIELD(funcid); WRITE_OID_FIELD(funcresulttype); WRITE_BOOL_FIELD(funcretset); WRITE_ENUM_FIELD(funcformat, CoercionForm); WRITE_NODE_FIELD(args); WRITE_LOCATION_FIELD(location); } static void _outNamedArgExpr(StringInfo str, NamedArgExpr *node) { WRITE_NODE_TYPE("NAMEDARGEXPR"); WRITE_NODE_FIELD(arg); WRITE_STRING_FIELD(name); WRITE_INT_FIELD(argnumber); WRITE_LOCATION_FIELD(location); } static void _outOpExpr(StringInfo str, OpExpr *node) { WRITE_NODE_TYPE("OPEXPR"); WRITE_OID_FIELD(opno); WRITE_OID_FIELD(opfuncid); WRITE_OID_FIELD(opresulttype); WRITE_BOOL_FIELD(opretset); WRITE_NODE_FIELD(args); WRITE_LOCATION_FIELD(location); } static void _outDistinctExpr(StringInfo str, DistinctExpr *node) { WRITE_NODE_TYPE("DISTINCTEXPR"); WRITE_OID_FIELD(opno); WRITE_OID_FIELD(opfuncid); WRITE_OID_FIELD(opresulttype); WRITE_BOOL_FIELD(opretset); WRITE_NODE_FIELD(args); WRITE_LOCATION_FIELD(location); } static void _outScalarArrayOpExpr(StringInfo str, ScalarArrayOpExpr *node) { WRITE_NODE_TYPE("SCALARARRAYOPEXPR"); WRITE_OID_FIELD(opno); WRITE_OID_FIELD(opfuncid); WRITE_BOOL_FIELD(useOr); WRITE_NODE_FIELD(args); WRITE_LOCATION_FIELD(location); } static void _outBoolExpr(StringInfo str, BoolExpr *node) { char *opstr = NULL; WRITE_NODE_TYPE("BOOLEXPR"); /* do-it-yourself enum representation */ switch (node->boolop) { case AND_EXPR: opstr = "and"; break; case OR_EXPR: opstr = "or"; break; case NOT_EXPR: opstr = "not"; break; } appendStringInfo(str, " :boolop "); _outToken(str, opstr); WRITE_NODE_FIELD(args); WRITE_LOCATION_FIELD(location); } static void _outSubLink(StringInfo str, SubLink *node) { WRITE_NODE_TYPE("SUBLINK"); WRITE_ENUM_FIELD(subLinkType, SubLinkType); WRITE_NODE_FIELD(testexpr); WRITE_NODE_FIELD(operName); WRITE_NODE_FIELD(subselect); WRITE_LOCATION_FIELD(location); } static void _outSubPlan(StringInfo str, SubPlan *node) { WRITE_NODE_TYPE("SUBPLAN"); WRITE_ENUM_FIELD(subLinkType, SubLinkType); WRITE_NODE_FIELD(testexpr); WRITE_NODE_FIELD(paramIds); WRITE_INT_FIELD(plan_id); WRITE_STRING_FIELD(plan_name); WRITE_OID_FIELD(firstColType); WRITE_INT_FIELD(firstColTypmod); WRITE_BOOL_FIELD(useHashTable); WRITE_BOOL_FIELD(unknownEqFalse); WRITE_NODE_FIELD(setParam); WRITE_NODE_FIELD(parParam); WRITE_NODE_FIELD(args); WRITE_FLOAT_FIELD(startup_cost, "%.2f"); WRITE_FLOAT_FIELD(per_call_cost, "%.2f"); } static void _outAlternativeSubPlan(StringInfo str, AlternativeSubPlan *node) { WRITE_NODE_TYPE("ALTERNATIVESUBPLAN"); WRITE_NODE_FIELD(subplans); } static void _outFieldSelect(StringInfo str, FieldSelect *node) { WRITE_NODE_TYPE("FIELDSELECT"); WRITE_NODE_FIELD(arg); WRITE_INT_FIELD(fieldnum); WRITE_OID_FIELD(resulttype); WRITE_INT_FIELD(resulttypmod); } static void _outFieldStore(StringInfo str, FieldStore *node) { WRITE_NODE_TYPE("FIELDSTORE"); WRITE_NODE_FIELD(arg); WRITE_NODE_FIELD(newvals); WRITE_NODE_FIELD(fieldnums); WRITE_OID_FIELD(resulttype); } static void _outRelabelType(StringInfo str, RelabelType *node) { WRITE_NODE_TYPE("RELABELTYPE"); WRITE_NODE_FIELD(arg); WRITE_OID_FIELD(resulttype); WRITE_INT_FIELD(resulttypmod); WRITE_ENUM_FIELD(relabelformat, CoercionForm); WRITE_LOCATION_FIELD(location); } static void _outCoerceViaIO(StringInfo str, CoerceViaIO *node) { WRITE_NODE_TYPE("COERCEVIAIO"); WRITE_NODE_FIELD(arg); WRITE_OID_FIELD(resulttype); WRITE_ENUM_FIELD(coerceformat, CoercionForm); WRITE_LOCATION_FIELD(location); } static void _outArrayCoerceExpr(StringInfo str, ArrayCoerceExpr *node) { WRITE_NODE_TYPE("ARRAYCOERCEEXPR"); WRITE_NODE_FIELD(arg); WRITE_OID_FIELD(elemfuncid); WRITE_OID_FIELD(resulttype); WRITE_INT_FIELD(resulttypmod); WRITE_BOOL_FIELD(isExplicit); WRITE_ENUM_FIELD(coerceformat, CoercionForm); WRITE_LOCATION_FIELD(location); } static void _outConvertRowtypeExpr(StringInfo str, ConvertRowtypeExpr *node) { WRITE_NODE_TYPE("CONVERTROWTYPEEXPR"); WRITE_NODE_FIELD(arg); WRITE_OID_FIELD(resulttype); WRITE_ENUM_FIELD(convertformat, CoercionForm); WRITE_LOCATION_FIELD(location); } static void _outCaseExpr(StringInfo str, CaseExpr *node) { WRITE_NODE_TYPE("CASE"); WRITE_OID_FIELD(casetype); WRITE_NODE_FIELD(arg); WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(defresult); WRITE_LOCATION_FIELD(location); } static void _outCaseWhen(StringInfo str, CaseWhen *node) { WRITE_NODE_TYPE("WHEN"); WRITE_NODE_FIELD(expr); WRITE_NODE_FIELD(result); WRITE_LOCATION_FIELD(location); } static void _outCaseTestExpr(StringInfo str, CaseTestExpr *node) { WRITE_NODE_TYPE("CASETESTEXPR"); WRITE_OID_FIELD(typeId); WRITE_INT_FIELD(typeMod); } static void _outArrayExpr(StringInfo str, ArrayExpr *node) { WRITE_NODE_TYPE("ARRAY"); WRITE_OID_FIELD(array_typeid); WRITE_OID_FIELD(element_typeid); WRITE_NODE_FIELD(elements); WRITE_BOOL_FIELD(multidims); WRITE_LOCATION_FIELD(location); } static void _outRowExpr(StringInfo str, RowExpr *node) { WRITE_NODE_TYPE("ROW"); WRITE_NODE_FIELD(args); WRITE_OID_FIELD(row_typeid); WRITE_ENUM_FIELD(row_format, CoercionForm); WRITE_NODE_FIELD(colnames); WRITE_LOCATION_FIELD(location); } static void _outRowCompareExpr(StringInfo str, RowCompareExpr *node) { WRITE_NODE_TYPE("ROWCOMPARE"); WRITE_ENUM_FIELD(rctype, RowCompareType); WRITE_NODE_FIELD(opnos); WRITE_NODE_FIELD(opfamilies); WRITE_NODE_FIELD(largs); WRITE_NODE_FIELD(rargs); } static void _outCoalesceExpr(StringInfo str, CoalesceExpr *node) { WRITE_NODE_TYPE("COALESCE"); WRITE_OID_FIELD(coalescetype); WRITE_NODE_FIELD(args); WRITE_LOCATION_FIELD(location); } static void _outMinMaxExpr(StringInfo str, MinMaxExpr *node) { WRITE_NODE_TYPE("MINMAX"); WRITE_OID_FIELD(minmaxtype); WRITE_ENUM_FIELD(op, MinMaxOp); WRITE_NODE_FIELD(args); WRITE_LOCATION_FIELD(location); } static void _outXmlExpr(StringInfo str, XmlExpr *node) { WRITE_NODE_TYPE("XMLEXPR"); WRITE_ENUM_FIELD(op, XmlExprOp); WRITE_STRING_FIELD(name); WRITE_NODE_FIELD(named_args); WRITE_NODE_FIELD(arg_names); WRITE_NODE_FIELD(args); WRITE_ENUM_FIELD(xmloption, XmlOptionType); WRITE_OID_FIELD(type); WRITE_INT_FIELD(typmod); WRITE_LOCATION_FIELD(location); } static void _outNullIfExpr(StringInfo str, NullIfExpr *node) { WRITE_NODE_TYPE("NULLIFEXPR"); WRITE_OID_FIELD(opno); WRITE_OID_FIELD(opfuncid); WRITE_OID_FIELD(opresulttype); WRITE_BOOL_FIELD(opretset); WRITE_NODE_FIELD(args); WRITE_LOCATION_FIELD(location); } static void _outNullTest(StringInfo str, NullTest *node) { WRITE_NODE_TYPE("NULLTEST"); WRITE_NODE_FIELD(arg); WRITE_ENUM_FIELD(nulltesttype, NullTestType); WRITE_BOOL_FIELD(argisrow); } static void _outBooleanTest(StringInfo str, BooleanTest *node) { WRITE_NODE_TYPE("BOOLEANTEST"); WRITE_NODE_FIELD(arg); WRITE_ENUM_FIELD(booltesttype, BoolTestType); } static void _outCoerceToDomain(StringInfo str, CoerceToDomain *node) { WRITE_NODE_TYPE("COERCETODOMAIN"); WRITE_NODE_FIELD(arg); WRITE_OID_FIELD(resulttype); WRITE_INT_FIELD(resulttypmod); WRITE_ENUM_FIELD(coercionformat, CoercionForm); WRITE_LOCATION_FIELD(location); } static void _outCoerceToDomainValue(StringInfo str, CoerceToDomainValue *node) { WRITE_NODE_TYPE("COERCETODOMAINVALUE"); WRITE_OID_FIELD(typeId); WRITE_INT_FIELD(typeMod); WRITE_LOCATION_FIELD(location); } static void _outSetToDefault(StringInfo str, SetToDefault *node) { WRITE_NODE_TYPE("SETTODEFAULT"); WRITE_OID_FIELD(typeId); WRITE_INT_FIELD(typeMod); WRITE_LOCATION_FIELD(location); } static void _outCurrentOfExpr(StringInfo str, CurrentOfExpr *node) { WRITE_NODE_TYPE("CURRENTOFEXPR"); WRITE_UINT_FIELD(cvarno); WRITE_STRING_FIELD(cursor_name); WRITE_INT_FIELD(cursor_param); } static void _outTargetEntry(StringInfo str, TargetEntry *node) { WRITE_NODE_TYPE("TARGETENTRY"); WRITE_NODE_FIELD(expr); WRITE_INT_FIELD(resno); WRITE_STRING_FIELD(resname); WRITE_UINT_FIELD(ressortgroupref); WRITE_OID_FIELD(resorigtbl); WRITE_INT_FIELD(resorigcol); WRITE_BOOL_FIELD(resjunk); } static void _outRangeTblRef(StringInfo str, RangeTblRef *node) { WRITE_NODE_TYPE("RANGETBLREF"); WRITE_INT_FIELD(rtindex); } static void _outJoinExpr(StringInfo str, JoinExpr *node) { WRITE_NODE_TYPE("JOINEXPR"); WRITE_ENUM_FIELD(jointype, JoinType); WRITE_BOOL_FIELD(isNatural); WRITE_NODE_FIELD(larg); WRITE_NODE_FIELD(rarg); WRITE_NODE_FIELD(usingClause); WRITE_NODE_FIELD(quals); WRITE_NODE_FIELD(alias); WRITE_INT_FIELD(rtindex); } static void _outFromExpr(StringInfo str, FromExpr *node) { WRITE_NODE_TYPE("FROMEXPR"); WRITE_NODE_FIELD(fromlist); WRITE_NODE_FIELD(quals); } /***************************************************************************** * * Stuff from relation.h. * *****************************************************************************/ /* * print the basic stuff of all nodes that inherit from Path * * Note we do NOT print the parent, else we'd be in infinite recursion */ static void _outPathInfo(StringInfo str, Path *node) { WRITE_ENUM_FIELD(pathtype, NodeTag); WRITE_FLOAT_FIELD(startup_cost, "%.2f"); WRITE_FLOAT_FIELD(total_cost, "%.2f"); WRITE_NODE_FIELD(pathkeys); } /* * print the basic stuff of all nodes that inherit from JoinPath */ static void _outJoinPathInfo(StringInfo str, JoinPath *node) { _outPathInfo(str, (Path *) node); WRITE_ENUM_FIELD(jointype, JoinType); WRITE_NODE_FIELD(outerjoinpath); WRITE_NODE_FIELD(innerjoinpath); WRITE_NODE_FIELD(joinrestrictinfo); } static void _outPath(StringInfo str, Path *node) { WRITE_NODE_TYPE("PATH"); _outPathInfo(str, (Path *) node); } static void _outIndexPath(StringInfo str, IndexPath *node) { WRITE_NODE_TYPE("INDEXPATH"); _outPathInfo(str, (Path *) node); WRITE_NODE_FIELD(indexinfo); WRITE_NODE_FIELD(indexclauses); WRITE_NODE_FIELD(indexquals); WRITE_BOOL_FIELD(isjoininner); WRITE_ENUM_FIELD(indexscandir, ScanDirection); WRITE_FLOAT_FIELD(indextotalcost, "%.2f"); WRITE_FLOAT_FIELD(indexselectivity, "%.4f"); WRITE_FLOAT_FIELD(rows, "%.0f"); } static void _outBitmapHeapPath(StringInfo str, BitmapHeapPath *node) { WRITE_NODE_TYPE("BITMAPHEAPPATH"); _outPathInfo(str, (Path *) node); WRITE_NODE_FIELD(bitmapqual); WRITE_BOOL_FIELD(isjoininner); WRITE_FLOAT_FIELD(rows, "%.0f"); } static void _outBitmapAndPath(StringInfo str, BitmapAndPath *node) { WRITE_NODE_TYPE("BITMAPANDPATH"); _outPathInfo(str, (Path *) node); WRITE_NODE_FIELD(bitmapquals); WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f"); } static void _outBitmapOrPath(StringInfo str, BitmapOrPath *node) { WRITE_NODE_TYPE("BITMAPORPATH"); _outPathInfo(str, (Path *) node); WRITE_NODE_FIELD(bitmapquals); WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f"); } static void _outTidPath(StringInfo str, TidPath *node) { WRITE_NODE_TYPE("TIDPATH"); _outPathInfo(str, (Path *) node); WRITE_NODE_FIELD(tidquals); } static void _outAppendPath(StringInfo str, AppendPath *node) { WRITE_NODE_TYPE("APPENDPATH"); _outPathInfo(str, (Path *) node); WRITE_NODE_FIELD(subpaths); } static void _outResultPath(StringInfo str, ResultPath *node) { WRITE_NODE_TYPE("RESULTPATH"); _outPathInfo(str, (Path *) node); WRITE_NODE_FIELD(quals); } static void _outMaterialPath(StringInfo str, MaterialPath *node) { WRITE_NODE_TYPE("MATERIALPATH"); _outPathInfo(str, (Path *) node); WRITE_NODE_FIELD(subpath); } static void _outUniquePath(StringInfo str, UniquePath *node) { WRITE_NODE_TYPE("UNIQUEPATH"); _outPathInfo(str, (Path *) node); WRITE_NODE_FIELD(subpath); WRITE_ENUM_FIELD(umethod, UniquePathMethod); WRITE_NODE_FIELD(in_operators); WRITE_NODE_FIELD(uniq_exprs); WRITE_FLOAT_FIELD(rows, "%.0f"); } static void _outNestPath(StringInfo str, NestPath *node) { WRITE_NODE_TYPE("NESTPATH"); _outJoinPathInfo(str, (JoinPath *) node); } static void _outMergePath(StringInfo str, MergePath *node) { WRITE_NODE_TYPE("MERGEPATH"); _outJoinPathInfo(str, (JoinPath *) node); WRITE_NODE_FIELD(path_mergeclauses); WRITE_NODE_FIELD(outersortkeys); WRITE_NODE_FIELD(innersortkeys); WRITE_BOOL_FIELD(materialize_inner); } static void _outHashPath(StringInfo str, HashPath *node) { WRITE_NODE_TYPE("HASHPATH"); _outJoinPathInfo(str, (JoinPath *) node); WRITE_NODE_FIELD(path_hashclauses); WRITE_INT_FIELD(num_batches); } static void _outPlannerGlobal(StringInfo str, PlannerGlobal *node) { WRITE_NODE_TYPE("PLANNERGLOBAL"); /* NB: this isn't a complete set of fields */ WRITE_NODE_FIELD(paramlist); WRITE_NODE_FIELD(subplans); WRITE_NODE_FIELD(subrtables); WRITE_NODE_FIELD(subrowmarks); WRITE_BITMAPSET_FIELD(rewindPlanIDs); WRITE_NODE_FIELD(finalrtable); WRITE_NODE_FIELD(finalrowmarks); WRITE_NODE_FIELD(relationOids); WRITE_NODE_FIELD(invalItems); WRITE_UINT_FIELD(lastPHId); WRITE_BOOL_FIELD(transientPlan); } static void _outPlannerInfo(StringInfo str, PlannerInfo *node) { WRITE_NODE_TYPE("PLANNERINFO"); /* NB: this isn't a complete set of fields */ WRITE_NODE_FIELD(parse); WRITE_NODE_FIELD(glob); WRITE_UINT_FIELD(query_level); WRITE_NODE_FIELD(join_rel_list); WRITE_INT_FIELD(join_cur_level); WRITE_NODE_FIELD(resultRelations); WRITE_NODE_FIELD(init_plans); WRITE_NODE_FIELD(cte_plan_ids); WRITE_NODE_FIELD(eq_classes); WRITE_NODE_FIELD(canon_pathkeys); WRITE_NODE_FIELD(left_join_clauses); WRITE_NODE_FIELD(right_join_clauses); WRITE_NODE_FIELD(full_join_clauses); WRITE_NODE_FIELD(join_info_list); WRITE_NODE_FIELD(append_rel_list); WRITE_NODE_FIELD(rowMarks); WRITE_NODE_FIELD(placeholder_list); WRITE_NODE_FIELD(query_pathkeys); WRITE_NODE_FIELD(group_pathkeys); WRITE_NODE_FIELD(window_pathkeys); WRITE_NODE_FIELD(distinct_pathkeys); WRITE_NODE_FIELD(sort_pathkeys); WRITE_FLOAT_FIELD(total_table_pages, "%.0f"); WRITE_FLOAT_FIELD(tuple_fraction, "%.4f"); WRITE_BOOL_FIELD(hasInheritedTarget); WRITE_BOOL_FIELD(hasJoinRTEs); WRITE_BOOL_FIELD(hasHavingQual); WRITE_BOOL_FIELD(hasPseudoConstantQuals); WRITE_BOOL_FIELD(hasRecursion); WRITE_INT_FIELD(wt_param_id); WRITE_BITMAPSET_FIELD(curOuterRels); WRITE_NODE_FIELD(curOuterParams); } static void _outRelOptInfo(StringInfo str, RelOptInfo *node) { WRITE_NODE_TYPE("RELOPTINFO"); /* NB: this isn't a complete set of fields */ WRITE_ENUM_FIELD(reloptkind, RelOptKind); WRITE_BITMAPSET_FIELD(relids); WRITE_FLOAT_FIELD(rows, "%.0f"); WRITE_INT_FIELD(width); WRITE_NODE_FIELD(reltargetlist); WRITE_NODE_FIELD(pathlist); WRITE_NODE_FIELD(cheapest_startup_path); WRITE_NODE_FIELD(cheapest_total_path); WRITE_NODE_FIELD(cheapest_unique_path); WRITE_UINT_FIELD(relid); WRITE_UINT_FIELD(reltablespace); WRITE_ENUM_FIELD(rtekind, RTEKind); WRITE_INT_FIELD(min_attr); WRITE_INT_FIELD(max_attr); WRITE_NODE_FIELD(indexlist); WRITE_UINT_FIELD(pages); WRITE_FLOAT_FIELD(tuples, "%.0f"); WRITE_NODE_FIELD(subplan); WRITE_NODE_FIELD(subrtable); WRITE_NODE_FIELD(subrowmark); WRITE_NODE_FIELD(baserestrictinfo); WRITE_NODE_FIELD(joininfo); WRITE_BOOL_FIELD(has_eclass_joins); WRITE_BITMAPSET_FIELD(index_outer_relids); WRITE_NODE_FIELD(index_inner_paths); } static void _outIndexOptInfo(StringInfo str, IndexOptInfo *node) { WRITE_NODE_TYPE("INDEXOPTINFO"); /* NB: this isn't a complete set of fields */ WRITE_OID_FIELD(indexoid); /* Do NOT print rel field, else infinite recursion */ WRITE_UINT_FIELD(pages); WRITE_FLOAT_FIELD(tuples, "%.0f"); WRITE_INT_FIELD(ncolumns); WRITE_NODE_FIELD(indexprs); WRITE_NODE_FIELD(indpred); WRITE_BOOL_FIELD(predOK); WRITE_BOOL_FIELD(unique); } static void _outEquivalenceClass(StringInfo str, EquivalenceClass *node) { /* * To simplify reading, we just chase up to the topmost merged EC and * print that, without bothering to show the merge-ees separately. */ while (node->ec_merged) node = node->ec_merged; WRITE_NODE_TYPE("EQUIVALENCECLASS"); WRITE_NODE_FIELD(ec_opfamilies); WRITE_NODE_FIELD(ec_members); WRITE_NODE_FIELD(ec_sources); WRITE_NODE_FIELD(ec_derives); WRITE_BITMAPSET_FIELD(ec_relids); WRITE_BOOL_FIELD(ec_has_const); WRITE_BOOL_FIELD(ec_has_volatile); WRITE_BOOL_FIELD(ec_below_outer_join); WRITE_BOOL_FIELD(ec_broken); WRITE_UINT_FIELD(ec_sortref); } static void _outEquivalenceMember(StringInfo str, EquivalenceMember *node) { WRITE_NODE_TYPE("EQUIVALENCEMEMBER"); WRITE_NODE_FIELD(em_expr); WRITE_BITMAPSET_FIELD(em_relids); WRITE_BOOL_FIELD(em_is_const); WRITE_BOOL_FIELD(em_is_child); WRITE_OID_FIELD(em_datatype); } static void _outPathKey(StringInfo str, PathKey *node) { WRITE_NODE_TYPE("PATHKEY"); WRITE_NODE_FIELD(pk_eclass); WRITE_OID_FIELD(pk_opfamily); WRITE_INT_FIELD(pk_strategy); WRITE_BOOL_FIELD(pk_nulls_first); } static void _outRestrictInfo(StringInfo str, RestrictInfo *node) { WRITE_NODE_TYPE("RESTRICTINFO"); /* NB: this isn't a complete set of fields */ WRITE_NODE_FIELD(clause); WRITE_BOOL_FIELD(is_pushed_down); WRITE_BOOL_FIELD(outerjoin_delayed); WRITE_BOOL_FIELD(can_join); WRITE_BOOL_FIELD(pseudoconstant); WRITE_BITMAPSET_FIELD(clause_relids); WRITE_BITMAPSET_FIELD(required_relids); WRITE_BITMAPSET_FIELD(nullable_relids); WRITE_BITMAPSET_FIELD(left_relids); WRITE_BITMAPSET_FIELD(right_relids); WRITE_NODE_FIELD(orclause); /* don't write parent_ec, leads to infinite recursion in plan tree dump */ WRITE_FLOAT_FIELD(norm_selec, "%.4f"); WRITE_FLOAT_FIELD(outer_selec, "%.4f"); WRITE_NODE_FIELD(mergeopfamilies); /* don't write left_ec, leads to infinite recursion in plan tree dump */ /* don't write right_ec, leads to infinite recursion in plan tree dump */ WRITE_NODE_FIELD(left_em); WRITE_NODE_FIELD(right_em); WRITE_BOOL_FIELD(outer_is_left); WRITE_OID_FIELD(hashjoinoperator); } static void _outInnerIndexscanInfo(StringInfo str, InnerIndexscanInfo *node) { WRITE_NODE_TYPE("INNERINDEXSCANINFO"); WRITE_BITMAPSET_FIELD(other_relids); WRITE_BOOL_FIELD(isouterjoin); WRITE_NODE_FIELD(cheapest_startup_innerpath); WRITE_NODE_FIELD(cheapest_total_innerpath); } static void _outPlaceHolderVar(StringInfo str, PlaceHolderVar *node) { WRITE_NODE_TYPE("PLACEHOLDERVAR"); WRITE_NODE_FIELD(phexpr); WRITE_BITMAPSET_FIELD(phrels); WRITE_UINT_FIELD(phid); WRITE_UINT_FIELD(phlevelsup); } static void _outSpecialJoinInfo(StringInfo str, SpecialJoinInfo *node) { WRITE_NODE_TYPE("SPECIALJOININFO"); WRITE_BITMAPSET_FIELD(min_lefthand); WRITE_BITMAPSET_FIELD(min_righthand); WRITE_BITMAPSET_FIELD(syn_lefthand); WRITE_BITMAPSET_FIELD(syn_righthand); WRITE_ENUM_FIELD(jointype, JoinType); WRITE_BOOL_FIELD(lhs_strict); WRITE_BOOL_FIELD(delay_upper_joins); WRITE_NODE_FIELD(join_quals); } static void _outAppendRelInfo(StringInfo str, AppendRelInfo *node) { WRITE_NODE_TYPE("APPENDRELINFO"); WRITE_UINT_FIELD(parent_relid); WRITE_UINT_FIELD(child_relid); WRITE_OID_FIELD(parent_reltype); WRITE_OID_FIELD(child_reltype); WRITE_NODE_FIELD(translated_vars); WRITE_OID_FIELD(parent_reloid); } static void _outPlaceHolderInfo(StringInfo str, PlaceHolderInfo *node) { WRITE_NODE_TYPE("PLACEHOLDERINFO"); WRITE_UINT_FIELD(phid); WRITE_NODE_FIELD(ph_var); WRITE_BITMAPSET_FIELD(ph_eval_at); WRITE_BITMAPSET_FIELD(ph_needed); WRITE_INT_FIELD(ph_width); } static void _outPlannerParamItem(StringInfo str, PlannerParamItem *node) { WRITE_NODE_TYPE("PLANNERPARAMITEM"); WRITE_NODE_FIELD(item); WRITE_UINT_FIELD(abslevel); } /***************************************************************************** * * Stuff from parsenodes.h. * *****************************************************************************/ static void _outCreateStmt(StringInfo str, CreateStmt *node) { WRITE_NODE_TYPE("CREATESTMT"); WRITE_NODE_FIELD(relation); WRITE_NODE_FIELD(tableElts); WRITE_NODE_FIELD(inhRelations); WRITE_NODE_FIELD(ofTypename); WRITE_NODE_FIELD(constraints); WRITE_NODE_FIELD(options); WRITE_ENUM_FIELD(oncommit, OnCommitAction); WRITE_STRING_FIELD(tablespacename); WRITE_BOOL_FIELD(if_not_exists); } static void _outIndexStmt(StringInfo str, IndexStmt *node) { WRITE_NODE_TYPE("INDEXSTMT"); WRITE_STRING_FIELD(idxname); WRITE_NODE_FIELD(relation); WRITE_STRING_FIELD(accessMethod); WRITE_STRING_FIELD(tableSpace); WRITE_NODE_FIELD(indexParams); WRITE_NODE_FIELD(options); WRITE_NODE_FIELD(whereClause); WRITE_NODE_FIELD(excludeOpNames); WRITE_BOOL_FIELD(unique); WRITE_BOOL_FIELD(primary); WRITE_BOOL_FIELD(isconstraint); WRITE_BOOL_FIELD(deferrable); WRITE_BOOL_FIELD(initdeferred); WRITE_BOOL_FIELD(concurrent); } static void _outNotifyStmt(StringInfo str, NotifyStmt *node) { WRITE_NODE_TYPE("NOTIFY"); WRITE_STRING_FIELD(conditionname); WRITE_STRING_FIELD(payload); } static void _outDeclareCursorStmt(StringInfo str, DeclareCursorStmt *node) { WRITE_NODE_TYPE("DECLARECURSOR"); WRITE_STRING_FIELD(portalname); WRITE_INT_FIELD(options); WRITE_NODE_FIELD(query); } static void _outSelectStmt(StringInfo str, SelectStmt *node) { WRITE_NODE_TYPE("SELECT"); WRITE_NODE_FIELD(distinctClause); WRITE_NODE_FIELD(intoClause); WRITE_NODE_FIELD(targetList); WRITE_NODE_FIELD(fromClause); WRITE_NODE_FIELD(whereClause); WRITE_NODE_FIELD(groupClause); WRITE_NODE_FIELD(havingClause); WRITE_NODE_FIELD(windowClause); WRITE_NODE_FIELD(withClause); WRITE_NODE_FIELD(valuesLists); WRITE_NODE_FIELD(sortClause); WRITE_NODE_FIELD(limitOffset); WRITE_NODE_FIELD(limitCount); WRITE_NODE_FIELD(lockingClause); WRITE_ENUM_FIELD(op, SetOperation); WRITE_BOOL_FIELD(all); WRITE_NODE_FIELD(larg); WRITE_NODE_FIELD(rarg); } static void _outFuncCall(StringInfo str, FuncCall *node) { WRITE_NODE_TYPE("FUNCCALL"); WRITE_NODE_FIELD(funcname); WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(agg_order); WRITE_BOOL_FIELD(agg_star); WRITE_BOOL_FIELD(agg_distinct); WRITE_BOOL_FIELD(func_variadic); WRITE_NODE_FIELD(over); WRITE_LOCATION_FIELD(location); } static void _outDefElem(StringInfo str, DefElem *node) { WRITE_NODE_TYPE("DEFELEM"); WRITE_STRING_FIELD(defnamespace); WRITE_STRING_FIELD(defname); WRITE_NODE_FIELD(arg); WRITE_ENUM_FIELD(defaction, DefElemAction); } static void _outLockingClause(StringInfo str, LockingClause *node) { WRITE_NODE_TYPE("LOCKINGCLAUSE"); WRITE_NODE_FIELD(lockedRels); WRITE_BOOL_FIELD(forUpdate); WRITE_BOOL_FIELD(noWait); } static void _outXmlSerialize(StringInfo str, XmlSerialize *node) { WRITE_NODE_TYPE("XMLSERIALIZE"); WRITE_ENUM_FIELD(xmloption, XmlOptionType); WRITE_NODE_FIELD(expr); WRITE_NODE_FIELD(typeName); WRITE_LOCATION_FIELD(location); } static void _outColumnDef(StringInfo str, ColumnDef *node) { WRITE_NODE_TYPE("COLUMNDEF"); WRITE_STRING_FIELD(colname); WRITE_NODE_FIELD(typeName); WRITE_INT_FIELD(inhcount); WRITE_BOOL_FIELD(is_local); WRITE_BOOL_FIELD(is_not_null); WRITE_INT_FIELD(storage); WRITE_NODE_FIELD(raw_default); WRITE_NODE_FIELD(cooked_default); WRITE_NODE_FIELD(constraints); } static void _outTypeName(StringInfo str, TypeName *node) { WRITE_NODE_TYPE("TYPENAME"); WRITE_NODE_FIELD(names); WRITE_OID_FIELD(typeOid); WRITE_BOOL_FIELD(setof); WRITE_BOOL_FIELD(pct_type); WRITE_NODE_FIELD(typmods); WRITE_INT_FIELD(typemod); WRITE_NODE_FIELD(arrayBounds); WRITE_LOCATION_FIELD(location); } static void _outTypeCast(StringInfo str, TypeCast *node) { WRITE_NODE_TYPE("TYPECAST"); WRITE_NODE_FIELD(arg); WRITE_NODE_FIELD(typeName); WRITE_LOCATION_FIELD(location); } static void _outIndexElem(StringInfo str, IndexElem *node) { WRITE_NODE_TYPE("INDEXELEM"); WRITE_STRING_FIELD(name); WRITE_NODE_FIELD(expr); WRITE_STRING_FIELD(indexcolname); WRITE_NODE_FIELD(opclass); WRITE_ENUM_FIELD(ordering, SortByDir); WRITE_ENUM_FIELD(nulls_ordering, SortByNulls); } static void _outQuery(StringInfo str, Query *node) { WRITE_NODE_TYPE("QUERY"); WRITE_ENUM_FIELD(commandType, CmdType); WRITE_ENUM_FIELD(querySource, QuerySource); WRITE_BOOL_FIELD(canSetTag); /* * Hack to work around missing outfuncs routines for a lot of the * utility-statement node types. (The only one we actually *need* for * rules support is NotifyStmt.) Someday we ought to support 'em all, but * for the meantime do this to avoid getting lots of warnings when running * with debug_print_parse on. */ if (node->utilityStmt) { switch (nodeTag(node->utilityStmt)) { case T_CreateStmt: case T_IndexStmt: case T_NotifyStmt: case T_DeclareCursorStmt: WRITE_NODE_FIELD(utilityStmt); break; default: appendStringInfo(str, " :utilityStmt ?"); break; } } else appendStringInfo(str, " :utilityStmt <>"); WRITE_INT_FIELD(resultRelation); WRITE_NODE_FIELD(intoClause); WRITE_BOOL_FIELD(hasAggs); WRITE_BOOL_FIELD(hasWindowFuncs); WRITE_BOOL_FIELD(hasSubLinks); WRITE_BOOL_FIELD(hasDistinctOn); WRITE_BOOL_FIELD(hasRecursive); WRITE_BOOL_FIELD(hasForUpdate); WRITE_NODE_FIELD(cteList); WRITE_NODE_FIELD(rtable); WRITE_NODE_FIELD(jointree); WRITE_NODE_FIELD(targetList); WRITE_NODE_FIELD(returningList); WRITE_NODE_FIELD(groupClause); WRITE_NODE_FIELD(havingQual); WRITE_NODE_FIELD(windowClause); WRITE_NODE_FIELD(distinctClause); WRITE_NODE_FIELD(sortClause); WRITE_NODE_FIELD(limitOffset); WRITE_NODE_FIELD(limitCount); WRITE_NODE_FIELD(rowMarks); WRITE_NODE_FIELD(setOperations); WRITE_NODE_FIELD(constraintDeps); } static void _outSortGroupClause(StringInfo str, SortGroupClause *node) { WRITE_NODE_TYPE("SORTGROUPCLAUSE"); WRITE_UINT_FIELD(tleSortGroupRef); WRITE_OID_FIELD(eqop); WRITE_OID_FIELD(sortop); WRITE_BOOL_FIELD(nulls_first); } static void _outWindowClause(StringInfo str, WindowClause *node) { WRITE_NODE_TYPE("WINDOWCLAUSE"); WRITE_STRING_FIELD(name); WRITE_STRING_FIELD(refname); WRITE_NODE_FIELD(partitionClause); WRITE_NODE_FIELD(orderClause); WRITE_INT_FIELD(frameOptions); WRITE_NODE_FIELD(startOffset); WRITE_NODE_FIELD(endOffset); WRITE_UINT_FIELD(winref); WRITE_BOOL_FIELD(copiedOrder); } static void _outRowMarkClause(StringInfo str, RowMarkClause *node) { WRITE_NODE_TYPE("ROWMARKCLAUSE"); WRITE_UINT_FIELD(rti); WRITE_BOOL_FIELD(forUpdate); WRITE_BOOL_FIELD(noWait); WRITE_BOOL_FIELD(pushedDown); } static void _outWithClause(StringInfo str, WithClause *node) { WRITE_NODE_TYPE("WITHCLAUSE"); WRITE_NODE_FIELD(ctes); WRITE_BOOL_FIELD(recursive); WRITE_LOCATION_FIELD(location); } static void _outCommonTableExpr(StringInfo str, CommonTableExpr *node) { WRITE_NODE_TYPE("COMMONTABLEEXPR"); WRITE_STRING_FIELD(ctename); WRITE_NODE_FIELD(aliascolnames); WRITE_NODE_FIELD(ctequery); WRITE_LOCATION_FIELD(location); WRITE_BOOL_FIELD(cterecursive); WRITE_INT_FIELD(cterefcount); WRITE_NODE_FIELD(ctecolnames); WRITE_NODE_FIELD(ctecoltypes); WRITE_NODE_FIELD(ctecoltypmods); } static void _outSetOperationStmt(StringInfo str, SetOperationStmt *node) { WRITE_NODE_TYPE("SETOPERATIONSTMT"); WRITE_ENUM_FIELD(op, SetOperation); WRITE_BOOL_FIELD(all); WRITE_NODE_FIELD(larg); WRITE_NODE_FIELD(rarg); WRITE_NODE_FIELD(colTypes); WRITE_NODE_FIELD(colTypmods); WRITE_NODE_FIELD(groupClauses); } static void _outRangeTblEntry(StringInfo str, RangeTblEntry *node) { WRITE_NODE_TYPE("RTE"); /* put alias + eref first to make dump more legible */ WRITE_NODE_FIELD(alias); WRITE_NODE_FIELD(eref); WRITE_ENUM_FIELD(rtekind, RTEKind); switch (node->rtekind) { case RTE_RELATION: case RTE_SPECIAL: WRITE_OID_FIELD(relid); break; case RTE_SUBQUERY: WRITE_NODE_FIELD(subquery); break; case RTE_JOIN: WRITE_ENUM_FIELD(jointype, JoinType); WRITE_NODE_FIELD(joinaliasvars); break; case RTE_FUNCTION: WRITE_NODE_FIELD(funcexpr); WRITE_NODE_FIELD(funccoltypes); WRITE_NODE_FIELD(funccoltypmods); break; case RTE_VALUES: WRITE_NODE_FIELD(values_lists); break; case RTE_CTE: WRITE_STRING_FIELD(ctename); WRITE_UINT_FIELD(ctelevelsup); WRITE_BOOL_FIELD(self_reference); WRITE_NODE_FIELD(ctecoltypes); WRITE_NODE_FIELD(ctecoltypmods); break; default: elog(ERROR, "unrecognized RTE kind: %d", (int) node->rtekind); break; } WRITE_BOOL_FIELD(inh); WRITE_BOOL_FIELD(inFromCl); WRITE_UINT_FIELD(requiredPerms); WRITE_OID_FIELD(checkAsUser); WRITE_BITMAPSET_FIELD(selectedCols); WRITE_BITMAPSET_FIELD(modifiedCols); } static void _outAExpr(StringInfo str, A_Expr *node) { WRITE_NODE_TYPE("AEXPR"); switch (node->kind) { case AEXPR_OP: appendStringInfo(str, " "); WRITE_NODE_FIELD(name); break; case AEXPR_AND: appendStringInfo(str, " AND"); break; case AEXPR_OR: appendStringInfo(str, " OR"); break; case AEXPR_NOT: appendStringInfo(str, " NOT"); break; case AEXPR_OP_ANY: appendStringInfo(str, " "); WRITE_NODE_FIELD(name); appendStringInfo(str, " ANY "); break; case AEXPR_OP_ALL: appendStringInfo(str, " "); WRITE_NODE_FIELD(name); appendStringInfo(str, " ALL "); break; case AEXPR_DISTINCT: appendStringInfo(str, " DISTINCT "); WRITE_NODE_FIELD(name); break; case AEXPR_NULLIF: appendStringInfo(str, " NULLIF "); WRITE_NODE_FIELD(name); break; case AEXPR_OF: appendStringInfo(str, " OF "); WRITE_NODE_FIELD(name); break; case AEXPR_IN: appendStringInfo(str, " IN "); WRITE_NODE_FIELD(name); break; default: appendStringInfo(str, " ??"); break; } WRITE_NODE_FIELD(lexpr); WRITE_NODE_FIELD(rexpr); WRITE_LOCATION_FIELD(location); } static void _outValue(StringInfo str, Value *value) { switch (value->type) { case T_Integer: appendStringInfo(str, "%ld", value->val.ival); break; case T_Float: /* * We assume the value is a valid numeric literal and so does not * need quoting. */ appendStringInfoString(str, value->val.str); break; case T_String: appendStringInfoChar(str, '"'); _outToken(str, value->val.str); appendStringInfoChar(str, '"'); break; case T_BitString: /* internal representation already has leading 'b' */ appendStringInfoString(str, value->val.str); break; case T_Null: /* this is seen only within A_Const, not in transformed trees */ appendStringInfoString(str, "NULL"); break; default: elog(ERROR, "unrecognized node type: %d", (int) value->type); break; } } static void _outColumnRef(StringInfo str, ColumnRef *node) { WRITE_NODE_TYPE("COLUMNREF"); WRITE_NODE_FIELD(fields); WRITE_LOCATION_FIELD(location); } static void _outParamRef(StringInfo str, ParamRef *node) { WRITE_NODE_TYPE("PARAMREF"); WRITE_INT_FIELD(number); WRITE_LOCATION_FIELD(location); } static void _outAConst(StringInfo str, A_Const *node) { WRITE_NODE_TYPE("A_CONST"); appendStringInfo(str, " :val "); _outValue(str, &(node->val)); WRITE_LOCATION_FIELD(location); } static void _outA_Star(StringInfo str, A_Star *node) { WRITE_NODE_TYPE("A_STAR"); } static void _outA_Indices(StringInfo str, A_Indices *node) { WRITE_NODE_TYPE("A_INDICES"); WRITE_NODE_FIELD(lidx); WRITE_NODE_FIELD(uidx); } static void _outA_Indirection(StringInfo str, A_Indirection *node) { WRITE_NODE_TYPE("A_INDIRECTION"); WRITE_NODE_FIELD(arg); WRITE_NODE_FIELD(indirection); } static void _outA_ArrayExpr(StringInfo str, A_ArrayExpr *node) { WRITE_NODE_TYPE("A_ARRAYEXPR"); WRITE_NODE_FIELD(elements); WRITE_LOCATION_FIELD(location); } static void _outResTarget(StringInfo str, ResTarget *node) { WRITE_NODE_TYPE("RESTARGET"); WRITE_STRING_FIELD(name); WRITE_NODE_FIELD(indirection); WRITE_NODE_FIELD(val); WRITE_LOCATION_FIELD(location); } static void _outSortBy(StringInfo str, SortBy *node) { WRITE_NODE_TYPE("SORTBY"); WRITE_NODE_FIELD(node); WRITE_ENUM_FIELD(sortby_dir, SortByDir); WRITE_ENUM_FIELD(sortby_nulls, SortByNulls); WRITE_NODE_FIELD(useOp); WRITE_LOCATION_FIELD(location); } static void _outWindowDef(StringInfo str, WindowDef *node) { WRITE_NODE_TYPE("WINDOWDEF"); WRITE_STRING_FIELD(name); WRITE_STRING_FIELD(refname); WRITE_NODE_FIELD(partitionClause); WRITE_NODE_FIELD(orderClause); WRITE_INT_FIELD(frameOptions); WRITE_NODE_FIELD(startOffset); WRITE_NODE_FIELD(endOffset); WRITE_LOCATION_FIELD(location); } static void _outRangeSubselect(StringInfo str, RangeSubselect *node) { WRITE_NODE_TYPE("RANGESUBSELECT"); WRITE_NODE_FIELD(subquery); WRITE_NODE_FIELD(alias); } static void _outRangeFunction(StringInfo str, RangeFunction *node) { WRITE_NODE_TYPE("RANGEFUNCTION"); WRITE_NODE_FIELD(funccallnode); WRITE_NODE_FIELD(alias); WRITE_NODE_FIELD(coldeflist); } static void _outConstraint(StringInfo str, Constraint *node) { WRITE_NODE_TYPE("CONSTRAINT"); WRITE_STRING_FIELD(conname); WRITE_BOOL_FIELD(deferrable); WRITE_BOOL_FIELD(initdeferred); WRITE_LOCATION_FIELD(location); appendStringInfo(str, " :contype "); switch (node->contype) { case CONSTR_NULL: appendStringInfo(str, "NULL"); break; case CONSTR_NOTNULL: appendStringInfo(str, "NOT_NULL"); break; case CONSTR_DEFAULT: appendStringInfo(str, "DEFAULT"); WRITE_NODE_FIELD(raw_expr); WRITE_STRING_FIELD(cooked_expr); break; case CONSTR_CHECK: appendStringInfo(str, "CHECK"); WRITE_NODE_FIELD(raw_expr); WRITE_STRING_FIELD(cooked_expr); break; case CONSTR_PRIMARY: appendStringInfo(str, "PRIMARY_KEY"); WRITE_NODE_FIELD(keys); WRITE_NODE_FIELD(options); WRITE_STRING_FIELD(indexspace); /* access_method and where_clause not currently used */ break; case CONSTR_UNIQUE: appendStringInfo(str, "UNIQUE"); WRITE_NODE_FIELD(keys); WRITE_NODE_FIELD(options); WRITE_STRING_FIELD(indexspace); /* access_method and where_clause not currently used */ break; case CONSTR_EXCLUSION: appendStringInfo(str, "EXCLUSION"); WRITE_NODE_FIELD(exclusions); WRITE_NODE_FIELD(options); WRITE_STRING_FIELD(indexspace); WRITE_STRING_FIELD(access_method); WRITE_NODE_FIELD(where_clause); break; case CONSTR_FOREIGN: appendStringInfo(str, "FOREIGN_KEY"); WRITE_NODE_FIELD(pktable); WRITE_NODE_FIELD(fk_attrs); WRITE_NODE_FIELD(pk_attrs); WRITE_CHAR_FIELD(fk_matchtype); WRITE_CHAR_FIELD(fk_upd_action); WRITE_CHAR_FIELD(fk_del_action); WRITE_BOOL_FIELD(skip_validation); break; case CONSTR_ATTR_DEFERRABLE: appendStringInfo(str, "ATTR_DEFERRABLE"); break; case CONSTR_ATTR_NOT_DEFERRABLE: appendStringInfo(str, "ATTR_NOT_DEFERRABLE"); break; case CONSTR_ATTR_DEFERRED: appendStringInfo(str, "ATTR_DEFERRED"); break; case CONSTR_ATTR_IMMEDIATE: appendStringInfo(str, "ATTR_IMMEDIATE"); break; default: appendStringInfo(str, "", (int) node->contype); break; } } /* * _outNode - * converts a Node into ascii string and append it to 'str' */ static void _outNode(StringInfo str, void *obj) { if (obj == NULL) appendStringInfo(str, "<>"); else if (IsA(obj, List) ||IsA(obj, IntList) || IsA(obj, OidList)) _outList(str, obj); else if (IsA(obj, Integer) || IsA(obj, Float) || IsA(obj, String) || IsA(obj, BitString)) { /* nodeRead does not want to see { } around these! */ _outValue(str, obj); } else { appendStringInfoChar(str, '{'); switch (nodeTag(obj)) { case T_PlannedStmt: _outPlannedStmt(str, obj); break; case T_Plan: _outPlan(str, obj); break; case T_Result: _outResult(str, obj); break; case T_ModifyTable: _outModifyTable(str, obj); break; case T_Append: _outAppend(str, obj); break; case T_RecursiveUnion: _outRecursiveUnion(str, obj); break; case T_BitmapAnd: _outBitmapAnd(str, obj); break; case T_BitmapOr: _outBitmapOr(str, obj); break; case T_Scan: _outScan(str, obj); break; case T_SeqScan: _outSeqScan(str, obj); break; case T_IndexScan: _outIndexScan(str, obj); break; case T_BitmapIndexScan: _outBitmapIndexScan(str, obj); break; case T_BitmapHeapScan: _outBitmapHeapScan(str, obj); break; case T_TidScan: _outTidScan(str, obj); break; case T_SubqueryScan: _outSubqueryScan(str, obj); break; case T_FunctionScan: _outFunctionScan(str, obj); break; case T_ValuesScan: _outValuesScan(str, obj); break; case T_CteScan: _outCteScan(str, obj); break; case T_WorkTableScan: _outWorkTableScan(str, obj); break; case T_Join: _outJoin(str, obj); break; case T_NestLoop: _outNestLoop(str, obj); break; case T_MergeJoin: _outMergeJoin(str, obj); break; case T_HashJoin: _outHashJoin(str, obj); break; case T_Agg: _outAgg(str, obj); break; case T_WindowAgg: _outWindowAgg(str, obj); break; case T_Group: _outGroup(str, obj); break; case T_Material: _outMaterial(str, obj); break; case T_Sort: _outSort(str, obj); break; case T_Unique: _outUnique(str, obj); break; case T_Hash: _outHash(str, obj); break; case T_SetOp: _outSetOp(str, obj); break; case T_LockRows: _outLockRows(str, obj); break; case T_Limit: _outLimit(str, obj); break; case T_NestLoopParam: _outNestLoopParam(str, obj); break; case T_PlanRowMark: _outPlanRowMark(str, obj); break; case T_PlanInvalItem: _outPlanInvalItem(str, obj); break; case T_Alias: _outAlias(str, obj); break; case T_RangeVar: _outRangeVar(str, obj); break; case T_IntoClause: _outIntoClause(str, obj); break; case T_Var: _outVar(str, obj); break; case T_Const: _outConst(str, obj); break; case T_Param: _outParam(str, obj); break; case T_Aggref: _outAggref(str, obj); break; case T_WindowFunc: _outWindowFunc(str, obj); break; case T_ArrayRef: _outArrayRef(str, obj); break; case T_FuncExpr: _outFuncExpr(str, obj); break; case T_NamedArgExpr: _outNamedArgExpr(str, obj); break; case T_OpExpr: _outOpExpr(str, obj); break; case T_DistinctExpr: _outDistinctExpr(str, obj); break; case T_ScalarArrayOpExpr: _outScalarArrayOpExpr(str, obj); break; case T_BoolExpr: _outBoolExpr(str, obj); break; case T_SubLink: _outSubLink(str, obj); break; case T_SubPlan: _outSubPlan(str, obj); break; case T_AlternativeSubPlan: _outAlternativeSubPlan(str, obj); break; case T_FieldSelect: _outFieldSelect(str, obj); break; case T_FieldStore: _outFieldStore(str, obj); break; case T_RelabelType: _outRelabelType(str, obj); break; case T_CoerceViaIO: _outCoerceViaIO(str, obj); break; case T_ArrayCoerceExpr: _outArrayCoerceExpr(str, obj); break; case T_ConvertRowtypeExpr: _outConvertRowtypeExpr(str, obj); break; case T_CaseExpr: _outCaseExpr(str, obj); break; case T_CaseWhen: _outCaseWhen(str, obj); break; case T_CaseTestExpr: _outCaseTestExpr(str, obj); break; case T_ArrayExpr: _outArrayExpr(str, obj); break; case T_RowExpr: _outRowExpr(str, obj); break; case T_RowCompareExpr: _outRowCompareExpr(str, obj); break; case T_CoalesceExpr: _outCoalesceExpr(str, obj); break; case T_MinMaxExpr: _outMinMaxExpr(str, obj); break; case T_XmlExpr: _outXmlExpr(str, obj); break; case T_NullIfExpr: _outNullIfExpr(str, obj); break; case T_NullTest: _outNullTest(str, obj); break; case T_BooleanTest: _outBooleanTest(str, obj); break; case T_CoerceToDomain: _outCoerceToDomain(str, obj); break; case T_CoerceToDomainValue: _outCoerceToDomainValue(str, obj); break; case T_SetToDefault: _outSetToDefault(str, obj); break; case T_CurrentOfExpr: _outCurrentOfExpr(str, obj); break; case T_TargetEntry: _outTargetEntry(str, obj); break; case T_RangeTblRef: _outRangeTblRef(str, obj); break; case T_JoinExpr: _outJoinExpr(str, obj); break; case T_FromExpr: _outFromExpr(str, obj); break; case T_Path: _outPath(str, obj); break; case T_IndexPath: _outIndexPath(str, obj); break; case T_BitmapHeapPath: _outBitmapHeapPath(str, obj); break; case T_BitmapAndPath: _outBitmapAndPath(str, obj); break; case T_BitmapOrPath: _outBitmapOrPath(str, obj); break; case T_TidPath: _outTidPath(str, obj); break; case T_AppendPath: _outAppendPath(str, obj); break; case T_ResultPath: _outResultPath(str, obj); break; case T_MaterialPath: _outMaterialPath(str, obj); break; case T_UniquePath: _outUniquePath(str, obj); break; case T_NestPath: _outNestPath(str, obj); break; case T_MergePath: _outMergePath(str, obj); break; case T_HashPath: _outHashPath(str, obj); break; case T_PlannerGlobal: _outPlannerGlobal(str, obj); break; case T_PlannerInfo: _outPlannerInfo(str, obj); break; case T_RelOptInfo: _outRelOptInfo(str, obj); break; case T_IndexOptInfo: _outIndexOptInfo(str, obj); break; case T_EquivalenceClass: _outEquivalenceClass(str, obj); break; case T_EquivalenceMember: _outEquivalenceMember(str, obj); break; case T_PathKey: _outPathKey(str, obj); break; case T_RestrictInfo: _outRestrictInfo(str, obj); break; case T_InnerIndexscanInfo: _outInnerIndexscanInfo(str, obj); break; case T_PlaceHolderVar: _outPlaceHolderVar(str, obj); break; case T_SpecialJoinInfo: _outSpecialJoinInfo(str, obj); break; case T_AppendRelInfo: _outAppendRelInfo(str, obj); break; case T_PlaceHolderInfo: _outPlaceHolderInfo(str, obj); break; case T_PlannerParamItem: _outPlannerParamItem(str, obj); break; case T_CreateStmt: _outCreateStmt(str, obj); break; case T_IndexStmt: _outIndexStmt(str, obj); break; case T_NotifyStmt: _outNotifyStmt(str, obj); break; case T_DeclareCursorStmt: _outDeclareCursorStmt(str, obj); break; case T_SelectStmt: _outSelectStmt(str, obj); break; case T_ColumnDef: _outColumnDef(str, obj); break; case T_TypeName: _outTypeName(str, obj); break; case T_TypeCast: _outTypeCast(str, obj); break; case T_IndexElem: _outIndexElem(str, obj); break; case T_Query: _outQuery(str, obj); break; case T_SortGroupClause: _outSortGroupClause(str, obj); break; case T_WindowClause: _outWindowClause(str, obj); break; case T_RowMarkClause: _outRowMarkClause(str, obj); break; case T_WithClause: _outWithClause(str, obj); break; case T_CommonTableExpr: _outCommonTableExpr(str, obj); break; case T_SetOperationStmt: _outSetOperationStmt(str, obj); break; case T_RangeTblEntry: _outRangeTblEntry(str, obj); break; case T_A_Expr: _outAExpr(str, obj); break; case T_ColumnRef: _outColumnRef(str, obj); break; case T_ParamRef: _outParamRef(str, obj); break; case T_A_Const: _outAConst(str, obj); break; case T_A_Star: _outA_Star(str, obj); break; case T_A_Indices: _outA_Indices(str, obj); break; case T_A_Indirection: _outA_Indirection(str, obj); break; case T_A_ArrayExpr: _outA_ArrayExpr(str, obj); break; case T_ResTarget: _outResTarget(str, obj); break; case T_SortBy: _outSortBy(str, obj); break; case T_WindowDef: _outWindowDef(str, obj); break; case T_RangeSubselect: _outRangeSubselect(str, obj); break; case T_RangeFunction: _outRangeFunction(str, obj); break; case T_Constraint: _outConstraint(str, obj); break; case T_FuncCall: _outFuncCall(str, obj); break; case T_DefElem: _outDefElem(str, obj); break; case T_LockingClause: _outLockingClause(str, obj); break; case T_XmlSerialize: _outXmlSerialize(str, obj); break; default: /* * This should be an ERROR, but it's too useful to be able to * dump structures that _outNode only understands part of. */ elog(WARNING, "could not dump unrecognized node type: %d", (int) nodeTag(obj)); break; } appendStringInfoChar(str, '}'); } } /* * nodeToString - * returns the ascii representation of the Node as a palloc'd string */ char * nodeToString(void *obj) { StringInfoData str; /* see stringinfo.h for an explanation of this maneuver */ initStringInfo(&str); _outNode(&str, obj); return str.data; }