postgresql/src/backend/nodes/outfuncs.c

3161 lines
69 KiB
C
Raw Normal View History

/*-------------------------------------------------------------------------
*
* outfuncs.c
* Output functions for Postgres tree nodes.
*
2011-01-01 19:18:15 +01:00
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
2010-09-20 22:08:53 +02:00
* src/backend/nodes/outfuncs.c
*
* NOTES
* Every node type that can appear in stored rules' parsetrees *must*
* have an output function defined here (as well as an input function
2003-08-04 02:43:34 +02:00
* 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 <ctype.h>
#include "foreign/fdwapi.h"
1999-07-16 07:00:38 +02:00
#include "utils/datum.h"
/*
2003-08-04 02:43:34 +02:00
* 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;
}
/*
2005-10-15 04:49:52 +02:00
* 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)
{
2004-08-29 07:07:03 +02:00
ListCell *lc;
appendStringInfoChar(str, '(');
if (IsA(node, IntList))
appendStringInfoChar(str, 'i');
else if (IsA(node, OidList))
appendStringInfoChar(str, 'o');
2004-08-29 07:07:03 +02:00
foreach(lc, node)
{
/*
* For the sake of backward compatibility, we emit a slightly
2005-10-15 04:49:52 +02:00
* 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
2004-08-29 07:07:03 +02:00
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);
1999-01-21 17:08:55 +01:00
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(hasModifyingCTE);
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_BOOL_FIELD(canSetTag);
WRITE_NODE_FIELD(resultRelations);
WRITE_INT_FIELD(resultRelIndex);
WRITE_NODE_FIELD(plans);
WRITE_NODE_FIELD(returningLists);
WRITE_NODE_FIELD(rowMarks);
WRITE_INT_FIELD(epqParam);
}
static void
1997-09-08 22:59:27 +02:00
_outAppend(StringInfo str, Append *node)
{
WRITE_NODE_TYPE("APPEND");
_outPlanInfo(str, (Plan *) node);
WRITE_NODE_FIELD(appendplans);
}
static void
_outMergeAppend(StringInfo str, MergeAppend *node)
{
int i;
WRITE_NODE_TYPE("MERGEAPPEND");
_outPlanInfo(str, (Plan *) node);
WRITE_NODE_FIELD(mergeplans);
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, " :collations");
for (i = 0; i < node->numCols; i++)
appendStringInfo(str, " %u", node->collations[i]);
appendStringInfo(str, " :nullsFirst");
for (i = 0; i < node->numCols; i++)
appendStringInfo(str, " %s", booltostr(node->nullsFirst[i]));
}
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_NODE_FIELD(indexorderby);
WRITE_NODE_FIELD(indexorderbyorig);
WRITE_ENUM_FIELD(indexorderdir, ScanDirection);
WRITE_BOOL_FIELD(indexonly);
}
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);
}
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);
WRITE_NODE_FIELD(funccolcollations);
}
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
_outForeignScan(StringInfo str, ForeignScan *node)
{
WRITE_NODE_TYPE("FOREIGNSCAN");
_outScanInfo(str, (Scan *) node);
WRITE_BOOL_FIELD(fsSystemCol);
WRITE_NODE_FIELD(fdwplan);
}
static void
_outFdwPlan(StringInfo str, FdwPlan *node)
{
WRITE_NODE_TYPE("FDWPLAN");
WRITE_FLOAT_FIELD(startup_cost, "%.2f");
WRITE_FLOAT_FIELD(total_cost, "%.2f");
WRITE_NODE_FIELD(fdw_private);
}
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, " :mergeCollations");
for (i = 0; i < numCols; i++)
appendStringInfo(str, " %u", node->mergeCollations[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, " :collations");
for (i = 0; i < node->numCols; i++)
appendStringInfo(str, " %u", node->collations[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)
{
2001-03-22 05:01:46 +01:00
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)
{
2001-03-22 05:01:46 +01:00
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_UINT_FIELD(rowmarkId);
WRITE_ENUM_FIELD(markType, RowMarkType);
WRITE_BOOL_FIELD(noWait);
WRITE_BOOL_FIELD(isParent);
}
static void
_outPlanInvalItem(StringInfo str, PlanInvalItem *node)
{
WRITE_NODE_TYPE("PLANINVALITEM");
WRITE_INT_FIELD(cacheId);
WRITE_UINT_FIELD(hashValue);
}
/*****************************************************************************
*
* 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_CHAR_FIELD(relpersistence);
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_OID_FIELD(varcollid);
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_OID_FIELD(constcollid);
WRITE_INT_FIELD(constlen);
WRITE_BOOL_FIELD(constbyval);
WRITE_BOOL_FIELD(constisnull);
WRITE_LOCATION_FIELD(location);
appendStringInfo(str, " :constvalue ");
if (node->constisnull)
1998-01-07 16:32:47 +01:00
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_OID_FIELD(paramcollid);
WRITE_LOCATION_FIELD(location);
}
static void
1999-05-26 00:43:53 +02:00
_outAggref(StringInfo str, Aggref *node)
{
WRITE_NODE_TYPE("AGGREF");
WRITE_OID_FIELD(aggfnoid);
WRITE_OID_FIELD(aggtype);
WRITE_OID_FIELD(aggcollid);
WRITE_OID_FIELD(inputcollid);
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_OID_FIELD(wincollid);
WRITE_OID_FIELD(inputcollid);
WRITE_NODE_FIELD(args);
WRITE_UINT_FIELD(winref);
WRITE_BOOL_FIELD(winstar);
WRITE_BOOL_FIELD(winagg);
WRITE_LOCATION_FIELD(location);
}
static void
1997-09-08 22:59:27 +02:00
_outArrayRef(StringInfo str, ArrayRef *node)
{
WRITE_NODE_TYPE("ARRAYREF");
WRITE_OID_FIELD(refarraytype);
WRITE_OID_FIELD(refelemtype);
WRITE_INT_FIELD(reftypmod);
WRITE_OID_FIELD(refcollid);
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_OID_FIELD(funccollid);
WRITE_OID_FIELD(inputcollid);
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_OID_FIELD(opcollid);
WRITE_OID_FIELD(inputcollid);
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_OID_FIELD(opcollid);
WRITE_OID_FIELD(inputcollid);
WRITE_NODE_FIELD(args);
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_OID_FIELD(opcollid);
WRITE_OID_FIELD(inputcollid);
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_OID_FIELD(inputcollid);
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_OID_FIELD(firstColCollation);
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);
WRITE_OID_FIELD(resultcollid);
}
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_OID_FIELD(resultcollid);
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_OID_FIELD(resultcollid);
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_OID_FIELD(resultcollid);
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
_outCollateExpr(StringInfo str, CollateExpr *node)
{
WRITE_NODE_TYPE("COLLATE");
WRITE_NODE_FIELD(arg);
WRITE_OID_FIELD(collOid);
WRITE_LOCATION_FIELD(location);
}
static void
_outCaseExpr(StringInfo str, CaseExpr *node)
{
WRITE_NODE_TYPE("CASE");
WRITE_OID_FIELD(casetype);
WRITE_OID_FIELD(casecollid);
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);
WRITE_OID_FIELD(collation);
}
static void
_outArrayExpr(StringInfo str, ArrayExpr *node)
{
WRITE_NODE_TYPE("ARRAY");
WRITE_OID_FIELD(array_typeid);
WRITE_OID_FIELD(array_collid);
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(inputcollids);
WRITE_NODE_FIELD(largs);
WRITE_NODE_FIELD(rargs);
}
static void
_outCoalesceExpr(StringInfo str, CoalesceExpr *node)
{
WRITE_NODE_TYPE("COALESCE");
WRITE_OID_FIELD(coalescetype);
WRITE_OID_FIELD(coalescecollid);
WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
}
static void
_outMinMaxExpr(StringInfo str, MinMaxExpr *node)
{
WRITE_NODE_TYPE("MINMAX");
WRITE_OID_FIELD(minmaxtype);
WRITE_OID_FIELD(minmaxcollid);
WRITE_OID_FIELD(inputcollid);
WRITE_ENUM_FIELD(op, MinMaxOp);
WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
}
static void
_outXmlExpr(StringInfo str, XmlExpr *node)
{
WRITE_NODE_TYPE("XMLEXPR");
2007-11-15 22:14:46 +01:00
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
_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_OID_FIELD(resultcollid);
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_OID_FIELD(collation);
WRITE_LOCATION_FIELD(location);
}
static void
_outSetToDefault(StringInfo str, SetToDefault *node)
{
WRITE_NODE_TYPE("SETTODEFAULT");
WRITE_OID_FIELD(typeId);
WRITE_INT_FIELD(typeMod);
WRITE_OID_FIELD(collation);
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);
1999-01-21 17:08:55 +01:00
}
/*****************************************************************************
*
* 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.
* We can print the parent's relids for identification purposes, though.
*/
static void
_outPathInfo(StringInfo str, Path *node)
{
WRITE_ENUM_FIELD(pathtype, NodeTag);
appendStringInfo(str, " :parent_relids ");
_outBitmapset(str, node->parent->relids);
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_NODE_FIELD(indexorderbys);
WRITE_BOOL_FIELD(isjoininner);
WRITE_ENUM_FIELD(indexscandir, ScanDirection);
WRITE_BOOL_FIELD(indexonly);
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
_outForeignPath(StringInfo str, ForeignPath *node)
{
WRITE_NODE_TYPE("FOREIGNPATH");
_outPathInfo(str, (Path *) node);
WRITE_NODE_FIELD(fdwplan);
}
static void
_outAppendPath(StringInfo str, AppendPath *node)
{
WRITE_NODE_TYPE("APPENDPATH");
_outPathInfo(str, (Path *) node);
WRITE_NODE_FIELD(subpaths);
}
static void
_outMergeAppendPath(StringInfo str, MergeAppendPath *node)
{
WRITE_NODE_TYPE("MERGEAPPENDPATH");
_outPathInfo(str, (Path *) node);
WRITE_NODE_FIELD(subpaths);
WRITE_FLOAT_FIELD(limit_tuples, "%.0f");
}
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
1999-05-26 00:43:53 +02:00
_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_BITMAPSET_FIELD(rewindPlanIDs);
WRITE_NODE_FIELD(finalrtable);
WRITE_NODE_FIELD(finalrowmarks);
WRITE_NODE_FIELD(resultRelations);
WRITE_NODE_FIELD(relationOids);
WRITE_NODE_FIELD(invalItems);
WRITE_UINT_FIELD(lastPHId);
WRITE_UINT_FIELD(lastRowMarkId);
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(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_NODE_FIELD(minmax_aggs);
WRITE_FLOAT_FIELD(total_table_pages, "%.0f");
WRITE_FLOAT_FIELD(tuple_fraction, "%.4f");
WRITE_FLOAT_FIELD(limit_tuples, "%.0f");
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(subroot);
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_OID_FIELD(relam);
WRITE_NODE_FIELD(indexprs);
WRITE_NODE_FIELD(indpred);
WRITE_BOOL_FIELD(predOK);
WRITE_BOOL_FIELD(unique);
WRITE_BOOL_FIELD(hypothetical);
}
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_OID_FIELD(ec_collation);
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
1999-05-26 00:43:53 +02:00
_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);
Rewrite make_outerjoininfo's construction of min_lefthand and min_righthand sets for outer joins, in the light of bug #3588 and additional thought and experimentation. The original methodology was fatally flawed for nests of more than two outer joins: it got the relationships between adjacent joins right, but didn't always come to the right conclusions about whether a join could be interchanged with one two or more levels below it. This was largely caused by a mistaken idea that we should use the min_lefthand + min_righthand sets of a sub-join as the minimum left or right input set of an upper join when we conclude that the sub-join can't commute with the upper one. If there's a still-lower join that the sub-join *can* commute with, this method led us to think that that one could commute with the topmost join; which it can't. Another problem (not directly connected to bug #3588) was that make_outerjoininfo's processing-order-dependent method for enforcing outer join identity #3 didn't work right: if we decided that join A could safely commute with lower join B, we dropped all information about sub-joins under B that join A could perhaps not safely commute with, because we removed B's entire min_righthand from A's. To fix, make an explicit computation of all inner join combinations that occur below an outer join, and add to that the full syntactic relsets of any lower outer joins that we determine it can't commute with. This method gives much more direct enforcement of the outer join rearrangement identities, and it turns out not to cost a lot of additional bookkeeping. Thanks to Richard Harris for the bug report and test case.
2007-08-31 03:44:06 +02:00
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_BITMAPSET_FIELD(ph_may_need);
WRITE_INT_FIELD(ph_width);
}
static void
_outMinMaxAggInfo(StringInfo str, MinMaxAggInfo *node)
{
WRITE_NODE_TYPE("MINMAXAGGINFO");
WRITE_OID_FIELD(aggfnoid);
WRITE_OID_FIELD(aggsortop);
WRITE_NODE_FIELD(target);
/* We intentionally omit subroot --- too large, not interesting enough */
WRITE_NODE_FIELD(path);
WRITE_FLOAT_FIELD(pathcost, "%.2f");
WRITE_NODE_FIELD(param);
}
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
_outCreateForeignTableStmt(StringInfo str, CreateForeignTableStmt *node)
{
WRITE_NODE_TYPE("CREATEFOREIGNTABLESTMT");
_outCreateStmt(str, (CreateStmt *) &node->base);
WRITE_STRING_FIELD(servername);
WRITE_NODE_FIELD(options);
}
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_OID_FIELD(indexOid);
WRITE_OID_FIELD(oldNode);
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
_outInhRelation(StringInfo str, InhRelation *node)
{
WRITE_NODE_TYPE("INHRELATION");
WRITE_NODE_FIELD(relation);
WRITE_UINT_FIELD(options);
}
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);
Remove collation information from TypeName, where it does not belong. The initial collations patch treated a COLLATE spec as part of a TypeName, following what can only be described as brain fade on the part of the SQL committee. It's a lot more reasonable to treat COLLATE as a syntactically separate object, so that it can be added in only the productions where it actually belongs, rather than needing to reject it in a boatload of places where it doesn't belong (something the original patch mostly failed to do). In addition this change lets us meet the spec's requirement to allow COLLATE anywhere in the clauses of a ColumnDef, and it avoids unfriendly behavior for constructs such as "foo::type COLLATE collation". To do this, pull collation information out of TypeName and put it in ColumnDef instead, thus reverting most of the collation-related changes in parse_type.c's API. I made one additional structural change, which was to use a ColumnDef as an intermediate node in AT_AlterColumnType AlterTableCmd nodes. This provides enough room to get rid of the "transform" wart in AlterTableCmd too, since the ColumnDef can carry the USING expression easily enough. Also fix some other minor bugs that have crept in in the same areas, like failure to copy recently-added fields of ColumnDef in copyfuncs.c. While at it, document the formerly secret ability to specify a collation in ALTER TABLE ALTER COLUMN TYPE, ALTER TYPE ADD ATTRIBUTE, and ALTER TYPE ALTER ATTRIBUTE TYPE; and correct some misstatements about what the default collation selection will be when COLLATE is omitted. BTW, the three-parameter form of format_type() should go away too, since it just contributes to the confusion in this area; but I'll do that in a separate patch.
2011-03-10 04:38:52 +01:00
WRITE_BOOL_FIELD(is_from_type);
WRITE_INT_FIELD(storage);
WRITE_NODE_FIELD(raw_default);
WRITE_NODE_FIELD(cooked_default);
Remove collation information from TypeName, where it does not belong. The initial collations patch treated a COLLATE spec as part of a TypeName, following what can only be described as brain fade on the part of the SQL committee. It's a lot more reasonable to treat COLLATE as a syntactically separate object, so that it can be added in only the productions where it actually belongs, rather than needing to reject it in a boatload of places where it doesn't belong (something the original patch mostly failed to do). In addition this change lets us meet the spec's requirement to allow COLLATE anywhere in the clauses of a ColumnDef, and it avoids unfriendly behavior for constructs such as "foo::type COLLATE collation". To do this, pull collation information out of TypeName and put it in ColumnDef instead, thus reverting most of the collation-related changes in parse_type.c's API. I made one additional structural change, which was to use a ColumnDef as an intermediate node in AT_AlterColumnType AlterTableCmd nodes. This provides enough room to get rid of the "transform" wart in AlterTableCmd too, since the ColumnDef can carry the USING expression easily enough. Also fix some other minor bugs that have crept in in the same areas, like failure to copy recently-added fields of ColumnDef in copyfuncs.c. While at it, document the formerly secret ability to specify a collation in ALTER TABLE ALTER COLUMN TYPE, ALTER TYPE ADD ATTRIBUTE, and ALTER TYPE ALTER ATTRIBUTE TYPE; and correct some misstatements about what the default collation selection will be when COLLATE is omitted. BTW, the three-parameter form of format_type() should go away too, since it just contributes to the confusion in this area; but I'll do that in a separate patch.
2011-03-10 04:38:52 +01:00
WRITE_NODE_FIELD(collClause);
WRITE_OID_FIELD(collOid);
WRITE_NODE_FIELD(constraints);
WRITE_NODE_FIELD(fdwoptions);
}
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
_outCollateClause(StringInfo str, CollateClause *node)
{
WRITE_NODE_TYPE("COLLATECLAUSE");
WRITE_NODE_FIELD(arg);
WRITE_NODE_FIELD(collname);
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(collation);
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
2005-10-15 04:49:52 +02:00
* 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(hasModifyingCTE);
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);
WRITE_BOOL_FIELD(hashable);
}
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);
WRITE_NODE_FIELD(ctecolcollations);
}
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(colCollations);
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:
WRITE_OID_FIELD(relid);
WRITE_CHAR_FIELD(relkind);
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);
WRITE_NODE_FIELD(funccolcollations);
break;
case RTE_VALUES:
WRITE_NODE_FIELD(values_lists);
WRITE_NODE_FIELD(values_collations);
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);
WRITE_NODE_FIELD(ctecolcollations);
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;
2000-05-26 00:43:12 +02:00
default:
appendStringInfo(str, " ??");
2000-05-26 00:43:12 +02:00
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:
2004-08-29 07:07:03 +02:00
/*
2005-10-15 04:49:52 +02:00
* 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);
}
1998-12-04 16:34:49 +01:00
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);
1998-12-04 16:34:49 +01:00
appendStringInfo(str, " :contype ");
1998-12-04 16:34:49 +01:00
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;
1998-12-04 16:34:49 +01:00
case CONSTR_PRIMARY:
appendStringInfo(str, "PRIMARY_KEY");
WRITE_NODE_FIELD(keys);
WRITE_NODE_FIELD(options);
WRITE_STRING_FIELD(indexname);
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(indexname);
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(indexname);
WRITE_STRING_FIELD(indexspace);
WRITE_STRING_FIELD(access_method);
WRITE_NODE_FIELD(where_clause);
1998-12-04 16:34:49 +01:00
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);
WRITE_BOOL_FIELD(initially_valid);
1998-12-04 16:34:49 +01:00
break;
case CONSTR_ATTR_DEFERRABLE:
appendStringInfo(str, "ATTR_DEFERRABLE");
1998-12-04 16:34:49 +01:00
break;
case CONSTR_ATTR_NOT_DEFERRABLE:
appendStringInfo(str, "ATTR_NOT_DEFERRABLE");
1998-12-04 16:34:49 +01:00
break;
case CONSTR_ATTR_DEFERRED:
appendStringInfo(str, "ATTR_DEFERRED");
1998-12-04 16:34:49 +01:00
break;
case CONSTR_ATTR_IMMEDIATE:
appendStringInfo(str, "ATTR_IMMEDIATE");
break;
default:
appendStringInfo(str, "<unrecognized_constraint %d>",
(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)
1998-01-07 16:32:47 +01:00
appendStringInfo(str, "<>");
2004-08-29 07:07:03 +02:00
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_MergeAppend:
_outMergeAppend(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_ForeignScan:
_outForeignScan(str, obj);
break;
case T_FdwPlan:
_outFdwPlan(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;
1999-01-24 01:28:37 +01:00
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_NullIfExpr:
_outNullIfExpr(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_CollateExpr:
_outCollateExpr(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_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_ForeignPath:
_outForeignPath(str, obj);
break;
case T_AppendPath:
_outAppendPath(str, obj);
break;
case T_MergeAppendPath:
_outMergeAppendPath(str, obj);
break;
case T_ResultPath:
_outResultPath(str, obj);
break;
case T_MaterialPath:
_outMaterialPath(str, obj);
break;
case T_UniquePath:
_outUniquePath(str, obj);
break;
1999-02-12 07:43:53 +01:00
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_MinMaxAggInfo:
_outMinMaxAggInfo(str, obj);
break;
case T_PlannerParamItem:
_outPlannerParamItem(str, obj);
break;
case T_CreateStmt:
_outCreateStmt(str, obj);
break;
case T_CreateForeignTableStmt:
_outCreateForeignTableStmt(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_CollateClause:
_outCollateClause(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;
1998-12-04 16:34:49 +01:00
case T_Constraint:
_outConstraint(str, obj);
break;
case T_FuncCall:
_outFuncCall(str, obj);
break;
case T_DefElem:
_outDefElem(str, obj);
break;
case T_InhRelation:
_outInhRelation(str, obj);
break;
case T_LockingClause:
_outLockingClause(str, obj);
break;
case T_XmlSerialize:
_outXmlSerialize(str, obj);
break;
default:
2003-08-04 02:43:34 +02:00
/*
2005-10-15 04:49:52 +02:00
* 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)
{
1999-05-25 18:15:34 +02:00
StringInfoData str;
/* see stringinfo.h for an explanation of this maneuver */
initStringInfo(&str);
_outNode(&str, obj);
return str.data;
}