Commit dbe100c4 authored by Tom Lane's avatar Tom Lane

Restructure outfuncs and readfuncs to use macros in the same style as

just done for copyfuncs/equalfuncs.  Read functions in particular get
a lot shorter than before, and it's much easier to compare an out function
with the corresponding read function to make sure they agree.
initdb forced due to small changes in nodestring format (regularizing
a few cases that were formerly idiosyncratic).
parent 0aa5b686
/* /*-------------------------------------------------------------------------
*
* outfuncs.c * outfuncs.c
* routines to convert a node to ascii representation * Output functions for Postgres tree nodes.
* *
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.181 2002/11/24 21:52:13 tgl Exp $ *
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.182 2002/11/25 18:12:09 tgl Exp $
* *
* NOTES * NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which * Every node type that can appear in stored rules' parsetrees *must*
* knows how to create its ascii representation. These functions are * have an output function defined here (as well as an input function
* useful for debugging as well as for storing plans in the system * in readfuncs.c). For use in debugging, we also provide output
* catalogs (eg. views). * functions for nodes that appear in raw parsetrees and plan trees.
* These nodes however need not have input functions.
*
*-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
...@@ -27,6 +33,72 @@ ...@@ -27,6 +33,72 @@
#include "utils/datum.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) \
appendStringInfo(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 Node field */
#define WRITE_NODE_FIELD(fldname) \
(appendStringInfo(str, " :" CppAsString(fldname) " "), \
_outNode(str, node->fldname))
/* Write an integer-list field */
#define WRITE_INTLIST_FIELD(fldname) \
(appendStringInfo(str, " :" CppAsString(fldname) " "), \
_outIntList(str, node->fldname))
/* Write an OID-list field */
#define WRITE_OIDLIST_FIELD(fldname) \
(appendStringInfo(str, " :" CppAsString(fldname) " "), \
_outOidList(str, node->fldname))
#define booltostr(x) ((x) ? "true" : "false") #define booltostr(x) ((x) ? "true" : "false")
static void _outDatum(StringInfo str, Datum value, int typlen, bool typbyval); static void _outDatum(StringInfo str, Datum value, int typlen, bool typbyval);
...@@ -105,133 +177,117 @@ _outOidList(StringInfo str, List *list) ...@@ -105,133 +177,117 @@ _outOidList(StringInfo str, List *list)
static void static void
_outCreateStmt(StringInfo str, CreateStmt *node) _outCreateStmt(StringInfo str, CreateStmt *node)
{ {
appendStringInfo(str, " CREATE :relation "); WRITE_NODE_TYPE("CREATE");
_outNode(str, node->relation);
appendStringInfo(str, " :tableElts ");
_outNode(str, node->tableElts);
appendStringInfo(str, " :inhRelations ");
_outNode(str, node->inhRelations);
appendStringInfo(str, " :constraints ");
_outNode(str, node->constraints);
appendStringInfo(str, " :hasoids %s :oncommit %d ", WRITE_NODE_FIELD(relation);
booltostr(node->hasoids), WRITE_NODE_FIELD(tableElts);
(int) node->oncommit); WRITE_NODE_FIELD(inhRelations);
WRITE_NODE_FIELD(constraints);
WRITE_BOOL_FIELD(hasoids);
WRITE_ENUM_FIELD(oncommit, OnCommitAction);
} }
static void static void
_outIndexStmt(StringInfo str, IndexStmt *node) _outIndexStmt(StringInfo str, IndexStmt *node)
{ {
appendStringInfo(str, " INDEX :idxname "); WRITE_NODE_TYPE("INDEX");
_outToken(str, node->idxname);
appendStringInfo(str, " :relation "); WRITE_STRING_FIELD(idxname);
_outNode(str, node->relation); WRITE_NODE_FIELD(relation);
appendStringInfo(str, " :accessMethod "); WRITE_STRING_FIELD(accessMethod);
_outToken(str, node->accessMethod); WRITE_NODE_FIELD(indexParams);
appendStringInfo(str, " :indexParams "); WRITE_NODE_FIELD(whereClause);
_outNode(str, node->indexParams); WRITE_NODE_FIELD(rangetable);
appendStringInfo(str, " :whereClause "); WRITE_BOOL_FIELD(unique);
_outNode(str, node->whereClause); WRITE_BOOL_FIELD(primary);
appendStringInfo(str, " :rangetable "); WRITE_BOOL_FIELD(isconstraint);
_outNode(str, node->rangetable);
appendStringInfo(str, " :unique %s :primary %s :isconstraint %s ",
booltostr(node->unique),
booltostr(node->primary),
booltostr(node->isconstraint));
} }
static void static void
_outNotifyStmt(StringInfo str, NotifyStmt *node) _outNotifyStmt(StringInfo str, NotifyStmt *node)
{ {
appendStringInfo(str, " NOTIFY :relation "); WRITE_NODE_TYPE("NOTIFY");
_outNode(str, node->relation);
WRITE_NODE_FIELD(relation);
} }
static void static void
_outSelectStmt(StringInfo str, SelectStmt *node) _outSelectStmt(StringInfo str, SelectStmt *node)
{ {
WRITE_NODE_TYPE("SELECT");
/* XXX this is pretty durn incomplete */ /* XXX this is pretty durn incomplete */
appendStringInfo(str, " SELECT :where "); WRITE_NODE_FIELD(whereClause);
_outNode(str, node->whereClause);
} }
static void static void
_outFuncCall(StringInfo str, FuncCall *node) _outFuncCall(StringInfo str, FuncCall *node)
{ {
appendStringInfo(str, " FUNCCALL "); WRITE_NODE_TYPE("FUNCCALL");
_outNode(str, node->funcname);
appendStringInfo(str, " :args "); WRITE_NODE_FIELD(funcname);
_outNode(str, node->args); WRITE_NODE_FIELD(args);
appendStringInfo(str, " :agg_star %s :agg_distinct %s ", WRITE_BOOL_FIELD(agg_star);
booltostr(node->agg_star), WRITE_BOOL_FIELD(agg_distinct);
booltostr(node->agg_distinct));
} }
static void static void
_outColumnDef(StringInfo str, ColumnDef *node) _outColumnDef(StringInfo str, ColumnDef *node)
{ {
appendStringInfo(str, " COLUMNDEF :colname "); WRITE_NODE_TYPE("COLUMNDEF");
_outToken(str, node->colname);
appendStringInfo(str, " :typename "); WRITE_STRING_FIELD(colname);
_outNode(str, node->typename); WRITE_NODE_FIELD(typename);
appendStringInfo(str, " :inhcount %d :is_local %s :is_not_null %s :raw_default ", WRITE_INT_FIELD(inhcount);
node->inhcount, WRITE_BOOL_FIELD(is_local);
booltostr(node->is_local), WRITE_BOOL_FIELD(is_not_null);
booltostr(node->is_not_null)); WRITE_NODE_FIELD(raw_default);
_outNode(str, node->raw_default); WRITE_STRING_FIELD(cooked_default);
appendStringInfo(str, " :cooked_default "); WRITE_NODE_FIELD(constraints);
_outToken(str, node->cooked_default); WRITE_NODE_FIELD(support);
appendStringInfo(str, " :constraints ");
_outNode(str, node->constraints);
appendStringInfo(str, " :support ");
_outNode(str, node->support);
} }
static void static void
_outTypeName(StringInfo str, TypeName *node) _outTypeName(StringInfo str, TypeName *node)
{ {
appendStringInfo(str, " TYPENAME :names "); WRITE_NODE_TYPE("TYPENAME");
_outNode(str, node->names);
appendStringInfo(str, " :typeid %u :timezone %s :setof %s" WRITE_NODE_FIELD(names);
" :pct_type %s :typmod %d :arrayBounds ", WRITE_OID_FIELD(typeid);
node->typeid, WRITE_BOOL_FIELD(timezone);
booltostr(node->timezone), WRITE_BOOL_FIELD(setof);
booltostr(node->setof), WRITE_BOOL_FIELD(pct_type);
booltostr(node->pct_type), WRITE_INT_FIELD(typmod);
node->typmod); WRITE_NODE_FIELD(arrayBounds);
_outNode(str, node->arrayBounds);
} }
static void static void
_outTypeCast(StringInfo str, TypeCast *node) _outTypeCast(StringInfo str, TypeCast *node)
{ {
appendStringInfo(str, " TYPECAST :arg "); WRITE_NODE_TYPE("TYPECAST");
_outNode(str, node->arg);
appendStringInfo(str, " :typename "); WRITE_NODE_FIELD(arg);
_outNode(str, node->typename); WRITE_NODE_FIELD(typename);
} }
static void static void
_outIndexElem(StringInfo str, IndexElem *node) _outIndexElem(StringInfo str, IndexElem *node)
{ {
appendStringInfo(str, " INDEXELEM :name "); WRITE_NODE_TYPE("INDEXELEM");
_outToken(str, node->name);
appendStringInfo(str, " :funcname "); WRITE_STRING_FIELD(name);
_outNode(str, node->funcname); WRITE_NODE_FIELD(funcname);
appendStringInfo(str, " :args "); WRITE_NODE_FIELD(args);
_outNode(str, node->args); WRITE_NODE_FIELD(opclass);
appendStringInfo(str, " :opclass ");
_outNode(str, node->opclass);
} }
static void static void
_outQuery(StringInfo str, Query *node) _outQuery(StringInfo str, Query *node)
{ {
appendStringInfo(str, " QUERY :command %d :source %d :utility ", WRITE_NODE_TYPE("QUERY");
(int) node->commandType, (int) node->querySource);
WRITE_ENUM_FIELD(commandType, CmdType);
WRITE_ENUM_FIELD(querySource, QuerySource);
/* /*
* Hack to work around missing outfuncs routines for a lot of the * Hack to work around missing outfuncs routines for a lot of the
...@@ -247,60 +303,34 @@ _outQuery(StringInfo str, Query *node) ...@@ -247,60 +303,34 @@ _outQuery(StringInfo str, Query *node)
case T_CreateStmt: case T_CreateStmt:
case T_IndexStmt: case T_IndexStmt:
case T_NotifyStmt: case T_NotifyStmt:
_outNode(str, node->utilityStmt); WRITE_NODE_FIELD(utilityStmt);
break; break;
default: default:
appendStringInfo(str, "?"); appendStringInfo(str, " :utilityStmt ?");
break; break;
} }
} }
else else
appendStringInfo(str, "<>"); appendStringInfo(str, " :utilityStmt <>");
appendStringInfo(str, " :resultRelation %d :into ", WRITE_INT_FIELD(resultRelation);
node->resultRelation); WRITE_NODE_FIELD(into);
_outNode(str, node->into); WRITE_BOOL_FIELD(isPortal);
WRITE_BOOL_FIELD(isBinary);
appendStringInfo(str, " :isPortal %s :isBinary %s" WRITE_BOOL_FIELD(hasAggs);
" :hasAggs %s :hasSubLinks %s :rtable ", WRITE_BOOL_FIELD(hasSubLinks);
booltostr(node->isPortal), WRITE_NODE_FIELD(rtable);
booltostr(node->isBinary), WRITE_NODE_FIELD(jointree);
booltostr(node->hasAggs), WRITE_INTLIST_FIELD(rowMarks);
booltostr(node->hasSubLinks)); WRITE_NODE_FIELD(targetList);
_outNode(str, node->rtable); WRITE_NODE_FIELD(groupClause);
WRITE_NODE_FIELD(havingQual);
appendStringInfo(str, " :jointree "); WRITE_NODE_FIELD(distinctClause);
_outNode(str, node->jointree); WRITE_NODE_FIELD(sortClause);
WRITE_NODE_FIELD(limitOffset);
appendStringInfo(str, " :rowMarks "); WRITE_NODE_FIELD(limitCount);
_outIntList(str, node->rowMarks); WRITE_NODE_FIELD(setOperations);
WRITE_INTLIST_FIELD(resultRelations);
appendStringInfo(str, " :targetList ");
_outNode(str, node->targetList);
appendStringInfo(str, " :groupClause ");
_outNode(str, node->groupClause);
appendStringInfo(str, " :havingQual ");
_outNode(str, node->havingQual);
appendStringInfo(str, " :distinctClause ");
_outNode(str, node->distinctClause);
appendStringInfo(str, " :sortClause ");
_outNode(str, node->sortClause);
appendStringInfo(str, " :limitOffset ");
_outNode(str, node->limitOffset);
appendStringInfo(str, " :limitCount ");
_outNode(str, node->limitCount);
appendStringInfo(str, " :setOperations ");
_outNode(str, node->setOperations);
appendStringInfo(str, " :resultRelations ");
_outIntList(str, node->resultRelations);
/* planner-internal fields are not written out */ /* planner-internal fields are not written out */
} }
...@@ -308,30 +338,37 @@ _outQuery(StringInfo str, Query *node) ...@@ -308,30 +338,37 @@ _outQuery(StringInfo str, Query *node)
static void static void
_outSortClause(StringInfo str, SortClause *node) _outSortClause(StringInfo str, SortClause *node)
{ {
appendStringInfo(str, " SORTCLAUSE :tleSortGroupRef %u :sortop %u ", WRITE_NODE_TYPE("SORTCLAUSE");
node->tleSortGroupRef, node->sortop);
WRITE_UINT_FIELD(tleSortGroupRef);
WRITE_OID_FIELD(sortop);
} }
static void static void
_outGroupClause(StringInfo str, GroupClause *node) _outGroupClause(StringInfo str, GroupClause *node)
{ {
appendStringInfo(str, " GROUPCLAUSE :tleSortGroupRef %u :sortop %u ", WRITE_NODE_TYPE("GROUPCLAUSE");
node->tleSortGroupRef, node->sortop);
WRITE_UINT_FIELD(tleSortGroupRef);
WRITE_OID_FIELD(sortop);
} }
static void static void
_outSetOperationStmt(StringInfo str, SetOperationStmt *node) _outSetOperationStmt(StringInfo str, SetOperationStmt *node)
{ {
appendStringInfo(str, " SETOPERATIONSTMT :op %d :all %s :larg ", WRITE_NODE_TYPE("SETOPERATIONSTMT");
(int) node->op,
booltostr(node->all)); WRITE_ENUM_FIELD(op, SetOperation);
_outNode(str, node->larg); WRITE_BOOL_FIELD(all);
appendStringInfo(str, " :rarg "); WRITE_NODE_FIELD(larg);
_outNode(str, node->rarg); WRITE_NODE_FIELD(rarg);
appendStringInfo(str, " :colTypes "); WRITE_OIDLIST_FIELD(colTypes);
_outOidList(str, node->colTypes);
} }
/*
* Stuff from plannodes.h
*/
/* /*
* print the basic stuff of all nodes that inherit from Plan * print the basic stuff of all nodes that inherit from Plan
* *
...@@ -340,274 +377,208 @@ _outSetOperationStmt(StringInfo str, SetOperationStmt *node) ...@@ -340,274 +377,208 @@ _outSetOperationStmt(StringInfo str, SetOperationStmt *node)
static void static void
_outPlanInfo(StringInfo str, Plan *node) _outPlanInfo(StringInfo str, Plan *node)
{ {
appendStringInfo(str, WRITE_FLOAT_FIELD(startup_cost, "%.2f");
":startup_cost %.2f :total_cost %.2f :rows %.0f :width %d :qptargetlist ", WRITE_FLOAT_FIELD(total_cost, "%.2f");
node->startup_cost, WRITE_FLOAT_FIELD(plan_rows, "%.0f");
node->total_cost, WRITE_INT_FIELD(plan_width);
node->plan_rows, WRITE_NODE_FIELD(targetlist);
node->plan_width); WRITE_NODE_FIELD(qual);
_outNode(str, node->targetlist); WRITE_NODE_FIELD(lefttree);
WRITE_NODE_FIELD(righttree);
appendStringInfo(str, " :qpqual "); WRITE_INTLIST_FIELD(extParam);
_outNode(str, node->qual); WRITE_INTLIST_FIELD(locParam);
/* chgParam is execution state too */
appendStringInfo(str, " :lefttree "); WRITE_NODE_FIELD(initPlan);
_outNode(str, node->lefttree); /* we don't write subPlan; reader must reconstruct list */
WRITE_INT_FIELD(nParamExec);
appendStringInfo(str, " :righttree "); }
_outNode(str, node->righttree);
appendStringInfo(str, " :extprm ");
_outIntList(str, node->extParam);
appendStringInfo(str, " :locprm ");
_outIntList(str, node->locParam);
appendStringInfo(str, " :initplan "); /*
_outNode(str, node->initPlan); * print the basic stuff of all nodes that inherit from Scan
*/
static void
_outScanInfo(StringInfo str, Scan *node)
{
_outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :nprm %d ", node->nParamExec); WRITE_UINT_FIELD(scanrelid);
} }
/* /*
* Stuff from plannodes.h * 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 static void
_outPlan(StringInfo str, Plan *node) _outPlan(StringInfo str, Plan *node)
{ {
appendStringInfo(str, " PLAN "); WRITE_NODE_TYPE("PLAN");
_outPlanInfo(str, (Plan *) node); _outPlanInfo(str, (Plan *) node);
} }
static void static void
_outResult(StringInfo str, Result *node) _outResult(StringInfo str, Result *node)
{ {
appendStringInfo(str, " RESULT "); WRITE_NODE_TYPE("RESULT");
_outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :resconstantqual "); _outPlanInfo(str, (Plan *) node);
_outNode(str, node->resconstantqual);
WRITE_NODE_FIELD(resconstantqual);
} }
/*
* Append is a subclass of Plan.
*/
static void static void
_outAppend(StringInfo str, Append *node) _outAppend(StringInfo str, Append *node)
{ {
appendStringInfo(str, " APPEND "); WRITE_NODE_TYPE("APPEND");
_outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :appendplans "); _outPlanInfo(str, (Plan *) node);
_outNode(str, node->appendplans);
appendStringInfo(str, " :isTarget %s ", WRITE_NODE_FIELD(appendplans);
booltostr(node->isTarget)); WRITE_BOOL_FIELD(isTarget);
} }
/*
* Join is a subclass of Plan
*/
static void static void
_outJoin(StringInfo str, Join *node) _outScan(StringInfo str, Scan *node)
{ {
appendStringInfo(str, " JOIN "); WRITE_NODE_TYPE("SCAN");
_outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :jointype %d :joinqual ", _outScanInfo(str, (Scan *) node);
(int) node->jointype);
_outNode(str, node->joinqual);
} }
/*
* NestLoop is a subclass of Join
*/
static void static void
_outNestLoop(StringInfo str, NestLoop *node) _outSeqScan(StringInfo str, SeqScan *node)
{ {
appendStringInfo(str, " NESTLOOP "); WRITE_NODE_TYPE("SEQSCAN");
_outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :jointype %d :joinqual ", _outScanInfo(str, (Scan *) node);
(int) node->join.jointype);
_outNode(str, node->join.joinqual);
} }
/*
* MergeJoin is a subclass of Join
*/
static void static void
_outMergeJoin(StringInfo str, MergeJoin *node) _outIndexScan(StringInfo str, IndexScan *node)
{ {
appendStringInfo(str, " MERGEJOIN "); WRITE_NODE_TYPE("INDEXSCAN");
_outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :jointype %d :joinqual ",
(int) node->join.jointype);
_outNode(str, node->join.joinqual);
appendStringInfo(str, " :mergeclauses "); _outScanInfo(str, (Scan *) node);
_outNode(str, node->mergeclauses);
WRITE_OIDLIST_FIELD(indxid);
WRITE_NODE_FIELD(indxqual);
WRITE_NODE_FIELD(indxqualorig);
WRITE_ENUM_FIELD(indxorderdir, ScanDirection);
} }
/*
* HashJoin is a subclass of Join.
*/
static void static void
_outHashJoin(StringInfo str, HashJoin *node) _outTidScan(StringInfo str, TidScan *node)
{ {
appendStringInfo(str, " HASHJOIN "); WRITE_NODE_TYPE("TIDSCAN");
_outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :jointype %d :joinqual ", _outScanInfo(str, (Scan *) node);
(int) node->join.jointype);
_outNode(str, node->join.joinqual);
appendStringInfo(str, " :hashclauses "); WRITE_BOOL_FIELD(needRescan);
_outNode(str, node->hashclauses); WRITE_NODE_FIELD(tideval);
appendStringInfo(str, " :hashjoinop %u ",
node->hashjoinop);
} }
static void static void
_outSubPlan(StringInfo str, SubPlan *node) _outSubqueryScan(StringInfo str, SubqueryScan *node)
{ {
appendStringInfo(str, " SUBPLAN :plan "); WRITE_NODE_TYPE("SUBQUERYSCAN");
_outNode(str, node->plan);
appendStringInfo(str, " :planid %d :rtable ", node->plan_id);
_outNode(str, node->rtable);
appendStringInfo(str, " :setprm "); _outScanInfo(str, (Scan *) node);
_outIntList(str, node->setParam);
appendStringInfo(str, " :parprm "); WRITE_NODE_FIELD(subplan);
_outIntList(str, node->parParam);
appendStringInfo(str, " :slink ");
_outNode(str, node->sublink);
} }
/*
* Scan is a subclass of Node
*/
static void static void
_outScan(StringInfo str, Scan *node) _outFunctionScan(StringInfo str, FunctionScan *node)
{ {
appendStringInfo(str, " SCAN "); WRITE_NODE_TYPE("FUNCTIONSCAN");
_outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :scanrelid %u ", node->scanrelid); _outScanInfo(str, (Scan *) node);
} }
/*
* SeqScan is a subclass of Scan
*/
static void static void
_outSeqScan(StringInfo str, SeqScan *node) _outJoin(StringInfo str, Join *node)
{ {
appendStringInfo(str, " SEQSCAN "); WRITE_NODE_TYPE("JOIN");
_outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :scanrelid %u ", node->scanrelid); _outJoinPlanInfo(str, (Join *) node);
} }
/*
* IndexScan is a subclass of Scan
*/
static void static void
_outIndexScan(StringInfo str, IndexScan *node) _outNestLoop(StringInfo str, NestLoop *node)
{ {
appendStringInfo(str, " INDEXSCAN "); WRITE_NODE_TYPE("NESTLOOP");
_outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :scanrelid %u :indxid ", node->scan.scanrelid); _outJoinPlanInfo(str, (Join *) node);
_outOidList(str, node->indxid); }
appendStringInfo(str, " :indxqual "); static void
_outNode(str, node->indxqual); _outMergeJoin(StringInfo str, MergeJoin *node)
{
WRITE_NODE_TYPE("MERGEJOIN");
appendStringInfo(str, " :indxqualorig "); _outJoinPlanInfo(str, (Join *) node);
_outNode(str, node->indxqualorig);
appendStringInfo(str, " :indxorderdir %d ", node->indxorderdir); WRITE_NODE_FIELD(mergeclauses);
} }
/*
* TidScan is a subclass of Scan
*/
static void static void
_outTidScan(StringInfo str, TidScan *node) _outHashJoin(StringInfo str, HashJoin *node)
{ {
appendStringInfo(str, " TIDSCAN "); WRITE_NODE_TYPE("HASHJOIN");
_outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :scanrelid %u ", node->scan.scanrelid); _outJoinPlanInfo(str, (Join *) node);
appendStringInfo(str, " :needrescan %d ", node->needRescan);
appendStringInfo(str, " :tideval ");
_outNode(str, node->tideval);
WRITE_NODE_FIELD(hashclauses);
WRITE_OID_FIELD(hashjoinop);
} }
/*
* SubqueryScan is a subclass of Scan
*/
static void static void
_outSubqueryScan(StringInfo str, SubqueryScan *node) _outAgg(StringInfo str, Agg *node)
{ {
appendStringInfo(str, " SUBQUERYSCAN "); WRITE_NODE_TYPE("AGG");
_outPlanInfo(str, (Plan *) node); _outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :scanrelid %u :subplan ", node->scan.scanrelid); WRITE_ENUM_FIELD(aggstrategy, AggStrategy);
_outNode(str, node->subplan); WRITE_INT_FIELD(numCols);
WRITE_LONG_FIELD(numGroups);
} }
/*
* FunctionScan is a subclass of Scan
*/
static void static void
_outFunctionScan(StringInfo str, FunctionScan *node) _outGroup(StringInfo str, Group *node)
{ {
appendStringInfo(str, " FUNCTIONSCAN "); WRITE_NODE_TYPE("GRP");
_outPlanInfo(str, (Plan *) node); _outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :scanrelid %u ", node->scan.scanrelid); WRITE_INT_FIELD(numCols);
} }
/*
* Material is a subclass of Plan
*/
static void static void
_outMaterial(StringInfo str, Material *node) _outMaterial(StringInfo str, Material *node)
{ {
appendStringInfo(str, " MATERIAL "); WRITE_NODE_TYPE("MATERIAL");
_outPlanInfo(str, (Plan *) node); _outPlanInfo(str, (Plan *) node);
} }
/*
* Sort is a subclass of Plan
*/
static void static void
_outSort(StringInfo str, Sort *node) _outSort(StringInfo str, Sort *node)
{ {
appendStringInfo(str, " SORT "); WRITE_NODE_TYPE("SORT");
_outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :keycount %d ", node->keycount);
}
static void
_outAgg(StringInfo str, Agg *node)
{
appendStringInfo(str, " AGG ");
_outPlanInfo(str, (Plan *) node); _outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :aggstrategy %d :numCols %d :numGroups %ld ",
(int) node->aggstrategy, node->numCols, node->numGroups);
}
static void WRITE_INT_FIELD(keycount);
_outGroup(StringInfo str, Group *node)
{
appendStringInfo(str, " GRP ");
_outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :numCols %d ", node->numCols);
} }
static void static void
...@@ -615,13 +586,15 @@ _outUnique(StringInfo str, Unique *node) ...@@ -615,13 +586,15 @@ _outUnique(StringInfo str, Unique *node)
{ {
int i; int i;
appendStringInfo(str, " UNIQUE "); WRITE_NODE_TYPE("UNIQUE");
_outPlanInfo(str, (Plan *) node); _outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :numCols %d :uniqColIdx ", WRITE_INT_FIELD(numCols);
node->numCols);
appendStringInfo(str, " :uniqColIdx");
for (i = 0; i < node->numCols; i++) for (i = 0; i < node->numCols; i++)
appendStringInfo(str, "%d ", (int) node->uniqColIdx[i]); appendStringInfo(str, " %d", node->uniqColIdx[i]);
} }
static void static void
...@@ -629,40 +602,52 @@ _outSetOp(StringInfo str, SetOp *node) ...@@ -629,40 +602,52 @@ _outSetOp(StringInfo str, SetOp *node)
{ {
int i; int i;
appendStringInfo(str, " SETOP "); WRITE_NODE_TYPE("SETOP");
_outPlanInfo(str, (Plan *) node); _outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :cmd %d :numCols %d :dupColIdx ", WRITE_ENUM_FIELD(cmd, SetOpCmd);
(int) node->cmd, node->numCols); WRITE_INT_FIELD(numCols);
appendStringInfo(str, " :dupColIdx");
for (i = 0; i < node->numCols; i++) for (i = 0; i < node->numCols; i++)
appendStringInfo(str, "%d ", (int) node->dupColIdx[i]); appendStringInfo(str, " %d", node->dupColIdx[i]);
appendStringInfo(str, " :flagColIdx %d ",
(int) node->flagColIdx); WRITE_INT_FIELD(flagColIdx);
} }
static void static void
_outLimit(StringInfo str, Limit *node) _outLimit(StringInfo str, Limit *node)
{ {
appendStringInfo(str, " LIMIT "); WRITE_NODE_TYPE("LIMIT");
_outPlanInfo(str, (Plan *) node); _outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :limitOffset "); WRITE_NODE_FIELD(limitOffset);
_outNode(str, node->limitOffset); WRITE_NODE_FIELD(limitCount);
appendStringInfo(str, " :limitCount ");
_outNode(str, node->limitCount);
} }
/*
* Hash is a subclass of Plan
*/
static void static void
_outHash(StringInfo str, Hash *node) _outHash(StringInfo str, Hash *node)
{ {
appendStringInfo(str, " HASH "); WRITE_NODE_TYPE("HASH");
_outPlanInfo(str, (Plan *) node); _outPlanInfo(str, (Plan *) node);
appendStringInfo(str, " :hashkey "); WRITE_NODE_FIELD(hashkey);
_outNode(str, node->hashkey); }
static void
_outSubPlan(StringInfo str, SubPlan *node)
{
WRITE_NODE_TYPE("SUBPLAN");
WRITE_NODE_FIELD(plan);
WRITE_INT_FIELD(plan_id);
WRITE_NODE_FIELD(rtable);
WRITE_INTLIST_FIELD(setParam);
WRITE_INTLIST_FIELD(parParam);
WRITE_NODE_FIELD(sublink);
} }
/***************************************************************************** /*****************************************************************************
...@@ -671,56 +656,31 @@ _outHash(StringInfo str, Hash *node) ...@@ -671,56 +656,31 @@ _outHash(StringInfo str, Hash *node)
* *
*****************************************************************************/ *****************************************************************************/
/*
* Resdom is a subclass of Node
*/
static void static void
_outResdom(StringInfo str, Resdom *node) _outResdom(StringInfo str, Resdom *node)
{ {
appendStringInfo(str, WRITE_NODE_TYPE("RESDOM");
" RESDOM :resno %d :restype %u :restypmod %d :resname ",
node->resno,
node->restype,
node->restypmod);
_outToken(str, node->resname);
appendStringInfo(str, " :reskey %u :reskeyop %u :ressortgroupref %u :resjunk %s ",
node->reskey,
node->reskeyop,
node->ressortgroupref,
booltostr(node->resjunk));
}
static void WRITE_INT_FIELD(resno);
_outFjoin(StringInfo str, Fjoin *node) WRITE_OID_FIELD(restype);
{ WRITE_INT_FIELD(restypmod);
int i; WRITE_STRING_FIELD(resname);
WRITE_UINT_FIELD(ressortgroupref);
appendStringInfo(str, " FJOIN :initialized %s :nNodes %d ", WRITE_UINT_FIELD(reskey);
booltostr(node->fj_initialized), WRITE_OID_FIELD(reskeyop);
node->fj_nNodes); WRITE_BOOL_FIELD(resjunk);
appendStringInfo(str, " :innerNode ");
_outNode(str, node->fj_innerNode);
appendStringInfo(str, " :results @ 0x%p :alwaysdone",
node->fj_results);
for (i = 0; i < node->fj_nNodes; i++)
appendStringInfo(str,
booltostr(node->fj_alwaysDone[i]));
} }
/*
* Expr is a subclass of Node
*/
static void static void
_outExpr(StringInfo str, Expr *node) _outExpr(StringInfo str, Expr *node)
{ {
char *opstr = NULL; char *opstr = NULL;
appendStringInfo(str, " EXPR :typeOid %u ", WRITE_NODE_TYPE("EXPR");
node->typeOid);
WRITE_OID_FIELD(typeOid);
/* do-it-yourself enum representation */
switch (node->opType) switch (node->opType)
{ {
case OP_EXPR: case OP_EXPR:
...@@ -747,504 +707,371 @@ _outExpr(StringInfo str, Expr *node) ...@@ -747,504 +707,371 @@ _outExpr(StringInfo str, Expr *node)
} }
appendStringInfo(str, " :opType "); appendStringInfo(str, " :opType ");
_outToken(str, opstr); _outToken(str, opstr);
appendStringInfo(str, " :oper ");
_outNode(str, node->oper);
appendStringInfo(str, " :args "); WRITE_NODE_FIELD(oper);
_outNode(str, node->args); WRITE_NODE_FIELD(args);
} }
/*
* Var is a subclass of Expr
*/
static void static void
_outVar(StringInfo str, Var *node) _outVar(StringInfo str, Var *node)
{ {
appendStringInfo(str, WRITE_NODE_TYPE("VAR");
" VAR :varno %u :varattno %d :vartype %u :vartypmod %d ",
node->varno,
node->varattno,
node->vartype,
node->vartypmod);
appendStringInfo(str, " :varlevelsup %u :varnoold %u :varoattno %d", WRITE_UINT_FIELD(varno);
node->varlevelsup, WRITE_INT_FIELD(varattno);
node->varnoold, WRITE_OID_FIELD(vartype);
node->varoattno); WRITE_INT_FIELD(vartypmod);
WRITE_UINT_FIELD(varlevelsup);
WRITE_UINT_FIELD(varnoold);
WRITE_INT_FIELD(varoattno);
} }
/*
* Const is a subclass of Expr
*/
static void static void
_outConst(StringInfo str, Const *node) _outConst(StringInfo str, Const *node)
{ {
appendStringInfo(str, WRITE_NODE_TYPE("CONST");
" CONST :consttype %u :constlen %d :constbyval %s"
" :constisnull %s :constvalue ", WRITE_OID_FIELD(consttype);
node->consttype, WRITE_INT_FIELD(constlen);
node->constlen, WRITE_BOOL_FIELD(constbyval);
booltostr(node->constbyval), WRITE_BOOL_FIELD(constisnull);
booltostr(node->constisnull)); /* XXX what about constisset, constiscast? */
appendStringInfo(str, " :constvalue ");
if (node->constisnull) if (node->constisnull)
appendStringInfo(str, "<>"); appendStringInfo(str, "<>");
else else
_outDatum(str, node->constvalue, node->constlen, node->constbyval); _outDatum(str, node->constvalue, node->constlen, node->constbyval);
} }
/*
* Aggref
*/
static void static void
_outAggref(StringInfo str, Aggref *node) _outAggref(StringInfo str, Aggref *node)
{ {
appendStringInfo(str, " AGGREG :aggfnoid %u :aggtype %u :target ", WRITE_NODE_TYPE("AGGREF");
node->aggfnoid, node->aggtype);
_outNode(str, node->target);
appendStringInfo(str, " :aggstar %s :aggdistinct %s ", WRITE_OID_FIELD(aggfnoid);
booltostr(node->aggstar), WRITE_OID_FIELD(aggtype);
booltostr(node->aggdistinct)); WRITE_NODE_FIELD(target);
/* aggno is not dumped */ WRITE_BOOL_FIELD(aggstar);
WRITE_BOOL_FIELD(aggdistinct);
/* aggno is not saved since it is just executor state */
} }
/*
* SubLink
*/
static void static void
_outSubLink(StringInfo str, SubLink *node) _outSubLink(StringInfo str, SubLink *node)
{ {
appendStringInfo(str, WRITE_NODE_TYPE("SUBLINK");
" SUBLINK :subLinkType %d :useor %s :lefthand ",
node->subLinkType,
booltostr(node->useor));
_outNode(str, node->lefthand);
appendStringInfo(str, " :oper ");
_outNode(str, node->oper);
appendStringInfo(str, " :subselect "); WRITE_ENUM_FIELD(subLinkType, SubLinkType);
_outNode(str, node->subselect); WRITE_BOOL_FIELD(useor);
WRITE_NODE_FIELD(lefthand);
WRITE_NODE_FIELD(oper);
WRITE_NODE_FIELD(subselect);
} }
/*
* ArrayRef is a subclass of Expr
*/
static void static void
_outArrayRef(StringInfo str, ArrayRef *node) _outArrayRef(StringInfo str, ArrayRef *node)
{ {
appendStringInfo(str, WRITE_NODE_TYPE("ARRAYREF");
" ARRAYREF :refrestype %u :refattrlength %d :refelemlength %d ",
node->refrestype,
node->refattrlength,
node->refelemlength);
appendStringInfo(str, WRITE_OID_FIELD(refrestype);
":refelembyval %s :refelemalign %c :refupperindexpr ", WRITE_INT_FIELD(refattrlength);
booltostr(node->refelembyval), WRITE_INT_FIELD(refelemlength);
node->refelemalign); WRITE_BOOL_FIELD(refelembyval);
_outNode(str, node->refupperindexpr); WRITE_CHAR_FIELD(refelemalign);
WRITE_NODE_FIELD(refupperindexpr);
appendStringInfo(str, " :reflowerindexpr "); WRITE_NODE_FIELD(reflowerindexpr);
_outNode(str, node->reflowerindexpr); WRITE_NODE_FIELD(refexpr);
WRITE_NODE_FIELD(refassgnexpr);
appendStringInfo(str, " :refexpr ");
_outNode(str, node->refexpr);
appendStringInfo(str, " :refassgnexpr ");
_outNode(str, node->refassgnexpr);
} }
/*
* Func is a subclass of Expr
*/
static void static void
_outFunc(StringInfo str, Func *node) _outFunc(StringInfo str, Func *node)
{ {
appendStringInfo(str, WRITE_NODE_TYPE("FUNC");
" FUNC :funcid %u :funcresulttype %u :funcretset %s :funcformat %d ",
node->funcid, WRITE_OID_FIELD(funcid);
node->funcresulttype, WRITE_OID_FIELD(funcresulttype);
booltostr(node->funcretset), WRITE_BOOL_FIELD(funcretset);
(int) node->funcformat); WRITE_ENUM_FIELD(funcformat, CoercionForm);
} }
/*
* Oper is a subclass of Expr
*/
static void static void
_outOper(StringInfo str, Oper *node) _outOper(StringInfo str, Oper *node)
{ {
appendStringInfo(str, WRITE_NODE_TYPE("OPER");
" OPER :opno %u :opid %u :opresulttype %u :opretset %s ",
node->opno, WRITE_OID_FIELD(opno);
node->opid, WRITE_OID_FIELD(opid);
node->opresulttype, WRITE_OID_FIELD(opresulttype);
booltostr(node->opretset)); WRITE_BOOL_FIELD(opretset);
} }
/*
* Param is a subclass of Expr
*/
static void static void
_outParam(StringInfo str, Param *node) _outParam(StringInfo str, Param *node)
{ {
appendStringInfo(str, " PARAM :paramkind %d :paramid %d :paramname ", WRITE_NODE_TYPE("PARAM");
node->paramkind,
node->paramid); WRITE_INT_FIELD(paramkind);
_outToken(str, node->paramname); WRITE_INT_FIELD(paramid);
appendStringInfo(str, " :paramtype %u ", node->paramtype); WRITE_STRING_FIELD(paramname);
WRITE_OID_FIELD(paramtype);
} }
/*
* FieldSelect
*/
static void static void
_outFieldSelect(StringInfo str, FieldSelect *node) _outFieldSelect(StringInfo str, FieldSelect *node)
{ {
appendStringInfo(str, " FIELDSELECT :arg "); WRITE_NODE_TYPE("FIELDSELECT");
_outNode(str, node->arg);
appendStringInfo(str, " :fieldnum %d :resulttype %u :resulttypmod %d ", WRITE_NODE_FIELD(arg);
node->fieldnum, node->resulttype, node->resulttypmod); WRITE_INT_FIELD(fieldnum);
WRITE_OID_FIELD(resulttype);
WRITE_INT_FIELD(resulttypmod);
} }
/*
* RelabelType
*/
static void static void
_outRelabelType(StringInfo str, RelabelType *node) _outRelabelType(StringInfo str, RelabelType *node)
{ {
appendStringInfo(str, " RELABELTYPE :arg "); WRITE_NODE_TYPE("RELABELTYPE");
_outNode(str, node->arg);
appendStringInfo(str, WRITE_NODE_FIELD(arg);
" :resulttype %u :resulttypmod %d :relabelformat %d ", WRITE_OID_FIELD(resulttype);
node->resulttype, WRITE_INT_FIELD(resulttypmod);
node->resulttypmod, WRITE_ENUM_FIELD(relabelformat, CoercionForm);
(int) node->relabelformat);
} }
/*
* RangeTblRef
*/
static void static void
_outRangeTblRef(StringInfo str, RangeTblRef *node) _outRangeTblRef(StringInfo str, RangeTblRef *node)
{ {
appendStringInfo(str, " RANGETBLREF %d ", WRITE_NODE_TYPE("RANGETBLREF");
node->rtindex);
WRITE_INT_FIELD(rtindex);
} }
/*
* FromExpr
*/
static void static void
_outFromExpr(StringInfo str, FromExpr *node) _outJoinExpr(StringInfo str, JoinExpr *node)
{ {
appendStringInfo(str, " FROMEXPR :fromlist "); WRITE_NODE_TYPE("JOINEXPR");
_outNode(str, node->fromlist);
appendStringInfo(str, " :quals "); WRITE_ENUM_FIELD(jointype, JoinType);
_outNode(str, node->quals); WRITE_BOOL_FIELD(isNatural);
WRITE_NODE_FIELD(larg);
WRITE_NODE_FIELD(rarg);
WRITE_NODE_FIELD(using);
WRITE_NODE_FIELD(quals);
WRITE_NODE_FIELD(alias);
WRITE_INT_FIELD(rtindex);
} }
/*
* JoinExpr
*/
static void static void
_outJoinExpr(StringInfo str, JoinExpr *node) _outFromExpr(StringInfo str, FromExpr *node)
{ {
appendStringInfo(str, " JOINEXPR :jointype %d :isNatural %s :larg ", WRITE_NODE_TYPE("FROMEXPR");
(int) node->jointype,
booltostr(node->isNatural)); WRITE_NODE_FIELD(fromlist);
_outNode(str, node->larg); WRITE_NODE_FIELD(quals);
appendStringInfo(str, " :rarg ");
_outNode(str, node->rarg);
appendStringInfo(str, " :using ");
_outNode(str, node->using);
appendStringInfo(str, " :quals ");
_outNode(str, node->quals);
appendStringInfo(str, " :alias ");
_outNode(str, node->alias);
appendStringInfo(str, " :rtindex %d ", node->rtindex);
} }
/*
* TargetEntry is a subclass of Node.
*/
static void static void
_outTargetEntry(StringInfo str, TargetEntry *node) _outTargetEntry(StringInfo str, TargetEntry *node)
{ {
appendStringInfo(str, " TARGETENTRY :resdom "); WRITE_NODE_TYPE("TARGETENTRY");
_outNode(str, node->resdom);
appendStringInfo(str, " :expr "); WRITE_NODE_FIELD(resdom);
_outNode(str, node->expr); /* fjoin not supported ... */
WRITE_NODE_FIELD(expr);
} }
static void static void
_outAlias(StringInfo str, Alias *node) _outAlias(StringInfo str, Alias *node)
{ {
appendStringInfo(str, " ALIAS :aliasname "); WRITE_NODE_TYPE("ALIAS");
_outToken(str, node->aliasname);
appendStringInfo(str, " :colnames "); WRITE_STRING_FIELD(aliasname);
_outNode(str, node->colnames); WRITE_NODE_FIELD(colnames);
} }
static void static void
_outRangeTblEntry(StringInfo str, RangeTblEntry *node) _outRangeTblEntry(StringInfo str, RangeTblEntry *node)
{ {
WRITE_NODE_TYPE("RTE");
/* put alias + eref first to make dump more legible */ /* put alias + eref first to make dump more legible */
appendStringInfo(str, " RTE :alias "); WRITE_NODE_FIELD(alias);
_outNode(str, node->alias); WRITE_NODE_FIELD(eref);
appendStringInfo(str, " :eref "); WRITE_ENUM_FIELD(rtekind, RTEKind);
_outNode(str, node->eref);
appendStringInfo(str, " :rtekind %d ",
(int) node->rtekind);
switch (node->rtekind) switch (node->rtekind)
{ {
case RTE_RELATION: case RTE_RELATION:
case RTE_SPECIAL: case RTE_SPECIAL:
appendStringInfo(str, ":relid %u", node->relid); WRITE_OID_FIELD(relid);
break; break;
case RTE_SUBQUERY: case RTE_SUBQUERY:
appendStringInfo(str, ":subquery "); WRITE_NODE_FIELD(subquery);
_outNode(str, node->subquery);
break; break;
case RTE_FUNCTION: case RTE_FUNCTION:
appendStringInfo(str, ":funcexpr "); WRITE_NODE_FIELD(funcexpr);
_outNode(str, node->funcexpr); WRITE_NODE_FIELD(coldeflist);
appendStringInfo(str, " :coldeflist ");
_outNode(str, node->coldeflist);
break; break;
case RTE_JOIN: case RTE_JOIN:
appendStringInfo(str, ":jointype %d :joinaliasvars ", WRITE_ENUM_FIELD(jointype, JoinType);
(int) node->jointype); WRITE_NODE_FIELD(joinaliasvars);
_outNode(str, node->joinaliasvars);
break; break;
default: default:
elog(ERROR, "bogus rte kind %d", (int) node->rtekind); elog(ERROR, "bogus rte kind %d", (int) node->rtekind);
break; break;
} }
appendStringInfo(str, " :inh %s :inFromCl %s :checkForRead %s"
" :checkForWrite %s :checkAsUser %u", WRITE_BOOL_FIELD(inh);
booltostr(node->inh), WRITE_BOOL_FIELD(inFromCl);
booltostr(node->inFromCl), WRITE_BOOL_FIELD(checkForRead);
booltostr(node->checkForRead), WRITE_BOOL_FIELD(checkForWrite);
booltostr(node->checkForWrite), WRITE_OID_FIELD(checkAsUser);
node->checkAsUser);
} }
/* /*
* Path is a subclass of Node. * print the basic stuff of all nodes that inherit from Path
*/ */
static void static void
_outPath(StringInfo str, Path *node) _outPathInfo(StringInfo str, Path *node)
{ {
appendStringInfo(str, WRITE_ENUM_FIELD(pathtype, NodeTag);
" PATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ", WRITE_FLOAT_FIELD(startup_cost, "%.2f");
node->pathtype, WRITE_FLOAT_FIELD(total_cost, "%.2f");
node->startup_cost, WRITE_NODE_FIELD(pathkeys);
node->total_cost);
_outNode(str, node->pathkeys);
} }
/* /*
* IndexPath is a subclass of Path. * print the basic stuff of all nodes that inherit from JoinPath
*/ */
static void static void
_outIndexPath(StringInfo str, IndexPath *node) _outJoinPathInfo(StringInfo str, JoinPath *node)
{ {
appendStringInfo(str, _outPathInfo(str, (Path *) node);
" INDEXPATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ",
node->path.pathtype,
node->path.startup_cost,
node->path.total_cost);
_outNode(str, node->path.pathkeys);
appendStringInfo(str, " :indexinfo "); WRITE_ENUM_FIELD(jointype, JoinType);
_outNode(str, node->indexinfo); WRITE_NODE_FIELD(outerjoinpath);
WRITE_NODE_FIELD(innerjoinpath);
WRITE_NODE_FIELD(joinrestrictinfo);
}
appendStringInfo(str, " :indexqual "); static void
_outNode(str, node->indexqual); _outPath(StringInfo str, Path *node)
{
WRITE_NODE_TYPE("PATH");
appendStringInfo(str, " :indexscandir %d :rows %.2f ", _outPathInfo(str, (Path *) node);
(int) node->indexscandir,
node->rows);
} }
/* /*
* TidPath is a subclass of Path. * IndexPath is a subclass of Path.
*/ */
static void
_outIndexPath(StringInfo str, IndexPath *node)
{
WRITE_NODE_TYPE("INDEXPATH");
_outPathInfo(str, (Path *) node);
WRITE_NODE_FIELD(indexinfo);
WRITE_NODE_FIELD(indexqual);
WRITE_ENUM_FIELD(indexscandir, ScanDirection);
WRITE_FLOAT_FIELD(rows, "%.2f");
}
static void static void
_outTidPath(StringInfo str, TidPath *node) _outTidPath(StringInfo str, TidPath *node)
{ {
appendStringInfo(str, WRITE_NODE_TYPE("TIDPATH");
" TIDPATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ",
node->path.pathtype,
node->path.startup_cost,
node->path.total_cost);
_outNode(str, node->path.pathkeys);
appendStringInfo(str, " :tideval "); _outPathInfo(str, (Path *) node);
_outNode(str, node->tideval);
appendStringInfo(str, " :unjoined_relids "); WRITE_NODE_FIELD(tideval);
_outIntList(str, node->unjoined_relids); WRITE_INTLIST_FIELD(unjoined_relids);
} }
/*
* AppendPath is a subclass of Path.
*/
static void static void
_outAppendPath(StringInfo str, AppendPath *node) _outAppendPath(StringInfo str, AppendPath *node)
{ {
appendStringInfo(str, WRITE_NODE_TYPE("APPENDPATH");
" APPENDPATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ",
node->path.pathtype, _outPathInfo(str, (Path *) node);
node->path.startup_cost,
node->path.total_cost);
_outNode(str, node->path.pathkeys);
appendStringInfo(str, " :subpaths "); WRITE_NODE_FIELD(subpaths);
_outNode(str, node->subpaths);
} }
/*
* ResultPath is a subclass of Path.
*/
static void static void
_outResultPath(StringInfo str, ResultPath *node) _outResultPath(StringInfo str, ResultPath *node)
{ {
appendStringInfo(str, WRITE_NODE_TYPE("RESULTPATH");
" RESULTPATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ",
node->path.pathtype,
node->path.startup_cost,
node->path.total_cost);
_outNode(str, node->path.pathkeys);
appendStringInfo(str, " :subpath "); _outPathInfo(str, (Path *) node);
_outNode(str, node->subpath);
appendStringInfo(str, " :constantqual "); WRITE_NODE_FIELD(subpath);
_outNode(str, node->constantqual); WRITE_NODE_FIELD(constantqual);
} }
/*
* NestPath is a subclass of Path
*/
static void static void
_outNestPath(StringInfo str, NestPath *node) _outNestPath(StringInfo str, NestPath *node)
{ {
appendStringInfo(str, WRITE_NODE_TYPE("NESTPATH");
" NESTPATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ",
node->path.pathtype, _outJoinPathInfo(str, (JoinPath *) node);
node->path.startup_cost,
node->path.total_cost);
_outNode(str, node->path.pathkeys);
appendStringInfo(str, " :jointype %d :outerjoinpath ",
(int) node->jointype);
_outNode(str, node->outerjoinpath);
appendStringInfo(str, " :innerjoinpath ");
_outNode(str, node->innerjoinpath);
appendStringInfo(str, " :joinrestrictinfo ");
_outNode(str, node->joinrestrictinfo);
} }
/*
* MergePath is a subclass of NestPath.
*/
static void static void
_outMergePath(StringInfo str, MergePath *node) _outMergePath(StringInfo str, MergePath *node)
{ {
appendStringInfo(str, WRITE_NODE_TYPE("MERGEPATH");
" MERGEPATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ",
node->jpath.path.pathtype,
node->jpath.path.startup_cost,
node->jpath.path.total_cost);
_outNode(str, node->jpath.path.pathkeys);
appendStringInfo(str, " :jointype %d :outerjoinpath ",
(int) node->jpath.jointype);
_outNode(str, node->jpath.outerjoinpath);
appendStringInfo(str, " :innerjoinpath ");
_outNode(str, node->jpath.innerjoinpath);
appendStringInfo(str, " :joinrestrictinfo ");
_outNode(str, node->jpath.joinrestrictinfo);
appendStringInfo(str, " :path_mergeclauses "); _outJoinPathInfo(str, (JoinPath *) node);
_outNode(str, node->path_mergeclauses);
appendStringInfo(str, " :outersortkeys "); WRITE_NODE_FIELD(path_mergeclauses);
_outNode(str, node->outersortkeys); WRITE_NODE_FIELD(outersortkeys);
WRITE_NODE_FIELD(innersortkeys);
appendStringInfo(str, " :innersortkeys ");
_outNode(str, node->innersortkeys);
} }
/*
* HashPath is a subclass of NestPath.
*/
static void static void
_outHashPath(StringInfo str, HashPath *node) _outHashPath(StringInfo str, HashPath *node)
{ {
appendStringInfo(str, WRITE_NODE_TYPE("HASHPATH");
" HASHPATH :pathtype %d :startup_cost %.2f :total_cost %.2f :pathkeys ",
node->jpath.path.pathtype, _outJoinPathInfo(str, (JoinPath *) node);
node->jpath.path.startup_cost,
node->jpath.path.total_cost);
_outNode(str, node->jpath.path.pathkeys);
appendStringInfo(str, " :jointype %d :outerjoinpath ",
(int) node->jpath.jointype);
_outNode(str, node->jpath.outerjoinpath);
appendStringInfo(str, " :innerjoinpath ");
_outNode(str, node->jpath.innerjoinpath);
appendStringInfo(str, " :joinrestrictinfo ");
_outNode(str, node->jpath.joinrestrictinfo);
appendStringInfo(str, " :path_hashclauses "); WRITE_NODE_FIELD(path_hashclauses);
_outNode(str, node->path_hashclauses);
} }
/*
* PathKeyItem is a subclass of Node.
*/
static void static void
_outPathKeyItem(StringInfo str, PathKeyItem *node) _outPathKeyItem(StringInfo str, PathKeyItem *node)
{ {
appendStringInfo(str, " PATHKEYITEM :sortop %u :key ", WRITE_NODE_TYPE("PATHKEYITEM");
node->sortop);
_outNode(str, node->key); WRITE_NODE_FIELD(key);
WRITE_OID_FIELD(sortop);
} }
/*
* RestrictInfo is a subclass of Node.
*/
static void static void
_outRestrictInfo(StringInfo str, RestrictInfo *node) _outRestrictInfo(StringInfo str, RestrictInfo *node)
{ {
appendStringInfo(str, " RESTRICTINFO :clause "); WRITE_NODE_TYPE("RESTRICTINFO");
_outNode(str, node->clause);
appendStringInfo(str, " :ispusheddown %s :subclauseindices ", WRITE_NODE_FIELD(clause);
booltostr(node->ispusheddown)); WRITE_BOOL_FIELD(ispusheddown);
_outNode(str, node->subclauseindices); WRITE_NODE_FIELD(subclauseindices);
WRITE_OID_FIELD(mergejoinoperator);
appendStringInfo(str, " :mergejoinoperator %u ", node->mergejoinoperator); WRITE_OID_FIELD(left_sortop);
appendStringInfo(str, " :left_sortop %u ", node->left_sortop); WRITE_OID_FIELD(right_sortop);
appendStringInfo(str, " :right_sortop %u ", node->right_sortop); WRITE_OID_FIELD(hashjoinoperator);
appendStringInfo(str, " :hashjoinoperator %u ", node->hashjoinoperator);
} }
/*
* JoinInfo is a subclass of Node.
*/
static void static void
_outJoinInfo(StringInfo str, JoinInfo *node) _outJoinInfo(StringInfo str, JoinInfo *node)
{ {
appendStringInfo(str, " JINFO :unjoined_relids "); WRITE_NODE_TYPE("JOININFO");
_outIntList(str, node->unjoined_relids);
appendStringInfo(str, " :jinfo_restrictinfo "); WRITE_INTLIST_FIELD(unjoined_relids);
_outNode(str, node->jinfo_restrictinfo); WRITE_NODE_FIELD(jinfo_restrictinfo);
} }
/* /*
...@@ -1262,22 +1089,22 @@ _outDatum(StringInfo str, Datum value, int typlen, bool typbyval) ...@@ -1262,22 +1089,22 @@ _outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
if (typbyval) if (typbyval)
{ {
s = (char *) (&value); s = (char *) (&value);
appendStringInfo(str, " %u [ ", (unsigned int) length); appendStringInfo(str, "%u [ ", (unsigned int) length);
for (i = 0; i < (Size) sizeof(Datum); i++) for (i = 0; i < (Size) sizeof(Datum); i++)
appendStringInfo(str, "%d ", (int) (s[i])); appendStringInfo(str, "%d ", (int) (s[i]));
appendStringInfo(str, "] "); appendStringInfo(str, "]");
} }
else else
{ {
s = (char *) DatumGetPointer(value); s = (char *) DatumGetPointer(value);
if (!PointerIsValid(s)) if (!PointerIsValid(s))
appendStringInfo(str, " 0 [ ] "); appendStringInfo(str, "0 [ ]");
else else
{ {
appendStringInfo(str, " %u [ ", (unsigned int) length); appendStringInfo(str, "%u [ ", (unsigned int) length);
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
appendStringInfo(str, "%d ", (int) (s[i])); appendStringInfo(str, "%d ", (int) (s[i]));
appendStringInfo(str, "] "); appendStringInfo(str, "]");
} }
} }
} }
...@@ -1285,29 +1112,30 @@ _outDatum(StringInfo str, Datum value, int typlen, bool typbyval) ...@@ -1285,29 +1112,30 @@ _outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
static void static void
_outAExpr(StringInfo str, A_Expr *node) _outAExpr(StringInfo str, A_Expr *node)
{ {
appendStringInfo(str, " AEXPR "); WRITE_NODE_TYPE("AEXPR");
switch (node->oper) switch (node->oper)
{ {
case AND: case AND:
appendStringInfo(str, "AND "); appendStringInfo(str, " AND");
break; break;
case OR: case OR:
appendStringInfo(str, "OR "); appendStringInfo(str, " OR");
break; break;
case NOT: case NOT:
appendStringInfo(str, "NOT "); appendStringInfo(str, " NOT");
break; break;
case OP: case OP:
_outNode(str, node->name);
appendStringInfo(str, " "); appendStringInfo(str, " ");
WRITE_NODE_FIELD(name);
break; break;
default: default:
appendStringInfo(str, "?? "); appendStringInfo(str, " ??");
break; break;
} }
_outNode(str, node->lexpr);
appendStringInfo(str, " "); WRITE_NODE_FIELD(lexpr);
_outNode(str, node->rexpr); WRITE_NODE_FIELD(rexpr);
} }
static void static void
...@@ -1316,7 +1144,7 @@ _outValue(StringInfo str, Value *value) ...@@ -1316,7 +1144,7 @@ _outValue(StringInfo str, Value *value)
switch (value->type) switch (value->type)
{ {
case T_Integer: case T_Integer:
appendStringInfo(str, " %ld ", value->val.ival); appendStringInfo(str, "%ld", value->val.ival);
break; break;
case T_Float: case T_Float:
...@@ -1324,19 +1152,19 @@ _outValue(StringInfo str, Value *value) ...@@ -1324,19 +1152,19 @@ _outValue(StringInfo str, Value *value)
* We assume the value is a valid numeric literal and so does * We assume the value is a valid numeric literal and so does
* not need quoting. * not need quoting.
*/ */
appendStringInfo(str, " %s ", value->val.str); appendStringInfo(str, "%s", value->val.str);
break; break;
case T_String: case T_String:
appendStringInfo(str, " \""); appendStringInfoChar(str, '"');
_outToken(str, value->val.str); _outToken(str, value->val.str);
appendStringInfo(str, "\" "); appendStringInfoChar(str, '"');
break; break;
case T_BitString: case T_BitString:
/* internal representation already has leading 'b' */ /* internal representation already has leading 'b' */
appendStringInfo(str, " %s ", value->val.str); appendStringInfo(str, "%s", value->val.str);
break; break;
default: default:
elog(WARNING, "_outValue: don't know how to print type %d ", elog(WARNING, "_outValue: don't know how to print type %d",
value->type); value->type);
break; break;
} }
...@@ -1345,86 +1173,82 @@ _outValue(StringInfo str, Value *value) ...@@ -1345,86 +1173,82 @@ _outValue(StringInfo str, Value *value)
static void static void
_outRangeVar(StringInfo str, RangeVar *node) _outRangeVar(StringInfo str, RangeVar *node)
{ {
appendStringInfo(str, " RANGEVAR :relation "); WRITE_NODE_TYPE("RANGEVAR");
/* /*
* we deliberately ignore catalogname here, since it is presently not * we deliberately ignore catalogname here, since it is presently not
* semantically meaningful * semantically meaningful
*/ */
_outToken(str, node->schemaname); WRITE_STRING_FIELD(schemaname);
appendStringInfo(str, " . "); WRITE_STRING_FIELD(relname);
_outToken(str, node->relname); WRITE_ENUM_FIELD(inhOpt, InhOption);
appendStringInfo(str, " :inhopt %d :istemp %s", WRITE_BOOL_FIELD(istemp);
(int) node->inhOpt, WRITE_NODE_FIELD(alias);
booltostr(node->istemp));
appendStringInfo(str, " :alias ");
_outNode(str, node->alias);
} }
static void static void
_outColumnRef(StringInfo str, ColumnRef *node) _outColumnRef(StringInfo str, ColumnRef *node)
{ {
appendStringInfo(str, " COLUMNREF :fields "); WRITE_NODE_TYPE("COLUMNREF");
_outNode(str, node->fields);
appendStringInfo(str, " :indirection "); WRITE_NODE_FIELD(fields);
_outNode(str, node->indirection); WRITE_NODE_FIELD(indirection);
} }
static void static void
_outParamRef(StringInfo str, ParamRef *node) _outParamRef(StringInfo str, ParamRef *node)
{ {
appendStringInfo(str, " PARAMREF :number %d :fields ", node->number); WRITE_NODE_TYPE("PARAMREF");
_outNode(str, node->fields);
appendStringInfo(str, " :indirection "); WRITE_INT_FIELD(number);
_outNode(str, node->indirection); WRITE_NODE_FIELD(fields);
WRITE_NODE_FIELD(indirection);
} }
static void static void
_outAConst(StringInfo str, A_Const *node) _outAConst(StringInfo str, A_Const *node)
{ {
appendStringInfo(str, "CONST "); WRITE_NODE_TYPE("CONST ");
_outValue(str, &(node->val)); _outValue(str, &(node->val));
appendStringInfo(str, " :typename "); WRITE_NODE_FIELD(typename);
_outNode(str, node->typename);
} }
static void static void
_outExprFieldSelect(StringInfo str, ExprFieldSelect *node) _outExprFieldSelect(StringInfo str, ExprFieldSelect *node)
{ {
appendStringInfo(str, " EXPRFIELDSELECT :arg "); WRITE_NODE_TYPE("EXPRFIELDSELECT");
_outNode(str, node->arg);
appendStringInfo(str, " :fields "); WRITE_NODE_FIELD(arg);
_outNode(str, node->fields); WRITE_NODE_FIELD(fields);
appendStringInfo(str, " :indirection "); WRITE_NODE_FIELD(indirection);
_outNode(str, node->indirection);
} }
static void static void
_outConstraint(StringInfo str, Constraint *node) _outConstraint(StringInfo str, Constraint *node)
{ {
appendStringInfo(str, " CONSTRAINT :name "); WRITE_NODE_TYPE("CONSTRAINT");
_outToken(str, node->name);
appendStringInfo(str, " :type "); WRITE_STRING_FIELD(name);
appendStringInfo(str, " :contype ");
switch (node->contype) switch (node->contype)
{ {
case CONSTR_PRIMARY: case CONSTR_PRIMARY:
appendStringInfo(str, "PRIMARY_KEY :keys "); appendStringInfo(str, "PRIMARY_KEY");
_outNode(str, node->keys); WRITE_NODE_FIELD(keys);
break; break;
case CONSTR_CHECK: case CONSTR_CHECK:
appendStringInfo(str, "CHECK :raw "); appendStringInfo(str, "CHECK");
_outNode(str, node->raw_expr); WRITE_NODE_FIELD(raw_expr);
appendStringInfo(str, " :cooked "); WRITE_STRING_FIELD(cooked_expr);
_outToken(str, node->cooked_expr);
break; break;
case CONSTR_DEFAULT: case CONSTR_DEFAULT:
appendStringInfo(str, "DEFAULT :raw "); appendStringInfo(str, "DEFAULT");
_outNode(str, node->raw_expr); WRITE_NODE_FIELD(raw_expr);
appendStringInfo(str, " :cooked "); WRITE_STRING_FIELD(cooked_expr);
_outToken(str, node->cooked_expr);
break; break;
case CONSTR_NOTNULL: case CONSTR_NOTNULL:
...@@ -1432,8 +1256,8 @@ _outConstraint(StringInfo str, Constraint *node) ...@@ -1432,8 +1256,8 @@ _outConstraint(StringInfo str, Constraint *node)
break; break;
case CONSTR_UNIQUE: case CONSTR_UNIQUE:
appendStringInfo(str, "UNIQUE :keys "); appendStringInfo(str, "UNIQUE");
_outNode(str, node->keys); WRITE_NODE_FIELD(keys);
break; break;
default: default:
...@@ -1445,108 +1269,86 @@ _outConstraint(StringInfo str, Constraint *node) ...@@ -1445,108 +1269,86 @@ _outConstraint(StringInfo str, Constraint *node)
static void static void
_outFkConstraint(StringInfo str, FkConstraint *node) _outFkConstraint(StringInfo str, FkConstraint *node)
{ {
appendStringInfo(str, " FKCONSTRAINT :constr_name "); WRITE_NODE_TYPE("FKCONSTRAINT");
_outToken(str, node->constr_name);
appendStringInfo(str, " :pktable "); WRITE_STRING_FIELD(constr_name);
_outNode(str, node->pktable); WRITE_NODE_FIELD(pktable);
appendStringInfo(str, " :fk_attrs "); WRITE_NODE_FIELD(fk_attrs);
_outNode(str, node->fk_attrs); WRITE_NODE_FIELD(pk_attrs);
appendStringInfo(str, " :pk_attrs "); WRITE_CHAR_FIELD(fk_matchtype);
_outNode(str, node->pk_attrs); WRITE_CHAR_FIELD(fk_upd_action);
appendStringInfo(str, " :fk_matchtype %c :fk_upd_action %c :fk_del_action %c :deferrable %s :initdeferred %s :skip_validation %s", WRITE_CHAR_FIELD(fk_del_action);
node->fk_matchtype, WRITE_BOOL_FIELD(deferrable);
node->fk_upd_action, WRITE_BOOL_FIELD(initdeferred);
node->fk_del_action, WRITE_BOOL_FIELD(skip_validation);
booltostr(node->deferrable),
booltostr(node->initdeferred),
booltostr(node->skip_validation));
} }
static void static void
_outCaseExpr(StringInfo str, CaseExpr *node) _outCaseExpr(StringInfo str, CaseExpr *node)
{ {
appendStringInfo(str, " CASE :casetype %u :arg ", WRITE_NODE_TYPE("CASE");
node->casetype);
_outNode(str, node->arg);
appendStringInfo(str, " :args ");
_outNode(str, node->args);
appendStringInfo(str, " :defresult "); WRITE_OID_FIELD(casetype);
_outNode(str, node->defresult); WRITE_NODE_FIELD(arg);
WRITE_NODE_FIELD(args);
WRITE_NODE_FIELD(defresult);
} }
static void static void
_outCaseWhen(StringInfo str, CaseWhen *node) _outCaseWhen(StringInfo str, CaseWhen *node)
{ {
appendStringInfo(str, " WHEN "); WRITE_NODE_TYPE("WHEN");
_outNode(str, node->expr);
appendStringInfo(str, " :then "); WRITE_NODE_FIELD(expr);
_outNode(str, node->result); WRITE_NODE_FIELD(result);
} }
/*
* NullTest
*/
static void static void
_outNullTest(StringInfo str, NullTest *node) _outNullTest(StringInfo str, NullTest *node)
{ {
appendStringInfo(str, " NULLTEST :arg "); WRITE_NODE_TYPE("NULLTEST");
_outNode(str, node->arg);
appendStringInfo(str, " :nulltesttype %d ", WRITE_NODE_FIELD(arg);
(int) node->nulltesttype); WRITE_ENUM_FIELD(nulltesttype, NullTestType);
} }
/*
* BooleanTest
*/
static void static void
_outBooleanTest(StringInfo str, BooleanTest *node) _outBooleanTest(StringInfo str, BooleanTest *node)
{ {
appendStringInfo(str, " BOOLEANTEST :arg "); WRITE_NODE_TYPE("BOOLEANTEST");
_outNode(str, node->arg);
appendStringInfo(str, " :booltesttype %d ", WRITE_NODE_FIELD(arg);
(int) node->booltesttype); WRITE_ENUM_FIELD(booltesttype, BoolTestType);
} }
/*
* ConstraintTest
*/
static void static void
_outConstraintTest(StringInfo str, ConstraintTest *node) _outConstraintTest(StringInfo str, ConstraintTest *node)
{ {
appendStringInfo(str, " CONSTRAINTTEST :arg "); WRITE_NODE_TYPE("CONSTRAINTTEST");
_outNode(str, node->arg);
appendStringInfo(str, " :testtype %d :name ", WRITE_NODE_FIELD(arg);
(int) node->testtype); WRITE_ENUM_FIELD(testtype, ConstraintTestType);
_outToken(str, node->name); WRITE_STRING_FIELD(name);
appendStringInfo(str, " :domain "); WRITE_STRING_FIELD(domname);
_outToken(str, node->domname); WRITE_NODE_FIELD(check_expr);
appendStringInfo(str, " :check_expr ");
_outNode(str, node->check_expr);
} }
/*
* ConstraintTestValue
*/
static void static void
_outConstraintTestValue(StringInfo str, ConstraintTestValue *node) _outDomainConstraintValue(StringInfo str, DomainConstraintValue *node)
{ {
appendStringInfo(str, " CONSTRAINTTESTVALUE :typeid %u :typemod %d ", WRITE_NODE_TYPE("DOMAINCONSTRAINTVALUE");
node->typeId,
node->typeMod);
} }
/*
* DomainConstraintValue
*/
static void static void
_outDomainConstraintValue(StringInfo str, DomainConstraintValue *node) _outConstraintTestValue(StringInfo str, ConstraintTestValue *node)
{ {
appendStringInfo(str, " DOMAINCONSTRAINTVALUE "); WRITE_NODE_TYPE("CONSTRAINTTESTVALUE");
WRITE_OID_FIELD(typeId);
WRITE_INT_FIELD(typeMod);
} }
/* /*
* _outNode - * _outNode -
* converts a Node into ascii string and append it to 'str' * converts a Node into ascii string and append it to 'str'
...@@ -1573,7 +1375,10 @@ _outNode(StringInfo str, void *obj) ...@@ -1573,7 +1375,10 @@ _outNode(StringInfo str, void *obj)
} }
appendStringInfoChar(str, ')'); appendStringInfoChar(str, ')');
} }
else if (IsA(obj, Integer) || IsA(obj, Float) || IsA(obj, String) || IsA(obj, BitString)) else if (IsA(obj, Integer) ||
IsA(obj, Float) ||
IsA(obj, String) ||
IsA(obj, BitString))
{ {
/* nodeRead does not want to see { } around these! */ /* nodeRead does not want to see { } around these! */
_outValue(str, obj); _outValue(str, obj);
...@@ -1688,9 +1493,6 @@ _outNode(StringInfo str, void *obj) ...@@ -1688,9 +1493,6 @@ _outNode(StringInfo str, void *obj)
case T_Resdom: case T_Resdom:
_outResdom(str, obj); _outResdom(str, obj);
break; break;
case T_Fjoin:
_outFjoin(str, obj);
break;
case T_Expr: case T_Expr:
_outExpr(str, obj); _outExpr(str, obj);
break; break;
...@@ -1825,7 +1627,7 @@ _outNode(StringInfo str, void *obj) ...@@ -1825,7 +1627,7 @@ _outNode(StringInfo str, void *obj)
break; break;
default: default:
elog(WARNING, "_outNode: don't know how to print type %d ", elog(WARNING, "_outNode: don't know how to print type %d",
nodeTag(obj)); nodeTag(obj));
break; break;
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.32 2002/06/20 20:29:29 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.33 2002/11/25 18:12:10 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -183,7 +183,7 @@ debackslash(char *token, int length) ...@@ -183,7 +183,7 @@ debackslash(char *token, int length)
#define RIGHT_PAREN (1000000 + 1) #define RIGHT_PAREN (1000000 + 1)
#define LEFT_PAREN (1000000 + 2) #define LEFT_PAREN (1000000 + 2)
#define PLAN_SYM (1000000 + 3) #define NODE_SYM (1000000 + 3)
#define AT_SYMBOL (1000000 + 4) #define AT_SYMBOL (1000000 + 4)
#define ATOM_TOKEN (1000000 + 5) #define ATOM_TOKEN (1000000 + 5)
...@@ -193,7 +193,7 @@ debackslash(char *token, int length) ...@@ -193,7 +193,7 @@ debackslash(char *token, int length)
* It returns one of the following valid NodeTags: * It returns one of the following valid NodeTags:
* T_Integer, T_Float, T_String, T_BitString * T_Integer, T_Float, T_String, T_BitString
* and some of its own: * and some of its own:
* RIGHT_PAREN, LEFT_PAREN, PLAN_SYM, AT_SYMBOL, ATOM_TOKEN * RIGHT_PAREN, LEFT_PAREN, NODE_SYM, AT_SYMBOL, ATOM_TOKEN
* *
* Assumption: the ascii representation is legal * Assumption: the ascii representation is legal
*/ */
...@@ -244,7 +244,7 @@ nodeTokenType(char *token, int length) ...@@ -244,7 +244,7 @@ nodeTokenType(char *token, int length)
else if (*token == ')') else if (*token == ')')
retval = RIGHT_PAREN; retval = RIGHT_PAREN;
else if (*token == '{') else if (*token == '{')
retval = PLAN_SYM; retval = NODE_SYM;
else if (*token == '@' && length == 1) else if (*token == '@' && length == 1)
retval = AT_SYMBOL; retval = AT_SYMBOL;
else if (*token == '\"' && length > 1 && token[length - 1] == '\"') else if (*token == '\"' && length > 1 && token[length - 1] == '\"')
...@@ -263,7 +263,7 @@ nodeTokenType(char *token, int length) ...@@ -263,7 +263,7 @@ nodeTokenType(char *token, int length)
* This routine applies some semantic knowledge on top of the purely * This routine applies some semantic knowledge on top of the purely
* lexical tokenizer pg_strtok(). It can read * lexical tokenizer pg_strtok(). It can read
* * Value token nodes (integers, floats, or strings); * * Value token nodes (integers, floats, or strings);
* * Plan nodes (via parsePlanString() from readfuncs.c); * * General nodes (via parseNodeString() from readfuncs.c);
* * Lists of the above. * * Lists of the above.
* *
* We assume pg_strtok is already initialized with a string to read (hence * We assume pg_strtok is already initialized with a string to read (hence
...@@ -289,11 +289,11 @@ nodeRead(bool read_car_only) ...@@ -289,11 +289,11 @@ nodeRead(bool read_car_only)
switch (type) switch (type)
{ {
case PLAN_SYM: case NODE_SYM:
this_value = parsePlanString(); this_value = parseNodeString();
token = pg_strtok(&tok_len); token = pg_strtok(&tok_len);
if (token == NULL || token[0] != '}') if (token == NULL || token[0] != '}')
elog(ERROR, "nodeRead: did not find '}' at end of plan node"); elog(ERROR, "nodeRead: did not find '}' at end of node");
if (!read_car_only) if (!read_car_only)
make_dotted_pair_cell = true; make_dotted_pair_cell = true;
else else
......
...@@ -8,18 +8,12 @@ ...@@ -8,18 +8,12 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.138 2002/11/24 21:52:13 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.139 2002/11/25 18:12:10 tgl Exp $
* *
* NOTES * NOTES
* Most of the read functions for plan nodes are tested. (In fact, they * Path and Plan nodes do not have any readfuncs support, because we
* pass the regression test as of 11/8/94.) The rest (for path selection) * never have occasion to read them in. (There was once code here that
* are probably never used. No effort has been made to get them to work. * claimed to read them, but it was broken as well as unused.)
* The simplest way to test these functions is by doing the following in
* ProcessQuery (before executing the plan):
* plan = stringToNode(nodeToString(plan));
* Then, run the regression test. Let's just say you'll notice if either
* of the above function are not properly done.
* - ay 11/94
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -27,9 +21,98 @@ ...@@ -27,9 +21,98 @@
#include <math.h> #include <math.h>
#include "nodes/plannodes.h" #include "nodes/parsenodes.h"
#include "nodes/readfuncs.h" #include "nodes/readfuncs.h"
#include "nodes/relation.h"
/*
* Macros to simplify reading 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 a Read
* routine.
*/
/* Declare appropriate local variables */
#define READ_LOCALS(nodeTypeName) \
nodeTypeName *local_node = makeNode(nodeTypeName); \
char *token; \
int length
/* A few guys need only local_node */
#define READ_LOCALS_NO_FIELDS(nodeTypeName) \
nodeTypeName *local_node = makeNode(nodeTypeName)
/* And a few guys need only the pg_strtok support fields */
#define READ_TEMP_LOCALS() \
char *token; \
int length
/* Read an integer field (anything written as ":fldname %d") */
#define READ_INT_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \
token = pg_strtok(&length); /* get field value */ \
local_node->fldname = atoi(token)
/* Read an unsigned integer field (anything written as ":fldname %u") */
#define READ_UINT_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \
token = pg_strtok(&length); /* get field value */ \
local_node->fldname = atoui(token)
/* Read an OID field (don't hard-wire assumption that OID is same as uint) */
#define READ_OID_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \
token = pg_strtok(&length); /* get field value */ \
local_node->fldname = atooid(token)
/* Read a char field (ie, one ascii character) */
#define READ_CHAR_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \
token = pg_strtok(&length); /* get field value */ \
local_node->fldname = token[0]
/* Read an enumerated-type field that was written as an integer code */
#define READ_ENUM_FIELD(fldname, enumtype) \
token = pg_strtok(&length); /* skip :fldname */ \
token = pg_strtok(&length); /* get field value */ \
local_node->fldname = (enumtype) atoi(token)
/* Read a float field */
#define READ_FLOAT_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \
token = pg_strtok(&length); /* get field value */ \
local_node->fldname = atof(token)
/* Read a boolean field */
#define READ_BOOL_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \
token = pg_strtok(&length); /* get field value */ \
local_node->fldname = strtobool(token)
/* Read a character-string field */
#define READ_STRING_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \
token = pg_strtok(&length); /* get field value */ \
local_node->fldname = nullable_string(token, length)
/* Read a Node field */
#define READ_NODE_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \
local_node->fldname = nodeRead(true)
/* Read an integer-list field */
#define READ_INTLIST_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \
local_node->fldname = toIntList(nodeRead(true))
/* Read an OID-list field */
#define READ_OIDLIST_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \
local_node->fldname = toOidList(nodeRead(true))
/* Routine exit */
#define READ_DONE() \
return local_node
/* /*
...@@ -51,11 +134,6 @@ ...@@ -51,11 +134,6 @@
static Datum readDatum(bool typbyval); static Datum readDatum(bool typbyval);
/* ----------------
* node creator declarations
* ----------------
*/
/* Convert Value list returned by nodeRead into list of integers */ /* Convert Value list returned by nodeRead into list of integers */
static List * static List *
toIntList(List *list) toIntList(List *list)
...@@ -106,2256 +184,744 @@ toOidList(List *list) ...@@ -106,2256 +184,744 @@ toOidList(List *list)
return list; return list;
} }
/* ---------------- /*
* _readQuery * _readQuery
* ----------------
*/ */
static Query * static Query *
_readQuery(void) _readQuery(void)
{ {
Query *local_node; READ_LOCALS(Query);
char *token;
int length; READ_ENUM_FIELD(commandType, CmdType);
READ_ENUM_FIELD(querySource, QuerySource);
local_node = makeNode(Query); READ_NODE_FIELD(utilityStmt);
READ_INT_FIELD(resultRelation);
token = pg_strtok(&length); /* skip :command */ READ_NODE_FIELD(into);
token = pg_strtok(&length); /* get commandType */ READ_BOOL_FIELD(isPortal);
local_node->commandType = atoi(token); READ_BOOL_FIELD(isBinary);
READ_BOOL_FIELD(hasAggs);
token = pg_strtok(&length); /* skip :source */ READ_BOOL_FIELD(hasSubLinks);
token = pg_strtok(&length); /* get querySource */ READ_NODE_FIELD(rtable);
local_node->querySource = atoi(token); READ_NODE_FIELD(jointree);
READ_INTLIST_FIELD(rowMarks);
token = pg_strtok(&length); /* skip :utility */ READ_NODE_FIELD(targetList);
local_node->utilityStmt = nodeRead(true); READ_NODE_FIELD(groupClause);
READ_NODE_FIELD(havingQual);
token = pg_strtok(&length); /* skip :resultRelation */ READ_NODE_FIELD(distinctClause);
token = pg_strtok(&length); /* get the resultRelation */ READ_NODE_FIELD(sortClause);
local_node->resultRelation = atoi(token); READ_NODE_FIELD(limitOffset);
READ_NODE_FIELD(limitCount);
token = pg_strtok(&length); /* skip :into */ READ_NODE_FIELD(setOperations);
local_node->into = nodeRead(true); READ_INTLIST_FIELD(resultRelations);
token = pg_strtok(&length); /* skip :isPortal */
token = pg_strtok(&length); /* get isPortal */
local_node->isPortal = strtobool(token);
token = pg_strtok(&length); /* skip :isBinary */
token = pg_strtok(&length); /* get isBinary */
local_node->isBinary = strtobool(token);
token = pg_strtok(&length); /* skip the :hasAggs */
token = pg_strtok(&length); /* get hasAggs */
local_node->hasAggs = strtobool(token);
token = pg_strtok(&length); /* skip the :hasSubLinks */
token = pg_strtok(&length); /* get hasSubLinks */
local_node->hasSubLinks = strtobool(token);
token = pg_strtok(&length); /* skip :rtable */
local_node->rtable = nodeRead(true);
token = pg_strtok(&length); /* skip :jointree */
local_node->jointree = nodeRead(true);
token = pg_strtok(&length); /* skip :rowMarks */
local_node->rowMarks = toIntList(nodeRead(true));
token = pg_strtok(&length); /* skip :targetlist */
local_node->targetList = nodeRead(true);
token = pg_strtok(&length); /* skip :groupClause */
local_node->groupClause = nodeRead(true);
token = pg_strtok(&length); /* skip :havingQual */
local_node->havingQual = nodeRead(true);
token = pg_strtok(&length); /* skip :distinctClause */
local_node->distinctClause = nodeRead(true);
token = pg_strtok(&length); /* skip :sortClause */
local_node->sortClause = nodeRead(true);
token = pg_strtok(&length); /* skip :limitOffset */
local_node->limitOffset = nodeRead(true);
token = pg_strtok(&length); /* skip :limitCount */
local_node->limitCount = nodeRead(true);
token = pg_strtok(&length); /* skip :setOperations */
local_node->setOperations = nodeRead(true);
token = pg_strtok(&length); /* skip :resultRelations */
local_node->resultRelations = toIntList(nodeRead(true));
/* planner-internal fields are left zero */ /* planner-internal fields are left zero */
return local_node; READ_DONE();
} }
/* ---------------- /*
* _readNotifyStmt * _readNotifyStmt
* ----------------
*/ */
static NotifyStmt * static NotifyStmt *
_readNotifyStmt(void) _readNotifyStmt(void)
{ {
NotifyStmt *local_node; READ_LOCALS(NotifyStmt);
char *token;
int length;
local_node = makeNode(NotifyStmt);
token = pg_strtok(&length); /* skip :relation */ READ_NODE_FIELD(relation);
local_node->relation = nodeRead(true);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _readSortClause * _readSortClause
* ----------------
*/ */
static SortClause * static SortClause *
_readSortClause(void) _readSortClause(void)
{ {
SortClause *local_node; READ_LOCALS(SortClause);
char *token;
int length;
local_node = makeNode(SortClause);
token = pg_strtok(&length); /* skip :tleSortGroupRef */
token = pg_strtok(&length); /* get tleSortGroupRef */
local_node->tleSortGroupRef = atoui(token);
token = pg_strtok(&length); /* skip :sortop */ READ_UINT_FIELD(tleSortGroupRef);
token = pg_strtok(&length); /* get sortop */ READ_OID_FIELD(sortop);
local_node->sortop = atooid(token);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _readGroupClause * _readGroupClause
* ----------------
*/ */
static GroupClause * static GroupClause *
_readGroupClause(void) _readGroupClause(void)
{ {
GroupClause *local_node; READ_LOCALS(GroupClause);
char *token;
int length;
local_node = makeNode(GroupClause);
token = pg_strtok(&length); /* skip :tleSortGroupRef */
token = pg_strtok(&length); /* get tleSortGroupRef */
local_node->tleSortGroupRef = atoui(token);
token = pg_strtok(&length); /* skip :sortop */ READ_UINT_FIELD(tleSortGroupRef);
token = pg_strtok(&length); /* get sortop */ READ_OID_FIELD(sortop);
local_node->sortop = atooid(token);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _readSetOperationStmt * _readSetOperationStmt
* ----------------
*/ */
static SetOperationStmt * static SetOperationStmt *
_readSetOperationStmt(void) _readSetOperationStmt(void)
{ {
SetOperationStmt *local_node; READ_LOCALS(SetOperationStmt);
char *token;
int length;
local_node = makeNode(SetOperationStmt); READ_ENUM_FIELD(op, SetOperation);
READ_BOOL_FIELD(all);
READ_NODE_FIELD(larg);
READ_NODE_FIELD(rarg);
READ_OIDLIST_FIELD(colTypes);
token = pg_strtok(&length); /* eat :op */ READ_DONE();
token = pg_strtok(&length); /* get op */ }
local_node->op = (SetOperation) atoi(token);
token = pg_strtok(&length); /* eat :all */
token = pg_strtok(&length); /* get all */
local_node->all = strtobool(token);
token = pg_strtok(&length); /* eat :larg */ /*
local_node->larg = nodeRead(true); /* get larg */ * Stuff from primnodes.h.
*/
token = pg_strtok(&length); /* eat :rarg */ /*
local_node->rarg = nodeRead(true); /* get rarg */ * _readResdom
*/
static Resdom *
_readResdom(void)
{
READ_LOCALS(Resdom);
token = pg_strtok(&length); /* eat :colTypes */ READ_INT_FIELD(resno);
local_node->colTypes = toOidList(nodeRead(true)); READ_OID_FIELD(restype);
READ_INT_FIELD(restypmod);
READ_STRING_FIELD(resname);
READ_UINT_FIELD(ressortgroupref);
READ_UINT_FIELD(reskey);
READ_OID_FIELD(reskeyop);
READ_BOOL_FIELD(resjunk);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _getPlan * _readExpr
* ----------------
*/ */
static void static Expr *
_getPlan(Plan *node) _readExpr(void)
{ {
char *token; READ_LOCALS(Expr);
int length;
token = pg_strtok(&length); /* first token is :startup_cost */
token = pg_strtok(&length); /* next is the actual cost */
node->startup_cost = (Cost) atof(token);
token = pg_strtok(&length); /* skip the :total_cost */ READ_OID_FIELD(typeOid);
token = pg_strtok(&length); /* next is the actual cost */
node->total_cost = (Cost) atof(token);
token = pg_strtok(&length); /* skip the :rows */ /* do-it-yourself enum representation */
token = pg_strtok(&length); /* get the plan_rows */ token = pg_strtok(&length); /* skip :opType */
node->plan_rows = atof(token); token = pg_strtok(&length); /* get field value */
if (strncmp(token, "op", 2) == 0)
token = pg_strtok(&length); /* skip the :width */ local_node->opType = OP_EXPR;
token = pg_strtok(&length); /* get the plan_width */ else if (strncmp(token, "distinct", 8) == 0)
node->plan_width = atoi(token); local_node->opType = DISTINCT_EXPR;
else if (strncmp(token, "func", 4) == 0)
token = pg_strtok(&length); /* eat :qptargetlist */ local_node->opType = FUNC_EXPR;
node->targetlist = nodeRead(true); else if (strncmp(token, "or", 2) == 0)
local_node->opType = OR_EXPR;
else if (strncmp(token, "and", 3) == 0)
local_node->opType = AND_EXPR;
else if (strncmp(token, "not", 3) == 0)
local_node->opType = NOT_EXPR;
else if (strncmp(token, "subp", 4) == 0)
local_node->opType = SUBPLAN_EXPR;
else
elog(ERROR, "_readExpr: unknown opType \"%.*s\"", length, token);
token = pg_strtok(&length); /* eat :qpqual */ READ_NODE_FIELD(oper);
node->qual = nodeRead(true); READ_NODE_FIELD(args);
token = pg_strtok(&length); /* eat :lefttree */ READ_DONE();
node->lefttree = (Plan *) nodeRead(true); }
token = pg_strtok(&length); /* eat :righttree */ /*
node->righttree = (Plan *) nodeRead(true); * _readVar
*/
static Var *
_readVar(void)
{
READ_LOCALS(Var);
node->state = (EState *) NULL; /* never read in */ READ_UINT_FIELD(varno);
READ_INT_FIELD(varattno);
READ_OID_FIELD(vartype);
READ_INT_FIELD(vartypmod);
READ_UINT_FIELD(varlevelsup);
READ_UINT_FIELD(varnoold);
READ_INT_FIELD(varoattno);
return; READ_DONE();
} }
/* /*
* Stuff from plannodes.h * _readArrayRef
*/
/* ----------------
* _readPlan
* ----------------
*/ */
static Plan * static ArrayRef *
_readPlan(void) _readArrayRef(void)
{ {
Plan *local_node; READ_LOCALS(ArrayRef);
local_node = makeNode(Plan);
_getPlan(local_node); READ_OID_FIELD(refrestype);
READ_INT_FIELD(refattrlength);
READ_INT_FIELD(refelemlength);
READ_BOOL_FIELD(refelembyval);
READ_CHAR_FIELD(refelemalign);
READ_NODE_FIELD(refupperindexpr);
READ_NODE_FIELD(reflowerindexpr);
READ_NODE_FIELD(refexpr);
READ_NODE_FIELD(refassgnexpr);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _readResult * _readConst
* ----------------
*/ */
static Result * static Const *
_readResult(void) _readConst(void)
{ {
Result *local_node; READ_LOCALS(Const);
char *token;
int length;
local_node = makeNode(Result); READ_OID_FIELD(consttype);
READ_INT_FIELD(constlen);
READ_BOOL_FIELD(constbyval);
READ_BOOL_FIELD(constisnull);
/* XXX what about constisset, constiscast? */
_getPlan((Plan *) local_node); token = pg_strtok(&length); /* skip :constvalue */
if (local_node->constisnull)
token = pg_strtok(&length); /* eat :resconstantqual */ token = pg_strtok(&length); /* skip "<>" */
local_node->resconstantqual = nodeRead(true); /* now read it */ else
local_node->constvalue = readDatum(local_node->constbyval);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _readAppend * _readFunc
*
* Append is a subclass of Plan.
* ----------------
*/ */
static Func *
static Append * _readFunc(void)
_readAppend(void)
{ {
Append *local_node; READ_LOCALS(Func);
char *token;
int length;
local_node = makeNode(Append); READ_OID_FIELD(funcid);
READ_OID_FIELD(funcresulttype);
READ_BOOL_FIELD(funcretset);
READ_ENUM_FIELD(funcformat, CoercionForm);
_getPlan((Plan *) local_node); local_node->func_fcache = NULL;
token = pg_strtok(&length); /* eat :appendplans */
local_node->appendplans = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :isTarget */
token = pg_strtok(&length); /* get isTarget */
local_node->isTarget = strtobool(token);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _getJoin * _readOper
* ----------------
*/ */
static void static Oper *
_getJoin(Join *node) _readOper(void)
{ {
char *token; READ_LOCALS(Oper);
int length;
_getPlan((Plan *) node); READ_OID_FIELD(opno);
READ_OID_FIELD(opid);
READ_OID_FIELD(opresulttype);
READ_BOOL_FIELD(opretset);
token = pg_strtok(&length); /* skip the :jointype */ local_node->op_fcache = NULL;
token = pg_strtok(&length); /* get the jointype */
node->jointype = (JoinType) atoi(token);
token = pg_strtok(&length); /* skip the :joinqual */ READ_DONE();
node->joinqual = nodeRead(true); /* get the joinqual */
} }
/*
/* ---------------- * _readParam
* _readJoin
*
* Join is a subclass of Plan
* ----------------
*/ */
static Join * static Param *
_readJoin(void) _readParam(void)
{ {
Join *local_node; READ_LOCALS(Param);
local_node = makeNode(Join);
_getJoin(local_node); READ_INT_FIELD(paramkind);
READ_INT_FIELD(paramid);
READ_STRING_FIELD(paramname);
READ_OID_FIELD(paramtype);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _readNestLoop * _readAggref
*
* NestLoop is a subclass of Join
* ----------------
*/ */
static Aggref *
static NestLoop * _readAggref(void)
_readNestLoop(void)
{ {
NestLoop *local_node; READ_LOCALS(Aggref);
local_node = makeNode(NestLoop);
_getJoin((Join *) local_node); READ_OID_FIELD(aggfnoid);
READ_OID_FIELD(aggtype);
READ_NODE_FIELD(target);
READ_BOOL_FIELD(aggstar);
READ_BOOL_FIELD(aggdistinct);
/* aggno is not saved since it is just executor state */
return local_node; READ_DONE();
} }
/* ---------------- static RangeVar *
* _readMergeJoin _readRangeVar(void)
*
* MergeJoin is a subclass of Join
* ----------------
*/
static MergeJoin *
_readMergeJoin(void)
{ {
MergeJoin *local_node; READ_LOCALS(RangeVar);
char *token;
int length;
local_node = makeNode(MergeJoin);
_getJoin((Join *) local_node); local_node->catalogname = NULL; /* not currently saved in output
* format */
token = pg_strtok(&length); /* eat :mergeclauses */ READ_STRING_FIELD(schemaname);
local_node->mergeclauses = nodeRead(true); /* now read it */ READ_STRING_FIELD(relname);
READ_ENUM_FIELD(inhOpt, InhOption);
READ_BOOL_FIELD(istemp);
READ_NODE_FIELD(alias);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _readHashJoin * _readSubLink
*
* HashJoin is a subclass of Join.
* ----------------
*/ */
static HashJoin * static SubLink *
_readHashJoin(void) _readSubLink(void)
{ {
HashJoin *local_node; READ_LOCALS(SubLink);
char *token;
int length;
local_node = makeNode(HashJoin); READ_ENUM_FIELD(subLinkType, SubLinkType);
READ_BOOL_FIELD(useor);
READ_NODE_FIELD(lefthand);
READ_NODE_FIELD(oper);
READ_NODE_FIELD(subselect);
_getJoin((Join *) local_node); READ_DONE();
}
token = pg_strtok(&length); /* eat :hashclauses */ /*
local_node->hashclauses = nodeRead(true); /* now read it */ * _readFieldSelect
*/
static FieldSelect *
_readFieldSelect(void)
{
READ_LOCALS(FieldSelect);
token = pg_strtok(&length); /* eat :hashjoinop */ READ_NODE_FIELD(arg);
token = pg_strtok(&length); /* get hashjoinop */ READ_INT_FIELD(fieldnum);
local_node->hashjoinop = atooid(token); READ_OID_FIELD(resulttype);
READ_INT_FIELD(resulttypmod);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _getScan * _readRelabelType
*
* Scan is a subclass of Plan.
*
* Scan gets its own get function since stuff inherits it.
* ----------------
*/ */
static void static RelabelType *
_getScan(Scan *node) _readRelabelType(void)
{ {
char *token; READ_LOCALS(RelabelType);
int length;
_getPlan((Plan *) node); READ_NODE_FIELD(arg);
READ_OID_FIELD(resulttype);
READ_INT_FIELD(resulttypmod);
READ_ENUM_FIELD(relabelformat, CoercionForm);
token = pg_strtok(&length); /* eat :scanrelid */ READ_DONE();
token = pg_strtok(&length); /* get scanrelid */
node->scanrelid = atoui(token);
} }
/* ---------------- /*
* _readScan * _readRangeTblRef
*
* Scan is a subclass of Plan.
* ----------------
*/ */
static Scan * static RangeTblRef *
_readScan(void) _readRangeTblRef(void)
{ {
Scan *local_node; READ_LOCALS(RangeTblRef);
local_node = makeNode(Scan);
_getScan(local_node); READ_INT_FIELD(rtindex);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _readSeqScan * _readJoinExpr
*
* SeqScan is a subclass of Scan
* ----------------
*/ */
static SeqScan * static JoinExpr *
_readSeqScan(void) _readJoinExpr(void)
{ {
SeqScan *local_node; READ_LOCALS(JoinExpr);
local_node = makeNode(SeqScan); READ_ENUM_FIELD(jointype, JoinType);
READ_BOOL_FIELD(isNatural);
READ_NODE_FIELD(larg);
READ_NODE_FIELD(rarg);
READ_NODE_FIELD(using);
READ_NODE_FIELD(quals);
READ_NODE_FIELD(alias);
READ_INT_FIELD(rtindex);
_getScan((Scan *) local_node); READ_DONE();
return local_node;
} }
/* ---------------- /*
* _readIndexScan * _readFromExpr
*
* IndexScan is a subclass of Scan
* ----------------
*/ */
static IndexScan * static FromExpr *
_readIndexScan(void) _readFromExpr(void)
{ {
IndexScan *local_node; READ_LOCALS(FromExpr);
char *token;
int length;
local_node = makeNode(IndexScan); READ_NODE_FIELD(fromlist);
READ_NODE_FIELD(quals);
_getScan((Scan *) local_node); READ_DONE();
}
token = pg_strtok(&length); /* eat :indxid */
local_node->indxid = toOidList(nodeRead(true)); /* now read it */
token = pg_strtok(&length); /* eat :indxqual */ /*
local_node->indxqual = nodeRead(true); /* now read it */ * Stuff from parsenodes.h.
*/
token = pg_strtok(&length); /* eat :indxqualorig */ /*
local_node->indxqualorig = nodeRead(true); /* now read it */ * _readCaseExpr
*/
static CaseExpr *
_readCaseExpr(void)
{
READ_LOCALS(CaseExpr);
token = pg_strtok(&length); /* eat :indxorderdir */ READ_OID_FIELD(casetype);
token = pg_strtok(&length); /* get indxorderdir */ READ_NODE_FIELD(arg);
local_node->indxorderdir = atoi(token); READ_NODE_FIELD(args);
READ_NODE_FIELD(defresult);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _readTidScan * _readCaseWhen
*
* TidScan is a subclass of Scan
* ----------------
*/ */
static TidScan * static CaseWhen *
_readTidScan(void) _readCaseWhen(void)
{ {
TidScan *local_node; READ_LOCALS(CaseWhen);
char *token;
int length;
local_node = makeNode(TidScan);
_getScan((Scan *) local_node);
token = pg_strtok(&length); /* eat :needrescan */
token = pg_strtok(&length); /* get needrescan */
local_node->needRescan = atoi(token);
token = pg_strtok(&length); /* eat :tideval */ READ_NODE_FIELD(expr);
local_node->tideval = nodeRead(true); /* now read it */ READ_NODE_FIELD(result);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _readSubqueryScan * _readNullTest
*
* SubqueryScan is a subclass of Scan
* ----------------
*/ */
static SubqueryScan * static NullTest *
_readSubqueryScan(void) _readNullTest(void)
{ {
SubqueryScan *local_node; READ_LOCALS(NullTest);
char *token;
int length;
local_node = makeNode(SubqueryScan);
_getScan((Scan *) local_node); READ_NODE_FIELD(arg);
READ_ENUM_FIELD(nulltesttype, NullTestType);
token = pg_strtok(&length); /* eat :subplan */ READ_DONE();
local_node->subplan = nodeRead(true); /* now read it */
return local_node;
} }
/* ---------------- /*
* _readFunctionScan * _readBooleanTest
*
* FunctionScan is a subclass of Scan
* ----------------
*/ */
static FunctionScan * static BooleanTest *
_readFunctionScan(void) _readBooleanTest(void)
{ {
FunctionScan *local_node; READ_LOCALS(BooleanTest);
local_node = makeNode(FunctionScan);
_getScan((Scan *) local_node); READ_NODE_FIELD(arg);
READ_ENUM_FIELD(booltesttype, BoolTestType);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _readSort * _readConstraintTest
*
* Sort is a subclass of Plan
* ----------------
*/ */
static Sort * static ConstraintTest *
_readSort(void) _readConstraintTest(void)
{ {
Sort *local_node; READ_LOCALS(ConstraintTest);
char *token;
int length;
local_node = makeNode(Sort);
_getPlan((Plan *) local_node); READ_NODE_FIELD(arg);
READ_ENUM_FIELD(testtype, ConstraintTestType);
READ_STRING_FIELD(name);
READ_STRING_FIELD(domname);
READ_NODE_FIELD(check_expr);
token = pg_strtok(&length); /* eat :keycount */ READ_DONE();
token = pg_strtok(&length); /* get keycount */
local_node->keycount = atoi(token);
return local_node;
} }
/* ---------------- /*
* _readHash * _readDomainConstraintValue
*
* Hash is a subclass of Plan
* ----------------
*/ */
static Hash * static DomainConstraintValue *
_readHash(void) _readDomainConstraintValue(void)
{ {
Hash *local_node; READ_LOCALS_NO_FIELDS(DomainConstraintValue);
char *token;
int length;
local_node = makeNode(Hash); READ_DONE();
}
_getPlan((Plan *) local_node); /*
* _readConstraintTestValue
*/
static ConstraintTestValue *
_readConstraintTestValue(void)
{
READ_LOCALS(ConstraintTestValue);
token = pg_strtok(&length); /* eat :hashkey */ READ_OID_FIELD(typeId);
local_node->hashkey = nodeRead(true); READ_INT_FIELD(typeMod);
return local_node; READ_DONE();
} }
/* /*
* Stuff from primnodes.h. * _readTargetEntry
*/
/* ----------------
* _readResdom
*
* Resdom is a subclass of Node
* ----------------
*/ */
static Resdom * static TargetEntry *
_readResdom(void) _readTargetEntry(void)
{ {
Resdom *local_node; READ_LOCALS(TargetEntry);
char *token;
int length; READ_NODE_FIELD(resdom);
/* fjoin not supported ... */
READ_NODE_FIELD(expr);
local_node = makeNode(Resdom); READ_DONE();
}
token = pg_strtok(&length); /* eat :resno */ static ColumnRef *
token = pg_strtok(&length); /* get resno */ _readColumnRef(void)
local_node->resno = atoi(token); {
READ_LOCALS(ColumnRef);
token = pg_strtok(&length); /* eat :restype */ READ_NODE_FIELD(fields);
token = pg_strtok(&length); /* get restype */ READ_NODE_FIELD(indirection);
local_node->restype = atooid(token);
token = pg_strtok(&length); /* eat :restypmod */ READ_DONE();
token = pg_strtok(&length); /* get restypmod */ }
local_node->restypmod = atoi(token);
token = pg_strtok(&length); /* eat :resname */ static ColumnDef *
token = pg_strtok(&length); /* get the name */ _readColumnDef(void)
local_node->resname = nullable_string(token, length); {
READ_LOCALS(ColumnDef);
token = pg_strtok(&length); /* eat :reskey */ READ_STRING_FIELD(colname);
token = pg_strtok(&length); /* get reskey */ READ_NODE_FIELD(typename);
local_node->reskey = atoui(token); READ_INT_FIELD(inhcount);
READ_BOOL_FIELD(is_local);
READ_BOOL_FIELD(is_not_null);
READ_NODE_FIELD(raw_default);
READ_STRING_FIELD(cooked_default);
READ_NODE_FIELD(constraints);
READ_NODE_FIELD(support);
token = pg_strtok(&length); /* eat :reskeyop */ READ_DONE();
token = pg_strtok(&length); /* get reskeyop */ }
local_node->reskeyop = atooid(token);
token = pg_strtok(&length); /* eat :ressortgroupref */ static TypeName *
token = pg_strtok(&length); /* get ressortgroupref */ _readTypeName(void)
local_node->ressortgroupref = atoui(token); {
READ_LOCALS(TypeName);
token = pg_strtok(&length); /* eat :resjunk */ READ_NODE_FIELD(names);
token = pg_strtok(&length); /* get resjunk */ READ_OID_FIELD(typeid);
local_node->resjunk = strtobool(token); READ_BOOL_FIELD(timezone);
READ_BOOL_FIELD(setof);
READ_BOOL_FIELD(pct_type);
READ_INT_FIELD(typmod);
READ_NODE_FIELD(arrayBounds);
return local_node; READ_DONE();
} }
/* ---------------- static ExprFieldSelect *
* _readExpr _readExprFieldSelect(void)
*
* Expr is a subclass of Node
* ----------------
*/
static Expr *
_readExpr(void)
{ {
Expr *local_node; READ_LOCALS(ExprFieldSelect);
char *token;
int length;
local_node = makeNode(Expr);
token = pg_strtok(&length); /* eat :typeOid */ READ_NODE_FIELD(arg);
token = pg_strtok(&length); /* get typeOid */ READ_NODE_FIELD(fields);
local_node->typeOid = atooid(token); READ_NODE_FIELD(indirection);
token = pg_strtok(&length); /* eat :opType */ READ_DONE();
token = pg_strtok(&length); /* get opType */ }
if (strncmp(token, "op", 2) == 0)
local_node->opType = OP_EXPR;
else if (strncmp(token, "distinct", 8) == 0)
local_node->opType = DISTINCT_EXPR;
else if (strncmp(token, "func", 4) == 0)
local_node->opType = FUNC_EXPR;
else if (strncmp(token, "or", 2) == 0)
local_node->opType = OR_EXPR;
else if (strncmp(token, "and", 3) == 0)
local_node->opType = AND_EXPR;
else if (strncmp(token, "not", 3) == 0)
local_node->opType = NOT_EXPR;
else if (strncmp(token, "subp", 4) == 0)
local_node->opType = SUBPLAN_EXPR;
else
elog(ERROR, "_readExpr: unknown opType \"%.*s\"", length, token);
token = pg_strtok(&length); /* eat :oper */ static Alias *
local_node->oper = nodeRead(true); _readAlias(void)
{
READ_LOCALS(Alias);
token = pg_strtok(&length); /* eat :args */ READ_STRING_FIELD(aliasname);
local_node->args = nodeRead(true); /* now read it */ READ_NODE_FIELD(colnames);
return local_node; READ_DONE();
} }
/* ---------------- /*
* _readCaseExpr * _readRangeTblEntry
*
* CaseExpr is a subclass of Node
* ----------------
*/
static CaseExpr *
_readCaseExpr(void)
{
CaseExpr *local_node;
char *token;
int length;
local_node = makeNode(CaseExpr);
token = pg_strtok(&length); /* eat :casetype */
token = pg_strtok(&length); /* get casetype */
local_node->casetype = atooid(token);
token = pg_strtok(&length); /* eat :arg */
local_node->arg = nodeRead(true);
token = pg_strtok(&length); /* eat :args */
local_node->args = nodeRead(true);
token = pg_strtok(&length); /* eat :defresult */
local_node->defresult = nodeRead(true);
return local_node;
}
/* ----------------
* _readCaseWhen
*
* CaseWhen is a subclass of Node
* ----------------
*/
static CaseWhen *
_readCaseWhen(void)
{
CaseWhen *local_node;
char *token;
int length;
local_node = makeNode(CaseWhen);
local_node->expr = nodeRead(true);
token = pg_strtok(&length); /* eat :then */
local_node->result = nodeRead(true);
return local_node;
}
/* ----------------
* _readNullTest
*
* NullTest is a subclass of Node
* ----------------
*/
static NullTest *
_readNullTest(void)
{
NullTest *local_node;
char *token;
int length;
local_node = makeNode(NullTest);
token = pg_strtok(&length); /* eat :arg */
local_node->arg = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :nulltesttype */
token = pg_strtok(&length); /* get nulltesttype */
local_node->nulltesttype = (NullTestType) atoi(token);
return local_node;
}
/* ----------------
* _readBooleanTest
*
* BooleanTest is a subclass of Node
* ----------------
*/
static BooleanTest *
_readBooleanTest(void)
{
BooleanTest *local_node;
char *token;
int length;
local_node = makeNode(BooleanTest);
token = pg_strtok(&length); /* eat :arg */
local_node->arg = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :booltesttype */
token = pg_strtok(&length); /* get booltesttype */
local_node->booltesttype = (BoolTestType) atoi(token);
return local_node;
}
/* ----------------
* _readConstraintTest
*
* ConstraintTest is a subclass of Node
* ----------------
*/
static ConstraintTest *
_readConstraintTest(void)
{
ConstraintTest *local_node;
char *token;
int length;
local_node = makeNode(ConstraintTest);
token = pg_strtok(&length); /* eat :arg */
local_node->arg = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :testtype */
token = pg_strtok(&length); /* get testtype */
local_node->testtype = (ConstraintTestType) atoi(token);
token = pg_strtok(&length); /* get :name */
token = pg_strtok(&length); /* now read it */
local_node->name = nullable_string(token, length);
token = pg_strtok(&length); /* get :domname */
token = pg_strtok(&length); /* get domname */
local_node->domname = nullable_string(token, length);
token = pg_strtok(&length); /* eat :check_expr */
local_node->check_expr = nodeRead(true); /* now read it */
return local_node;
}
/* ----------------
* _readConstraintTestValue
*
* ConstraintTestValue is a subclass of Node
* ----------------
*/
static ConstraintTestValue *
_readConstraintTestValue(void)
{
ConstraintTestValue *local_node;
char *token;
int length;
local_node = makeNode(ConstraintTestValue);
token = pg_strtok(&length); /* eat :typeid */
token = pg_strtok(&length); /* get typeid */
local_node->typeId = atooid(token);
token = pg_strtok(&length); /* eat :typemod */
token = pg_strtok(&length); /* get typemod */
local_node->typeMod = atoi(token);
return local_node;
}
/* ----------------
* _readDomainConstraintValue
*
* DomainConstraintValue is a subclass of Node
* ----------------
*/
static DomainConstraintValue *
_readDomainConstraintValue(void)
{
DomainConstraintValue *local_node;
local_node = makeNode(DomainConstraintValue);
return local_node;
}
/* ----------------
* _readVar
*
* Var is a subclass of Expr
* ----------------
*/
static Var *
_readVar(void)
{
Var *local_node;
char *token;
int length;
local_node = makeNode(Var);
token = pg_strtok(&length); /* eat :varno */
token = pg_strtok(&length); /* get varno */
local_node->varno = atoui(token);
token = pg_strtok(&length); /* eat :varattno */
token = pg_strtok(&length); /* get varattno */
local_node->varattno = atoi(token);
token = pg_strtok(&length); /* eat :vartype */
token = pg_strtok(&length); /* get vartype */
local_node->vartype = atooid(token);
token = pg_strtok(&length); /* eat :vartypmod */
token = pg_strtok(&length); /* get vartypmod */
local_node->vartypmod = atoi(token);
token = pg_strtok(&length); /* eat :varlevelsup */
token = pg_strtok(&length); /* get varlevelsup */
local_node->varlevelsup = atoui(token);
token = pg_strtok(&length); /* eat :varnoold */
token = pg_strtok(&length); /* get varnoold */
local_node->varnoold = atoui(token);
token = pg_strtok(&length); /* eat :varoattno */
token = pg_strtok(&length); /* eat :varoattno */
local_node->varoattno = atoi(token);
return local_node;
}
/* ----------------
* _readArrayRef
*
* ArrayRef is a subclass of Expr
* ----------------
*/
static ArrayRef *
_readArrayRef(void)
{
ArrayRef *local_node;
char *token;
int length;
local_node = makeNode(ArrayRef);
token = pg_strtok(&length); /* eat :refrestype */
token = pg_strtok(&length); /* get refrestype */
local_node->refrestype = atooid(token);
token = pg_strtok(&length); /* eat :refattrlength */
token = pg_strtok(&length); /* get refattrlength */
local_node->refattrlength = atoi(token);
token = pg_strtok(&length); /* eat :refelemlength */
token = pg_strtok(&length); /* get refelemlength */
local_node->refelemlength = atoi(token);
token = pg_strtok(&length); /* eat :refelembyval */
token = pg_strtok(&length); /* get refelembyval */
local_node->refelembyval = strtobool(token);
token = pg_strtok(&length); /* eat :refelemalign */
token = pg_strtok(&length); /* get refelemalign */
local_node->refelemalign = token[0];
token = pg_strtok(&length); /* eat :refupperindexpr */
local_node->refupperindexpr = nodeRead(true);
token = pg_strtok(&length); /* eat :reflowerindexpr */
local_node->reflowerindexpr = nodeRead(true);
token = pg_strtok(&length); /* eat :refexpr */
local_node->refexpr = nodeRead(true);
token = pg_strtok(&length); /* eat :refassgnexpr */
local_node->refassgnexpr = nodeRead(true);
return local_node;
}
/* ----------------
* _readConst
*
* Const is a subclass of Expr
* ----------------
*/
static Const *
_readConst(void)
{
Const *local_node;
char *token;
int length;
local_node = makeNode(Const);
token = pg_strtok(&length); /* get :consttype */
token = pg_strtok(&length); /* now read it */
local_node->consttype = atooid(token);
token = pg_strtok(&length); /* get :constlen */
token = pg_strtok(&length); /* now read it */
local_node->constlen = atoi(token);
token = pg_strtok(&length); /* get :constbyval */
token = pg_strtok(&length); /* now read it */
local_node->constbyval = strtobool(token);
token = pg_strtok(&length); /* get :constisnull */
token = pg_strtok(&length); /* now read it */
local_node->constisnull = strtobool(token);
token = pg_strtok(&length); /* get :constvalue */
if (local_node->constisnull)
{
token = pg_strtok(&length); /* skip "NIL" */
}
else
local_node->constvalue = readDatum(local_node->constbyval);
return local_node;
}
/* ----------------
* _readFunc
*
* Func is a subclass of Expr
* ----------------
*/
static Func *
_readFunc(void)
{
Func *local_node;
char *token;
int length;
local_node = makeNode(Func);
token = pg_strtok(&length); /* get :funcid */
token = pg_strtok(&length); /* now read it */
local_node->funcid = atooid(token);
token = pg_strtok(&length); /* get :funcresulttype */
token = pg_strtok(&length); /* now read it */
local_node->funcresulttype = atooid(token);
token = pg_strtok(&length); /* get :funcretset */
token = pg_strtok(&length); /* now read it */
local_node->funcretset = strtobool(token);
token = pg_strtok(&length); /* get :funcformat */
token = pg_strtok(&length); /* now read it */
local_node->funcformat = (CoercionForm) atoi(token);
local_node->func_fcache = NULL;
return local_node;
}
/* ----------------
* _readOper
*
* Oper is a subclass of Expr
* ----------------
*/
static Oper *
_readOper(void)
{
Oper *local_node;
char *token;
int length;
local_node = makeNode(Oper);
token = pg_strtok(&length); /* get :opno */
token = pg_strtok(&length); /* now read it */
local_node->opno = atooid(token);
token = pg_strtok(&length); /* get :opid */
token = pg_strtok(&length); /* now read it */
local_node->opid = atooid(token);
token = pg_strtok(&length); /* get :opresulttype */
token = pg_strtok(&length); /* now read it */
local_node->opresulttype = atooid(token);
token = pg_strtok(&length); /* get :opretset */
token = pg_strtok(&length); /* now read it */
local_node->opretset = strtobool(token);
local_node->op_fcache = NULL;
return local_node;
}
/* ----------------
* _readParam
*
* Param is a subclass of Expr
* ----------------
*/
static Param *
_readParam(void)
{
Param *local_node;
char *token;
int length;
local_node = makeNode(Param);
token = pg_strtok(&length); /* get :paramkind */
token = pg_strtok(&length); /* now read it */
local_node->paramkind = atoi(token);
token = pg_strtok(&length); /* get :paramid */
token = pg_strtok(&length); /* now read it */
local_node->paramid = atoi(token);
token = pg_strtok(&length); /* get :paramname */
token = pg_strtok(&length); /* now read it */
local_node->paramname = nullable_string(token, length);
token = pg_strtok(&length); /* get :paramtype */
token = pg_strtok(&length); /* now read it */
local_node->paramtype = atooid(token);
return local_node;
}
/* ----------------
* _readAggref
*
* Aggref is a subclass of Node
* ----------------
*/
static Aggref *
_readAggref(void)
{
Aggref *local_node;
char *token;
int length;
local_node = makeNode(Aggref);
token = pg_strtok(&length); /* eat :aggfnoid */
token = pg_strtok(&length); /* get aggfnoid */
local_node->aggfnoid = atooid(token);
token = pg_strtok(&length); /* eat :aggtype */
token = pg_strtok(&length); /* get aggtype */
local_node->aggtype = atooid(token);
token = pg_strtok(&length); /* eat :target */
local_node->target = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :aggstar */
token = pg_strtok(&length); /* get aggstar */
local_node->aggstar = strtobool(token);
token = pg_strtok(&length); /* eat :aggdistinct */
token = pg_strtok(&length); /* get aggdistinct */
local_node->aggdistinct = strtobool(token);
return local_node;
}
/* ----------------
* _readSubLink
*
* SubLink is a subclass of Node
* ----------------
*/
static SubLink *
_readSubLink(void)
{
SubLink *local_node;
char *token;
int length;
local_node = makeNode(SubLink);
token = pg_strtok(&length); /* eat :subLinkType */
token = pg_strtok(&length); /* get subLinkType */
local_node->subLinkType = atoi(token);
token = pg_strtok(&length); /* eat :useor */
token = pg_strtok(&length); /* get useor */
local_node->useor = strtobool(token);
token = pg_strtok(&length); /* eat :lefthand */
local_node->lefthand = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :oper */
local_node->oper = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :subselect */
local_node->subselect = nodeRead(true); /* now read it */
return local_node;
}
/* ----------------
* _readFieldSelect
*
* FieldSelect is a subclass of Node
* ----------------
*/
static FieldSelect *
_readFieldSelect(void)
{
FieldSelect *local_node;
char *token;
int length;
local_node = makeNode(FieldSelect);
token = pg_strtok(&length); /* eat :arg */
local_node->arg = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :fieldnum */
token = pg_strtok(&length); /* get fieldnum */
local_node->fieldnum = (AttrNumber) atoi(token);
token = pg_strtok(&length); /* eat :resulttype */
token = pg_strtok(&length); /* get resulttype */
local_node->resulttype = atooid(token);
token = pg_strtok(&length); /* eat :resulttypmod */
token = pg_strtok(&length); /* get resulttypmod */
local_node->resulttypmod = atoi(token);
return local_node;
}
/* ----------------
* _readRelabelType
*
* RelabelType is a subclass of Node
* ----------------
*/
static RelabelType *
_readRelabelType(void)
{
RelabelType *local_node;
char *token;
int length;
local_node = makeNode(RelabelType);
token = pg_strtok(&length); /* eat :arg */
local_node->arg = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :resulttype */
token = pg_strtok(&length); /* get resulttype */
local_node->resulttype = atooid(token);
token = pg_strtok(&length); /* eat :resulttypmod */
token = pg_strtok(&length); /* get resulttypmod */
local_node->resulttypmod = atoi(token);
token = pg_strtok(&length); /* eat :relabelformat */
token = pg_strtok(&length); /* get relabelformat */
local_node->relabelformat = (CoercionForm) atoi(token);
return local_node;
}
/* ----------------
* _readRangeTblRef
*
* RangeTblRef is a subclass of Node
* ----------------
*/
static RangeTblRef *
_readRangeTblRef(void)
{
RangeTblRef *local_node;
char *token;
int length;
local_node = makeNode(RangeTblRef);
token = pg_strtok(&length); /* get rtindex */
local_node->rtindex = atoi(token);
return local_node;
}
/* ----------------
* _readFromExpr
*
* FromExpr is a subclass of Node
* ----------------
*/
static FromExpr *
_readFromExpr(void)
{
FromExpr *local_node;
char *token;
int length;
local_node = makeNode(FromExpr);
token = pg_strtok(&length); /* eat :fromlist */
local_node->fromlist = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :quals */
local_node->quals = nodeRead(true); /* now read it */
return local_node;
}
/* ----------------
* _readJoinExpr
*
* JoinExpr is a subclass of Node
* ----------------
*/
static JoinExpr *
_readJoinExpr(void)
{
JoinExpr *local_node;
char *token;
int length;
local_node = makeNode(JoinExpr);
token = pg_strtok(&length); /* eat :jointype */
token = pg_strtok(&length); /* get jointype */
local_node->jointype = (JoinType) atoi(token);
token = pg_strtok(&length); /* eat :isNatural */
token = pg_strtok(&length); /* get isNatural */
local_node->isNatural = strtobool(token);
token = pg_strtok(&length); /* eat :larg */
local_node->larg = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :rarg */
local_node->rarg = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :using */
local_node->using = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :quals */
local_node->quals = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :alias */
local_node->alias = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :rtindex */
token = pg_strtok(&length); /* get rtindex */
local_node->rtindex = atoi(token);
return local_node;
}
/* ----------------
* _readTargetEntry
* ----------------
*/
static TargetEntry *
_readTargetEntry(void)
{
TargetEntry *local_node;
char *token;
int length;
local_node = makeNode(TargetEntry);
token = pg_strtok(&length); /* get :resdom */
local_node->resdom = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :expr */
local_node->expr = nodeRead(true); /* now read it */
return local_node;
}
static RangeVar *
_readRangeVar(void)
{
RangeVar *local_node;
char *token;
int length;
local_node = makeNode(RangeVar);
local_node->catalogname = NULL; /* not currently saved in output
* format */
token = pg_strtok(&length); /* eat :relation */
token = pg_strtok(&length); /* get schemaname */
local_node->schemaname = nullable_string(token, length);
token = pg_strtok(&length); /* eat "." */
token = pg_strtok(&length); /* get relname */
local_node->relname = nullable_string(token, length);
token = pg_strtok(&length); /* eat :inhopt */
token = pg_strtok(&length); /* get inhopt */
local_node->inhOpt = (InhOption) atoi(token);
token = pg_strtok(&length); /* eat :istemp */
token = pg_strtok(&length); /* get istemp */
local_node->istemp = strtobool(token);
token = pg_strtok(&length); /* eat :alias */
local_node->alias = nodeRead(true); /* now read it */
return local_node;
}
static ColumnRef *
_readColumnRef(void)
{
ColumnRef *local_node;
char *token;
int length;
local_node = makeNode(ColumnRef);
token = pg_strtok(&length); /* eat :fields */
local_node->fields = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :indirection */
local_node->indirection = nodeRead(true); /* now read it */
return local_node;
}
static ColumnDef *
_readColumnDef(void)
{
ColumnDef *local_node;
char *token;
int length;
local_node = makeNode(ColumnDef);
token = pg_strtok(&length); /* eat :colname */
token = pg_strtok(&length); /* now read it */
local_node->colname = nullable_string(token, length);
token = pg_strtok(&length); /* eat :typename */
local_node->typename = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :inhcount */
token = pg_strtok(&length); /* get :inhcount */
local_node->inhcount = atoi(token);
token = pg_strtok(&length); /* eat :is_local */
token = pg_strtok(&length); /* get :is_local */
local_node->is_local = strtobool(token);
token = pg_strtok(&length); /* eat :is_not_null */
token = pg_strtok(&length); /* get :is_not_null */
local_node->is_not_null = strtobool(token);
token = pg_strtok(&length); /* eat :raw_default */
local_node->raw_default = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :cooked_default */
token = pg_strtok(&length); /* now read it */
local_node->cooked_default = nullable_string(token, length);
token = pg_strtok(&length); /* eat :constraints */
local_node->constraints = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :support */
local_node->support = nodeRead(true); /* now read it */
return local_node;
}
static TypeName *
_readTypeName(void)
{
TypeName *local_node;
char *token;
int length;
local_node = makeNode(TypeName);
token = pg_strtok(&length); /* eat :names */
local_node->names = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :typeid */
token = pg_strtok(&length); /* get typeid */
local_node->typeid = atooid(token);
token = pg_strtok(&length); /* eat :timezone */
token = pg_strtok(&length); /* get timezone */
local_node->timezone = strtobool(token);
token = pg_strtok(&length); /* eat :setof */
token = pg_strtok(&length); /* get setof */
local_node->setof = strtobool(token);
token = pg_strtok(&length); /* eat :pct_type */
token = pg_strtok(&length); /* get pct_type */
local_node->pct_type = strtobool(token);
token = pg_strtok(&length); /* eat :typmod */
token = pg_strtok(&length); /* get typmod */
local_node->typmod = atoi(token);
token = pg_strtok(&length); /* eat :arrayBounds */
local_node->arrayBounds = nodeRead(true); /* now read it */
return local_node;
}
static ExprFieldSelect *
_readExprFieldSelect(void)
{
ExprFieldSelect *local_node;
char *token;
int length;
local_node = makeNode(ExprFieldSelect);
token = pg_strtok(&length); /* eat :arg */
local_node->arg = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :fields */
local_node->fields = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :indirection */
local_node->indirection = nodeRead(true); /* now read it */
return local_node;
}
static Alias *
_readAlias(void)
{
Alias *local_node;
char *token;
int length;
local_node = makeNode(Alias);
token = pg_strtok(&length); /* eat :aliasname */
token = pg_strtok(&length); /* get aliasname */
local_node->aliasname = debackslash(token, length);
token = pg_strtok(&length); /* eat :colnames */
local_node->colnames = nodeRead(true); /* now read it */
return local_node;
}
/* ----------------
* _readRangeTblEntry
* ----------------
*/ */
static RangeTblEntry * static RangeTblEntry *
_readRangeTblEntry(void) _readRangeTblEntry(void)
{ {
RangeTblEntry *local_node; READ_LOCALS(RangeTblEntry);
char *token;
int length;
local_node = makeNode(RangeTblEntry);
token = pg_strtok(&length); /* eat :alias */ /* put alias + eref first to make dump more legible */
local_node->alias = nodeRead(true); /* now read it */ READ_NODE_FIELD(alias);
READ_NODE_FIELD(eref);
token = pg_strtok(&length); /* eat :eref */ READ_ENUM_FIELD(rtekind, RTEKind);
local_node->eref = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :rtekind */
token = pg_strtok(&length); /* get rtekind */
local_node->rtekind = (RTEKind) atoi(token);
switch (local_node->rtekind) switch (local_node->rtekind)
{ {
case RTE_RELATION: case RTE_RELATION:
case RTE_SPECIAL: case RTE_SPECIAL:
token = pg_strtok(&length); /* eat :relid */ READ_OID_FIELD(relid);
token = pg_strtok(&length); /* get :relid */
local_node->relid = atooid(token);
break; break;
case RTE_SUBQUERY: case RTE_SUBQUERY:
token = pg_strtok(&length); /* eat :subquery */ READ_NODE_FIELD(subquery);
local_node->subquery = nodeRead(true); /* now read it */
break; break;
case RTE_FUNCTION: case RTE_FUNCTION:
token = pg_strtok(&length); /* eat :funcexpr */ READ_NODE_FIELD(funcexpr);
local_node->funcexpr = nodeRead(true); /* now read it */ READ_NODE_FIELD(coldeflist);
token = pg_strtok(&length); /* eat :coldeflist */
local_node->coldeflist = nodeRead(true); /* now read it */
break; break;
case RTE_JOIN: case RTE_JOIN:
token = pg_strtok(&length); /* eat :jointype */ READ_ENUM_FIELD(jointype, JoinType);
token = pg_strtok(&length); /* get jointype */ READ_NODE_FIELD(joinaliasvars);
local_node->jointype = (JoinType) atoi(token);
token = pg_strtok(&length); /* eat :joinaliasvars */
local_node->joinaliasvars = nodeRead(true); /* now read it */
break; break;
default: default:
elog(ERROR, "bogus rte kind %d", (int) local_node->rtekind); elog(ERROR, "bogus rte kind %d", (int) local_node->rtekind);
break; break;
} }
token = pg_strtok(&length); /* eat :inh */ READ_BOOL_FIELD(inh);
token = pg_strtok(&length); /* get :inh */ READ_BOOL_FIELD(inFromCl);
local_node->inh = strtobool(token); READ_BOOL_FIELD(checkForRead);
READ_BOOL_FIELD(checkForWrite);
token = pg_strtok(&length); /* eat :inFromCl */ READ_OID_FIELD(checkAsUser);
token = pg_strtok(&length); /* get :inFromCl */
local_node->inFromCl = strtobool(token);
token = pg_strtok(&length); /* eat :checkForRead */
token = pg_strtok(&length); /* get :checkForRead */
local_node->checkForRead = strtobool(token);
token = pg_strtok(&length); /* eat :checkForWrite */
token = pg_strtok(&length); /* get :checkForWrite */
local_node->checkForWrite = strtobool(token);
token = pg_strtok(&length); /* eat :checkAsUser */
token = pg_strtok(&length); /* get :checkAsUser */
local_node->checkAsUser = atooid(token);
return local_node;
}
/* ----------------
* _readPath
*
* Path is a subclass of Node.
* ----------------
*/
static Path *
_readPath(void)
{
Path *local_node;
char *token;
int length;
local_node = makeNode(Path);
token = pg_strtok(&length); /* get :pathtype */
token = pg_strtok(&length); /* now read it */
local_node->pathtype = atoi(token);
token = pg_strtok(&length); /* get :startup_cost */
token = pg_strtok(&length); /* now read it */
local_node->startup_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :total_cost */
token = pg_strtok(&length); /* now read it */
local_node->total_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :pathkeys */
local_node->pathkeys = nodeRead(true); /* now read it */
return local_node;
}
/* ----------------
* _readIndexPath
*
* IndexPath is a subclass of Path.
* ----------------
*/
static IndexPath *
_readIndexPath(void)
{
IndexPath *local_node;
char *token;
int length;
local_node = makeNode(IndexPath);
token = pg_strtok(&length); /* get :pathtype */
token = pg_strtok(&length); /* now read it */
local_node->path.pathtype = atoi(token);
token = pg_strtok(&length); /* get :startup_cost */
token = pg_strtok(&length); /* now read it */
local_node->path.startup_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :total_cost */
token = pg_strtok(&length); /* now read it */
local_node->path.total_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :pathkeys */
local_node->path.pathkeys = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :indexinfo */
local_node->indexinfo = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :indexqual */
local_node->indexqual = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :indexscandir */
token = pg_strtok(&length); /* now read it */
local_node->indexscandir = (ScanDirection) atoi(token);
token = pg_strtok(&length); /* get :rows */
token = pg_strtok(&length); /* now read it */
local_node->rows = atof(token);
return local_node;
}
/* ----------------
* _readTidPath
*
* TidPath is a subclass of Path.
* ----------------
*/
static TidPath *
_readTidPath(void)
{
TidPath *local_node;
char *token;
int length;
local_node = makeNode(TidPath);
token = pg_strtok(&length); /* get :pathtype */
token = pg_strtok(&length); /* now read it */
local_node->path.pathtype = atoi(token);
token = pg_strtok(&length); /* get :startup_cost */
token = pg_strtok(&length); /* now read it */
local_node->path.startup_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :total_cost */
token = pg_strtok(&length); /* now read it */
local_node->path.total_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :pathkeys */
local_node->path.pathkeys = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :tideval */
local_node->tideval = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :unjoined_relids */
local_node->unjoined_relids = toIntList(nodeRead(true));
return local_node;
}
/* ----------------
* _readAppendPath
*
* AppendPath is a subclass of Path.
* ----------------
*/
static AppendPath *
_readAppendPath(void)
{
AppendPath *local_node;
char *token;
int length;
local_node = makeNode(AppendPath);
token = pg_strtok(&length); /* get :pathtype */
token = pg_strtok(&length); /* now read it */
local_node->path.pathtype = atoi(token);
token = pg_strtok(&length); /* get :startup_cost */
token = pg_strtok(&length); /* now read it */
local_node->path.startup_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :total_cost */
token = pg_strtok(&length); /* now read it */
local_node->path.total_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :pathkeys */
local_node->path.pathkeys = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :subpaths */
local_node->subpaths = nodeRead(true); /* now read it */
return local_node;
}
/* ----------------
* _readResultPath
*
* ResultPath is a subclass of Path.
* ----------------
*/
static ResultPath *
_readResultPath(void)
{
ResultPath *local_node;
char *token;
int length;
local_node = makeNode(ResultPath);
token = pg_strtok(&length); /* get :pathtype */
token = pg_strtok(&length); /* now read it */
local_node->path.pathtype = atoi(token);
token = pg_strtok(&length); /* get :startup_cost */
token = pg_strtok(&length); /* now read it */
local_node->path.startup_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :total_cost */
token = pg_strtok(&length); /* now read it */
local_node->path.total_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :pathkeys */
local_node->path.pathkeys = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :subpath */
local_node->subpath = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :constantqual */
local_node->constantqual = nodeRead(true); /* now read it */
return local_node;
}
/* ----------------
* _readNestPath
*
* NestPath is a subclass of Path
* ----------------
*/
static NestPath *
_readNestPath(void)
{
NestPath *local_node;
char *token;
int length;
local_node = makeNode(NestPath);
token = pg_strtok(&length); /* get :pathtype */
token = pg_strtok(&length); /* now read it */
local_node->path.pathtype = atoi(token);
token = pg_strtok(&length); /* get :startup_cost */
token = pg_strtok(&length); /* now read it */
local_node->path.startup_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :total_cost */
token = pg_strtok(&length); /* now read it */
local_node->path.total_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :pathkeys */
local_node->path.pathkeys = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :jointype */
token = pg_strtok(&length); /* now read it */
local_node->jointype = (JoinType) atoi(token);
token = pg_strtok(&length); /* get :outerjoinpath */
local_node->outerjoinpath = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :innerjoinpath */
local_node->innerjoinpath = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :joinrestrictinfo */
local_node->joinrestrictinfo = nodeRead(true); /* now read it */
return local_node;
}
/* ----------------
* _readMergePath
*
* MergePath is a subclass of NestPath.
* ----------------
*/
static MergePath *
_readMergePath(void)
{
MergePath *local_node;
char *token;
int length;
local_node = makeNode(MergePath);
token = pg_strtok(&length); /* get :pathtype */
token = pg_strtok(&length); /* now read it */
local_node->jpath.path.pathtype = atoi(token);
token = pg_strtok(&length); /* get :startup_cost */
token = pg_strtok(&length); /* now read it */
local_node->jpath.path.startup_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :total_cost */
token = pg_strtok(&length); /* now read it */
local_node->jpath.path.total_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :pathkeys */
local_node->jpath.path.pathkeys = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :jointype */
token = pg_strtok(&length); /* now read it */
local_node->jpath.jointype = (JoinType) atoi(token);
token = pg_strtok(&length); /* get :outerjoinpath */
local_node->jpath.outerjoinpath = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :innerjoinpath */ READ_DONE();
local_node->jpath.innerjoinpath = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :joinrestrictinfo */
local_node->jpath.joinrestrictinfo = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :path_mergeclauses */
local_node->path_mergeclauses = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :outersortkeys */
local_node->outersortkeys = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :innersortkeys */
local_node->innersortkeys = nodeRead(true); /* now read it */
return local_node;
}
/* ----------------
* _readHashPath
*
* HashPath is a subclass of NestPath.
* ----------------
*/
static HashPath *
_readHashPath(void)
{
HashPath *local_node;
char *token;
int length;
local_node = makeNode(HashPath);
token = pg_strtok(&length); /* get :pathtype */
token = pg_strtok(&length); /* now read it */
local_node->jpath.path.pathtype = atoi(token);
token = pg_strtok(&length); /* get :startup_cost */
token = pg_strtok(&length); /* now read it */
local_node->jpath.path.startup_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :total_cost */
token = pg_strtok(&length); /* now read it */
local_node->jpath.path.total_cost = (Cost) atof(token);
token = pg_strtok(&length); /* get :pathkeys */
local_node->jpath.path.pathkeys = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :jointype */
token = pg_strtok(&length); /* now read it */
local_node->jpath.jointype = (JoinType) atoi(token);
token = pg_strtok(&length); /* get :outerjoinpath */
local_node->jpath.outerjoinpath = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :innerjoinpath */
local_node->jpath.innerjoinpath = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :joinrestrictinfo */
local_node->jpath.joinrestrictinfo = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :path_hashclauses */
local_node->path_hashclauses = nodeRead(true); /* now read it */
return local_node;
}
/* ----------------
* _readPathKeyItem
*
* PathKeyItem is a subclass of Node.
* ----------------
*/
static PathKeyItem *
_readPathKeyItem(void)
{
PathKeyItem *local_node;
char *token;
int length;
local_node = makeNode(PathKeyItem);
token = pg_strtok(&length); /* get :sortop */
token = pg_strtok(&length); /* now read it */
local_node->sortop = atooid(token);
token = pg_strtok(&length); /* get :key */
local_node->key = nodeRead(true); /* now read it */
return local_node;
}
/* ----------------
* _readRestrictInfo
*
* RestrictInfo is a subclass of Node.
* ----------------
*/
static RestrictInfo *
_readRestrictInfo(void)
{
RestrictInfo *local_node;
char *token;
int length;
local_node = makeNode(RestrictInfo);
token = pg_strtok(&length); /* get :clause */
local_node->clause = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :ispusheddown */
token = pg_strtok(&length); /* now read it */
local_node->ispusheddown = strtobool(token);
token = pg_strtok(&length); /* get :subclauseindices */
local_node->subclauseindices = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* get :mergejoinoperator */
token = pg_strtok(&length); /* now read it */
local_node->mergejoinoperator = atooid(token);
token = pg_strtok(&length); /* get :left_sortop */
token = pg_strtok(&length); /* now read it */
local_node->left_sortop = atooid(token);
token = pg_strtok(&length); /* get :right_sortop */
token = pg_strtok(&length); /* now read it */
local_node->right_sortop = atooid(token);
token = pg_strtok(&length); /* get :hashjoinoperator */
token = pg_strtok(&length); /* now read it */
local_node->hashjoinoperator = atooid(token);
/* eval_cost is not part of saved representation; compute on first use */
local_node->eval_cost = -1;
/* ditto for this_selec */
local_node->this_selec = -1;
/* ditto for cached pathkeys, selectivity, bucketsize */
local_node->left_pathkey = NIL;
local_node->right_pathkey = NIL;
local_node->left_mergescansel = -1;
local_node->right_mergescansel = -1;
local_node->left_bucketsize = -1;
local_node->right_bucketsize = -1;
return local_node;
}
/* ----------------
* _readJoinInfo()
*
* JoinInfo is a subclass of Node.
* ----------------
*/
static JoinInfo *
_readJoinInfo(void)
{
JoinInfo *local_node;
char *token;
int length;
local_node = makeNode(JoinInfo);
token = pg_strtok(&length); /* get :unjoined_relids */
local_node->unjoined_relids = toIntList(nodeRead(true)); /* now read it */
token = pg_strtok(&length); /* get :jinfo_restrictinfo */
local_node->jinfo_restrictinfo = nodeRead(true); /* now read it */
return local_node;
} }
/* ---------------- /*
* parsePlanString * parseNodeString
* *
* Given a character string containing a plan, parsePlanString sets up the * Given a character string representing a node tree, parseNodeString creates
* plan structure representing that plan. * the internal node structure.
* *
* The string to be read must already have been loaded into pg_strtok(). * The string to be read must already have been loaded into pg_strtok().
* ----------------
*/ */
Node * Node *
parsePlanString(void) parseNodeString(void)
{ {
char *token; void *return_value;
int length; READ_TEMP_LOCALS();
void *return_value = NULL;
token = pg_strtok(&length); token = pg_strtok(&length);
if (length == 4 && strncmp(token, "PLAN", length) == 0) #define MATCH(tokname, namelen) \
return_value = _readPlan(); (length == namelen && strncmp(token, tokname, namelen) == 0)
else if (length == 6 && strncmp(token, "RESULT", length) == 0)
return_value = _readResult(); if (MATCH("AGGREF", 6))
else if (length == 6 && strncmp(token, "APPEND", length) == 0)
return_value = _readAppend();
else if (length == 4 && strncmp(token, "JOIN", length) == 0)
return_value = _readJoin();
else if (length == 8 && strncmp(token, "NESTLOOP", length) == 0)
return_value = _readNestLoop();
else if (length == 9 && strncmp(token, "MERGEJOIN", length) == 0)
return_value = _readMergeJoin();
else if (length == 8 && strncmp(token, "HASHJOIN", length) == 0)
return_value = _readHashJoin();
else if (length == 4 && strncmp(token, "SCAN", length) == 0)
return_value = _readScan();
else if (length == 7 && strncmp(token, "SEQSCAN", length) == 0)
return_value = _readSeqScan();
else if (length == 9 && strncmp(token, "INDEXSCAN", length) == 0)
return_value = _readIndexScan();
else if (length == 7 && strncmp(token, "TIDSCAN", length) == 0)
return_value = _readTidScan();
else if (length == 12 && strncmp(token, "SUBQUERYSCAN", length) == 0)
return_value = _readSubqueryScan();
else if (length == 12 && strncmp(token, "FUNCTIONSCAN", length) == 0)
return_value = _readFunctionScan();
else if (length == 4 && strncmp(token, "SORT", length) == 0)
return_value = _readSort();
else if (length == 6 && strncmp(token, "AGGREG", length) == 0)
return_value = _readAggref(); return_value = _readAggref();
else if (length == 7 && strncmp(token, "SUBLINK", length) == 0) else if (MATCH("SUBLINK", 7))
return_value = _readSubLink(); return_value = _readSubLink();
else if (length == 11 && strncmp(token, "FIELDSELECT", length) == 0) else if (MATCH("FIELDSELECT", 11))
return_value = _readFieldSelect(); return_value = _readFieldSelect();
else if (length == 11 && strncmp(token, "RELABELTYPE", length) == 0) else if (MATCH("RELABELTYPE", 11))
return_value = _readRelabelType(); return_value = _readRelabelType();
else if (length == 11 && strncmp(token, "RANGETBLREF", length) == 0) else if (MATCH("RANGETBLREF", 11))
return_value = _readRangeTblRef(); return_value = _readRangeTblRef();
else if (length == 8 && strncmp(token, "FROMEXPR", length) == 0) else if (MATCH("FROMEXPR", 8))
return_value = _readFromExpr(); return_value = _readFromExpr();
else if (length == 8 && strncmp(token, "JOINEXPR", length) == 0) else if (MATCH("JOINEXPR", 8))
return_value = _readJoinExpr(); return_value = _readJoinExpr();
else if (length == 4 && strncmp(token, "HASH", length) == 0) else if (MATCH("RESDOM", 6))
return_value = _readHash();
else if (length == 6 && strncmp(token, "RESDOM", length) == 0)
return_value = _readResdom(); return_value = _readResdom();
else if (length == 4 && strncmp(token, "EXPR", length) == 0) else if (MATCH("EXPR", 4))
return_value = _readExpr(); return_value = _readExpr();
else if (length == 8 && strncmp(token, "ARRAYREF", length) == 0) else if (MATCH("ARRAYREF", 8))
return_value = _readArrayRef(); return_value = _readArrayRef();
else if (length == 3 && strncmp(token, "VAR", length) == 0) else if (MATCH("VAR", 3))
return_value = _readVar(); return_value = _readVar();
else if (length == 5 && strncmp(token, "CONST", length) == 0) else if (MATCH("CONST", 5))
return_value = _readConst(); return_value = _readConst();
else if (length == 4 && strncmp(token, "FUNC", length) == 0) else if (MATCH("FUNC", 4))
return_value = _readFunc(); return_value = _readFunc();
else if (length == 4 && strncmp(token, "OPER", length) == 0) else if (MATCH("OPER", 4))
return_value = _readOper(); return_value = _readOper();
else if (length == 5 && strncmp(token, "PARAM", length) == 0) else if (MATCH("PARAM", 5))
return_value = _readParam(); return_value = _readParam();
else if (length == 11 && strncmp(token, "TARGETENTRY", length) == 0) else if (MATCH("TARGETENTRY", 11))
return_value = _readTargetEntry(); return_value = _readTargetEntry();
else if (length == 8 && strncmp(token, "RANGEVAR", length) == 0) else if (MATCH("RANGEVAR", 8))
return_value = _readRangeVar(); return_value = _readRangeVar();
else if (length == 9 && strncmp(token, "COLUMNREF", length) == 0) else if (MATCH("COLUMNREF", 9))
return_value = _readColumnRef(); return_value = _readColumnRef();
else if (length == 9 && strncmp(token, "COLUMNDEF", length) == 0) else if (MATCH("COLUMNDEF", 9))
return_value = _readColumnDef(); return_value = _readColumnDef();
else if (length == 8 && strncmp(token, "TYPENAME", length) == 0) else if (MATCH("TYPENAME", 8))
return_value = _readTypeName(); return_value = _readTypeName();
else if (length == 15 && strncmp(token, "EXPRFIELDSELECT", length) == 0) else if (MATCH("EXPRFIELDSELECT", 15))
return_value = _readExprFieldSelect(); return_value = _readExprFieldSelect();
else if (length == 5 && strncmp(token, "ALIAS", length) == 0) else if (MATCH("ALIAS", 5))
return_value = _readAlias(); return_value = _readAlias();
else if (length == 3 && strncmp(token, "RTE", length) == 0) else if (MATCH("RTE", 3))
return_value = _readRangeTblEntry(); return_value = _readRangeTblEntry();
else if (length == 4 && strncmp(token, "PATH", length) == 0) else if (MATCH("QUERY", 5))
return_value = _readPath();
else if (length == 9 && strncmp(token, "INDEXPATH", length) == 0)
return_value = _readIndexPath();
else if (length == 7 && strncmp(token, "TIDPATH", length) == 0)
return_value = _readTidPath();
else if (length == 10 && strncmp(token, "APPENDPATH", length) == 0)
return_value = _readAppendPath();
else if (length == 10 && strncmp(token, "RESULTPATH", length) == 0)
return_value = _readResultPath();
else if (length == 8 && strncmp(token, "NESTPATH", length) == 0)
return_value = _readNestPath();
else if (length == 9 && strncmp(token, "MERGEPATH", length) == 0)
return_value = _readMergePath();
else if (length == 8 && strncmp(token, "HASHPATH", length) == 0)
return_value = _readHashPath();
else if (length == 11 && strncmp(token, "PATHKEYITEM", length) == 0)
return_value = _readPathKeyItem();
else if (length == 12 && strncmp(token, "RESTRICTINFO", length) == 0)
return_value = _readRestrictInfo();
else if (length == 8 && strncmp(token, "JOININFO", length) == 0)
return_value = _readJoinInfo();
else if (length == 5 && strncmp(token, "QUERY", length) == 0)
return_value = _readQuery(); return_value = _readQuery();
else if (length == 6 && strncmp(token, "NOTIFY", length) == 0) else if (MATCH("NOTIFY", 6))
return_value = _readNotifyStmt(); return_value = _readNotifyStmt();
else if (length == 10 && strncmp(token, "SORTCLAUSE", length) == 0) else if (MATCH("SORTCLAUSE", 10))
return_value = _readSortClause(); return_value = _readSortClause();
else if (length == 11 && strncmp(token, "GROUPCLAUSE", length) == 0) else if (MATCH("GROUPCLAUSE", 11))
return_value = _readGroupClause(); return_value = _readGroupClause();
else if (length == 16 && strncmp(token, "SETOPERATIONSTMT", length) == 0) else if (MATCH("SETOPERATIONSTMT", 16))
return_value = _readSetOperationStmt(); return_value = _readSetOperationStmt();
else if (length == 4 && strncmp(token, "CASE", length) == 0) else if (MATCH("CASE", 4))
return_value = _readCaseExpr(); return_value = _readCaseExpr();
else if (length == 4 && strncmp(token, "WHEN", length) == 0) else if (MATCH("WHEN", 4))
return_value = _readCaseWhen(); return_value = _readCaseWhen();
else if (length == 8 && strncmp(token, "NULLTEST", length) == 0) else if (MATCH("NULLTEST", 8))
return_value = _readNullTest(); return_value = _readNullTest();
else if (length == 11 && strncmp(token, "BOOLEANTEST", length) == 0) else if (MATCH("BOOLEANTEST", 11))
return_value = _readBooleanTest(); return_value = _readBooleanTest();
else if (length == 14 && strncmp(token, "CONSTRAINTTEST", length) == 0) else if (MATCH("CONSTRAINTTEST", 14))
return_value = _readConstraintTest(); return_value = _readConstraintTest();
else if (length == 21 && strncmp(token, "DOMAINCONSTRAINTVALUE", length) == 0) else if (MATCH("DOMAINCONSTRAINTVALUE", 21))
return_value = _readDomainConstraintValue(); return_value = _readDomainConstraintValue();
else if (length == 19 && strncmp(token, "CONSTRAINTTESTVALUE", length) == 0) else if (MATCH("CONSTRAINTTESTVALUE", 19))
return_value = _readConstraintTestValue(); return_value = _readConstraintTestValue();
else else
elog(ERROR, "badly formatted planstring \"%.10s\"...", token); {
elog(ERROR, "badly formatted node string \"%.32s\"...", token);
return_value = NULL; /* keep compiler quiet */
}
return (Node *) return_value; return (Node *) return_value;
} }
/*------------------------------------------------------------*/
/* ---------------- /*
* readDatum * readDatum
* *
* Given a string representation of a constant, recreate the appropriate * Given a string representation of a constant, recreate the appropriate
* Datum. The string representation embeds length info, but not byValue, * Datum. The string representation embeds length info, but not byValue,
* so we must be told that. * so we must be told that.
* ----------------
*/ */
static Datum static Datum
readDatum(bool typbyval) readDatum(bool typbyval)
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: catversion.h,v 1.165 2002/11/23 18:13:22 momjian Exp $ * $Id: catversion.h,v 1.166 2002/11/25 18:12:11 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200211231 #define CATALOG_VERSION_NO 200211251
#endif #endif
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: readfuncs.h,v 1.15 2002/06/20 20:29:51 momjian Exp $ * $Id: readfuncs.h,v 1.16 2002/11/25 18:12:12 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -26,6 +26,6 @@ extern void *nodeRead(bool read_car_only); ...@@ -26,6 +26,6 @@ extern void *nodeRead(bool read_car_only);
/* /*
* prototypes for functions in readfuncs.c * prototypes for functions in readfuncs.c
*/ */
extern Node *parsePlanString(void); extern Node *parseNodeString(void);
#endif /* READFUNCS_H */ #endif /* READFUNCS_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment