postgresql/src/backend/nodes/copyfuncs.c

1862 lines
38 KiB
C
Raw Normal View History

/*-------------------------------------------------------------------------
*
* copyfuncs.c
* Copy functions for Postgres tree nodes.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.75 1999/03/01 00:10:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include <stdio.h>
#include <string.h>
#include "postgres.h"
#include "nodes/pg_list.h"
#include "nodes/execnodes.h"
#include "nodes/plannodes.h"
#include "nodes/parsenodes.h"
#include "nodes/primnodes.h"
#include "nodes/relation.h"
#include "utils/syscache.h"
#include "utils/builtins.h" /* for namecpy */
#include "utils/elog.h"
#include "utils/palloc.h"
#include "catalog/pg_type.h"
#include "storage/lmgr.h"
#include "optimizer/planmain.h"
/*
* listCopy
* this copy function only copies the "lcons-cells" of the list but not
* its contents. (good for list of pointers as well as list of integers).
*/
List *
listCopy(List *list)
{
List *newlist = NIL;
List *l,
*nl = NIL;
foreach(l, list)
{
if (newlist == NIL)
newlist = nl = lcons(lfirst(l), NIL);
else
{
lnext(nl) = lcons(lfirst(l), NIL);
nl = lnext(nl);
}
}
return newlist;
}
/*
* Node_Copy
* a macro to simplify calling of copyObject on the specified field
*/
#define Node_Copy(from, newnode, field) \
newnode->field = copyObject(from->field)
/* ****************************************************************
* 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 void
CopyPlanFields(Plan *from, Plan *newnode)
{
extern List *SS_pull_subplan(void *expr);
newnode->cost = from->cost;
newnode->plan_size = from->plan_size;
newnode->plan_width = from->plan_width;
1998-01-11 21:02:32 +01:00
newnode->plan_tupperpage = from->plan_tupperpage;
newnode->targetlist = copyObject(from->targetlist);
newnode->qual = copyObject(from->qual);
newnode->lefttree = copyObject(from->lefttree);
newnode->righttree = copyObject(from->righttree);
newnode->extParam = listCopy(from->extParam);
newnode->locParam = listCopy(from->locParam);
newnode->chgParam = listCopy(from->chgParam);
Node_Copy(from, newnode, initPlan);
if (from->subPlan != NULL)
newnode->subPlan = SS_pull_subplan(newnode->qual);
else
newnode->subPlan = NULL;
newnode->nParamExec = from->nParamExec;
}
/* ----------------
* _copyPlan
* ----------------
*/
static Plan *
_copyPlan(Plan *from)
{
Plan *newnode = makeNode(Plan);
/* ----------------
* copy the 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
* ----------------
*/
Node_Copy(from, newnode, resconstantqual);
return newnode;
}
/* ----------------
* _copyAppend
* ----------------
*/
static Append *
1997-09-08 22:59:27 +02:00
_copyAppend(Append *from)
{
Append *newnode = makeNode(Append);
/* ----------------
* copy node superclass fields
* ----------------
*/
CopyPlanFields((Plan *) from, (Plan *) newnode);
/* ----------------
* copy remainder of node
* ----------------
*/
Node_Copy(from, newnode, appendplans);
Node_Copy(from, newnode, unionrtables);
newnode->inheritrelid = from->inheritrelid;
Node_Copy(from, newnode, inheritrtable);
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 void
CopyScanFields(Scan *from, Scan *newnode)
{
newnode->scanrelid = from->scanrelid;
return;
}
/* ----------------
* _copyScan
* ----------------
*/
static Scan *
_copyScan(Scan *from)
{
Scan *newnode = makeNode(Scan);
/* ----------------
* copy node superclass fields
* ----------------
*/
CopyPlanFields((Plan *) from, (Plan *) newnode);
1998-01-11 21:02:32 +01:00
CopyScanFields((Scan *) from, (Scan *) newnode);
return newnode;
}
/* ----------------
* _copySeqScan
* ----------------
*/
static SeqScan *
_copySeqScan(SeqScan *from)
{
SeqScan *newnode = makeNode(SeqScan);
/* ----------------
* copy node superclass fields
* ----------------
*/
CopyPlanFields((Plan *) from, (Plan *) newnode);
CopyScanFields((Scan *) from, (Scan *) newnode);
return newnode;
}
/* ----------------
* _copyIndexScan
* ----------------
*/
static IndexScan *
_copyIndexScan(IndexScan *from)
{
IndexScan *newnode = makeNode(IndexScan);
/* ----------------
* copy node superclass fields
* ----------------
*/
CopyPlanFields((Plan *) from, (Plan *) newnode);
CopyScanFields((Scan *) from, (Scan *) newnode);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->indxid = listCopy(from->indxid);
Node_Copy(from, newnode, indxqual);
Node_Copy(from, newnode, indxqualorig);
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 void
CopyJoinFields(Join *from, Join *newnode)
{
/* nothing extra */
return;
}
/* ----------------
* _copyJoin
* ----------------
*/
static Join *
_copyJoin(Join *from)
{
Join *newnode = makeNode(Join);
/* ----------------
* copy node superclass fields
* ----------------
*/
CopyPlanFields((Plan *) from, (Plan *) newnode);
CopyJoinFields(from, newnode);
return newnode;
}
/* ----------------
* _copyNestLoop
* ----------------
*/
static NestLoop *
_copyNestLoop(NestLoop *from)
{
NestLoop *newnode = makeNode(NestLoop);
/* ----------------
* copy node superclass fields
* ----------------
*/
CopyPlanFields((Plan *) from, (Plan *) newnode);
CopyJoinFields((Join *) from, (Join *) newnode);
return newnode;
}
/* ----------------
* _copyMergeJoin
* ----------------
*/
static MergeJoin *
_copyMergeJoin(MergeJoin *from)
{
MergeJoin *newnode = makeNode(MergeJoin);
/* ----------------
* copy node superclass fields
* ----------------
*/
CopyPlanFields((Plan *) from, (Plan *) newnode);
CopyJoinFields((Join *) from, (Join *) newnode);
/* ----------------
* copy remainder of node
* ----------------
*/
Node_Copy(from, newnode, mergeclauses);
return newnode;
}
/* ----------------
* _copyHashJoin
* ----------------
*/
static HashJoin *
_copyHashJoin(HashJoin *from)
{
HashJoin *newnode = makeNode(HashJoin);
/* ----------------
* copy node superclass fields
* ----------------
*/
CopyPlanFields((Plan *) from, (Plan *) newnode);
CopyJoinFields((Join *) from, (Join *) newnode);
/* ----------------
* copy remainder of node
* ----------------
*/
Node_Copy(from, newnode, hashclauses);
newnode->hashjoinop = from->hashjoinop;
/* both are unused !.. */
newnode->hashjointablekey = from->hashjointablekey;
newnode->hashjointablesize = from->hashjointablesize;
return newnode;
}
/* ----------------
* CopyNonameFields
*
* This function copies the fields of the Noname node. It is used by
* all the copy functions for classes which inherit from Noname.
* ----------------
*/
static void
CopyNonameFields(Noname *from, Noname *newnode)
{
newnode->nonameid = from->nonameid;
newnode->keycount = from->keycount;
return;
}
/* ----------------
* _copyNoname
* ----------------
*/
static Noname *
_copyNoname(Noname *from)
{
Noname *newnode = makeNode(Noname);
/* ----------------
* copy node superclass fields
* ----------------
*/
CopyPlanFields((Plan *) from, (Plan *) newnode);
CopyNonameFields(from, newnode);
return newnode;
}
/* ----------------
* _copyMaterial
* ----------------
*/
static Material *
_copyMaterial(Material *from)
{
Material *newnode = makeNode(Material);
/* ----------------
* copy node superclass fields
* ----------------
*/
CopyPlanFields((Plan *) from, (Plan *) newnode);
CopyNonameFields((Noname *) from, (Noname *) newnode);
return newnode;
}
/* ----------------
* _copySort
* ----------------
*/
static Sort *
_copySort(Sort *from)
{
Sort *newnode = makeNode(Sort);
/* ----------------
* copy node superclass fields
* ----------------
*/
CopyPlanFields((Plan *) from, (Plan *) newnode);
CopyNonameFields((Noname *) from, (Noname *) newnode);
return newnode;
}
1997-09-19 08:52:49 +02:00
/* ----------------
* _copyGroup
* ----------------
*/
static Group *
_copyGroup(Group *from)
{
Group *newnode = makeNode(Group);
1997-09-19 08:52:49 +02:00
CopyPlanFields((Plan *) from, (Plan *) newnode);
1998-01-11 21:02:32 +01:00
1997-09-19 08:52:49 +02:00
newnode->tuplePerGroup = from->tuplePerGroup;
newnode->numCols = from->numCols;
newnode->grpColIdx = palloc(from->numCols * sizeof(AttrNumber));
memcpy(newnode->grpColIdx, from->grpColIdx, from->numCols * sizeof(AttrNumber));
1997-09-19 08:52:49 +02:00
return newnode;
}
/* ---------------
* _copyAgg
* --------------
*/
static Agg *
1997-09-08 22:59:27 +02:00
_copyAgg(Agg *from)
{
Agg *newnode = makeNode(Agg);
CopyPlanFields((Plan *) from, (Plan *) newnode);
newnode->aggs = get_agg_tlist_references(newnode);
return newnode;
}
/* ---------------
* _copyGroupClause
* --------------
*/
static GroupClause *
_copyGroupClause(GroupClause *from)
{
GroupClause *newnode = makeNode(GroupClause);
Node_Copy(from, newnode, entry);
newnode->grpOpoid = from->grpOpoid;
return newnode;
}
/* ----------------
* _copyUnique
* ----------------
*/
static Unique *
_copyUnique(Unique *from)
{
Unique *newnode = makeNode(Unique);
/* ----------------
* copy node superclass fields
* ----------------
*/
CopyPlanFields((Plan *) from, (Plan *) newnode);
CopyNonameFields((Noname *) from, (Noname *) newnode);
/* ----------------
* copy remainder of node
* ----------------
*/
if (newnode->uniqueAttr)
newnode->uniqueAttr = pstrdup(from->uniqueAttr);
else
newnode->uniqueAttr = NULL;
1998-01-11 21:02:32 +01:00
newnode->uniqueAttrNum = from->uniqueAttrNum;
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
* ----------------
*/
Node_Copy(from, newnode, hashkey);
/* both are unused !.. */
newnode->hashtablekey = from->hashtablekey;
newnode->hashtablesize = from->hashtablesize;
return newnode;
}
static SubPlan *
_copySubPlan(SubPlan *from)
{
SubPlan *newnode = makeNode(SubPlan);
Node_Copy(from, newnode, plan);
newnode->plan_id = from->plan_id;
Node_Copy(from, newnode, rtable);
newnode->setParam = listCopy(from->setParam);
newnode->parParam = listCopy(from->parParam);
Node_Copy(from, newnode, sublink);
return newnode;
}
/* ****************************************************************
* primnodes.h copy functions
* ****************************************************************
*/
/* ----------------
* _copyResdom
* ----------------
*/
static Resdom *
_copyResdom(Resdom *from)
{
Resdom *newnode = makeNode(Resdom);
newnode->resno = from->resno;
newnode->restype = from->restype;
newnode->restypmod = from->restypmod;
if (from->resname != NULL)
1998-01-11 21:02:32 +01:00
newnode->resname = pstrdup(from->resname);
newnode->reskey = from->reskey;
newnode->reskeyop = from->reskeyop;
newnode->resjunk = from->resjunk;
return newnode;
}
static Fjoin *
_copyFjoin(Fjoin *from)
{
Fjoin *newnode = makeNode(Fjoin);
/* ----------------
* copy node superclass fields
* ----------------
*/
newnode->fj_initialized = from->fj_initialized;
newnode->fj_nNodes = from->fj_nNodes;
Node_Copy(from, newnode, fj_innerNode);
newnode->fj_results = (DatumPtr)
palloc((from->fj_nNodes) * sizeof(Datum));
memmove(from->fj_results,
newnode->fj_results,
(from->fj_nNodes) * sizeof(Datum));
1998-01-11 21:02:32 +01:00
newnode->fj_alwaysDone = (BoolPtr)
palloc((from->fj_nNodes) * sizeof(bool));
memmove(from->fj_alwaysDone,
newnode->fj_alwaysDone,
(from->fj_nNodes) * sizeof(bool));
return newnode;
}
/* ----------------
* _copyExpr
* ----------------
*/
static Expr *
_copyExpr(Expr *from)
{
Expr *newnode = makeNode(Expr);
/* ----------------
* copy node superclass fields
* ----------------
*/
newnode->typeOid = from->typeOid;
newnode->opType = from->opType;
Node_Copy(from, newnode, oper);
Node_Copy(from, newnode, args);
return newnode;
}
/* ----------------
* _copyVar
* ----------------
*/
static Var *
_copyVar(Var *from)
{
Var *newnode = makeNode(Var);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->varno = from->varno;
newnode->varattno = from->varattno;
newnode->vartype = from->vartype;
newnode->vartypmod = from->vartypmod;
newnode->varlevelsup = from->varlevelsup;
newnode->varnoold = from->varnoold;
newnode->varoattno = from->varoattno;
return newnode;
}
/* ----------------
* _copyOper
* ----------------
*/
static Oper *
_copyOper(Oper *from)
{
Oper *newnode = makeNode(Oper);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->opno = from->opno;
newnode->opid = from->opid;
newnode->opresulttype = from->opresulttype;
newnode->opsize = from->opsize;
/*
* NOTE: shall we copy the cache structure or just the pointer ?
* Alternatively we can set 'op_fcache' to NULL, in which case the
* executor will initialize it when it needs it...
*/
newnode->op_fcache = from->op_fcache;
return newnode;
}
/* ----------------
* _copyConst
* ----------------
*/
static Const *
_copyConst(Const *from)
{
static Oid cached_type;
static bool cached_typbyval;
Const *newnode = makeNode(Const);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->consttype = from->consttype;
newnode->constlen = from->constlen;
/* ----------------
* XXX super cheesy hack until parser/planner
* puts in the right values here.
1998-01-11 21:02:32 +01:00
*
* But I like cheese.
* ----------------
*/
1997-09-13 13:45:50 +02:00
if (!from->constisnull && cached_type != from->consttype)
{
HeapTuple typeTuple;
1998-09-01 05:29:17 +02:00
Form_pg_type typeStruct;
/* ----------------
* get the type tuple corresponding to the paramList->type,
* If this fails, returnValue has been pre-initialized
* to "null" so we just return it.
* ----------------
*/
typeTuple = SearchSysCacheTuple(TYPOID,
ObjectIdGetDatum(from->consttype),
0, 0, 0);
/* ----------------
* get the type length and by-value from the type tuple and
* save the information in our one element cache.
* ----------------
*/
Assert(PointerIsValid(typeTuple));
1998-09-01 05:29:17 +02:00
typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
cached_typbyval = (typeStruct)->typbyval ? true : false;
cached_type = from->consttype;
}
from->constbyval = cached_typbyval;
if (!from->constisnull)
{
/* ----------------
* copying the Datum in a const node is a bit trickier
* because it might be a pointer and it might also be of
* variable length...
* ----------------
*/
if (from->constbyval == true)
{
/* ----------------
* passed by value so just copy the datum.
* ----------------
*/
newnode->constvalue = from->constvalue;
}
else
{
/* ----------------
* not passed by value. datum contains a pointer.
* ----------------
*/
if (from->constlen != -1)
{
/* ----------------
* fixed length structure
* ----------------
*/
newnode->constvalue = PointerGetDatum(palloc(from->constlen));
memmove((char *) newnode->constvalue,
(char *) from->constvalue, from->constlen);
}
else
{
/* ----------------
* variable length structure. here the length is stored
* in the first int pointed to by the constval.
* ----------------
*/
int length;
1998-01-22 00:42:15 +01:00
length = VARSIZE(from->constvalue);
newnode->constvalue = PointerGetDatum(palloc(length));
memmove((char *) newnode->constvalue,
(char *) from->constvalue, length);
}
}
}
else
newnode->constvalue = from->constvalue;
newnode->constisnull = from->constisnull;
newnode->constbyval = from->constbyval;
1998-01-11 21:02:32 +01:00
newnode->constisset = from->constisset;
newnode->constiscast = from->constiscast;
return newnode;
}
/* ----------------
* _copyParam
* ----------------
*/
static Param *
_copyParam(Param *from)
{
Param *newnode = makeNode(Param);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->paramkind = from->paramkind;
newnode->paramid = from->paramid;
if (from->paramname != NULL)
newnode->paramname = pstrdup(from->paramname);
newnode->paramtype = from->paramtype;
Node_Copy(from, newnode, param_tlist);
return newnode;
}
/* ----------------
* _copyFunc
* ----------------
*/
static Func *
_copyFunc(Func *from)
{
Func *newnode = makeNode(Func);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->funcid = from->funcid;
newnode->functype = from->functype;
newnode->funcisindex = from->funcisindex;
newnode->funcsize = from->funcsize;
newnode->func_fcache = from->func_fcache;
Node_Copy(from, newnode, func_tlist);
Node_Copy(from, newnode, func_planlist);
return newnode;
}
/* ----------------
1999-01-24 01:28:37 +01:00
* _copyAggref
* ----------------
*/
1999-01-24 01:28:37 +01:00
static Aggref *
_copyAggref(Aggref *from)
{
1999-01-24 01:28:37 +01:00
Aggref *newnode = makeNode(Aggref);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->aggname = pstrdup(from->aggname);
newnode->basetype = from->basetype;
newnode->aggtype = from->aggtype;
Node_Copy(from, newnode, target);
newnode->aggno = from->aggno;
1998-01-11 21:02:32 +01:00
newnode->usenulls = from->usenulls;
return newnode;
}
/* ----------------
* _copySubLink
* ----------------
*/
static SubLink *
_copySubLink(SubLink *from)
{
SubLink *newnode = makeNode(SubLink);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->subLinkType = from->subLinkType;
newnode->useor = from->useor;
Node_Copy(from, newnode, lefthand);
1998-01-20 06:05:08 +01:00
Node_Copy(from, newnode, oper);
Node_Copy(from, newnode, subselect);
return newnode;
}
1998-12-04 16:34:49 +01:00
/* ----------------
* _copyCaseExpr
* ----------------
*/
static CaseExpr *
_copyCaseExpr(CaseExpr *from)
{
CaseExpr *newnode = makeNode(CaseExpr);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->casetype = from->casetype;
Node_Copy(from, newnode, arg);
Node_Copy(from, newnode, args);
Node_Copy(from, newnode, defresult);
return newnode;
}
/* ----------------
* _copyCaseWhen
* ----------------
*/
static CaseWhen *
_copyCaseWhen(CaseWhen *from)
{
CaseWhen *newnode = makeNode(CaseWhen);
/* ----------------
* copy remainder of node
* ----------------
*/
Node_Copy(from, newnode, expr);
Node_Copy(from, newnode, result);
return newnode;
}
static Array *
1997-09-08 22:59:27 +02:00
_copyArray(Array *from)
{
Array *newnode = makeNode(Array);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->arrayelemtype = from->arrayelemtype;
newnode->arrayelemlength = from->arrayelemlength;
newnode->arrayelembyval = from->arrayelembyval;
newnode->arrayndim = from->arrayndim;
newnode->arraylow = from->arraylow;
newnode->arrayhigh = from->arrayhigh;
newnode->arraylen = from->arraylen;
return newnode;
}
static ArrayRef *
1997-09-08 22:59:27 +02:00
_copyArrayRef(ArrayRef *from)
{
ArrayRef *newnode = makeNode(ArrayRef);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->refattrlength = from->refattrlength;
newnode->refelemlength = from->refelemlength;
1998-01-11 21:02:32 +01:00
newnode->refelemtype = from->refelemtype;
newnode->refelembyval = from->refelembyval;
Node_Copy(from, newnode, refupperindexpr);
Node_Copy(from, newnode, reflowerindexpr);
Node_Copy(from, newnode, refexpr);
Node_Copy(from, newnode, refassgnexpr);
return newnode;
}
/* ****************************************************************
* relation.h copy functions
* ****************************************************************
*/
/* ----------------
1998-08-02 00:12:13 +02:00
* _copyRelOptInfo
* ----------------
*/
/*
1999-02-22 20:55:44 +01:00
* when you change this, also make sure to fix up xfunc_copyRelOptInfo in
* planner/path/xfunc.c accordingly!!!
* -- JMH, 8/2/93
*/
1998-07-18 06:22:52 +02:00
static RelOptInfo *
_copyRelOptInfo(RelOptInfo * from)
{
RelOptInfo *newnode = makeNode(RelOptInfo);
int i,
len;
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->relids = listCopy(from->relids);
newnode->indexed = from->indexed;
newnode->pages = from->pages;
newnode->tuples = from->tuples;
newnode->size = from->size;
newnode->width = from->width;
Node_Copy(from, newnode, targetlist);
Node_Copy(from, newnode, pathlist);
Node_Copy(from, newnode, cheapestpath);
newnode->pruneable = from->pruneable;
if (from->classlist)
{
for (len = 0; from->classlist[len] != 0; len++)
;
newnode->classlist = (Oid *) palloc(sizeof(Oid) * (len + 1));
for (i = 0; i < len; i++)
newnode->classlist[i] = from->classlist[i];
newnode->classlist[len] = 0;
}
if (from->indexkeys)
{
for (len = 0; from->indexkeys[len] != 0; len++)
;
newnode->indexkeys = (int *) palloc(sizeof(int) * (len + 1));
for (i = 0; i < len; i++)
newnode->indexkeys[i] = from->indexkeys[i];
newnode->indexkeys[len] = 0;
}
1998-01-11 21:02:32 +01:00
newnode->relam = from->relam;
newnode->indproc = from->indproc;
Node_Copy(from, newnode, indpred);
if (from->ordering)
{
for (len = 0; from->ordering[len] != 0; len++)
;
newnode->ordering = (Oid *) palloc(sizeof(Oid) * (len + 1));
for (i = 0; i < len; i++)
newnode->ordering[i] = from->ordering[i];
newnode->ordering[len] = 0;
}
Node_Copy(from, newnode, restrictinfo);
Node_Copy(from, newnode, joininfo);
Node_Copy(from, newnode, innerjoin);
return newnode;
}
/* ----------------
* CopyPathFields
*
* This function copies the fields of the Path node. It is used by
* all the copy functions for classes which inherit from Path.
* ----------------
*/
static void
CopyPathFields(Path *from, Path *newnode)
{
newnode->pathtype = from->pathtype;
/*
* Modify the next line, since it causes the copying to cycle (i.e.
* the parent points right back here! -- JMH, 7/7/92. Old version:
* Node_Copy(from, newnode, parent);
*/
newnode->parent = from->parent;
newnode->path_cost = from->path_cost;
1999-02-11 15:59:09 +01:00
newnode->pathorder = makeNode(PathOrder);
newnode->pathorder->ordtype = from->pathorder->ordtype;
if (from->pathorder->ordtype == SORTOP_ORDER)
{
int len,
i;
1999-02-11 15:59:09 +01:00
Oid *ordering = from->pathorder->ord.sortop;
if (ordering)
{
for (len = 0; ordering[len] != 0; len++)
;
1999-02-11 15:59:09 +01:00
newnode->pathorder->ord.sortop = (Oid *) palloc(sizeof(Oid) * (len + 1));
for (i = 0; i < len; i++)
1999-02-11 15:59:09 +01:00
newnode->pathorder->ord.sortop[i] = ordering[i];
newnode->pathorder->ord.sortop[len] = 0;
}
}
else
1999-02-11 15:59:09 +01:00
Node_Copy(from, newnode, pathorder->ord.merge);
Node_Copy(from, newnode, pathkeys);
newnode->outerjoincost = from->outerjoincost;
newnode->joinid = listCopy(from->joinid);
Node_Copy(from, newnode, loc_restrictinfo);
}
/* ----------------
* _copyPath
* ----------------
*/
static Path *
_copyPath(Path *from)
{
Path *newnode = makeNode(Path);
CopyPathFields(from, newnode);
return newnode;
}
/* ----------------
* _copyIndexPath
* ----------------
*/
static IndexPath *
_copyIndexPath(IndexPath *from)
{
IndexPath *newnode = makeNode(IndexPath);
/* ----------------
* copy the node superclass fields
* ----------------
*/
CopyPathFields((Path *) from, (Path *) newnode);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->indexid = listCopy(from->indexid);
Node_Copy(from, newnode, indexqual);
if (from->indexkeys)
{
int i,
len;
for (len = 0; from->indexkeys[len] != 0; len++)
;
newnode->indexkeys = (int *) palloc(sizeof(int) * (len + 1));
for (i = 0; i < len; i++)
newnode->indexkeys[i] = from->indexkeys[i];
newnode->indexkeys[len] = 0;
1997-04-10 09:59:09 +02:00
}
return newnode;
}
/* ----------------
1999-02-12 07:43:53 +01:00
* CopyNestPathFields
*
1999-02-12 07:43:53 +01:00
* This function copies the fields of the NestPath node. It is used by
* all the copy functions for classes which inherit from NestPath.
* ----------------
*/
static void
1999-02-12 07:43:53 +01:00
CopyNestPathFields(NestPath *from, NestPath *newnode)
{
Node_Copy(from, newnode, pathinfo);
Node_Copy(from, newnode, outerjoinpath);
Node_Copy(from, newnode, innerjoinpath);
}
/* ----------------
1999-02-12 07:43:53 +01:00
* _copyNestPath
* ----------------
*/
1999-02-12 07:43:53 +01:00
static NestPath *
_copyNestPath(NestPath *from)
{
1999-02-12 07:43:53 +01:00
NestPath *newnode = makeNode(NestPath);
/* ----------------
* copy the node superclass fields
* ----------------
*/
CopyPathFields((Path *) from, (Path *) newnode);
1999-02-12 07:43:53 +01:00
CopyNestPathFields(from, newnode);
return newnode;
}
/* ----------------
* _copyMergePath
* ----------------
*/
static MergePath *
_copyMergePath(MergePath *from)
{
MergePath *newnode = makeNode(MergePath);
/* ----------------
* copy the node superclass fields
* ----------------
*/
CopyPathFields((Path *) from, (Path *) newnode);
1999-02-12 07:43:53 +01:00
CopyNestPathFields((NestPath *) from, (NestPath *) newnode);
/* ----------------
* copy the remainder of the node
* ----------------
*/
Node_Copy(from, newnode, path_mergeclauses);
Node_Copy(from, newnode, outersortkeys);
Node_Copy(from, newnode, innersortkeys);
return newnode;
}
/* ----------------
* _copyHashPath
* ----------------
*/
static HashPath *
_copyHashPath(HashPath *from)
{
HashPath *newnode = makeNode(HashPath);
/* ----------------
* copy the node superclass fields
* ----------------
*/
CopyPathFields((Path *) from, (Path *) newnode);
1999-02-12 07:43:53 +01:00
CopyNestPathFields((NestPath *) from, (NestPath *) newnode);
/* ----------------
* copy remainder of node
* ----------------
*/
Node_Copy(from, newnode, path_hashclauses);
Node_Copy(from, newnode, outerhashkeys);
Node_Copy(from, newnode, innerhashkeys);
return newnode;
}
/* ----------------
* _copyOrderKey
* ----------------
*/
static OrderKey *
_copyOrderKey(OrderKey *from)
{
OrderKey *newnode = makeNode(OrderKey);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->attribute_number = from->attribute_number;
newnode->array_index = from->array_index;
return newnode;
}
/* ----------------
* _copyJoinKey
* ----------------
*/
static JoinKey *
_copyJoinKey(JoinKey *from)
{
JoinKey *newnode = makeNode(JoinKey);
/* ----------------
* copy remainder of node
* ----------------
*/
Node_Copy(from, newnode, outer);
Node_Copy(from, newnode, inner);
return newnode;
}
/* ----------------
* _copyMergeOrder
* ----------------
*/
static MergeOrder *
_copyMergeOrder(MergeOrder *from)
{
MergeOrder *newnode = makeNode(MergeOrder);
/* ----------------
* copy remainder of node
* ----------------
*/
newnode->join_operator = from->join_operator;
newnode->left_operator = from->left_operator;
newnode->right_operator = from->right_operator;
newnode->left_type = from->left_type;
newnode->right_type = from->right_type;
return newnode;
}
/* ----------------
* _copyRestrictInfo
* ----------------
*/
static RestrictInfo *
_copyRestrictInfo(RestrictInfo *from)
{
RestrictInfo *newnode = makeNode(RestrictInfo);
/* ----------------
* copy remainder of node
* ----------------
*/
Node_Copy(from, newnode, clause);
newnode->selectivity = from->selectivity;
newnode->notclause = from->notclause;
Node_Copy(from, newnode, indexids);
Node_Copy(from, newnode, mergejoinorder);
newnode->hashjoinoperator = from->hashjoinoperator;
1999-02-05 20:59:31 +01:00
newnode->restrictinfojoinid = listCopy(from->restrictinfojoinid);
return newnode;
}
/* ----------------
* CopyJoinMethodFields
*
* This function copies the fields of the JoinMethod node. It is used by
* all the copy functions for classes which inherit from JoinMethod.
* ----------------
*/
static void
CopyJoinMethodFields(JoinMethod *from, JoinMethod *newnode)
{
Node_Copy(from, newnode, jmkeys);
Node_Copy(from, newnode, clauses);
return;
}
/* ----------------
* _copyJoinMethod
* ----------------
*/
static JoinMethod *
_copyJoinMethod(JoinMethod *from)
{
JoinMethod *newnode = makeNode(JoinMethod);
CopyJoinMethodFields(from, newnode);
return newnode;
}
/* ----------------
* _copyHashInfo
* ----------------
*/
static HashInfo *
_copyHashInfo(HashInfo *from)
{
HashInfo *newnode = makeNode(HashInfo);
/* ----------------
* copy remainder of node
* ----------------
*/
CopyJoinMethodFields((JoinMethod *) from, (JoinMethod *) newnode);
newnode->hashop = from->hashop;
return newnode;
}
/* ----------------
1999-02-04 04:19:11 +01:00
* _copyMergeInfo
* ----------------
*/
1999-02-04 04:19:11 +01:00
static MergeInfo *
_copyMergeInfo(MergeInfo *from)
{
1999-02-04 04:19:11 +01:00
MergeInfo *newnode = makeNode(MergeInfo);
/* ----------------
* copy remainder of node
* ----------------
*/
CopyJoinMethodFields((JoinMethod *) from, (JoinMethod *) newnode);
Node_Copy(from, newnode, m_ordering);
return newnode;
}
/* ----------------
1998-09-01 05:29:17 +02:00
* _copyJoinInfo
* ----------------
*/
1998-09-01 05:29:17 +02:00
static JoinInfo *
_copyJoinInfo(JoinInfo *from)
{
JoinInfo *newnode = makeNode(JoinInfo);
/* ----------------
* copy remainder of node
* ----------------
*/
1999-02-18 01:49:48 +01:00
newnode->unjoined_relids = listCopy(from->unjoined_relids);
Node_Copy(from, newnode, jinfo_restrictinfo);
newnode->mergejoinable = from->mergejoinable;
newnode->hashjoinable = from->hashjoinable;
return newnode;
}
static Iter *
_copyIter(Iter *from)
{
Iter *newnode = makeNode(Iter);
Node_Copy(from, newnode, iterexpr);
newnode->itertype = from->itertype;
return newnode;
}
static Stream *
_copyStream(Stream *from)
{
Stream *newnode = makeNode(Stream);
newnode->pathptr = from->pathptr;
newnode->cinfo = from->cinfo;
newnode->clausetype = from->clausetype;
1998-01-11 21:02:32 +01:00
newnode->upstream = (StreamPtr) NULL; /* only copy nodes
* downwards! */
Node_Copy(from, newnode, downstream);
if (newnode->downstream)
((Stream *) newnode->downstream)->upstream = (Stream *) newnode;
1998-01-11 21:02:32 +01:00
newnode->groupup = from->groupup;
newnode->groupcost = from->groupcost;
newnode->groupsel = from->groupsel;
return newnode;
}
1999-02-22 20:55:44 +01:00
/*
* parsenodes.h routines have no copy functions
*/
static TargetEntry *
_copyTargetEntry(TargetEntry *from)
{
TargetEntry *newnode = makeNode(TargetEntry);
Node_Copy(from, newnode, resdom);
Node_Copy(from, newnode, fjoin);
Node_Copy(from, newnode, expr);
return newnode;
}
static RangeTblEntry *
_copyRangeTblEntry(RangeTblEntry *from)
{
RangeTblEntry *newnode = makeNode(RangeTblEntry);
if (from->relname)
newnode->relname = pstrdup(from->relname);
if (from->refname)
newnode->refname = pstrdup(from->refname);
1998-01-11 21:02:32 +01:00
newnode->relid = from->relid;
newnode->inh = from->inh;
newnode->inFromCl = from->inFromCl;
newnode->skipAcl = from->skipAcl;
return newnode;
}
static RowMark *
_copyRowMark(RowMark *from)
{
RowMark *newnode = makeNode(RowMark);
newnode->rti = from->rti;
newnode->info = from->info;
return newnode;
}
static SortClause *
_copySortClause(SortClause *from)
{
SortClause *newnode = makeNode(SortClause);
Node_Copy(from, newnode, resdom);
newnode->opoid = from->opoid;
return newnode;
}
static A_Const *
1997-09-08 22:59:27 +02:00
_copyAConst(A_Const *from)
{
A_Const *newnode = makeNode(A_Const);
newnode->val = *((Value *) (copyObject(&(from->val))));
Node_Copy(from, newnode, typename);
return newnode;
}
static TypeName *
_copyTypeName(TypeName *from)
{
TypeName *newnode = makeNode(TypeName);
if (from->name)
newnode->name = pstrdup(from->name);
1998-01-11 21:02:32 +01:00
newnode->timezone = from->timezone;
newnode->setof = from->setof;
newnode->typmod = from->typmod;
Node_Copy(from, newnode, arrayBounds);
return newnode;
}
static Query *
_copyQuery(Query *from)
{
Query *newnode = makeNode(Query);
newnode->commandType = from->commandType;
1998-01-09 06:48:22 +01:00
if (from->utilityStmt && nodeTag(from->utilityStmt) == T_NotifyStmt)
{
NotifyStmt *from_notify = (NotifyStmt *) from->utilityStmt;
NotifyStmt *n = makeNode(NotifyStmt);
1998-01-11 21:02:32 +01:00
n->relname = pstrdup(from_notify->relname);
1998-01-09 06:48:22 +01:00
newnode->utilityStmt = (Node *) n;
}
newnode->resultRelation = from->resultRelation;
if (from->into)
newnode->into = pstrdup(from->into);
newnode->isPortal = from->isPortal;
1998-01-09 06:48:22 +01:00
newnode->isBinary = from->isBinary;
newnode->isTemp = from->isTemp;
1998-01-09 06:48:22 +01:00
newnode->unionall = from->unionall;
if (from->uniqueFlag)
1998-01-11 21:02:32 +01:00
newnode->uniqueFlag = pstrdup(from->uniqueFlag);
Node_Copy(from, newnode, sortClause);
1998-01-09 06:48:22 +01:00
Node_Copy(from, newnode, rtable);
Node_Copy(from, newnode, targetList);
Node_Copy(from, newnode, qual);
Node_Copy(from, newnode, groupClause);
1998-01-11 21:02:32 +01:00
Node_Copy(from, newnode, havingQual);
newnode->hasAggs = from->hasAggs;
newnode->hasSubLinks = from->hasSubLinks;
1997-12-24 07:06:58 +01:00
if (from->unionClause)
{
List *ulist,
*temp_list = NIL;
1997-12-24 07:06:58 +01:00
foreach(ulist, from->unionClause)
temp_list = lappend(temp_list, copyObject(lfirst(ulist)));
1997-12-24 07:06:58 +01:00
newnode->unionClause = temp_list;
}
1998-10-22 15:52:24 +02:00
Node_Copy(from, newnode, limitOffset);
Node_Copy(from, newnode, limitCount);
Node_Copy(from, newnode, rowMark);
return newnode;
}
1999-02-22 20:55:44 +01:00
/*
* mnodes.h routines have no copy functions
*/
/* ****************************************************************
* pg_list.h copy functions
* ****************************************************************
*/
static Value *
_copyValue(Value *from)
{
Value *newnode = makeNode(Value);
newnode->type = from->type;
switch (from->type)
{
case T_String:
newnode->val.str = pstrdup(from->val.str);
break;
case T_Integer:
newnode->val.ival = from->val.ival;
break;
case T_Float:
newnode->val.dval = from->val.dval;
break;
default:
break;
}
return newnode;
}
/* ----------------
* copyObject returns a copy of the node or list. If it is a list, it
* recursively copies its items.
* ----------------
*/
void *
copyObject(void *from)
{
void *retval;
if (from == NULL)
return NULL;
switch (nodeTag(from))
{
/*
* PLAN NODES
*/
case T_Plan:
retval = _copyPlan(from);
break;
case T_Result:
retval = _copyResult(from);
break;
case T_Append:
retval = _copyAppend(from);
break;
case T_Scan:
retval = _copyScan(from);
break;
case T_SeqScan:
retval = _copySeqScan(from);
break;
case T_IndexScan:
retval = _copyIndexScan(from);
break;
case T_Join:
retval = _copyJoin(from);
break;
case T_NestLoop:
retval = _copyNestLoop(from);
break;
case T_MergeJoin:
retval = _copyMergeJoin(from);
break;
case T_HashJoin:
retval = _copyHashJoin(from);
break;
case T_Noname:
retval = _copyNoname(from);
break;
case T_Material:
retval = _copyMaterial(from);
break;
case T_Sort:
retval = _copySort(from);
break;
1997-09-19 08:52:49 +02:00
case T_Group:
retval = _copyGroup(from);
break;
case T_Agg:
retval = _copyAgg(from);
break;
case T_GroupClause:
retval = _copyGroupClause(from);
break;
case T_Unique:
retval = _copyUnique(from);
break;
case T_Hash:
retval = _copyHash(from);
break;
case T_SubPlan:
retval = _copySubPlan(from);
break;
/*
* PRIMITIVE NODES
*/
case T_Resdom:
retval = _copyResdom(from);
break;
case T_Fjoin:
retval = _copyFjoin(from);
break;
case T_Expr:
retval = _copyExpr(from);
break;
case T_Var:
retval = _copyVar(from);
break;
case T_Oper:
retval = _copyOper(from);
break;
case T_Const:
retval = _copyConst(from);
break;
case T_Param:
retval = _copyParam(from);
break;
case T_Func:
retval = _copyFunc(from);
break;
case T_Array:
retval = _copyArray(from);
break;
case T_ArrayRef:
retval = _copyArrayRef(from);
break;
1999-01-24 01:28:37 +01:00
case T_Aggref:
retval = _copyAggref(from);
break;
case T_SubLink:
retval = _copySubLink(from);
break;
1998-12-04 16:34:49 +01:00
case T_CaseExpr:
retval = _copyCaseExpr(from);
break;
case T_CaseWhen:
retval = _copyCaseWhen(from);
break;
/*
* RELATION NODES
*/
1998-07-18 06:22:52 +02:00
case T_RelOptInfo:
1998-08-02 00:12:13 +02:00
retval = _copyRelOptInfo(from);
break;
case T_Path:
retval = _copyPath(from);
break;
case T_IndexPath:
retval = _copyIndexPath(from);
break;
1999-02-12 07:43:53 +01:00
case T_NestPath:
retval = _copyNestPath(from);
break;
case T_MergePath:
retval = _copyMergePath(from);
break;
case T_HashPath:
retval = _copyHashPath(from);
break;
case T_OrderKey:
retval = _copyOrderKey(from);
break;
case T_JoinKey:
retval = _copyJoinKey(from);
break;
case T_MergeOrder:
retval = _copyMergeOrder(from);
break;
case T_RestrictInfo:
retval = _copyRestrictInfo(from);
break;
case T_JoinMethod:
retval = _copyJoinMethod(from);
break;
case T_HashInfo:
retval = _copyHashInfo(from);
break;
1999-02-04 04:19:11 +01:00
case T_MergeInfo:
retval = _copyMergeInfo(from);
break;
1998-09-01 05:29:17 +02:00
case T_JoinInfo:
retval = _copyJoinInfo(from);
break;
case T_Iter:
retval = _copyIter(from);
break;
case T_Stream:
retval = _copyStream(from);
break;
/*
* PARSE NODES
*/
case T_Query:
retval = _copyQuery(from);
break;
case T_TargetEntry:
retval = _copyTargetEntry(from);
break;
case T_RangeTblEntry:
retval = _copyRangeTblEntry(from);
break;
case T_RowMark:
retval = _copyRowMark(from);
break;
case T_SortClause:
retval = _copySortClause(from);
break;
case T_A_Const:
retval = _copyAConst(from);
break;
case T_TypeName:
retval = _copyTypeName(from);
break;
/*
* VALUE NODES
*/
case T_Integer:
case T_String:
case T_Float:
retval = _copyValue(from);
break;
case T_List:
{
List *list = from,
*l;
List *newlist = NIL,
*nl = NIL;
foreach(l, list)
{
if (newlist == NIL)
newlist = nl = lcons(copyObject(lfirst(l)), NIL);
else
{
lnext(nl) = lcons(copyObject(lfirst(l)), NIL);
nl = lnext(nl);
}
}
retval = newlist;
}
break;
default:
elog(ERROR, "copyObject: don't know how to copy %d", nodeTag(from));
retval = from;
break;
}
return retval;
}