📄 outfuncs.c
字号:
/* * * outfuncs.c * routines to convert a node to ascii representation * * Copyright (c) 1994, Regents of the University of California * * $Id: outfuncs.c,v 1.86 1999/05/25 22:41:14 momjian 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. indexes). This is also the plan string sent out in * Mariposa. * * These functions update the in/out argument of type StringInfo * passed to them. This argument contains the string holding the ASCII * representation plus some other information (string length, etc.) * */#include <stdio.h>#include "postgres.h"#include "access/heapam.h"#include "access/htup.h"#include "utils/syscache.h"#include "utils/lsyscache.h"#include "fmgr.h"#include "utils/elog.h"#include "utils/datum.h"#include "utils/palloc.h"#include "nodes/nodes.h"#include "nodes/execnodes.h"#include "nodes/pg_list.h"#include "nodes/plannodes.h"#include "nodes/parsenodes.h"#include "nodes/primnodes.h"#include "nodes/relation.h"#include "catalog/pg_type.h"#include "lib/stringinfo.h"#include "../parse.h"static void _outDatum(StringInfo str, Datum value, Oid type);static void _outNode(StringInfo str, void *obj);/* * _outIntList - * converts a List of integers */static void_outIntList(StringInfo str, List *list){ List *l; appendStringInfo(str, "("); foreach(l, list) appendStringInfo(str, " %d ", lfirsti(l)); appendStringInfo(str, ")");}static void_outCreateStmt(StringInfo str, CreateStmt *node){ appendStringInfo(str, " CREATE :relname %s ", stringStringInfo(node->relname)); appendStringInfo(str, " :istemp %s ", node->istemp ? "true" : "false"); appendStringInfo(str, " :columns "); _outNode(str, node->tableElts); appendStringInfo(str, " :inhRelnames "); _outNode(str, node->inhRelnames); appendStringInfo(str, " :constraints "); _outNode(str, node->constraints);}static void_outIndexStmt(StringInfo str, IndexStmt *node){ appendStringInfo(str, " INDEX :idxname %s :relname %s :accessMethod %s :indexParams ", stringStringInfo(node->idxname), stringStringInfo(node->relname), stringStringInfo(node->accessMethod)); _outNode(str, node->indexParams); appendStringInfo(str, " :withClause "); _outNode(str, node->withClause); appendStringInfo(str, " :whereClause "); _outNode(str, node->whereClause); appendStringInfo(str, " :rangetable "); _outNode(str, node->rangetable); appendStringInfo(str, " :lossy %s :unique %s ", node->lossy ? "true" : "false", node->unique ? "true" : "false");}static void_outSelectStmt(StringInfo str, SelectStmt *node){ appendStringInfo(str, "SELECT :where "); _outNode(str, node->whereClause);}static void_outFuncCall(StringInfo str, FuncCall *node){ appendStringInfo(str, "FUNCTION %s :args ", stringStringInfo(node->funcname)); _outNode(str, node->args);}static void_outColumnDef(StringInfo str, ColumnDef *node){ appendStringInfo(str, " COLUMNDEF :colname %s :typename ", stringStringInfo(node->colname)); _outNode(str, node->typename); appendStringInfo(str, " :is_not_null %s :defval %s :constraints ", node->is_not_null ? "true" : "false", stringStringInfo(node->defval)); _outNode(str, node->constraints);}static void_outTypeName(StringInfo str, TypeName *node){ appendStringInfo(str, " TYPENAME :name %s :timezone %s :setof %s typmod %d :arrayBounds ", stringStringInfo(node->name), node->timezone ? "true" : "false", node->setof ? "true" : "false", node->typmod); appendStringInfo(str, " :arrayBounds "); _outNode(str, node->arrayBounds);}static void_outIndexElem(StringInfo str, IndexElem *node){ appendStringInfo(str, " INDEXELEM :name %s :args ", stringStringInfo(node->name)); _outNode(str, node->args); appendStringInfo(str, " :class %s :typename ", stringStringInfo(node->class)); _outNode(str, node->typename);}static void_outQuery(StringInfo str, Query *node){ appendStringInfo(str, " QUERY :command %d ", node->commandType); if (node->utilityStmt) { switch (nodeTag(node->utilityStmt)) { case T_CreateStmt: appendStringInfo(str, " :create %s ", stringStringInfo(((CreateStmt *) (node->utilityStmt))->relname)); _outNode(str, node->utilityStmt); break; case T_IndexStmt: appendStringInfo(str, " :index %s on %s ", stringStringInfo(((IndexStmt *) (node->utilityStmt))->idxname), stringStringInfo(((IndexStmt *) (node->utilityStmt))->relname)); _outNode(str, node->utilityStmt); break; case T_NotifyStmt: appendStringInfo(str, " :utility %s ", stringStringInfo(((NotifyStmt *) (node->utilityStmt))->relname)); break; default: appendStringInfo(str, " :utility ? "); } } else appendStringInfo(str, " :utility <>"); appendStringInfo(str, " :resultRelation %u :into %s :isPortal %s :isBinary %s :isTemp %s :unionall %s ", node->resultRelation, stringStringInfo(node->into), node->isPortal ? "true" : "false", node->isBinary ? "true" : "false", node->isTemp ? "true" : "false", node->unionall ? "true" : "false"); appendStringInfo(str, " :unique %s :sortClause ", stringStringInfo(node->uniqueFlag)); _outNode(str, node->sortClause); appendStringInfo(str, " :rtable "); _outNode(str, node->rtable); appendStringInfo(str, " :targetlist "); _outNode(str, node->targetList); appendStringInfo(str, " :qual "); _outNode(str, node->qual); appendStringInfo(str, " :groupClause "); _outNode(str, node->groupClause); appendStringInfo(str, " :havingQual "); _outNode(str, node->havingQual); appendStringInfo(str, " :hasAggs %s :hasSubLinks %s :unionClause ", node->hasAggs ? "true" : "false", node->hasSubLinks ? "true" : "false"); _outNode(str, node->unionClause); appendStringInfo(str, " :intersectClause "); _outNode(str, node->intersectClause); appendStringInfo(str, " :limitOffset "); _outNode(str, node->limitOffset); appendStringInfo(str, " :limitCount "); _outNode(str, node->limitCount); appendStringInfo(str, " :rowMark "); _outNode(str, node->rowMark);}static void_outSortClause(StringInfo str, SortClause *node){ appendStringInfo(str, " SORTCLAUSE :resdom "); _outNode(str, node->resdom); appendStringInfo(str, " :opoid %u ", node->opoid);}static void_outGroupClause(StringInfo str, GroupClause *node){ appendStringInfo(str, " GROUPCLAUSE :grpOpoid %u :tleGroupref %d", node->grpOpoid, node->tleGroupref);}/* * print the basic stuff of all nodes that inherit from Plan */static void_outPlanInfo(StringInfo str, Plan *node){ appendStringInfo(str, ":cost %g :size %d :width %d :state %s :qptargetlist ", node->cost, node->plan_size, node->plan_width, node->state ? "not-NULL" : "<>"); _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);}/* * Stuff from plannodes.h */static void_outPlan(StringInfo str, Plan *node){ appendStringInfo(str, " PLAN "); _outPlanInfo(str, (Plan *) node);}static void_outResult(StringInfo str, Result *node){ appendStringInfo(str, " RESULT "); _outPlanInfo(str, (Plan *) node); appendStringInfo(str, " :resconstantqual "); _outNode(str, node->resconstantqual);}/* * Append is a subclass of Plan. */static void_outAppend(StringInfo str, Append *node){ appendStringInfo(str, " APPEND "); _outPlanInfo(str, (Plan *) node); appendStringInfo(str, " :appendplans "); _outNode(str, node->appendplans); appendStringInfo(str, " :unionrtables "); _outNode(str, node->unionrtables); appendStringInfo(str, " :inheritrelid %u :inheritrtable ", node->inheritrelid); _outNode(str, node->inheritrtable);}/* * Join is a subclass of Plan */static void_outJoin(StringInfo str, Join *node){ appendStringInfo(str, " JOIN "); _outPlanInfo(str, (Plan *) node);}/* * NestLoop is a subclass of Join */static void_outNestLoop(StringInfo str, NestLoop *node){ appendStringInfo(str, " NESTLOOP "); _outPlanInfo(str, (Plan *) node);}/* * MergeJoin is a subclass of Join */static void_outMergeJoin(StringInfo str, MergeJoin *node){ appendStringInfo(str, " MERGEJOIN "); _outPlanInfo(str, (Plan *) node); 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, " :hashclauses "); _outNode(str, node->hashclauses); appendStringInfo(str, " :hashjoinop %u ", node->hashjoinop); appendStringInfo(str, " :hashdone %d ", node->hashdone);}static void_outSubPlan(StringInfo str, SubPlan *node){ appendStringInfo(str, " SUBPLAN :plan "); _outNode(str, node->plan); appendStringInfo(str, " :planid %u :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); appendStringInfo(str, " :scanrelid %u ", node->scanrelid);}/* * SeqScan is a subclass of Scan */static void_outSeqScan(StringInfo str, SeqScan *node){ appendStringInfo(str, " SEQSCAN "); _outPlanInfo(str, (Plan *) node); appendStringInfo(str, " :scanrelid %u ", node->scanrelid);}/* * IndexScan is a subclass of Scan */static void_outIndexScan(StringInfo str, IndexScan *node){ appendStringInfo(str, " INDEXSCAN "); _outPlanInfo(str, (Plan *) node); appendStringInfo(str, " :scanrelid %u :indxid ", node->scan.scanrelid); _outIntList(str, node->indxid); appendStringInfo(str, " :indxqual "); _outNode(str, node->indxqual); appendStringInfo(str, " :indxqualorig "); _outNode(str, node->indxqualorig);}/* * Noname is a subclass of Plan */static void_outNoname(StringInfo str, Noname *node){ appendStringInfo(str, " NONAME "); _outPlanInfo(str, (Plan *) node); appendStringInfo(str, " :nonameid %u :keycount %d ", node->nonameid, node->keycount);}/* * Sort is a subclass of Noname */static void_outSort(StringInfo str, Sort *node){ appendStringInfo(str, " SORT "); _outPlanInfo(str, (Plan *) node); appendStringInfo(str, " :nonameid %u :keycount %d ", node->nonameid, node->keycount);}static void_outAgg(StringInfo str, Agg *node){ appendStringInfo(str, " AGG "); _outPlanInfo(str, (Plan *) node); appendStringInfo(str, " :aggs "); _outNode(str, node->aggs);}static void_outGroup(StringInfo str, Group *node){ appendStringInfo(str, " GRP "); _outPlanInfo(str, (Plan *) node); /* the actual Group fields */ appendStringInfo(str, " :numCols %d :tuplePerGroup %s ", node->numCols, node->tuplePerGroup ? "true" : "false");}/* * For some reason, unique is a subclass of Noname. */static void_outUnique(StringInfo str, Unique *node){ appendStringInfo(str, " UNIQUE "); _outPlanInfo(str, (Plan *) node); appendStringInfo(str, " :nonameid %u :keycount %d ", node->nonameid, node->keycount);}/* * Hash is a subclass of Noname */static void_outHash(StringInfo str, Hash *node){ appendStringInfo(str, " HASH "); _outPlanInfo(str, (Plan *) node); appendStringInfo(str, " :hashkey "); _outNode(str, node->hashkey);}/***************************************************************************** * * Stuff from primnodes.h. * *****************************************************************************//* * Resdom is a subclass of Node */static void_outResdom(StringInfo str, Resdom *node){ appendStringInfo(str, " RESDOM :resno %d :restype %u :restypmod %d", node->resno, node->restype, node->restypmod); appendStringInfo(str, " :resname \"%s\" :reskey %d :reskeyop %u", stringStringInfo(node->resname),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -