📄 copyfuncs.c
字号:
/*------------------------------------------------------------------------- * * copyfuncs.c * Copy functions for Postgres tree nodes. * * NOTE: we currently support copying all node types found in parse and * plan trees. We do not support copying executor state trees; there * is no need for that, and no point in maintaining all the code that * would be needed. We also do not support copying Path trees, mainly * because the circular linkages between RelOptInfo and Path nodes can't * be handled easily in a simple depth-first traversal. * * * 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/copyfuncs.c,v 1.265 2003/08/17 23:43:25 tgl Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "nodes/parsenodes.h"#include "nodes/plannodes.h"#include "nodes/relation.h"#include "utils/datum.h"/* * Macros to simplify copying of different kinds of fields. Use these * wherever possible to reduce the chance for silly typos. Note that these * hard-wire the convention that the local variables in a Copy routine are * named 'newnode' and 'from'. *//* Copy a simple scalar field (int, float, bool, enum, etc) */#define COPY_SCALAR_FIELD(fldname) \ (newnode->fldname = from->fldname)/* Copy a field that is a pointer to some kind of Node or Node tree */#define COPY_NODE_FIELD(fldname) \ (newnode->fldname = copyObject(from->fldname))/* Copy a field that is a pointer to a list of integers */#define COPY_INTLIST_FIELD(fldname) \ (newnode->fldname = listCopy(from->fldname))/* Copy a field that is a pointer to a list of Oids */#define COPY_OIDLIST_FIELD(fldname) \ (newnode->fldname = listCopy(from->fldname))/* Copy a field that is a pointer to a Bitmapset */#define COPY_BITMAPSET_FIELD(fldname) \ (newnode->fldname = bms_copy(from->fldname))/* Copy a field that is a pointer to a C string, or perhaps NULL */#define COPY_STRING_FIELD(fldname) \ (newnode->fldname = from->fldname ? pstrdup(from->fldname) : (char *) NULL)/* Copy a field that is a pointer to a simple palloc'd object of size sz */#define COPY_POINTER_FIELD(fldname, sz) \ do { \ Size _size = (sz); \ newnode->fldname = palloc(_size); \ memcpy(newnode->fldname, from->fldname, _size); \ } while (0)/* * listCopy * This copy function only copies the "cons-cells" of the list, not the * pointed-to objects. (Use copyObject if you want a "deep" copy.) * * We also use this function for copying lists of integers and Oids, * which is notationally a bit ugly, but perfectly safe. * * Note that copyObject will surely coredump if applied to a list * of integers or Oids! */List *listCopy(List *list){ List *newlist, *oldl, *newcell, *prev; /* rather ugly coding for speed... */ if (list == NIL) return NIL; newcell = makeNode(List); newcell->elem = list->elem; newlist = prev = newcell; foreach(oldl, lnext(list)) { newcell = makeNode(List); newcell->elem = oldl->elem; prev->next = newcell; prev = newcell; } prev->next = NIL; return newlist;}/* **************************************************************** * plannodes.h copy functions * **************************************************************** *//* * CopyPlanFields * * This function copies the fields of the Plan node. It is used by * all the copy functions for classes which inherit from Plan. */static voidCopyPlanFields(Plan *from, Plan *newnode){ COPY_SCALAR_FIELD(startup_cost); COPY_SCALAR_FIELD(total_cost); COPY_SCALAR_FIELD(plan_rows); COPY_SCALAR_FIELD(plan_width); COPY_NODE_FIELD(targetlist); COPY_NODE_FIELD(qual); COPY_NODE_FIELD(lefttree); COPY_NODE_FIELD(righttree); COPY_NODE_FIELD(initPlan); COPY_BITMAPSET_FIELD(extParam); COPY_BITMAPSET_FIELD(allParam); COPY_SCALAR_FIELD(nParamExec);}/* * _copyPlan */static Plan *_copyPlan(Plan *from){ Plan *newnode = makeNode(Plan); /* * copy node superclass fields */ CopyPlanFields(from, newnode); return newnode;}/* * _copyResult */static Result *_copyResult(Result *from){ Result *newnode = makeNode(Result); /* * copy node superclass fields */ CopyPlanFields((Plan *) from, (Plan *) newnode); /* * copy remainder of node */ COPY_NODE_FIELD(resconstantqual); return newnode;}/* * _copyAppend */static Append *_copyAppend(Append *from){ Append *newnode = makeNode(Append); /* * copy node superclass fields */ CopyPlanFields((Plan *) from, (Plan *) newnode); /* * copy remainder of node */ COPY_NODE_FIELD(appendplans); COPY_SCALAR_FIELD(isTarget); return newnode;}/* * CopyScanFields * * This function copies the fields of the Scan node. It is used by * all the copy functions for classes which inherit from Scan. */static voidCopyScanFields(Scan *from, Scan *newnode){ CopyPlanFields((Plan *) from, (Plan *) newnode); COPY_SCALAR_FIELD(scanrelid);}/* * _copyScan */static Scan *_copyScan(Scan *from){ Scan *newnode = makeNode(Scan); /* * copy node superclass fields */ CopyScanFields((Scan *) from, (Scan *) newnode); return newnode;}/* * _copySeqScan */static SeqScan *_copySeqScan(SeqScan *from){ SeqScan *newnode = makeNode(SeqScan); /* * copy node superclass fields */ CopyScanFields((Scan *) from, (Scan *) newnode); return newnode;}/* * _copyIndexScan */static IndexScan *_copyIndexScan(IndexScan *from){ IndexScan *newnode = makeNode(IndexScan); /* * copy node superclass fields */ CopyScanFields((Scan *) from, (Scan *) newnode); /* * copy remainder of node */ COPY_OIDLIST_FIELD(indxid); COPY_NODE_FIELD(indxqual); COPY_NODE_FIELD(indxqualorig); COPY_SCALAR_FIELD(indxorderdir); return newnode;}/* * _copyTidScan */static TidScan *_copyTidScan(TidScan *from){ TidScan *newnode = makeNode(TidScan); /* * copy node superclass fields */ CopyScanFields((Scan *) from, (Scan *) newnode); /* * copy remainder of node */ COPY_NODE_FIELD(tideval); return newnode;}/* * _copySubqueryScan */static SubqueryScan *_copySubqueryScan(SubqueryScan *from){ SubqueryScan *newnode = makeNode(SubqueryScan); /* * copy node superclass fields */ CopyScanFields((Scan *) from, (Scan *) newnode); /* * copy remainder of node */ COPY_NODE_FIELD(subplan); return newnode;}/* * _copyFunctionScan */static FunctionScan *_copyFunctionScan(FunctionScan *from){ FunctionScan *newnode = makeNode(FunctionScan); /* * copy node superclass fields */ CopyScanFields((Scan *) from, (Scan *) newnode); return newnode;}/* * CopyJoinFields * * This function copies the fields of the Join node. It is used by * all the copy functions for classes which inherit from Join. */static voidCopyJoinFields(Join *from, Join *newnode){ CopyPlanFields((Plan *) from, (Plan *) newnode); COPY_SCALAR_FIELD(jointype); COPY_NODE_FIELD(joinqual);}/* * _copyJoin */static Join *_copyJoin(Join *from){ Join *newnode = makeNode(Join); /* * copy node superclass fields */ CopyJoinFields(from, newnode); return newnode;}/* * _copyNestLoop */static NestLoop *_copyNestLoop(NestLoop *from){ NestLoop *newnode = makeNode(NestLoop); /* * copy node superclass fields */ CopyJoinFields((Join *) from, (Join *) newnode); return newnode;}/* * _copyMergeJoin */static MergeJoin *_copyMergeJoin(MergeJoin *from){ MergeJoin *newnode = makeNode(MergeJoin); /* * copy node superclass fields */ CopyJoinFields((Join *) from, (Join *) newnode); /* * copy remainder of node */ COPY_NODE_FIELD(mergeclauses); return newnode;}/* * _copyHashJoin */static HashJoin *_copyHashJoin(HashJoin *from){ HashJoin *newnode = makeNode(HashJoin); /* * copy node superclass fields */ CopyJoinFields((Join *) from, (Join *) newnode); /* * copy remainder of node */ COPY_NODE_FIELD(hashclauses); return newnode;}/* * _copyMaterial */static Material *_copyMaterial(Material *from){ Material *newnode = makeNode(Material); /* * copy node superclass fields */ CopyPlanFields((Plan *) from, (Plan *) newnode); return newnode;}/* * _copySort */static Sort *_copySort(Sort *from){ Sort *newnode = makeNode(Sort); /* * copy node superclass fields */ CopyPlanFields((Plan *) from, (Plan *) newnode); COPY_SCALAR_FIELD(numCols); COPY_POINTER_FIELD(sortColIdx, from->numCols * sizeof(AttrNumber)); COPY_POINTER_FIELD(sortOperators, from->numCols * sizeof(Oid)); return newnode;}/* * _copyGroup */static Group *_copyGroup(Group *from){ Group *newnode = makeNode(Group); CopyPlanFields((Plan *) from, (Plan *) newnode); COPY_SCALAR_FIELD(numCols); COPY_POINTER_FIELD(grpColIdx, from->numCols * sizeof(AttrNumber)); return newnode;}/* * _copyAgg */static Agg *_copyAgg(Agg *from){ Agg *newnode = makeNode(Agg); CopyPlanFields((Plan *) from, (Plan *) newnode); COPY_SCALAR_FIELD(aggstrategy); COPY_SCALAR_FIELD(numCols); if (from->numCols > 0) COPY_POINTER_FIELD(grpColIdx, from->numCols * sizeof(AttrNumber)); COPY_SCALAR_FIELD(numGroups); return newnode;}/* * _copyUnique */static Unique *_copyUnique(Unique *from){ Unique *newnode = makeNode(Unique); /* * copy node superclass fields */ CopyPlanFields((Plan *) from, (Plan *) newnode); /* * copy remainder of node */ COPY_SCALAR_FIELD(numCols); COPY_POINTER_FIELD(uniqColIdx, from->numCols * sizeof(AttrNumber)); return newnode;}/* * _copyHash */static Hash *_copyHash(Hash *from){ Hash *newnode = makeNode(Hash); /* * copy node superclass fields */ CopyPlanFields((Plan *) from, (Plan *) newnode); /* * copy remainder of node */ COPY_NODE_FIELD(hashkeys); return newnode;}/* * _copySetOp */static SetOp *_copySetOp(SetOp *from){ SetOp *newnode = makeNode(SetOp); /* * copy node superclass fields */ CopyPlanFields((Plan *) from, (Plan *) newnode); /* * copy remainder of node */ COPY_SCALAR_FIELD(cmd); COPY_SCALAR_FIELD(numCols); COPY_POINTER_FIELD(dupColIdx, from->numCols * sizeof(AttrNumber)); COPY_SCALAR_FIELD(flagColIdx); return newnode;}/* * _copyLimit */static Limit *_copyLimit(Limit *from){ Limit *newnode = makeNode(Limit); /* * copy node superclass fields */ CopyPlanFields((Plan *) from, (Plan *) newnode); /* * copy remainder of node */ COPY_NODE_FIELD(limitOffset); COPY_NODE_FIELD(limitCount); return newnode;}/* **************************************************************** * primnodes.h copy functions * **************************************************************** *//* * _copyResdom */static Resdom *_copyResdom(Resdom *from){ Resdom *newnode = makeNode(Resdom); COPY_SCALAR_FIELD(resno); COPY_SCALAR_FIELD(restype); COPY_SCALAR_FIELD(restypmod); COPY_STRING_FIELD(resname); COPY_SCALAR_FIELD(ressortgroupref); COPY_SCALAR_FIELD(resorigtbl); COPY_SCALAR_FIELD(resorigcol); COPY_SCALAR_FIELD(resjunk); return newnode;}/* * _copyAlias */static Alias *_copyAlias(Alias *from){ Alias *newnode = makeNode(Alias); COPY_STRING_FIELD(aliasname); COPY_NODE_FIELD(colnames); return newnode;}/* * _copyRangeVar */static RangeVar *_copyRangeVar(RangeVar *from){ RangeVar *newnode = makeNode(RangeVar); COPY_STRING_FIELD(catalogname); COPY_STRING_FIELD(schemaname); COPY_STRING_FIELD(relname); COPY_SCALAR_FIELD(inhOpt); COPY_SCALAR_FIELD(istemp); COPY_NODE_FIELD(alias); return newnode;}/* * We don't need a _copyExpr because Expr is an abstract supertype which * should never actually get instantiated. Also, since it has no common * fields except NodeTag, there's no need for a helper routine to factor * out copying the common fields... *//* * _copyVar */static Var *_copyVar(Var *from){ Var *newnode = makeNode(Var); COPY_SCALAR_FIELD(varno); COPY_SCALAR_FIELD(varattno); COPY_SCALAR_FIELD(vartype); COPY_SCALAR_FIELD(vartypmod); COPY_SCALAR_FIELD(varlevelsup); COPY_SCALAR_FIELD(varnoold); COPY_SCALAR_FIELD(varoattno); return newnode;}/* * _copyConst */static Const *_copyConst(Const *from){ Const *newnode = makeNode(Const); COPY_SCALAR_FIELD(consttype); COPY_SCALAR_FIELD(constlen); if (from->constbyval || from->constisnull) { /* * passed by value so just copy the datum. Also, don't try to copy * struct when value is null! */ newnode->constvalue = from->constvalue; } else { /* * passed by reference. We need a palloc'd copy. */ newnode->constvalue = datumCopy(from->constvalue, from->constbyval, from->constlen); } COPY_SCALAR_FIELD(constisnull); COPY_SCALAR_FIELD(constbyval); return newnode;}/* * _copyParam */static Param *_copyParam(Param *from){ Param *newnode = makeNode(Param); COPY_SCALAR_FIELD(paramkind); COPY_SCALAR_FIELD(paramid); COPY_STRING_FIELD(paramname); COPY_SCALAR_FIELD(paramtype); return newnode;}/* * _copyAggref */static Aggref *_copyAggref(Aggref *from){ Aggref *newnode = makeNode(Aggref); COPY_SCALAR_FIELD(aggfnoid); COPY_SCALAR_FIELD(aggtype); COPY_NODE_FIELD(target); COPY_SCALAR_FIELD(agglevelsup); COPY_SCALAR_FIELD(aggstar); COPY_SCALAR_FIELD(aggdistinct); return newnode;}/* * _copyArrayRef */static ArrayRef *_copyArrayRef(ArrayRef *from){ ArrayRef *newnode = makeNode(ArrayRef); COPY_SCALAR_FIELD(refrestype); COPY_SCALAR_FIELD(refarraytype); COPY_SCALAR_FIELD(refelemtype);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -