📄 outfuncs.c
字号:
/*------------------------------------------------------------------------- * * outfuncs.c * Output 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/outfuncs.c,v 1.261.2.1 2005/11/14 23:54:34 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 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 == '\"' || 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++); }}static void_outList(StringInfo str, List *node){ ListCell *lc; appendStringInfoChar(str, '('); if (IsA(node, IntList)) appendStringInfoChar(str, 'i'); else if (IsA(node, OidList)) appendStringInfoChar(str, 'o'); foreach(lc, node) { /* * For the sake of backward compatibility, we emit a slightly * different whitespace format for lists of nodes vs. other types of * lists. XXX: is this necessary? */ if (IsA(node, List)) { _outNode(str, lfirst(lc)); if (lnext(lc)) appendStringInfoChar(str, ' '); } else if (IsA(node, IntList)) appendStringInfo(str, " %d", lfirst_int(lc)); else if (IsA(node, OidList)) appendStringInfo(str, " %u", lfirst_oid(lc)); else elog(ERROR, "unrecognized list node type: %d", (int) node->type); } appendStringInfoChar(str, ')');}/* * _outBitmapset - * converts a bitmap set of integers * * Note: the output format is "(b int int ...)", similar to an integer List. * Currently bitmapsets do not appear in any node type that is stored in * rules, so there is no support in readfuncs.c for reading this format. */static void_outBitmapset(StringInfo str, Bitmapset *bms){ Bitmapset *tmpset; int x; appendStringInfoChar(str, '('); appendStringInfoChar(str, 'b'); 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_outBitmapAnd(StringInfo str, BitmapAnd *node){ WRITE_NODE_TYPE("BITMAPAND"); _outPlanInfo(str, (Plan *) node); WRITE_NODE_FIELD(bitmapplans);}static void_outBitmapOr(StringInfo str, BitmapOr *node){ WRITE_NODE_TYPE("BITMAPOR"); _outPlanInfo(str, (Plan *) node); WRITE_NODE_FIELD(bitmapplans);}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_OID_FIELD(indexid); WRITE_NODE_FIELD(indexqual); WRITE_NODE_FIELD(indexqualorig); WRITE_NODE_FIELD(indexstrategy); WRITE_NODE_FIELD(indexsubtype); WRITE_ENUM_FIELD(indexorderdir, ScanDirection);}static void_outBitmapIndexScan(StringInfo str, BitmapIndexScan *node){ WRITE_NODE_TYPE("BITMAPINDEXSCAN"); _outScanInfo(str, (Scan *) node); WRITE_OID_FIELD(indexid); WRITE_NODE_FIELD(indexqual); WRITE_NODE_FIELD(indexqualorig); WRITE_NODE_FIELD(indexstrategy); WRITE_NODE_FIELD(indexsubtype);}static void_outBitmapHeapScan(StringInfo str, BitmapHeapScan *node){ WRITE_NODE_TYPE("BITMAPHEAPSCAN"); _outScanInfo(str, (Scan *) node); WRITE_NODE_FIELD(bitmapqualorig);}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);}/***************************************************************************** * * Stuff from primnodes.h. * *****************************************************************************/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);}static void_outArrayRef(StringInfo str, ArrayRef *node){ WRITE_NODE_TYPE("ARRAYREF"); WRITE_OID_FIELD(refrestype); WRITE_OID_FIELD(refarraytype); WRITE_OID_FIELD(refelemtype); WRITE_NODE_FIELD(refupperindexpr); WRITE_NODE_FIELD(reflowerindexpr); WRITE_NODE_FIELD(refexpr); WRITE_NODE_FIELD(refassgnexpr);}static void_outFuncExpr(StringInfo str, FuncExpr *node){ WRITE_NODE_TYPE("FUNCEXPR"); WRITE_OID_FIELD(funcid); WRITE_OID_FIELD(funcresulttype); WRITE_BOOL_FIELD(funcretset); WRITE_ENUM_FIELD(funcformat, CoercionForm); WRITE_NODE_FIELD(args);}static void_outOpExpr(StringInfo str, OpExpr *node){ WRITE_NODE_TYPE("OPEXPR"); WRITE_OID_FIELD(opno); WRITE_OID_FIELD(opfuncid); WRITE_OID_FIELD(opresulttype); WRITE_BOOL_FIELD(opretset); WRITE_NODE_FIELD(args);}static void_outDistinctExpr(StringInfo str, DistinctExpr *node){ WRITE_NODE_TYPE("DISTINCTEXPR"); WRITE_OID_FIELD(opno); WRITE_OID_FIELD(opfuncid); WRITE_OID_FIELD(opresulttype); WRITE_BOOL_FIELD(opretset); WRITE_NODE_FIELD(args);}static void_outScalarArrayOpExpr(StringInfo str, ScalarArrayOpExpr *node){ WRITE_NODE_TYPE("SCALARARRAYOPEXPR"); WRITE_OID_FIELD(opno); WRITE_OID_FIELD(opfuncid); WRITE_BOOL_FIELD(useOr); WRITE_NODE_FIELD(args);}static void_outBoolExpr(StringInfo str, BoolExpr *node){ char *opstr = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -