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