📄 readfuncs.c
字号:
/*------------------------------------------------------------------------- * * readfuncs.c * Reader functions for Postgres tree nodes. * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.182 2005/10/15 02:49:19 momjian Exp $ * * NOTES * 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.) We * never read executor state trees, either. * *------------------------------------------------------------------------- */#include "postgres.h"#include <math.h>#include "nodes/parsenodes.h"#include "nodes/readfuncs.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. *//* Macros for declaring appropriate local variables *//* 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/* ... but most need both */#define READ_LOCALS(nodeTypeName) \ READ_LOCALS_NO_FIELDS(nodeTypeName); \ READ_TEMP_LOCALS()/* 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(NULL, 0)/* Routine exit */#define READ_DONE() \ return local_node/* * NOTE: use atoi() to read values written with %d, or atoui() to read * values written with %u in outfuncs.c. An exception is OID values, * for which use atooid(). (As of 7.1, outfuncs.c writes OIDs as %u, * but this will probably change in the future.) */#define atoui(x) ((unsigned int) strtoul((x), NULL, 10))#define atooid(x) ((Oid) strtoul((x), NULL, 10))#define strtobool(x) ((*(x) == 't') ? true : false)#define nullable_string(token,length) \ ((length) == 0 ? NULL : debackslash(token, length))static Datum readDatum(bool typbyval);/* * _readQuery */static Query *_readQuery(void){ READ_LOCALS(Query); READ_ENUM_FIELD(commandType, CmdType); READ_ENUM_FIELD(querySource, QuerySource); READ_BOOL_FIELD(canSetTag); READ_NODE_FIELD(utilityStmt); READ_INT_FIELD(resultRelation); READ_NODE_FIELD(into); READ_BOOL_FIELD(hasAggs); READ_BOOL_FIELD(hasSubLinks); READ_NODE_FIELD(rtable); READ_NODE_FIELD(jointree); READ_NODE_FIELD(rowMarks); READ_BOOL_FIELD(forUpdate); READ_BOOL_FIELD(rowNoWait); 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_NODE_FIELD(resultRelations); READ_DONE();}/* * _readNotifyStmt */static NotifyStmt *_readNotifyStmt(void){ READ_LOCALS(NotifyStmt); READ_NODE_FIELD(relation); READ_DONE();}/* * _readDeclareCursorStmt */static DeclareCursorStmt *_readDeclareCursorStmt(void){ READ_LOCALS(DeclareCursorStmt); READ_STRING_FIELD(portalname); READ_INT_FIELD(options); READ_NODE_FIELD(query); READ_DONE();}/* * _readSortClause */static SortClause *_readSortClause(void){ READ_LOCALS(SortClause); READ_UINT_FIELD(tleSortGroupRef); READ_OID_FIELD(sortop); READ_DONE();}/* * _readGroupClause */static GroupClause *_readGroupClause(void){ READ_LOCALS(GroupClause); READ_UINT_FIELD(tleSortGroupRef); READ_OID_FIELD(sortop); READ_DONE();}/* * _readSetOperationStmt */static SetOperationStmt *_readSetOperationStmt(void){ READ_LOCALS(SetOperationStmt); READ_ENUM_FIELD(op, SetOperation); READ_BOOL_FIELD(all); READ_NODE_FIELD(larg); READ_NODE_FIELD(rarg); READ_NODE_FIELD(colTypes); READ_DONE();}/* * Stuff from primnodes.h. */static Alias *_readAlias(void){ READ_LOCALS(Alias); READ_STRING_FIELD(aliasname); READ_NODE_FIELD(colnames); READ_DONE();}static RangeVar *_readRangeVar(void){ READ_LOCALS(RangeVar); local_node->catalogname = NULL; /* not currently saved in output * format */ READ_STRING_FIELD(schemaname); READ_STRING_FIELD(relname); READ_ENUM_FIELD(inhOpt, InhOption); READ_BOOL_FIELD(istemp); READ_NODE_FIELD(alias); READ_DONE();}/* * _readVar */static Var *_readVar(void){ READ_LOCALS(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); READ_DONE();}/* * _readConst */static Const *_readConst(void){ READ_LOCALS(Const); READ_OID_FIELD(consttype); READ_INT_FIELD(constlen); READ_BOOL_FIELD(constbyval); READ_BOOL_FIELD(constisnull); token = pg_strtok(&length); /* skip :constvalue */ if (local_node->constisnull) token = pg_strtok(&length); /* skip "<>" */ else local_node->constvalue = readDatum(local_node->constbyval); READ_DONE();}/* * _readParam */static Param *_readParam(void){ READ_LOCALS(Param); READ_INT_FIELD(paramkind); READ_INT_FIELD(paramid); READ_STRING_FIELD(paramname); READ_OID_FIELD(paramtype); READ_DONE();}/* * _readAggref */static Aggref *_readAggref(void){ READ_LOCALS(Aggref); READ_OID_FIELD(aggfnoid); READ_OID_FIELD(aggtype); READ_NODE_FIELD(target); READ_UINT_FIELD(agglevelsup); READ_BOOL_FIELD(aggstar); READ_BOOL_FIELD(aggdistinct); READ_DONE();}/* * _readArrayRef */static ArrayRef *_readArrayRef(void){ READ_LOCALS(ArrayRef); READ_OID_FIELD(refrestype); READ_OID_FIELD(refarraytype); READ_OID_FIELD(refelemtype); READ_NODE_FIELD(refupperindexpr); READ_NODE_FIELD(reflowerindexpr); READ_NODE_FIELD(refexpr); READ_NODE_FIELD(refassgnexpr); READ_DONE();}/* * _readFuncExpr */static FuncExpr *_readFuncExpr(void){ READ_LOCALS(FuncExpr); READ_OID_FIELD(funcid); READ_OID_FIELD(funcresulttype); READ_BOOL_FIELD(funcretset); READ_ENUM_FIELD(funcformat, CoercionForm); READ_NODE_FIELD(args); READ_DONE();}/* * _readOpExpr */static OpExpr *_readOpExpr(void){ READ_LOCALS(OpExpr); READ_OID_FIELD(opno); READ_OID_FIELD(opfuncid); /* * The opfuncid is stored in the textual format primarily for debugging * and documentation reasons. We want to always read it as zero to force * it to be re-looked-up in the pg_operator entry. This ensures that * stored rules don't have hidden dependencies on operators' functions. * (We don't currently support an ALTER OPERATOR command, but might * someday.) */ local_node->opfuncid = InvalidOid; READ_OID_FIELD(opresulttype); READ_BOOL_FIELD(opretset); READ_NODE_FIELD(args); READ_DONE();}/* * _readDistinctExpr */static DistinctExpr *_readDistinctExpr(void){ READ_LOCALS(DistinctExpr); READ_OID_FIELD(opno); READ_OID_FIELD(opfuncid); /* * The opfuncid is stored in the textual format primarily for debugging * and documentation reasons. We want to always read it as zero to force * it to be re-looked-up in the pg_operator entry. This ensures that * stored rules don't have hidden dependencies on operators' functions. * (We don't currently support an ALTER OPERATOR command, but might * someday.) */ local_node->opfuncid = InvalidOid; READ_OID_FIELD(opresulttype); READ_BOOL_FIELD(opretset); READ_NODE_FIELD(args); READ_DONE();}/* * _readScalarArrayOpExpr */static ScalarArrayOpExpr *_readScalarArrayOpExpr(void){ READ_LOCALS(ScalarArrayOpExpr); READ_OID_FIELD(opno); READ_OID_FIELD(opfuncid); /* * The opfuncid is stored in the textual format primarily for debugging * and documentation reasons. We want to always read it as zero to force * it to be re-looked-up in the pg_operator entry. This ensures that * stored rules don't have hidden dependencies on operators' functions. * (We don't currently support an ALTER OPERATOR command, but might * someday.) */ local_node->opfuncid = InvalidOid; READ_BOOL_FIELD(useOr); READ_NODE_FIELD(args); READ_DONE();}/* * _readBoolExpr */static BoolExpr *_readBoolExpr(void){ READ_LOCALS(BoolExpr); /* do-it-yourself enum representation */ token = pg_strtok(&length); /* skip :boolop */ token = pg_strtok(&length); /* get field value */ if (strncmp(token, "and", 3) == 0) local_node->boolop = AND_EXPR; else if (strncmp(token, "or", 2) == 0) local_node->boolop = OR_EXPR; else if (strncmp(token, "not", 3) == 0) local_node->boolop = NOT_EXPR; else elog(ERROR, "unrecognized boolop \"%.*s\"", length, token); READ_NODE_FIELD(args); READ_DONE();}/* * _readSubLink */static SubLink *_readSubLink(void){ READ_LOCALS(SubLink); READ_ENUM_FIELD(subLinkType, SubLinkType); READ_BOOL_FIELD(useOr); READ_NODE_FIELD(lefthand); READ_NODE_FIELD(operName); READ_NODE_FIELD(operOids); READ_NODE_FIELD(subselect); READ_DONE();}/* * _readSubPlan is not needed since it doesn't appear in stored rules. *//* * _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();}/* * _readFieldStore */static FieldStore *_readFieldStore(void){ READ_LOCALS(FieldStore); READ_NODE_FIELD(arg); READ_NODE_FIELD(newvals); READ_NODE_FIELD(fieldnums); READ_OID_FIELD(resulttype); 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -