Header And Logo

PostgreSQL
| The world's most advanced open source database.

readfuncs.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * readfuncs.c
00004  *    Reader functions for Postgres tree nodes.
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/nodes/readfuncs.c
00012  *
00013  * NOTES
00014  *    Path and Plan nodes do not have any readfuncs support, because we
00015  *    never have occasion to read them in.  (There was once code here that
00016  *    claimed to read them, but it was broken as well as unused.)  We
00017  *    never read executor state trees, either.
00018  *
00019  *    Parse location fields are written out by outfuncs.c, but only for
00020  *    possible debugging use.  When reading a location field, we discard
00021  *    the stored value and set the location field to -1 (ie, "unknown").
00022  *    This is because nodes coming from a stored rule should not be thought
00023  *    to have a known location in the current query's text.
00024  *
00025  *-------------------------------------------------------------------------
00026  */
00027 #include "postgres.h"
00028 
00029 #include <math.h>
00030 
00031 #include "nodes/parsenodes.h"
00032 #include "nodes/readfuncs.h"
00033 
00034 
00035 /*
00036  * Macros to simplify reading of different kinds of fields.  Use these
00037  * wherever possible to reduce the chance for silly typos.  Note that these
00038  * hard-wire conventions about the names of the local variables in a Read
00039  * routine.
00040  */
00041 
00042 /* Macros for declaring appropriate local variables */
00043 
00044 /* A few guys need only local_node */
00045 #define READ_LOCALS_NO_FIELDS(nodeTypeName) \
00046     nodeTypeName *local_node = makeNode(nodeTypeName)
00047 
00048 /* And a few guys need only the pg_strtok support fields */
00049 #define READ_TEMP_LOCALS()  \
00050     char       *token;      \
00051     int         length
00052 
00053 /* ... but most need both */
00054 #define READ_LOCALS(nodeTypeName)           \
00055     READ_LOCALS_NO_FIELDS(nodeTypeName);    \
00056     READ_TEMP_LOCALS()
00057 
00058 /* Read an integer field (anything written as ":fldname %d") */
00059 #define READ_INT_FIELD(fldname) \
00060     token = pg_strtok(&length);     /* skip :fldname */ \
00061     token = pg_strtok(&length);     /* get field value */ \
00062     local_node->fldname = atoi(token)
00063 
00064 /* Read an unsigned integer field (anything written as ":fldname %u") */
00065 #define READ_UINT_FIELD(fldname) \
00066     token = pg_strtok(&length);     /* skip :fldname */ \
00067     token = pg_strtok(&length);     /* get field value */ \
00068     local_node->fldname = atoui(token)
00069 
00070 /* Read an OID field (don't hard-wire assumption that OID is same as uint) */
00071 #define READ_OID_FIELD(fldname) \
00072     token = pg_strtok(&length);     /* skip :fldname */ \
00073     token = pg_strtok(&length);     /* get field value */ \
00074     local_node->fldname = atooid(token)
00075 
00076 /* Read a char field (ie, one ascii character) */
00077 #define READ_CHAR_FIELD(fldname) \
00078     token = pg_strtok(&length);     /* skip :fldname */ \
00079     token = pg_strtok(&length);     /* get field value */ \
00080     local_node->fldname = token[0]
00081 
00082 /* Read an enumerated-type field that was written as an integer code */
00083 #define READ_ENUM_FIELD(fldname, enumtype) \
00084     token = pg_strtok(&length);     /* skip :fldname */ \
00085     token = pg_strtok(&length);     /* get field value */ \
00086     local_node->fldname = (enumtype) atoi(token)
00087 
00088 /* Read a float field */
00089 #define READ_FLOAT_FIELD(fldname) \
00090     token = pg_strtok(&length);     /* skip :fldname */ \
00091     token = pg_strtok(&length);     /* get field value */ \
00092     local_node->fldname = atof(token)
00093 
00094 /* Read a boolean field */
00095 #define READ_BOOL_FIELD(fldname) \
00096     token = pg_strtok(&length);     /* skip :fldname */ \
00097     token = pg_strtok(&length);     /* get field value */ \
00098     local_node->fldname = strtobool(token)
00099 
00100 /* Read a character-string field */
00101 #define READ_STRING_FIELD(fldname) \
00102     token = pg_strtok(&length);     /* skip :fldname */ \
00103     token = pg_strtok(&length);     /* get field value */ \
00104     local_node->fldname = nullable_string(token, length)
00105 
00106 /* Read a parse location field (and throw away the value, per notes above) */
00107 #define READ_LOCATION_FIELD(fldname) \
00108     token = pg_strtok(&length);     /* skip :fldname */ \
00109     token = pg_strtok(&length);     /* get field value */ \
00110     local_node->fldname = -1    /* set field to "unknown" */
00111 
00112 /* Read a Node field */
00113 #define READ_NODE_FIELD(fldname) \
00114     token = pg_strtok(&length);     /* skip :fldname */ \
00115     (void) token;               /* in case not used elsewhere */ \
00116     local_node->fldname = nodeRead(NULL, 0)
00117 
00118 /* Read a bitmapset field */
00119 #define READ_BITMAPSET_FIELD(fldname) \
00120     token = pg_strtok(&length);     /* skip :fldname */ \
00121     local_node->fldname = _readBitmapset()
00122 
00123 /* Routine exit */
00124 #define READ_DONE() \
00125     return local_node
00126 
00127 
00128 /*
00129  * NOTE: use atoi() to read values written with %d, or atoui() to read
00130  * values written with %u in outfuncs.c.  An exception is OID values,
00131  * for which use atooid().  (As of 7.1, outfuncs.c writes OIDs as %u,
00132  * but this will probably change in the future.)
00133  */
00134 #define atoui(x)  ((unsigned int) strtoul((x), NULL, 10))
00135 
00136 #define atooid(x)  ((Oid) strtoul((x), NULL, 10))
00137 
00138 #define strtobool(x)  ((*(x) == 't') ? true : false)
00139 
00140 #define nullable_string(token,length)  \
00141     ((length) == 0 ? NULL : debackslash(token, length))
00142 
00143 
00144 static Datum readDatum(bool typbyval);
00145 
00146 /*
00147  * _readBitmapset
00148  */
00149 static Bitmapset *
00150 _readBitmapset(void)
00151 {
00152     Bitmapset  *result = NULL;
00153 
00154     READ_TEMP_LOCALS();
00155 
00156     token = pg_strtok(&length);
00157     if (token == NULL)
00158         elog(ERROR, "incomplete Bitmapset structure");
00159     if (length != 1 || token[0] != '(')
00160         elog(ERROR, "unrecognized token: \"%.*s\"", length, token);
00161 
00162     token = pg_strtok(&length);
00163     if (token == NULL)
00164         elog(ERROR, "incomplete Bitmapset structure");
00165     if (length != 1 || token[0] != 'b')
00166         elog(ERROR, "unrecognized token: \"%.*s\"", length, token);
00167 
00168     for (;;)
00169     {
00170         int         val;
00171         char       *endptr;
00172 
00173         token = pg_strtok(&length);
00174         if (token == NULL)
00175             elog(ERROR, "unterminated Bitmapset structure");
00176         if (length == 1 && token[0] == ')')
00177             break;
00178         val = (int) strtol(token, &endptr, 10);
00179         if (endptr != token + length)
00180             elog(ERROR, "unrecognized integer: \"%.*s\"", length, token);
00181         result = bms_add_member(result, val);
00182     }
00183 
00184     return result;
00185 }
00186 
00187 
00188 /*
00189  * _readQuery
00190  */
00191 static Query *
00192 _readQuery(void)
00193 {
00194     READ_LOCALS(Query);
00195 
00196     READ_ENUM_FIELD(commandType, CmdType);
00197     READ_ENUM_FIELD(querySource, QuerySource);
00198     local_node->queryId = 0;    /* not saved in output format */
00199     READ_BOOL_FIELD(canSetTag);
00200     READ_NODE_FIELD(utilityStmt);
00201     READ_INT_FIELD(resultRelation);
00202     READ_BOOL_FIELD(hasAggs);
00203     READ_BOOL_FIELD(hasWindowFuncs);
00204     READ_BOOL_FIELD(hasSubLinks);
00205     READ_BOOL_FIELD(hasDistinctOn);
00206     READ_BOOL_FIELD(hasRecursive);
00207     READ_BOOL_FIELD(hasModifyingCTE);
00208     READ_BOOL_FIELD(hasForUpdate);
00209     READ_NODE_FIELD(cteList);
00210     READ_NODE_FIELD(rtable);
00211     READ_NODE_FIELD(jointree);
00212     READ_NODE_FIELD(targetList);
00213     READ_NODE_FIELD(returningList);
00214     READ_NODE_FIELD(groupClause);
00215     READ_NODE_FIELD(havingQual);
00216     READ_NODE_FIELD(windowClause);
00217     READ_NODE_FIELD(distinctClause);
00218     READ_NODE_FIELD(sortClause);
00219     READ_NODE_FIELD(limitOffset);
00220     READ_NODE_FIELD(limitCount);
00221     READ_NODE_FIELD(rowMarks);
00222     READ_NODE_FIELD(setOperations);
00223     READ_NODE_FIELD(constraintDeps);
00224 
00225     READ_DONE();
00226 }
00227 
00228 /*
00229  * _readNotifyStmt
00230  */
00231 static NotifyStmt *
00232 _readNotifyStmt(void)
00233 {
00234     READ_LOCALS(NotifyStmt);
00235 
00236     READ_STRING_FIELD(conditionname);
00237     READ_STRING_FIELD(payload);
00238 
00239     READ_DONE();
00240 }
00241 
00242 /*
00243  * _readDeclareCursorStmt
00244  */
00245 static DeclareCursorStmt *
00246 _readDeclareCursorStmt(void)
00247 {
00248     READ_LOCALS(DeclareCursorStmt);
00249 
00250     READ_STRING_FIELD(portalname);
00251     READ_INT_FIELD(options);
00252     READ_NODE_FIELD(query);
00253 
00254     READ_DONE();
00255 }
00256 
00257 /*
00258  * _readSortGroupClause
00259  */
00260 static SortGroupClause *
00261 _readSortGroupClause(void)
00262 {
00263     READ_LOCALS(SortGroupClause);
00264 
00265     READ_UINT_FIELD(tleSortGroupRef);
00266     READ_OID_FIELD(eqop);
00267     READ_OID_FIELD(sortop);
00268     READ_BOOL_FIELD(nulls_first);
00269     READ_BOOL_FIELD(hashable);
00270 
00271     READ_DONE();
00272 }
00273 
00274 /*
00275  * _readWindowClause
00276  */
00277 static WindowClause *
00278 _readWindowClause(void)
00279 {
00280     READ_LOCALS(WindowClause);
00281 
00282     READ_STRING_FIELD(name);
00283     READ_STRING_FIELD(refname);
00284     READ_NODE_FIELD(partitionClause);
00285     READ_NODE_FIELD(orderClause);
00286     READ_INT_FIELD(frameOptions);
00287     READ_NODE_FIELD(startOffset);
00288     READ_NODE_FIELD(endOffset);
00289     READ_UINT_FIELD(winref);
00290     READ_BOOL_FIELD(copiedOrder);
00291 
00292     READ_DONE();
00293 }
00294 
00295 /*
00296  * _readRowMarkClause
00297  */
00298 static RowMarkClause *
00299 _readRowMarkClause(void)
00300 {
00301     READ_LOCALS(RowMarkClause);
00302 
00303     READ_UINT_FIELD(rti);
00304     READ_ENUM_FIELD(strength, LockClauseStrength);
00305     READ_BOOL_FIELD(noWait);
00306     READ_BOOL_FIELD(pushedDown);
00307 
00308     READ_DONE();
00309 }
00310 
00311 /*
00312  * _readCommonTableExpr
00313  */
00314 static CommonTableExpr *
00315 _readCommonTableExpr(void)
00316 {
00317     READ_LOCALS(CommonTableExpr);
00318 
00319     READ_STRING_FIELD(ctename);
00320     READ_NODE_FIELD(aliascolnames);
00321     READ_NODE_FIELD(ctequery);
00322     READ_LOCATION_FIELD(location);
00323     READ_BOOL_FIELD(cterecursive);
00324     READ_INT_FIELD(cterefcount);
00325     READ_NODE_FIELD(ctecolnames);
00326     READ_NODE_FIELD(ctecoltypes);
00327     READ_NODE_FIELD(ctecoltypmods);
00328     READ_NODE_FIELD(ctecolcollations);
00329 
00330     READ_DONE();
00331 }
00332 
00333 /*
00334  * _readSetOperationStmt
00335  */
00336 static SetOperationStmt *
00337 _readSetOperationStmt(void)
00338 {
00339     READ_LOCALS(SetOperationStmt);
00340 
00341     READ_ENUM_FIELD(op, SetOperation);
00342     READ_BOOL_FIELD(all);
00343     READ_NODE_FIELD(larg);
00344     READ_NODE_FIELD(rarg);
00345     READ_NODE_FIELD(colTypes);
00346     READ_NODE_FIELD(colTypmods);
00347     READ_NODE_FIELD(colCollations);
00348     READ_NODE_FIELD(groupClauses);
00349 
00350     READ_DONE();
00351 }
00352 
00353 
00354 /*
00355  *  Stuff from primnodes.h.
00356  */
00357 
00358 static Alias *
00359 _readAlias(void)
00360 {
00361     READ_LOCALS(Alias);
00362 
00363     READ_STRING_FIELD(aliasname);
00364     READ_NODE_FIELD(colnames);
00365 
00366     READ_DONE();
00367 }
00368 
00369 static RangeVar *
00370 _readRangeVar(void)
00371 {
00372     READ_LOCALS(RangeVar);
00373 
00374     local_node->catalogname = NULL;     /* not currently saved in output
00375                                          * format */
00376 
00377     READ_STRING_FIELD(schemaname);
00378     READ_STRING_FIELD(relname);
00379     READ_ENUM_FIELD(inhOpt, InhOption);
00380     READ_CHAR_FIELD(relpersistence);
00381     READ_NODE_FIELD(alias);
00382     READ_LOCATION_FIELD(location);
00383 
00384     READ_DONE();
00385 }
00386 
00387 static IntoClause *
00388 _readIntoClause(void)
00389 {
00390     READ_LOCALS(IntoClause);
00391 
00392     READ_NODE_FIELD(rel);
00393     READ_NODE_FIELD(colNames);
00394     READ_NODE_FIELD(options);
00395     READ_ENUM_FIELD(onCommit, OnCommitAction);
00396     READ_STRING_FIELD(tableSpaceName);
00397     READ_NODE_FIELD(viewQuery);
00398     READ_BOOL_FIELD(skipData);
00399 
00400     READ_DONE();
00401 }
00402 
00403 /*
00404  * _readVar
00405  */
00406 static Var *
00407 _readVar(void)
00408 {
00409     READ_LOCALS(Var);
00410 
00411     READ_UINT_FIELD(varno);
00412     READ_INT_FIELD(varattno);
00413     READ_OID_FIELD(vartype);
00414     READ_INT_FIELD(vartypmod);
00415     READ_OID_FIELD(varcollid);
00416     READ_UINT_FIELD(varlevelsup);
00417     READ_UINT_FIELD(varnoold);
00418     READ_INT_FIELD(varoattno);
00419     READ_LOCATION_FIELD(location);
00420 
00421     READ_DONE();
00422 }
00423 
00424 /*
00425  * _readConst
00426  */
00427 static Const *
00428 _readConst(void)
00429 {
00430     READ_LOCALS(Const);
00431 
00432     READ_OID_FIELD(consttype);
00433     READ_INT_FIELD(consttypmod);
00434     READ_OID_FIELD(constcollid);
00435     READ_INT_FIELD(constlen);
00436     READ_BOOL_FIELD(constbyval);
00437     READ_BOOL_FIELD(constisnull);
00438     READ_LOCATION_FIELD(location);
00439 
00440     token = pg_strtok(&length); /* skip :constvalue */
00441     if (local_node->constisnull)
00442         token = pg_strtok(&length);     /* skip "<>" */
00443     else
00444         local_node->constvalue = readDatum(local_node->constbyval);
00445 
00446     READ_DONE();
00447 }
00448 
00449 /*
00450  * _readParam
00451  */
00452 static Param *
00453 _readParam(void)
00454 {
00455     READ_LOCALS(Param);
00456 
00457     READ_ENUM_FIELD(paramkind, ParamKind);
00458     READ_INT_FIELD(paramid);
00459     READ_OID_FIELD(paramtype);
00460     READ_INT_FIELD(paramtypmod);
00461     READ_OID_FIELD(paramcollid);
00462     READ_LOCATION_FIELD(location);
00463 
00464     READ_DONE();
00465 }
00466 
00467 /*
00468  * _readAggref
00469  */
00470 static Aggref *
00471 _readAggref(void)
00472 {
00473     READ_LOCALS(Aggref);
00474 
00475     READ_OID_FIELD(aggfnoid);
00476     READ_OID_FIELD(aggtype);
00477     READ_OID_FIELD(aggcollid);
00478     READ_OID_FIELD(inputcollid);
00479     READ_NODE_FIELD(args);
00480     READ_NODE_FIELD(aggorder);
00481     READ_NODE_FIELD(aggdistinct);
00482     READ_BOOL_FIELD(aggstar);
00483     READ_UINT_FIELD(agglevelsup);
00484     READ_LOCATION_FIELD(location);
00485 
00486     READ_DONE();
00487 }
00488 
00489 /*
00490  * _readWindowFunc
00491  */
00492 static WindowFunc *
00493 _readWindowFunc(void)
00494 {
00495     READ_LOCALS(WindowFunc);
00496 
00497     READ_OID_FIELD(winfnoid);
00498     READ_OID_FIELD(wintype);
00499     READ_OID_FIELD(wincollid);
00500     READ_OID_FIELD(inputcollid);
00501     READ_NODE_FIELD(args);
00502     READ_UINT_FIELD(winref);
00503     READ_BOOL_FIELD(winstar);
00504     READ_BOOL_FIELD(winagg);
00505     READ_LOCATION_FIELD(location);
00506 
00507     READ_DONE();
00508 }
00509 
00510 /*
00511  * _readArrayRef
00512  */
00513 static ArrayRef *
00514 _readArrayRef(void)
00515 {
00516     READ_LOCALS(ArrayRef);
00517 
00518     READ_OID_FIELD(refarraytype);
00519     READ_OID_FIELD(refelemtype);
00520     READ_INT_FIELD(reftypmod);
00521     READ_OID_FIELD(refcollid);
00522     READ_NODE_FIELD(refupperindexpr);
00523     READ_NODE_FIELD(reflowerindexpr);
00524     READ_NODE_FIELD(refexpr);
00525     READ_NODE_FIELD(refassgnexpr);
00526 
00527     READ_DONE();
00528 }
00529 
00530 /*
00531  * _readFuncExpr
00532  */
00533 static FuncExpr *
00534 _readFuncExpr(void)
00535 {
00536     READ_LOCALS(FuncExpr);
00537 
00538     READ_OID_FIELD(funcid);
00539     READ_OID_FIELD(funcresulttype);
00540     READ_BOOL_FIELD(funcretset);
00541     READ_BOOL_FIELD(funcvariadic);
00542     READ_ENUM_FIELD(funcformat, CoercionForm);
00543     READ_OID_FIELD(funccollid);
00544     READ_OID_FIELD(inputcollid);
00545     READ_NODE_FIELD(args);
00546     READ_LOCATION_FIELD(location);
00547 
00548     READ_DONE();
00549 }
00550 
00551 /*
00552  * _readNamedArgExpr
00553  */
00554 static NamedArgExpr *
00555 _readNamedArgExpr(void)
00556 {
00557     READ_LOCALS(NamedArgExpr);
00558 
00559     READ_NODE_FIELD(arg);
00560     READ_STRING_FIELD(name);
00561     READ_INT_FIELD(argnumber);
00562     READ_LOCATION_FIELD(location);
00563 
00564     READ_DONE();
00565 }
00566 
00567 /*
00568  * _readOpExpr
00569  */
00570 static OpExpr *
00571 _readOpExpr(void)
00572 {
00573     READ_LOCALS(OpExpr);
00574 
00575     READ_OID_FIELD(opno);
00576     READ_OID_FIELD(opfuncid);
00577 
00578     /*
00579      * The opfuncid is stored in the textual format primarily for debugging
00580      * and documentation reasons.  We want to always read it as zero to force
00581      * it to be re-looked-up in the pg_operator entry.  This ensures that
00582      * stored rules don't have hidden dependencies on operators' functions.
00583      * (We don't currently support an ALTER OPERATOR command, but might
00584      * someday.)
00585      */
00586     local_node->opfuncid = InvalidOid;
00587 
00588     READ_OID_FIELD(opresulttype);
00589     READ_BOOL_FIELD(opretset);
00590     READ_OID_FIELD(opcollid);
00591     READ_OID_FIELD(inputcollid);
00592     READ_NODE_FIELD(args);
00593     READ_LOCATION_FIELD(location);
00594 
00595     READ_DONE();
00596 }
00597 
00598 /*
00599  * _readDistinctExpr
00600  */
00601 static DistinctExpr *
00602 _readDistinctExpr(void)
00603 {
00604     READ_LOCALS(DistinctExpr);
00605 
00606     READ_OID_FIELD(opno);
00607     READ_OID_FIELD(opfuncid);
00608 
00609     /*
00610      * The opfuncid is stored in the textual format primarily for debugging
00611      * and documentation reasons.  We want to always read it as zero to force
00612      * it to be re-looked-up in the pg_operator entry.  This ensures that
00613      * stored rules don't have hidden dependencies on operators' functions.
00614      * (We don't currently support an ALTER OPERATOR command, but might
00615      * someday.)
00616      */
00617     local_node->opfuncid = InvalidOid;
00618 
00619     READ_OID_FIELD(opresulttype);
00620     READ_BOOL_FIELD(opretset);
00621     READ_OID_FIELD(opcollid);
00622     READ_OID_FIELD(inputcollid);
00623     READ_NODE_FIELD(args);
00624     READ_LOCATION_FIELD(location);
00625 
00626     READ_DONE();
00627 }
00628 
00629 /*
00630  * _readNullIfExpr
00631  */
00632 static NullIfExpr *
00633 _readNullIfExpr(void)
00634 {
00635     READ_LOCALS(NullIfExpr);
00636 
00637     READ_OID_FIELD(opno);
00638     READ_OID_FIELD(opfuncid);
00639 
00640     /*
00641      * The opfuncid is stored in the textual format primarily for debugging
00642      * and documentation reasons.  We want to always read it as zero to force
00643      * it to be re-looked-up in the pg_operator entry.  This ensures that
00644      * stored rules don't have hidden dependencies on operators' functions.
00645      * (We don't currently support an ALTER OPERATOR command, but might
00646      * someday.)
00647      */
00648     local_node->opfuncid = InvalidOid;
00649 
00650     READ_OID_FIELD(opresulttype);
00651     READ_BOOL_FIELD(opretset);
00652     READ_OID_FIELD(opcollid);
00653     READ_OID_FIELD(inputcollid);
00654     READ_NODE_FIELD(args);
00655     READ_LOCATION_FIELD(location);
00656 
00657     READ_DONE();
00658 }
00659 
00660 /*
00661  * _readScalarArrayOpExpr
00662  */
00663 static ScalarArrayOpExpr *
00664 _readScalarArrayOpExpr(void)
00665 {
00666     READ_LOCALS(ScalarArrayOpExpr);
00667 
00668     READ_OID_FIELD(opno);
00669     READ_OID_FIELD(opfuncid);
00670 
00671     /*
00672      * The opfuncid is stored in the textual format primarily for debugging
00673      * and documentation reasons.  We want to always read it as zero to force
00674      * it to be re-looked-up in the pg_operator entry.  This ensures that
00675      * stored rules don't have hidden dependencies on operators' functions.
00676      * (We don't currently support an ALTER OPERATOR command, but might
00677      * someday.)
00678      */
00679     local_node->opfuncid = InvalidOid;
00680 
00681     READ_BOOL_FIELD(useOr);
00682     READ_OID_FIELD(inputcollid);
00683     READ_NODE_FIELD(args);
00684     READ_LOCATION_FIELD(location);
00685 
00686     READ_DONE();
00687 }
00688 
00689 /*
00690  * _readBoolExpr
00691  */
00692 static BoolExpr *
00693 _readBoolExpr(void)
00694 {
00695     READ_LOCALS(BoolExpr);
00696 
00697     /* do-it-yourself enum representation */
00698     token = pg_strtok(&length); /* skip :boolop */
00699     token = pg_strtok(&length); /* get field value */
00700     if (strncmp(token, "and", 3) == 0)
00701         local_node->boolop = AND_EXPR;
00702     else if (strncmp(token, "or", 2) == 0)
00703         local_node->boolop = OR_EXPR;
00704     else if (strncmp(token, "not", 3) == 0)
00705         local_node->boolop = NOT_EXPR;
00706     else
00707         elog(ERROR, "unrecognized boolop \"%.*s\"", length, token);
00708 
00709     READ_NODE_FIELD(args);
00710     READ_LOCATION_FIELD(location);
00711 
00712     READ_DONE();
00713 }
00714 
00715 /*
00716  * _readSubLink
00717  */
00718 static SubLink *
00719 _readSubLink(void)
00720 {
00721     READ_LOCALS(SubLink);
00722 
00723     READ_ENUM_FIELD(subLinkType, SubLinkType);
00724     READ_NODE_FIELD(testexpr);
00725     READ_NODE_FIELD(operName);
00726     READ_NODE_FIELD(subselect);
00727     READ_LOCATION_FIELD(location);
00728 
00729     READ_DONE();
00730 }
00731 
00732 /*
00733  * _readSubPlan is not needed since it doesn't appear in stored rules.
00734  */
00735 
00736 /*
00737  * _readFieldSelect
00738  */
00739 static FieldSelect *
00740 _readFieldSelect(void)
00741 {
00742     READ_LOCALS(FieldSelect);
00743 
00744     READ_NODE_FIELD(arg);
00745     READ_INT_FIELD(fieldnum);
00746     READ_OID_FIELD(resulttype);
00747     READ_INT_FIELD(resulttypmod);
00748     READ_OID_FIELD(resultcollid);
00749 
00750     READ_DONE();
00751 }
00752 
00753 /*
00754  * _readFieldStore
00755  */
00756 static FieldStore *
00757 _readFieldStore(void)
00758 {
00759     READ_LOCALS(FieldStore);
00760 
00761     READ_NODE_FIELD(arg);
00762     READ_NODE_FIELD(newvals);
00763     READ_NODE_FIELD(fieldnums);
00764     READ_OID_FIELD(resulttype);
00765 
00766     READ_DONE();
00767 }
00768 
00769 /*
00770  * _readRelabelType
00771  */
00772 static RelabelType *
00773 _readRelabelType(void)
00774 {
00775     READ_LOCALS(RelabelType);
00776 
00777     READ_NODE_FIELD(arg);
00778     READ_OID_FIELD(resulttype);
00779     READ_INT_FIELD(resulttypmod);
00780     READ_OID_FIELD(resultcollid);
00781     READ_ENUM_FIELD(relabelformat, CoercionForm);
00782     READ_LOCATION_FIELD(location);
00783 
00784     READ_DONE();
00785 }
00786 
00787 /*
00788  * _readCoerceViaIO
00789  */
00790 static CoerceViaIO *
00791 _readCoerceViaIO(void)
00792 {
00793     READ_LOCALS(CoerceViaIO);
00794 
00795     READ_NODE_FIELD(arg);
00796     READ_OID_FIELD(resulttype);
00797     READ_OID_FIELD(resultcollid);
00798     READ_ENUM_FIELD(coerceformat, CoercionForm);
00799     READ_LOCATION_FIELD(location);
00800 
00801     READ_DONE();
00802 }
00803 
00804 /*
00805  * _readArrayCoerceExpr
00806  */
00807 static ArrayCoerceExpr *
00808 _readArrayCoerceExpr(void)
00809 {
00810     READ_LOCALS(ArrayCoerceExpr);
00811 
00812     READ_NODE_FIELD(arg);
00813     READ_OID_FIELD(elemfuncid);
00814     READ_OID_FIELD(resulttype);
00815     READ_INT_FIELD(resulttypmod);
00816     READ_OID_FIELD(resultcollid);
00817     READ_BOOL_FIELD(isExplicit);
00818     READ_ENUM_FIELD(coerceformat, CoercionForm);
00819     READ_LOCATION_FIELD(location);
00820 
00821     READ_DONE();
00822 }
00823 
00824 /*
00825  * _readConvertRowtypeExpr
00826  */
00827 static ConvertRowtypeExpr *
00828 _readConvertRowtypeExpr(void)
00829 {
00830     READ_LOCALS(ConvertRowtypeExpr);
00831 
00832     READ_NODE_FIELD(arg);
00833     READ_OID_FIELD(resulttype);
00834     READ_ENUM_FIELD(convertformat, CoercionForm);
00835     READ_LOCATION_FIELD(location);
00836 
00837     READ_DONE();
00838 }
00839 
00840 /*
00841  * _readCollateExpr
00842  */
00843 static CollateExpr *
00844 _readCollateExpr(void)
00845 {
00846     READ_LOCALS(CollateExpr);
00847 
00848     READ_NODE_FIELD(arg);
00849     READ_OID_FIELD(collOid);
00850     READ_LOCATION_FIELD(location);
00851 
00852     READ_DONE();
00853 }
00854 
00855 /*
00856  * _readCaseExpr
00857  */
00858 static CaseExpr *
00859 _readCaseExpr(void)
00860 {
00861     READ_LOCALS(CaseExpr);
00862 
00863     READ_OID_FIELD(casetype);
00864     READ_OID_FIELD(casecollid);
00865     READ_NODE_FIELD(arg);
00866     READ_NODE_FIELD(args);
00867     READ_NODE_FIELD(defresult);
00868     READ_LOCATION_FIELD(location);
00869 
00870     READ_DONE();
00871 }
00872 
00873 /*
00874  * _readCaseWhen
00875  */
00876 static CaseWhen *
00877 _readCaseWhen(void)
00878 {
00879     READ_LOCALS(CaseWhen);
00880 
00881     READ_NODE_FIELD(expr);
00882     READ_NODE_FIELD(result);
00883     READ_LOCATION_FIELD(location);
00884 
00885     READ_DONE();
00886 }
00887 
00888 /*
00889  * _readCaseTestExpr
00890  */
00891 static CaseTestExpr *
00892 _readCaseTestExpr(void)
00893 {
00894     READ_LOCALS(CaseTestExpr);
00895 
00896     READ_OID_FIELD(typeId);
00897     READ_INT_FIELD(typeMod);
00898     READ_OID_FIELD(collation);
00899 
00900     READ_DONE();
00901 }
00902 
00903 /*
00904  * _readArrayExpr
00905  */
00906 static ArrayExpr *
00907 _readArrayExpr(void)
00908 {
00909     READ_LOCALS(ArrayExpr);
00910 
00911     READ_OID_FIELD(array_typeid);
00912     READ_OID_FIELD(array_collid);
00913     READ_OID_FIELD(element_typeid);
00914     READ_NODE_FIELD(elements);
00915     READ_BOOL_FIELD(multidims);
00916     READ_LOCATION_FIELD(location);
00917 
00918     READ_DONE();
00919 }
00920 
00921 /*
00922  * _readRowExpr
00923  */
00924 static RowExpr *
00925 _readRowExpr(void)
00926 {
00927     READ_LOCALS(RowExpr);
00928 
00929     READ_NODE_FIELD(args);
00930     READ_OID_FIELD(row_typeid);
00931     READ_ENUM_FIELD(row_format, CoercionForm);
00932     READ_NODE_FIELD(colnames);
00933     READ_LOCATION_FIELD(location);
00934 
00935     READ_DONE();
00936 }
00937 
00938 /*
00939  * _readRowCompareExpr
00940  */
00941 static RowCompareExpr *
00942 _readRowCompareExpr(void)
00943 {
00944     READ_LOCALS(RowCompareExpr);
00945 
00946     READ_ENUM_FIELD(rctype, RowCompareType);
00947     READ_NODE_FIELD(opnos);
00948     READ_NODE_FIELD(opfamilies);
00949     READ_NODE_FIELD(inputcollids);
00950     READ_NODE_FIELD(largs);
00951     READ_NODE_FIELD(rargs);
00952 
00953     READ_DONE();
00954 }
00955 
00956 /*
00957  * _readCoalesceExpr
00958  */
00959 static CoalesceExpr *
00960 _readCoalesceExpr(void)
00961 {
00962     READ_LOCALS(CoalesceExpr);
00963 
00964     READ_OID_FIELD(coalescetype);
00965     READ_OID_FIELD(coalescecollid);
00966     READ_NODE_FIELD(args);
00967     READ_LOCATION_FIELD(location);
00968 
00969     READ_DONE();
00970 }
00971 
00972 /*
00973  * _readMinMaxExpr
00974  */
00975 static MinMaxExpr *
00976 _readMinMaxExpr(void)
00977 {
00978     READ_LOCALS(MinMaxExpr);
00979 
00980     READ_OID_FIELD(minmaxtype);
00981     READ_OID_FIELD(minmaxcollid);
00982     READ_OID_FIELD(inputcollid);
00983     READ_ENUM_FIELD(op, MinMaxOp);
00984     READ_NODE_FIELD(args);
00985     READ_LOCATION_FIELD(location);
00986 
00987     READ_DONE();
00988 }
00989 
00990 /*
00991  * _readXmlExpr
00992  */
00993 static XmlExpr *
00994 _readXmlExpr(void)
00995 {
00996     READ_LOCALS(XmlExpr);
00997 
00998     READ_ENUM_FIELD(op, XmlExprOp);
00999     READ_STRING_FIELD(name);
01000     READ_NODE_FIELD(named_args);
01001     READ_NODE_FIELD(arg_names);
01002     READ_NODE_FIELD(args);
01003     READ_ENUM_FIELD(xmloption, XmlOptionType);
01004     READ_OID_FIELD(type);
01005     READ_INT_FIELD(typmod);
01006     READ_LOCATION_FIELD(location);
01007 
01008     READ_DONE();
01009 }
01010 
01011 /*
01012  * _readNullTest
01013  */
01014 static NullTest *
01015 _readNullTest(void)
01016 {
01017     READ_LOCALS(NullTest);
01018 
01019     READ_NODE_FIELD(arg);
01020     READ_ENUM_FIELD(nulltesttype, NullTestType);
01021     READ_BOOL_FIELD(argisrow);
01022 
01023     READ_DONE();
01024 }
01025 
01026 /*
01027  * _readBooleanTest
01028  */
01029 static BooleanTest *
01030 _readBooleanTest(void)
01031 {
01032     READ_LOCALS(BooleanTest);
01033 
01034     READ_NODE_FIELD(arg);
01035     READ_ENUM_FIELD(booltesttype, BoolTestType);
01036 
01037     READ_DONE();
01038 }
01039 
01040 /*
01041  * _readCoerceToDomain
01042  */
01043 static CoerceToDomain *
01044 _readCoerceToDomain(void)
01045 {
01046     READ_LOCALS(CoerceToDomain);
01047 
01048     READ_NODE_FIELD(arg);
01049     READ_OID_FIELD(resulttype);
01050     READ_INT_FIELD(resulttypmod);
01051     READ_OID_FIELD(resultcollid);
01052     READ_ENUM_FIELD(coercionformat, CoercionForm);
01053     READ_LOCATION_FIELD(location);
01054 
01055     READ_DONE();
01056 }
01057 
01058 /*
01059  * _readCoerceToDomainValue
01060  */
01061 static CoerceToDomainValue *
01062 _readCoerceToDomainValue(void)
01063 {
01064     READ_LOCALS(CoerceToDomainValue);
01065 
01066     READ_OID_FIELD(typeId);
01067     READ_INT_FIELD(typeMod);
01068     READ_OID_FIELD(collation);
01069     READ_LOCATION_FIELD(location);
01070 
01071     READ_DONE();
01072 }
01073 
01074 /*
01075  * _readSetToDefault
01076  */
01077 static SetToDefault *
01078 _readSetToDefault(void)
01079 {
01080     READ_LOCALS(SetToDefault);
01081 
01082     READ_OID_FIELD(typeId);
01083     READ_INT_FIELD(typeMod);
01084     READ_OID_FIELD(collation);
01085     READ_LOCATION_FIELD(location);
01086 
01087     READ_DONE();
01088 }
01089 
01090 /*
01091  * _readCurrentOfExpr
01092  */
01093 static CurrentOfExpr *
01094 _readCurrentOfExpr(void)
01095 {
01096     READ_LOCALS(CurrentOfExpr);
01097 
01098     READ_UINT_FIELD(cvarno);
01099     READ_STRING_FIELD(cursor_name);
01100     READ_INT_FIELD(cursor_param);
01101 
01102     READ_DONE();
01103 }
01104 
01105 /*
01106  * _readTargetEntry
01107  */
01108 static TargetEntry *
01109 _readTargetEntry(void)
01110 {
01111     READ_LOCALS(TargetEntry);
01112 
01113     READ_NODE_FIELD(expr);
01114     READ_INT_FIELD(resno);
01115     READ_STRING_FIELD(resname);
01116     READ_UINT_FIELD(ressortgroupref);
01117     READ_OID_FIELD(resorigtbl);
01118     READ_INT_FIELD(resorigcol);
01119     READ_BOOL_FIELD(resjunk);
01120 
01121     READ_DONE();
01122 }
01123 
01124 /*
01125  * _readRangeTblRef
01126  */
01127 static RangeTblRef *
01128 _readRangeTblRef(void)
01129 {
01130     READ_LOCALS(RangeTblRef);
01131 
01132     READ_INT_FIELD(rtindex);
01133 
01134     READ_DONE();
01135 }
01136 
01137 /*
01138  * _readJoinExpr
01139  */
01140 static JoinExpr *
01141 _readJoinExpr(void)
01142 {
01143     READ_LOCALS(JoinExpr);
01144 
01145     READ_ENUM_FIELD(jointype, JoinType);
01146     READ_BOOL_FIELD(isNatural);
01147     READ_NODE_FIELD(larg);
01148     READ_NODE_FIELD(rarg);
01149     READ_NODE_FIELD(usingClause);
01150     READ_NODE_FIELD(quals);
01151     READ_NODE_FIELD(alias);
01152     READ_INT_FIELD(rtindex);
01153 
01154     READ_DONE();
01155 }
01156 
01157 /*
01158  * _readFromExpr
01159  */
01160 static FromExpr *
01161 _readFromExpr(void)
01162 {
01163     READ_LOCALS(FromExpr);
01164 
01165     READ_NODE_FIELD(fromlist);
01166     READ_NODE_FIELD(quals);
01167 
01168     READ_DONE();
01169 }
01170 
01171 
01172 /*
01173  *  Stuff from parsenodes.h.
01174  */
01175 
01176 /*
01177  * _readRangeTblEntry
01178  */
01179 static RangeTblEntry *
01180 _readRangeTblEntry(void)
01181 {
01182     READ_LOCALS(RangeTblEntry);
01183 
01184     /* put alias + eref first to make dump more legible */
01185     READ_NODE_FIELD(alias);
01186     READ_NODE_FIELD(eref);
01187     READ_ENUM_FIELD(rtekind, RTEKind);
01188 
01189     switch (local_node->rtekind)
01190     {
01191         case RTE_RELATION:
01192             READ_OID_FIELD(relid);
01193             READ_CHAR_FIELD(relkind);
01194             break;
01195         case RTE_SUBQUERY:
01196             READ_NODE_FIELD(subquery);
01197             READ_BOOL_FIELD(security_barrier);
01198             break;
01199         case RTE_JOIN:
01200             READ_ENUM_FIELD(jointype, JoinType);
01201             READ_NODE_FIELD(joinaliasvars);
01202             break;
01203         case RTE_FUNCTION:
01204             READ_NODE_FIELD(funcexpr);
01205             READ_NODE_FIELD(funccoltypes);
01206             READ_NODE_FIELD(funccoltypmods);
01207             READ_NODE_FIELD(funccolcollations);
01208             break;
01209         case RTE_VALUES:
01210             READ_NODE_FIELD(values_lists);
01211             READ_NODE_FIELD(values_collations);
01212             break;
01213         case RTE_CTE:
01214             READ_STRING_FIELD(ctename);
01215             READ_UINT_FIELD(ctelevelsup);
01216             READ_BOOL_FIELD(self_reference);
01217             READ_NODE_FIELD(ctecoltypes);
01218             READ_NODE_FIELD(ctecoltypmods);
01219             READ_NODE_FIELD(ctecolcollations);
01220             break;
01221         default:
01222             elog(ERROR, "unrecognized RTE kind: %d",
01223                  (int) local_node->rtekind);
01224             break;
01225     }
01226 
01227     READ_BOOL_FIELD(lateral);
01228     READ_BOOL_FIELD(inh);
01229     READ_BOOL_FIELD(inFromCl);
01230     READ_UINT_FIELD(requiredPerms);
01231     READ_OID_FIELD(checkAsUser);
01232     READ_BITMAPSET_FIELD(selectedCols);
01233     READ_BITMAPSET_FIELD(modifiedCols);
01234 
01235     READ_DONE();
01236 }
01237 
01238 
01239 /*
01240  * parseNodeString
01241  *
01242  * Given a character string representing a node tree, parseNodeString creates
01243  * the internal node structure.
01244  *
01245  * The string to be read must already have been loaded into pg_strtok().
01246  */
01247 Node *
01248 parseNodeString(void)
01249 {
01250     void       *return_value;
01251 
01252     READ_TEMP_LOCALS();
01253 
01254     token = pg_strtok(&length);
01255 
01256 #define MATCH(tokname, namelen) \
01257     (length == namelen && memcmp(token, tokname, namelen) == 0)
01258 
01259     if (MATCH("QUERY", 5))
01260         return_value = _readQuery();
01261     else if (MATCH("SORTGROUPCLAUSE", 15))
01262         return_value = _readSortGroupClause();
01263     else if (MATCH("WINDOWCLAUSE", 12))
01264         return_value = _readWindowClause();
01265     else if (MATCH("ROWMARKCLAUSE", 13))
01266         return_value = _readRowMarkClause();
01267     else if (MATCH("COMMONTABLEEXPR", 15))
01268         return_value = _readCommonTableExpr();
01269     else if (MATCH("SETOPERATIONSTMT", 16))
01270         return_value = _readSetOperationStmt();
01271     else if (MATCH("ALIAS", 5))
01272         return_value = _readAlias();
01273     else if (MATCH("RANGEVAR", 8))
01274         return_value = _readRangeVar();
01275     else if (MATCH("INTOCLAUSE", 10))
01276         return_value = _readIntoClause();
01277     else if (MATCH("VAR", 3))
01278         return_value = _readVar();
01279     else if (MATCH("CONST", 5))
01280         return_value = _readConst();
01281     else if (MATCH("PARAM", 5))
01282         return_value = _readParam();
01283     else if (MATCH("AGGREF", 6))
01284         return_value = _readAggref();
01285     else if (MATCH("WINDOWFUNC", 10))
01286         return_value = _readWindowFunc();
01287     else if (MATCH("ARRAYREF", 8))
01288         return_value = _readArrayRef();
01289     else if (MATCH("FUNCEXPR", 8))
01290         return_value = _readFuncExpr();
01291     else if (MATCH("NAMEDARGEXPR", 12))
01292         return_value = _readNamedArgExpr();
01293     else if (MATCH("OPEXPR", 6))
01294         return_value = _readOpExpr();
01295     else if (MATCH("DISTINCTEXPR", 12))
01296         return_value = _readDistinctExpr();
01297     else if (MATCH("NULLIFEXPR", 10))
01298         return_value = _readNullIfExpr();
01299     else if (MATCH("SCALARARRAYOPEXPR", 17))
01300         return_value = _readScalarArrayOpExpr();
01301     else if (MATCH("BOOLEXPR", 8))
01302         return_value = _readBoolExpr();
01303     else if (MATCH("SUBLINK", 7))
01304         return_value = _readSubLink();
01305     else if (MATCH("FIELDSELECT", 11))
01306         return_value = _readFieldSelect();
01307     else if (MATCH("FIELDSTORE", 10))
01308         return_value = _readFieldStore();
01309     else if (MATCH("RELABELTYPE", 11))
01310         return_value = _readRelabelType();
01311     else if (MATCH("COERCEVIAIO", 11))
01312         return_value = _readCoerceViaIO();
01313     else if (MATCH("ARRAYCOERCEEXPR", 15))
01314         return_value = _readArrayCoerceExpr();
01315     else if (MATCH("CONVERTROWTYPEEXPR", 18))
01316         return_value = _readConvertRowtypeExpr();
01317     else if (MATCH("COLLATE", 7))
01318         return_value = _readCollateExpr();
01319     else if (MATCH("CASE", 4))
01320         return_value = _readCaseExpr();
01321     else if (MATCH("WHEN", 4))
01322         return_value = _readCaseWhen();
01323     else if (MATCH("CASETESTEXPR", 12))
01324         return_value = _readCaseTestExpr();
01325     else if (MATCH("ARRAY", 5))
01326         return_value = _readArrayExpr();
01327     else if (MATCH("ROW", 3))
01328         return_value = _readRowExpr();
01329     else if (MATCH("ROWCOMPARE", 10))
01330         return_value = _readRowCompareExpr();
01331     else if (MATCH("COALESCE", 8))
01332         return_value = _readCoalesceExpr();
01333     else if (MATCH("MINMAX", 6))
01334         return_value = _readMinMaxExpr();
01335     else if (MATCH("XMLEXPR", 7))
01336         return_value = _readXmlExpr();
01337     else if (MATCH("NULLTEST", 8))
01338         return_value = _readNullTest();
01339     else if (MATCH("BOOLEANTEST", 11))
01340         return_value = _readBooleanTest();
01341     else if (MATCH("COERCETODOMAIN", 14))
01342         return_value = _readCoerceToDomain();
01343     else if (MATCH("COERCETODOMAINVALUE", 19))
01344         return_value = _readCoerceToDomainValue();
01345     else if (MATCH("SETTODEFAULT", 12))
01346         return_value = _readSetToDefault();
01347     else if (MATCH("CURRENTOFEXPR", 13))
01348         return_value = _readCurrentOfExpr();
01349     else if (MATCH("TARGETENTRY", 11))
01350         return_value = _readTargetEntry();
01351     else if (MATCH("RANGETBLREF", 11))
01352         return_value = _readRangeTblRef();
01353     else if (MATCH("JOINEXPR", 8))
01354         return_value = _readJoinExpr();
01355     else if (MATCH("FROMEXPR", 8))
01356         return_value = _readFromExpr();
01357     else if (MATCH("RTE", 3))
01358         return_value = _readRangeTblEntry();
01359     else if (MATCH("NOTIFY", 6))
01360         return_value = _readNotifyStmt();
01361     else if (MATCH("DECLARECURSOR", 13))
01362         return_value = _readDeclareCursorStmt();
01363     else
01364     {
01365         elog(ERROR, "badly formatted node string \"%.32s\"...", token);
01366         return_value = NULL;    /* keep compiler quiet */
01367     }
01368 
01369     return (Node *) return_value;
01370 }
01371 
01372 
01373 /*
01374  * readDatum
01375  *
01376  * Given a string representation of a constant, recreate the appropriate
01377  * Datum.  The string representation embeds length info, but not byValue,
01378  * so we must be told that.
01379  */
01380 static Datum
01381 readDatum(bool typbyval)
01382 {
01383     Size        length,
01384                 i;
01385     int         tokenLength;
01386     char       *token;
01387     Datum       res;
01388     char       *s;
01389 
01390     /*
01391      * read the actual length of the value
01392      */
01393     token = pg_strtok(&tokenLength);
01394     length = atoui(token);
01395 
01396     token = pg_strtok(&tokenLength);    /* read the '[' */
01397     if (token == NULL || token[0] != '[')
01398         elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %lu",
01399              token ? (const char *) token : "[NULL]",
01400              (unsigned long) length);
01401 
01402     if (typbyval)
01403     {
01404         if (length > (Size) sizeof(Datum))
01405             elog(ERROR, "byval datum but length = %lu",
01406                  (unsigned long) length);
01407         res = (Datum) 0;
01408         s = (char *) (&res);
01409         for (i = 0; i < (Size) sizeof(Datum); i++)
01410         {
01411             token = pg_strtok(&tokenLength);
01412             s[i] = (char) atoi(token);
01413         }
01414     }
01415     else if (length <= 0)
01416         res = (Datum) NULL;
01417     else
01418     {
01419         s = (char *) palloc(length);
01420         for (i = 0; i < length; i++)
01421         {
01422             token = pg_strtok(&tokenLength);
01423             s[i] = (char) atoi(token);
01424         }
01425         res = PointerGetDatum(s);
01426     }
01427 
01428     token = pg_strtok(&tokenLength);    /* read the ']' */
01429     if (token == NULL || token[0] != ']')
01430         elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %lu",
01431              token ? (const char *) token : "[NULL]",
01432              (unsigned long) length);
01433 
01434     return res;
01435 }