📄 outfuncs.c
字号:
/*------------------------------------------------------------------------- * * outfuncs.c * Output functions for Postgres tree nodes. * * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.218 2003/08/17 23:43:26 tgl Exp $ * * NOTES * 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, path, and plan trees. * These nodes however need not have input functions. * *------------------------------------------------------------------------- */#include "postgres.h"#include <ctype.h>#include "lib/stringinfo.h"#include "nodes/parsenodes.h"#include "nodes/plannodes.h"#include "nodes/relation.h"#include "utils/datum.h"/* * Macros to simplify output of different kinds of fields. Use these * wherever possible to reduce the chance for silly typos. Note that these * hard-wire conventions about the names of the local variables in an Out * routine. *//* Write the label for the node type */#define WRITE_NODE_TYPE(nodelabel) \ appendStringInfoString(str, nodelabel)/* Write an integer field (anything written as ":fldname %d") */#define WRITE_INT_FIELD(fldname) \ appendStringInfo(str, " :" CppAsString(fldname) " %d", node->fldname)/* Write an unsigned integer field (anything written as ":fldname %u") */#define WRITE_UINT_FIELD(fldname) \ appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname)/* Write an OID field (don't hard-wire assumption that OID is same as uint) */#define WRITE_OID_FIELD(fldname) \ appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname)/* Write a long-integer field */#define WRITE_LONG_FIELD(fldname) \ appendStringInfo(str, " :" CppAsString(fldname) " %ld", node->fldname)/* Write a char field (ie, one ascii character) */#define WRITE_CHAR_FIELD(fldname) \ appendStringInfo(str, " :" CppAsString(fldname) " %c", node->fldname)/* Write an enumerated-type field as an integer code */#define WRITE_ENUM_FIELD(fldname, enumtype) \ appendStringInfo(str, " :" CppAsString(fldname) " %d", \ (int) node->fldname)/* Write a float field --- caller must give format to define precision */#define WRITE_FLOAT_FIELD(fldname,format) \ appendStringInfo(str, " :" CppAsString(fldname) " " format, node->fldname)/* Write a boolean field */#define WRITE_BOOL_FIELD(fldname) \ appendStringInfo(str, " :" CppAsString(fldname) " %s", \ booltostr(node->fldname))/* Write a character-string (possibly NULL) field */#define WRITE_STRING_FIELD(fldname) \ (appendStringInfo(str, " :" CppAsString(fldname) " "), \ _outToken(str, node->fldname))/* Write a 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))/* Write a bitmapset field */#define WRITE_BITMAPSET_FIELD(fldname) \ (appendStringInfo(str, " :" CppAsString(fldname) " "), \ _outBitmapset(str, node->fldname))#define booltostr(x) ((x) ? "true" : "false")static void _outNode(StringInfo str, void *obj);/* * _outToken * Convert an ordinary string (eg, an identifier) into a form that * will be decoded back to a plain token by read.c's functions. * * If a null or empty string is given, it is encoded as "<>". */static void_outToken(StringInfo str, char *s){ if (s == NULL || *s == '\0') { appendStringInfo(str, "<>"); return; } /* * Look for characters or patterns that are treated specially by * read.c (either in pg_strtok() or in nodeRead()), and therefore need * a protective backslash. */ /* These characters only need to be quoted at the start of the string */ if (*s == '<' || *s == '\"' || *s == '@' || isdigit((unsigned char) *s) || ((*s == '+' || *s == '-') && (isdigit((unsigned char) s[1]) || s[1] == '.'))) appendStringInfoChar(str, '\\'); while (*s) { /* These chars must be backslashed anywhere in the string */ if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '(' || *s == ')' || *s == '{' || *s == '}' || *s == '\\') appendStringInfoChar(str, '\\'); appendStringInfoChar(str, *s++); }}/* * _outIntList - * converts a List of integers */static void_outIntList(StringInfo str, List *list){ List *l; appendStringInfoChar(str, '('); foreach(l, list) appendStringInfo(str, " %d", lfirsti(l)); appendStringInfoChar(str, ')');}/* * _outOidList - * converts a List of OIDs */static void_outOidList(StringInfo str, List *list){ List *l; appendStringInfoChar(str, '('); foreach(l, list) appendStringInfo(str, " %u", lfirsto(l)); appendStringInfoChar(str, ')');}/* * _outBitmapset - * converts a bitmap set of integers * * Note: for historical reasons, the output is formatted exactly like * an integer List would be. */static void_outBitmapset(StringInfo str, Bitmapset *bms){ Bitmapset *tmpset; int x; appendStringInfoChar(str, '('); tmpset = bms_copy(bms); while ((x = bms_first_member(tmpset)) >= 0) appendStringInfo(str, " %d", x); bms_free(tmpset); appendStringInfoChar(str, ')');}/* * Print the value of a Datum given its type. */static void_outDatum(StringInfo str, Datum value, int typlen, bool typbyval){ Size length, i; char *s; length = datumGetSize(value, typbyval, typlen); if (typbyval) { s = (char *) (&value); appendStringInfo(str, "%u [ ", (unsigned int) length); for (i = 0; i < (Size) sizeof(Datum); i++) appendStringInfo(str, "%d ", (int) (s[i])); appendStringInfo(str, "]"); } else { s = (char *) DatumGetPointer(value); if (!PointerIsValid(s)) appendStringInfo(str, "0 [ ]"); else { appendStringInfo(str, "%u [ ", (unsigned int) length); for (i = 0; i < length; i++) appendStringInfo(str, "%d ", (int) (s[i])); appendStringInfo(str, "]"); } }}/* * Stuff from plannodes.h *//* * print the basic stuff of all nodes that inherit from Plan */static void_outPlanInfo(StringInfo str, Plan *node){ WRITE_FLOAT_FIELD(startup_cost, "%.2f"); WRITE_FLOAT_FIELD(total_cost, "%.2f"); WRITE_FLOAT_FIELD(plan_rows, "%.0f"); WRITE_INT_FIELD(plan_width); WRITE_NODE_FIELD(targetlist); WRITE_NODE_FIELD(qual); WRITE_NODE_FIELD(lefttree); WRITE_NODE_FIELD(righttree); WRITE_NODE_FIELD(initPlan); WRITE_BITMAPSET_FIELD(extParam); WRITE_BITMAPSET_FIELD(allParam); WRITE_INT_FIELD(nParamExec);}/* * print the basic stuff of all nodes that inherit from Scan */static void_outScanInfo(StringInfo str, Scan *node){ _outPlanInfo(str, (Plan *) node); WRITE_UINT_FIELD(scanrelid);}/* * print the basic stuff of all nodes that inherit from Join */static void_outJoinPlanInfo(StringInfo str, Join *node){ _outPlanInfo(str, (Plan *) node); WRITE_ENUM_FIELD(jointype, JoinType); WRITE_NODE_FIELD(joinqual);}static void_outPlan(StringInfo str, Plan *node){ WRITE_NODE_TYPE("PLAN"); _outPlanInfo(str, (Plan *) node);}static void_outResult(StringInfo str, Result *node){ WRITE_NODE_TYPE("RESULT"); _outPlanInfo(str, (Plan *) node); WRITE_NODE_FIELD(resconstantqual);}static void_outAppend(StringInfo str, Append *node){ WRITE_NODE_TYPE("APPEND"); _outPlanInfo(str, (Plan *) node); WRITE_NODE_FIELD(appendplans); WRITE_BOOL_FIELD(isTarget);}static void_outScan(StringInfo str, Scan *node){ WRITE_NODE_TYPE("SCAN"); _outScanInfo(str, (Scan *) node);}static void_outSeqScan(StringInfo str, SeqScan *node){ WRITE_NODE_TYPE("SEQSCAN"); _outScanInfo(str, (Scan *) node);}static void_outIndexScan(StringInfo str, IndexScan *node){ WRITE_NODE_TYPE("INDEXSCAN"); _outScanInfo(str, (Scan *) node); WRITE_OIDLIST_FIELD(indxid); WRITE_NODE_FIELD(indxqual); WRITE_NODE_FIELD(indxqualorig); WRITE_ENUM_FIELD(indxorderdir, ScanDirection);}static void_outTidScan(StringInfo str, TidScan *node){ WRITE_NODE_TYPE("TIDSCAN"); _outScanInfo(str, (Scan *) node); WRITE_NODE_FIELD(tideval);}static void_outSubqueryScan(StringInfo str, SubqueryScan *node){ WRITE_NODE_TYPE("SUBQUERYSCAN"); _outScanInfo(str, (Scan *) node); WRITE_NODE_FIELD(subplan);}static void_outFunctionScan(StringInfo str, FunctionScan *node){ WRITE_NODE_TYPE("FUNCTIONSCAN"); _outScanInfo(str, (Scan *) node);}static void_outJoin(StringInfo str, Join *node){ WRITE_NODE_TYPE("JOIN"); _outJoinPlanInfo(str, (Join *) node);}static void_outNestLoop(StringInfo str, NestLoop *node){ WRITE_NODE_TYPE("NESTLOOP"); _outJoinPlanInfo(str, (Join *) node);}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);}static void_outAgg(StringInfo str, Agg *node){ WRITE_NODE_TYPE("AGG"); _outPlanInfo(str, (Plan *) node); WRITE_ENUM_FIELD(aggstrategy, AggStrategy); WRITE_INT_FIELD(numCols); WRITE_LONG_FIELD(numGroups);}static void_outGroup(StringInfo str, Group *node){ int i; WRITE_NODE_TYPE("GROUP"); _outPlanInfo(str, (Plan *) node); WRITE_INT_FIELD(numCols); appendStringInfo(str, " :grpColIdx"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %d", node->grpColIdx[i]);}static void_outMaterial(StringInfo str, Material *node){ WRITE_NODE_TYPE("MATERIAL"); _outPlanInfo(str, (Plan *) node);}static void_outSort(StringInfo str, Sort *node){ int i; WRITE_NODE_TYPE("SORT"); _outPlanInfo(str, (Plan *) node); WRITE_INT_FIELD(numCols); appendStringInfo(str, " :sortColIdx"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %d", node->sortColIdx[i]); appendStringInfo(str, " :sortOperators"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %u", node->sortOperators[i]);}static void_outUnique(StringInfo str, Unique *node){ int i; WRITE_NODE_TYPE("UNIQUE"); _outPlanInfo(str, (Plan *) node); WRITE_INT_FIELD(numCols); appendStringInfo(str, " :uniqColIdx"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %d", node->uniqColIdx[i]);}static void_outSetOp(StringInfo str, SetOp *node){ int i; WRITE_NODE_TYPE("SETOP"); _outPlanInfo(str, (Plan *) node); WRITE_ENUM_FIELD(cmd, SetOpCmd); WRITE_INT_FIELD(numCols); appendStringInfo(str, " :dupColIdx"); for (i = 0; i < node->numCols; i++) appendStringInfo(str, " %d", node->dupColIdx[i]); WRITE_INT_FIELD(flagColIdx);}static void_outLimit(StringInfo str, Limit *node){ WRITE_NODE_TYPE("LIMIT"); _outPlanInfo(str, (Plan *) node); WRITE_NODE_FIELD(limitOffset); WRITE_NODE_FIELD(limitCount);}static void_outHash(StringInfo str, Hash *node){ WRITE_NODE_TYPE("HASH"); _outPlanInfo(str, (Plan *) node); WRITE_NODE_FIELD(hashkeys);}/***************************************************************************** * * Stuff from primnodes.h. * *****************************************************************************/static void_outResdom(StringInfo str, Resdom *node){ 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_OID_FIELD(resorigtbl); WRITE_INT_FIELD(resorigcol); WRITE_BOOL_FIELD(resjunk);}static void_outAlias(StringInfo str, Alias *node){ WRITE_NODE_TYPE("ALIAS"); WRITE_STRING_FIELD(aliasname); WRITE_NODE_FIELD(colnames);}static void_outRangeVar(StringInfo str, RangeVar *node){ WRITE_NODE_TYPE("RANGEVAR"); /* * we deliberately ignore catalogname here, since it is presently not * semantically meaningful */ WRITE_STRING_FIELD(schemaname); WRITE_STRING_FIELD(relname); WRITE_ENUM_FIELD(inhOpt, InhOption); WRITE_BOOL_FIELD(istemp); WRITE_NODE_FIELD(alias);}static void_outVar(StringInfo str, Var *node){ WRITE_NODE_TYPE("VAR"); WRITE_UINT_FIELD(varno); WRITE_INT_FIELD(varattno); WRITE_OID_FIELD(vartype); WRITE_INT_FIELD(vartypmod); WRITE_UINT_FIELD(varlevelsup); WRITE_UINT_FIELD(varnoold); WRITE_INT_FIELD(varoattno);}static void_outConst(StringInfo str, Const *node){ WRITE_NODE_TYPE("CONST"); WRITE_OID_FIELD(consttype); WRITE_INT_FIELD(constlen); WRITE_BOOL_FIELD(constbyval); WRITE_BOOL_FIELD(constisnull); appendStringInfo(str, " :constvalue "); if (node->constisnull) appendStringInfo(str, "<>"); else _outDatum(str, node->constvalue, node->constlen, node->constbyval);}static void_outParam(StringInfo str, Param *node){ WRITE_NODE_TYPE("PARAM"); WRITE_INT_FIELD(paramkind); WRITE_INT_FIELD(paramid); WRITE_STRING_FIELD(paramname); WRITE_OID_FIELD(paramtype);}static void_outAggref(StringInfo str, Aggref *node){ WRITE_NODE_TYPE("AGGREF"); WRITE_OID_FIELD(aggfnoid); WRITE_OID_FIELD(aggtype); WRITE_NODE_FIELD(target); WRITE_UINT_FIELD(agglevelsup); WRITE_BOOL_FIELD(aggstar); WRITE_BOOL_FIELD(aggdistinct);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -