copyfuncs.c 37.5 KB
Newer Older
1 2 3
/*-------------------------------------------------------------------------
 *
 * copyfuncs.c--
4
 *	  Copy functions for Postgres tree nodes.
5 6 7 8 9
 *
 * Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
B
Bruce Momjian 已提交
10
 *	  $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.44 1998/07/18 04:22:25 momjian Exp $
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 *
 *-------------------------------------------------------------------------
 */
#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"
27
#include "utils/builtins.h"		/* for namecpy */
28 29 30 31 32 33 34
#include "utils/elog.h"
#include "utils/palloc.h"
#include "catalog/pg_type.h"
#include "storage/lmgr.h"

/*
 * listCopy--
35 36
 *	  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).
37
 */
38
List *
39
listCopy(List *list)
40
{
41 42 43
	List	   *newlist = NIL;
	List	   *l,
			   *nl = NIL;
44 45 46 47 48 49 50 51 52 53

	foreach(l, list)
	{
		if (newlist == NIL)
			newlist = nl = lcons(lfirst(l), NIL);
		else
		{
			lnext(nl) = lcons(lfirst(l), NIL);
			nl = lnext(nl);
		}
54
	}
55
	return newlist;
56
}
57

58 59
/*
 * Node_Copy--
60
 *	  a macro to simplify calling of copyObject on the specified field
61 62
 */
#define Node_Copy(from, newnode, field) \
63
	newnode->field = copyObject(from->field)
64 65

/* ****************************************************************
66
 *					 plannodes.h copy functions
67 68 69 70
 * ****************************************************************
 */

/* ----------------
71
 *		CopyPlanFields
72
 *
73 74
 *		This function copies the fields of the Plan node.  It is used by
 *		all the copy functions for classes which inherit from Plan.
75 76 77
 * ----------------
 */
static void
78
CopyPlanFields(Plan *from, Plan *newnode)
79
{
80 81
	extern List *SS_pull_subplan(void *expr);

82 83 84
	newnode->cost = from->cost;
	newnode->plan_size = from->plan_size;
	newnode->plan_width = from->plan_width;
B
Bruce Momjian 已提交
85
	newnode->plan_tupperpage = from->plan_tupperpage;
86 87 88 89 90
	newnode->state = from->state;
	newnode->targetlist = copyObject(from->targetlist);
	newnode->qual = copyObject(from->qual);
	newnode->lefttree = copyObject(from->lefttree);
	newnode->righttree = copyObject(from->righttree);
91 92 93
	newnode->extParam = listCopy(from->extParam);
	newnode->locParam = listCopy(from->locParam);
	newnode->chgParam = listCopy(from->chgParam);
V
Vadim B. Mikheev 已提交
94
	Node_Copy(from, newnode, initPlan);
95 96
	if (from->subPlan != NULL)
		newnode->subPlan = SS_pull_subplan(newnode->qual);
V
Vadim B. Mikheev 已提交
97 98 99
	else
		newnode->subPlan = NULL;
	newnode->nParamExec = from->nParamExec;
100 101 102
}

/* ----------------
103
 *		_copyPlan
104 105
 * ----------------
 */
106
static Plan *
107
_copyPlan(Plan *from)
108
{
109
	Plan	   *newnode = makeNode(Plan);
110 111 112 113 114 115 116 117

	/* ----------------
	 *	copy the node superclass fields
	 * ----------------
	 */
	CopyPlanFields(from, newnode);

	return newnode;
118 119 120 121
}


/* ----------------
122
 *		_copyResult
123 124
 * ----------------
 */
125
static Result *
126
_copyResult(Result *from)
127
{
128
	Result	   *newnode = makeNode(Result);
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143

	/* ----------------
	 *	copy node superclass fields
	 * ----------------
	 */
	CopyPlanFields((Plan *) from, (Plan *) newnode);

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
	Node_Copy(from, newnode, resconstantqual);
	Node_Copy(from, newnode, resstate);

	return newnode;
144 145 146
}

/* ----------------
147
 *		_copyAppend
148 149
 * ----------------
 */
150
static Append *
B
Bruce Momjian 已提交
151
_copyAppend(Append *from)
152
{
153
	Append	   *newnode = makeNode(Append);
154 155 156 157 158 159 160 161 162 163 164

	/* ----------------
	 *	copy node superclass fields
	 * ----------------
	 */
	CopyPlanFields((Plan *) from, (Plan *) newnode);

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
165 166 167 168 169
	Node_Copy(from, newnode, appendplans);
	Node_Copy(from, newnode, unionrtables);
	newnode->inheritrelid = from->inheritrelid;
	Node_Copy(from, newnode, inheritrtable);
	Node_Copy(from, newnode, appendstate);
170 171

	return newnode;
172 173 174 175
}


/* ----------------
176
 *		CopyScanFields
177
 *
178 179
 *		This function copies the fields of the Scan node.  It is used by
 *		all the copy functions for classes which inherit from Scan.
180 181 182
 * ----------------
 */
static void
183
CopyScanFields(Scan *from, Scan *newnode)
184
{
185 186 187
	newnode->scanrelid = from->scanrelid;
	Node_Copy(from, newnode, scanstate);
	return;
188 189 190
}

/* ----------------
191
 *		_copyScan
192 193
 * ----------------
 */
194
static Scan *
195
_copyScan(Scan *from)
196
{
197
	Scan	   *newnode = makeNode(Scan);
198 199 200 201 202 203

	/* ----------------
	 *	copy node superclass fields
	 * ----------------
	 */
	CopyPlanFields((Plan *) from, (Plan *) newnode);
B
Bruce Momjian 已提交
204
	CopyScanFields((Scan *) from, (Scan *) newnode);
205 206

	return newnode;
207 208 209
}

/* ----------------
210
 *		_copySeqScan
211 212 213
 * ----------------
 */
static SeqScan *
214
_copySeqScan(SeqScan *from)
215
{
216
	SeqScan    *newnode = makeNode(SeqScan);
217 218 219 220 221 222 223 224 225

	/* ----------------
	 *	copy node superclass fields
	 * ----------------
	 */
	CopyPlanFields((Plan *) from, (Plan *) newnode);
	CopyScanFields((Scan *) from, (Scan *) newnode);

	return newnode;
226 227 228
}

/* ----------------
229
 *		_copyIndexScan
230 231 232
 * ----------------
 */
static IndexScan *
233
_copyIndexScan(IndexScan *from)
234
{
235
	IndexScan  *newnode = makeNode(IndexScan);
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252

	/* ----------------
	 *	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, indxstate);

	return newnode;
253 254 255
}

/* ----------------
256
 *		CopyJoinFields
257
 *
258 259
 *		This function copies the fields of the Join node.  It is used by
 *		all the copy functions for classes which inherit from Join.
260 261 262
 * ----------------
 */
static void
263
CopyJoinFields(Join *from, Join *newnode)
264
{
265 266
	/* nothing extra */
	return;
267 268 269 270
}


/* ----------------
271
 *		_copyJoin
272 273
 * ----------------
 */
274
static Join *
275
_copyJoin(Join *from)
276
{
277
	Join	   *newnode = makeNode(Join);
278 279 280 281 282 283 284 285 286

	/* ----------------
	 *	copy node superclass fields
	 * ----------------
	 */
	CopyPlanFields((Plan *) from, (Plan *) newnode);
	CopyJoinFields(from, newnode);

	return newnode;
287 288 289 290
}


/* ----------------
291
 *		_copyNestLoop
292 293 294
 * ----------------
 */
static NestLoop *
295
_copyNestLoop(NestLoop *from)
296
{
297
	NestLoop   *newnode = makeNode(NestLoop);
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312

	/* ----------------
	 *	copy node superclass fields
	 * ----------------
	 */
	CopyPlanFields((Plan *) from, (Plan *) newnode);
	CopyJoinFields((Join *) from, (Join *) newnode);

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
	Node_Copy(from, newnode, nlstate);

	return newnode;
313 314 315 316
}


/* ----------------
317
 *		_copyMergeJoin
318 319 320
 * ----------------
 */
static MergeJoin *
321
_copyMergeJoin(MergeJoin *from)
322
{
323
	MergeJoin  *newnode = makeNode(MergeJoin);
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350

	/* ----------------
	 *	copy node superclass fields
	 * ----------------
	 */
	CopyPlanFields((Plan *) from, (Plan *) newnode);
	CopyJoinFields((Join *) from, (Join *) newnode);

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
	Node_Copy(from, newnode, mergeclauses);

	newnode->mergesortop = from->mergesortop;

	newnode->mergerightorder = (Oid *) palloc(sizeof(Oid) * 2);
	newnode->mergerightorder[0] = from->mergerightorder[0];
	newnode->mergerightorder[1] = 0;

	newnode->mergeleftorder = (Oid *) palloc(sizeof(Oid) * 2);
	newnode->mergeleftorder[0] = from->mergeleftorder[0];
	newnode->mergeleftorder[1] = 0;

	Node_Copy(from, newnode, mergestate);

	return newnode;
351 352 353
}

/* ----------------
354
 *		_copyHashJoin
355 356 357
 * ----------------
 */
static HashJoin *
358
_copyHashJoin(HashJoin *from)
359
{
360
	HashJoin   *newnode = makeNode(HashJoin);
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384

	/* ----------------
	 *	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;

	Node_Copy(from, newnode, hashjoinstate);

	newnode->hashjointable = from->hashjointable;
	newnode->hashjointablekey = from->hashjointablekey;
	newnode->hashjointablesize = from->hashjointablesize;
	newnode->hashdone = from->hashdone;

	return newnode;
385 386 387 388
}


/* ----------------
389
 *		CopyTempFields
390
 *
391 392
 *		This function copies the fields of the Temp node.  It is used by
 *		all the copy functions for classes which inherit from Temp.
393 394 395
 * ----------------
 */
static void
396
CopyTempFields(Temp *from, Temp *newnode)
397
{
398 399 400
	newnode->tempid = from->tempid;
	newnode->keycount = from->keycount;
	return;
401 402 403 404
}


/* ----------------
405
 *		_copyTemp
406 407
 * ----------------
 */
408
static Temp *
409
_copyTemp(Temp *from)
410
{
411
	Temp	   *newnode = makeNode(Temp);
412 413 414 415 416 417 418 419 420

	/* ----------------
	 *	copy node superclass fields
	 * ----------------
	 */
	CopyPlanFields((Plan *) from, (Plan *) newnode);
	CopyTempFields(from, newnode);

	return newnode;
421 422 423
}

/* ----------------
424
 *		_copyMaterial
425 426 427
 * ----------------
 */
static Material *
428
_copyMaterial(Material *from)
429
{
430
	Material   *newnode = makeNode(Material);
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445

	/* ----------------
	 *	copy node superclass fields
	 * ----------------
	 */
	CopyPlanFields((Plan *) from, (Plan *) newnode);
	CopyTempFields((Temp *) from, (Temp *) newnode);

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
	Node_Copy(from, newnode, matstate);

	return newnode;
446 447 448 449
}


/* ----------------
450
 *		_copySort
451 452
 * ----------------
 */
453
static Sort *
454
_copySort(Sort *from)
455
{
456
	Sort	   *newnode = makeNode(Sort);
457 458 459 460 461 462 463 464 465 466 467 468 469

	/* ----------------
	 *	copy node superclass fields
	 * ----------------
	 */
	CopyPlanFields((Plan *) from, (Plan *) newnode);
	CopyTempFields((Temp *) from, (Temp *) newnode);

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
	Node_Copy(from, newnode, sortstate);
B
Bruce Momjian 已提交
470 471
	Node_Copy(from, newnode, psortstate);
	newnode->cleaned = from->cleaned;
472

473
	return newnode;
474 475
}

V
Vadim B. Mikheev 已提交
476 477 478 479 480 481 482 483 484

/* ----------------
 *		_copyGroup
 * ----------------
 */
static Group *
_copyGroup(Group *from)
{
	Group	   *newnode = makeNode(Group);
485

V
Vadim B. Mikheev 已提交
486
	CopyPlanFields((Plan *) from, (Plan *) newnode);
B
Bruce Momjian 已提交
487

V
Vadim B. Mikheev 已提交
488 489
	newnode->tuplePerGroup = from->tuplePerGroup;
	newnode->numCols = from->numCols;
490 491
	newnode->grpColIdx = palloc(from->numCols * sizeof(AttrNumber));
	memcpy(newnode->grpColIdx, from->grpColIdx, from->numCols * sizeof(AttrNumber));
V
Vadim B. Mikheev 已提交
492 493 494 495 496
	Node_Copy(from, newnode, grpstate);

	return newnode;
}

497
/* ---------------
498
 *	_copyAgg
499 500
 * --------------
 */
501
static Agg *
B
Bruce Momjian 已提交
502
_copyAgg(Agg *from)
503
{
504
	Agg		   *newnode = makeNode(Agg);
505 506 507

	CopyPlanFields((Plan *) from, (Plan *) newnode);

508
	Node_Copy(from, newnode, aggs);
509 510 511
	Node_Copy(from, newnode, aggstate);

	return newnode;
512 513
}

514 515 516 517 518 519 520
/* ---------------
 *	_copyGroupClause
 * --------------
 */
static GroupClause *
_copyGroupClause(GroupClause *from)
{
521
	GroupClause *newnode = makeNode(GroupClause);
522

523 524
	Node_Copy(from, newnode, entry);
	newnode->grpOpoid = from->grpOpoid;
525

526
	return newnode;
527 528
}

529 530

/* ----------------
531
 *		_copyUnique
532 533
 * ----------------
 */
534
static Unique *
535
_copyUnique(Unique *from)
536
{
537
	Unique	   *newnode = makeNode(Unique);
538 539 540 541 542 543 544 545 546 547 548 549

	/* ----------------
	 *	copy node superclass fields
	 * ----------------
	 */
	CopyPlanFields((Plan *) from, (Plan *) newnode);
	CopyTempFields((Temp *) from, (Temp *) newnode);

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
550 551 552 553
	if (newnode->uniqueAttr)
		newnode->uniqueAttr = pstrdup(from->uniqueAttr);
	else
		newnode->uniqueAttr = NULL;
B
Bruce Momjian 已提交
554
	newnode->uniqueAttrNum = from->uniqueAttrNum;
555 556 557
	Node_Copy(from, newnode, uniquestate);

	return newnode;
558 559 560 561
}


/* ----------------
562
 *		_copyHash
563 564
 * ----------------
 */
565
static Hash *
566
_copyHash(Hash *from)
567
{
568
	Hash	   *newnode = makeNode(Hash);
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587

	/* ----------------
	 *	copy node superclass fields
	 * ----------------
	 */
	CopyPlanFields((Plan *) from, (Plan *) newnode);

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
	Node_Copy(from, newnode, hashkey);
	Node_Copy(from, newnode, hashstate);

	newnode->hashtable = from->hashtable;
	newnode->hashtablekey = from->hashtablekey;
	newnode->hashtablesize = from->hashtablesize;

	return newnode;
588 589
}

V
Vadim B. Mikheev 已提交
590 591 592
static SubPlan *
_copySubPlan(SubPlan *from)
{
593 594
	SubPlan    *newnode = makeNode(SubPlan);

V
Vadim B. Mikheev 已提交
595 596 597
	Node_Copy(from, newnode, plan);
	newnode->plan_id = from->plan_id;
	Node_Copy(from, newnode, rtable);
598 599
	newnode->setParam = listCopy(from->setParam);
	newnode->parParam = listCopy(from->parParam);
V
Vadim B. Mikheev 已提交
600 601 602 603 604 605
	Node_Copy(from, newnode, sublink);
	newnode->shutdown = from->shutdown;

	return newnode;
}

606
/* ****************************************************************
607
 *					   primnodes.h copy functions
608 609 610 611
 * ****************************************************************
 */

/* ----------------
612
 *		_copyResdom
613 614
 * ----------------
 */
615
static Resdom *
616
_copyResdom(Resdom *from)
617
{
618
	Resdom	   *newnode = makeNode(Resdom);
619 620 621

	newnode->resno = from->resno;
	newnode->restype = from->restype;
622
	newnode->restypmod = from->restypmod;
623 624

	if (from->resname != NULL)
B
Bruce Momjian 已提交
625
		newnode->resname = pstrdup(from->resname);
626 627 628 629 630
	newnode->reskey = from->reskey;
	newnode->reskeyop = from->reskeyop;
	newnode->resjunk = from->resjunk;

	return newnode;
631 632
}

633
static Fjoin *
634
_copyFjoin(Fjoin *from)
635
{
636
	Fjoin	   *newnode = makeNode(Fjoin);
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653

	/* ----------------
	 *	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));

B
Bruce Momjian 已提交
654 655
	newnode->fj_alwaysDone = (BoolPtr)
		palloc((from->fj_nNodes) * sizeof(bool));
656 657 658 659 660 661
	memmove(from->fj_alwaysDone,
			newnode->fj_alwaysDone,
			(from->fj_nNodes) * sizeof(bool));


	return newnode;
662 663 664
}

/* ----------------
665
 *		_copyExpr
666 667
 * ----------------
 */
668
static Expr *
669
_copyExpr(Expr *from)
670
{
671
	Expr	   *newnode = makeNode(Expr);
672 673 674 675 676 677 678 679 680 681 682 683

	/* ----------------
	 *	copy node superclass fields
	 * ----------------
	 */
	newnode->typeOid = from->typeOid;
	newnode->opType = from->opType;

	Node_Copy(from, newnode, oper);
	Node_Copy(from, newnode, args);

	return newnode;
684 685 686
}

/* ----------------
687
 *		_copyVar
688 689
 * ----------------
 */
690
static Var *
691
_copyVar(Var *from)
692
{
693
	Var		   *newnode = makeNode(Var);
694 695 696 697 698 699 700 701

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
	newnode->varno = from->varno;
	newnode->varattno = from->varattno;
	newnode->vartype = from->vartype;
702
	newnode->vartypmod = from->vartypmod;
703
	newnode->varlevelsup = from->varlevelsup;
704 705 706 707 708

	newnode->varnoold = from->varnoold;
	newnode->varoattno = from->varoattno;

	return newnode;
709 710 711
}

/* ----------------
712
 *		_copyOper
713 714
 * ----------------
 */
715
static Oper *
716
_copyOper(Oper *from)
717
{
718
	Oper	   *newnode = makeNode(Oper);
719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736

	/* ----------------
	 *	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;
737 738 739
}

/* ----------------
740
 *		_copyConst
741 742
 * ----------------
 */
743
static Const *
744
_copyConst(Const *from)
745
{
746 747
	static Oid	cached_type;
	static bool cached_typbyval;
748

749
	Const	   *newnode = makeNode(Const);
750

751
	/* ----------------
752
	 *	copy remainder of node
753 754
	 * ----------------
	 */
755 756 757
	newnode->consttype = from->consttype;
	newnode->constlen = from->constlen;

758
	/* ----------------
759 760
	 *	XXX super cheesy hack until parser/planner
	 *	puts in the right values here.
B
Bruce Momjian 已提交
761
	 *
762
	 *	But I like cheese.
763 764
	 * ----------------
	 */
B
Bruce Momjian 已提交
765
	if (!from->constisnull && cached_type != from->consttype)
766
	{
767 768
		HeapTuple	typeTuple;
		TypeTupleForm typeStruct;
769 770 771 772 773 774 775 776 777 778 779

		/* ----------------
		 *	 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);

780
		/* ----------------
781 782
		 *	 get the type length and by-value from the type tuple and
		 *	 save the information in our one element cache.
783 784
		 * ----------------
		 */
785 786 787 788 789 790 791 792 793 794 795
		Assert(PointerIsValid(typeTuple));

		typeStruct = (TypeTupleForm) GETSTRUCT(typeTuple);
		cached_typbyval = (typeStruct)->typbyval ? true : false;
		cached_type = from->consttype;
	}

	from->constbyval = cached_typbyval;

	if (!from->constisnull)
	{
796
		/* ----------------
797 798 799
		 *		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...
800 801
		 * ----------------
		 */
802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832
		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.
				 * ----------------
				 */
833
				int			length;
834

B
Bruce Momjian 已提交
835
				length = VARSIZE(from->constvalue);
836 837 838 839 840 841 842 843 844 845
				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;
B
Bruce Momjian 已提交
846 847
	newnode->constisset = from->constisset;
	newnode->constiscast = from->constiscast;
848 849

	return newnode;
850 851 852
}

/* ----------------
853
 *		_copyParam
854 855
 * ----------------
 */
856
static Param *
857
_copyParam(Param *from)
858
{
859
	Param	   *newnode = makeNode(Param);
860 861 862 863 864 865 866 867 868 869 870 871 872 873

	/* ----------------
	 *	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;
874 875 876
}

/* ----------------
877
 *		_copyFunc
878 879
 * ----------------
 */
880
static Func *
881
_copyFunc(Func *from)
882
{
883
	Func	   *newnode = makeNode(Func);
884 885 886 887 888 889 890 891 892 893 894 895 896 897

	/* ----------------
	 *	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;
898 899 900
}

/* ----------------
901
 *		_copyAggreg
902 903
 * ----------------
 */
904
static Aggreg *
B
Bruce Momjian 已提交
905
_copyAggreg(Aggreg *from)
906
{
907
	Aggreg	   *newnode = makeNode(Aggreg);
908 909 910 911 912 913 914 915 916 917

	/* ----------------
	 *	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;
B
Bruce Momjian 已提交
918
	newnode->usenulls = from->usenulls;
919 920

	return newnode;
921 922
}

923 924 925 926 927 928 929
/* ----------------
 *		_copySubLink
 * ----------------
 */
static SubLink *
_copySubLink(SubLink *from)
{
930
	SubLink    *newnode = makeNode(SubLink);
931 932 933 934 935 936 937 938

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
	newnode->subLinkType = from->subLinkType;
	newnode->useor = from->useor;
	Node_Copy(from, newnode, lefthand);
B
Bruce Momjian 已提交
939
	Node_Copy(from, newnode, oper);
940 941 942 943 944
	Node_Copy(from, newnode, subselect);

	return newnode;
}

945
static Array *
B
Bruce Momjian 已提交
946
_copyArray(Array *from)
947
{
948
	Array	   *newnode = makeNode(Array);
949 950 951 952 953 954 955 956 957 958 959 960 961 962

	/* ----------------
	 *	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;
963 964 965
}

static ArrayRef *
B
Bruce Momjian 已提交
966
_copyArrayRef(ArrayRef *from)
967
{
968
	ArrayRef   *newnode = makeNode(ArrayRef);
969 970 971 972 973 974 975

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
	newnode->refattrlength = from->refattrlength;
	newnode->refelemlength = from->refelemlength;
B
Bruce Momjian 已提交
976
	newnode->refelemtype = from->refelemtype;
977 978 979 980 981 982 983 984
	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;
985 986 987
}

/* ****************************************************************
988
 *						relation.h copy functions
989 990 991 992
 * ****************************************************************
 */

/* ----------------
993
 *		_copyRel
994 995 996
 * ----------------
 */
/*
997
 ** when you change this, also make sure to fix up xfunc_copyRel in
998
 ** planner/path/xfunc.c accordingly!!!
999
 **			-- JMH, 8/2/93
1000
 */
B
Bruce Momjian 已提交
1001 1002
static RelOptInfo *
_copyRel(RelOptInfo *from)
1003
{
B
Bruce Momjian 已提交
1004
	RelOptInfo		   *newnode = makeNode(RelOptInfo);
1005 1006
	int			i,
				len;
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032

	/* ----------------
	 *	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, unorderedpath);
	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;
1033
	}
1034 1035 1036 1037 1038 1039 1040 1041 1042

	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;
1043
	}
1044

B
Bruce Momjian 已提交
1045 1046 1047
	newnode->relam = from->relam;
	newnode->indproc = from->indproc;
	Node_Copy(from, newnode, indpred);
1048

1049 1050 1051 1052 1053 1054 1055 1056
	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;
1057
	}
1058 1059 1060 1061 1062 1063 1064

	Node_Copy(from, newnode, clauseinfo);
	Node_Copy(from, newnode, joininfo);
	Node_Copy(from, newnode, innerjoin);
	Node_Copy(from, newnode, superrels);

	return newnode;
1065 1066 1067
}

/* ----------------
1068
 *		CopyPathFields
1069
 *
1070 1071
 *		This function copies the fields of the Path node.  It is used by
 *		all the copy functions for classes which inherit from Path.
1072 1073 1074
 * ----------------
 */
static void
1075
CopyPathFields(Path *from, Path *newnode)
1076
{
1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
	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;

	newnode->p_ordering.ordtype = from->p_ordering.ordtype;
	if (from->p_ordering.ordtype == SORTOP_ORDER)
	{
1091 1092 1093
		int			len,
					i;
		Oid		   *ordering = from->p_ordering.ord.sortop;
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114

		if (ordering)
		{
			for (len = 0; ordering[len] != 0; len++)
				;
			newnode->p_ordering.ord.sortop =
				(Oid *) palloc(sizeof(Oid) * (len + 1));
			for (i = 0; i < len; i++)
				newnode->p_ordering.ord.sortop[i] = ordering[i];
			newnode->p_ordering.ord.sortop[len] = 0;
		}
	}
	else
		Node_Copy(from, newnode, p_ordering.ord.merge);

	Node_Copy(from, newnode, keys);

	newnode->outerjoincost = from->outerjoincost;

	newnode->joinid = listCopy(from->joinid);
	Node_Copy(from, newnode, locclauseinfo);
1115 1116 1117
}

/* ----------------
1118
 *		_copyPath
1119 1120
 * ----------------
 */
1121
static Path *
1122
_copyPath(Path *from)
1123
{
1124
	Path	   *newnode = makeNode(Path);
1125 1126 1127 1128

	CopyPathFields(from, newnode);

	return newnode;
1129 1130 1131
}

/* ----------------
1132
 *		_copyIndexPath
1133 1134 1135
 * ----------------
 */
static IndexPath *
1136
_copyIndexPath(IndexPath *from)
1137
{
1138
	IndexPath  *newnode = makeNode(IndexPath);
1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154

	/* ----------------
	 *	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)
	{
1155 1156
		int			i,
					len;
1157 1158 1159 1160 1161 1162 1163

		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;
1164
	}
1165 1166

	return newnode;
1167 1168 1169
}

/* ----------------
1170
 *		CopyJoinPathFields
1171
 *
1172 1173
 *		This function copies the fields of the JoinPath node.  It is used by
 *		all the copy functions for classes which inherit from JoinPath.
1174 1175 1176
 * ----------------
 */
static void
1177
CopyJoinPathFields(JoinPath *from, JoinPath *newnode)
1178
{
1179 1180 1181
	Node_Copy(from, newnode, pathclauseinfo);
	Node_Copy(from, newnode, outerjoinpath);
	Node_Copy(from, newnode, innerjoinpath);
1182 1183 1184
}

/* ----------------
1185
 *		_copyJoinPath
1186 1187 1188
 * ----------------
 */
static JoinPath *
1189
_copyJoinPath(JoinPath *from)
1190
{
1191
	JoinPath   *newnode = makeNode(JoinPath);
1192 1193 1194 1195 1196 1197 1198 1199 1200

	/* ----------------
	 *	copy the node superclass fields
	 * ----------------
	 */
	CopyPathFields((Path *) from, (Path *) newnode);
	CopyJoinPathFields(from, newnode);

	return newnode;
1201 1202 1203
}

/* ----------------
1204
 *		_copyMergePath
1205 1206 1207
 * ----------------
 */
static MergePath *
1208
_copyMergePath(MergePath *from)
1209
{
1210
	MergePath  *newnode = makeNode(MergePath);
1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227

	/* ----------------
	 *	copy the node superclass fields
	 * ----------------
	 */
	CopyPathFields((Path *) from, (Path *) newnode);
	CopyJoinPathFields((JoinPath *) from, (JoinPath *) 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;
1228 1229 1230
}

/* ----------------
1231
 *		_copyHashPath
1232 1233 1234
 * ----------------
 */
static HashPath *
1235
_copyHashPath(HashPath *from)
1236
{
1237
	HashPath   *newnode = makeNode(HashPath);
1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254

	/* ----------------
	 *	copy the node superclass fields
	 * ----------------
	 */
	CopyPathFields((Path *) from, (Path *) newnode);
	CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
	Node_Copy(from, newnode, path_hashclauses);
	Node_Copy(from, newnode, outerhashkeys);
	Node_Copy(from, newnode, innerhashkeys);

	return newnode;
1255 1256 1257
}

/* ----------------
1258
 *		_copyOrderKey
1259 1260 1261
 * ----------------
 */
static OrderKey *
1262
_copyOrderKey(OrderKey *from)
1263
{
1264
	OrderKey   *newnode = makeNode(OrderKey);
1265 1266 1267 1268 1269 1270 1271 1272 1273

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
	newnode->attribute_number = from->attribute_number;
	newnode->array_index = from->array_index;

	return newnode;
1274 1275 1276 1277
}


/* ----------------
1278
 *		_copyJoinKey
1279 1280 1281
 * ----------------
 */
static JoinKey *
1282
_copyJoinKey(JoinKey *from)
1283
{
1284
	JoinKey    *newnode = makeNode(JoinKey);
1285 1286 1287 1288 1289 1290 1291 1292 1293

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
	Node_Copy(from, newnode, outer);
	Node_Copy(from, newnode, inner);

	return newnode;
1294 1295 1296
}

/* ----------------
1297
 *		_copyMergeOrder
1298 1299 1300
 * ----------------
 */
static MergeOrder *
1301
_copyMergeOrder(MergeOrder *from)
1302
{
1303
	MergeOrder *newnode = makeNode(MergeOrder);
1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315

	/* ----------------
	 *	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;
1316 1317 1318
}

/* ----------------
1319
 *		_copyCInfo
1320 1321
 * ----------------
 */
1322
static CInfo *
1323
_copyCInfo(CInfo *from)
1324
{
1325
	CInfo	   *newnode = makeNode(CInfo);
1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341

	/* ----------------
	 *	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, mergesortorder);
	newnode->hashjoinoperator = from->hashjoinoperator;
	newnode->cinfojoinid = listCopy(from->cinfojoinid);

	return newnode;
1342 1343 1344
}

/* ----------------
1345
 *		CopyJoinMethodFields
1346
 *
1347 1348
 *		This function copies the fields of the JoinMethod node.  It is used by
 *		all the copy functions for classes which inherit from JoinMethod.
1349 1350 1351
 * ----------------
 */
static void
1352
CopyJoinMethodFields(JoinMethod *from, JoinMethod *newnode)
1353
{
1354 1355 1356
	Node_Copy(from, newnode, jmkeys);
	Node_Copy(from, newnode, clauses);
	return;
1357 1358 1359
}

/* ----------------
1360
 *		_copyJoinMethod
1361 1362 1363
 * ----------------
 */
static JoinMethod *
1364
_copyJoinMethod(JoinMethod *from)
1365
{
1366
	JoinMethod *newnode = makeNode(JoinMethod);
1367 1368 1369 1370

	CopyJoinMethodFields(from, newnode);

	return newnode;
1371 1372 1373
}

/* ----------------
1374
 *		_copyHInfo
1375 1376
 * ----------------
 */
1377
static HInfo *
1378
_copyHInfo(HInfo *from)
1379
{
1380
	HInfo	   *newnode = makeNode(HInfo);
1381 1382 1383 1384 1385

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
1386
	CopyJoinMethodFields((JoinMethod *) from, (JoinMethod *) newnode);
1387 1388 1389
	newnode->hashop = from->hashop;

	return newnode;
1390 1391 1392
}

/* ----------------
1393
 *		_copyMInfo
1394 1395
 * ----------------
 */
1396
static MInfo *
1397
_copyMInfo(MInfo *from)
1398
{
1399
	MInfo	   *newnode = makeNode(MInfo);
1400 1401 1402 1403 1404

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
1405
	CopyJoinMethodFields((JoinMethod *) from, (JoinMethod *) newnode);
1406 1407 1408
	Node_Copy(from, newnode, m_ordering);

	return newnode;
1409 1410 1411
}

/* ----------------
1412
 *		_copyJInfo
1413 1414
 * ----------------
 */
1415
static JInfo *
1416
_copyJInfo(JInfo *from)
1417
{
1418
	JInfo	   *newnode = makeNode(JInfo);
1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431

	/* ----------------
	 *	copy remainder of node
	 * ----------------
	 */
	newnode->otherrels = listCopy(from->otherrels);
	Node_Copy(from, newnode, jinfoclauseinfo);

	newnode->mergesortable = from->mergesortable;
	newnode->hashjoinable = from->hashjoinable;
	newnode->inactive = from->inactive;

	return newnode;
1432 1433
}

1434
static Iter *
1435
_copyIter(Iter *from)
1436
{
1437
	Iter	   *newnode = makeNode(Iter);
1438 1439 1440

	Node_Copy(from, newnode, iterexpr);
	newnode->itertype = from->itertype;
1441

1442
	return newnode;
1443 1444
}

1445
static Stream *
1446
_copyStream(Stream *from)
1447
{
1448
	Stream	   *newnode = makeNode(Stream);
1449 1450 1451 1452

	newnode->pathptr = from->pathptr;
	newnode->cinfo = from->cinfo;
	newnode->clausetype = from->clausetype;
B
Bruce Momjian 已提交
1453

1454 1455 1456 1457 1458 1459
	newnode->upstream = (StreamPtr) NULL;		/* only copy nodes
												 * downwards! */
	Node_Copy(from, newnode, downstream);
	if (newnode->downstream)
		((Stream *) newnode->downstream)->upstream = (Stream *) newnode;

B
Bruce Momjian 已提交
1460 1461 1462 1463
	newnode->groupup = from->groupup;
	newnode->groupcost = from->groupcost;
	newnode->groupsel = from->groupsel;

1464
	return newnode;
1465 1466 1467
}

/* ****************
1468
 *			  parsenodes.h routines have no copy functions
1469 1470 1471 1472
 * ****************
 */

static TargetEntry *
1473
_copyTargetEntry(TargetEntry *from)
1474
{
1475
	TargetEntry *newnode = makeNode(TargetEntry);
1476

1477 1478 1479 1480
	Node_Copy(from, newnode, resdom);
	Node_Copy(from, newnode, fjoin);
	Node_Copy(from, newnode, expr);
	return newnode;
1481 1482 1483
}

static RangeTblEntry *
1484
_copyRangeTblEntry(RangeTblEntry *from)
1485
{
1486
	RangeTblEntry *newnode = makeNode(RangeTblEntry);
1487 1488 1489 1490 1491

	if (from->relname)
		newnode->relname = pstrdup(from->relname);
	if (from->refname)
		newnode->refname = pstrdup(from->refname);
B
Bruce Momjian 已提交
1492 1493 1494
	newnode->relid = from->relid;
	newnode->inh = from->inh;
	newnode->inFromCl = from->inFromCl;
1495 1496
	newnode->skipAcl = from->skipAcl;

1497 1498

	return newnode;
1499 1500 1501
}

static SortClause *
1502
_copySortClause(SortClause *from)
1503
{
1504
	SortClause *newnode = makeNode(SortClause);
1505 1506 1507

	Node_Copy(from, newnode, resdom);
	newnode->opoid = from->opoid;
1508

1509
	return newnode;
1510 1511
}

1512
static A_Const *
B
Bruce Momjian 已提交
1513
_copyAConst(A_Const *from)
1514
{
1515
	A_Const    *newnode = makeNode(A_Const);
1516

1517 1518
	newnode->val = *((Value *) (copyObject(&(from->val))));
	Node_Copy(from, newnode, typename);
1519

1520
	return newnode;
1521 1522 1523
}

static TypeName *
1524
_copyTypeName(TypeName *from)
1525
{
1526
	TypeName   *newnode = makeNode(TypeName);
1527 1528 1529

	if (from->name)
		newnode->name = pstrdup(from->name);
B
Bruce Momjian 已提交
1530
	newnode->timezone = from->timezone;
1531
	newnode->setof = from->setof;
1532
	newnode->typmod = from->typmod;
1533 1534 1535
	Node_Copy(from, newnode, arrayBounds);

	return newnode;
1536 1537
}

1538
static Query *
1539
_copyQuery(Query *from)
1540
{
1541
	Query	   *newnode = makeNode(Query);
1542

1543
	newnode->commandType = from->commandType;
B
Bruce Momjian 已提交
1544 1545 1546 1547 1548
	if (from->utilityStmt && nodeTag(from->utilityStmt) == T_NotifyStmt)
	{
		NotifyStmt *from_notify = (NotifyStmt *) from->utilityStmt;
		NotifyStmt *n = makeNode(NotifyStmt);

B
Bruce Momjian 已提交
1549
		n->relname = pstrdup(from_notify->relname);
B
Bruce Momjian 已提交
1550 1551
		newnode->utilityStmt = (Node *) n;
	}
1552 1553 1554 1555
	newnode->resultRelation = from->resultRelation;
	if (from->into)
		newnode->into = pstrdup(from->into);
	newnode->isPortal = from->isPortal;
B
Bruce Momjian 已提交
1556 1557
	newnode->isBinary = from->isBinary;
	newnode->unionall = from->unionall;
1558
	if (from->uniqueFlag)
B
Bruce Momjian 已提交
1559
		newnode->uniqueFlag = pstrdup(from->uniqueFlag);
1560
	Node_Copy(from, newnode, sortClause);
B
Bruce Momjian 已提交
1561
	Node_Copy(from, newnode, rtable);
1562 1563 1564
	Node_Copy(from, newnode, targetList);
	Node_Copy(from, newnode, qual);

1565
	Node_Copy(from, newnode, groupClause);
B
Bruce Momjian 已提交
1566
	Node_Copy(from, newnode, havingQual);
1567

1568
	newnode->hasAggs = from->hasAggs;
1569
	newnode->hasSubLinks = from->hasSubLinks;
B
Bruce Momjian 已提交
1570 1571 1572

	if (from->unionClause)
	{
1573 1574
		List	   *ulist,
				   *temp_list = NIL;
B
Bruce Momjian 已提交
1575 1576

		foreach(ulist, from->unionClause)
1577
			temp_list = lappend(temp_list, copyObject(lfirst(ulist)));
B
Bruce Momjian 已提交
1578 1579
		newnode->unionClause = temp_list;
	}
1580

1581
	return newnode;
1582 1583 1584 1585
}


/* ****************
1586
 *			  mnodes.h routines have no copy functions
1587 1588 1589 1590
 * ****************
 */

/* ****************************************************************
1591
 *					pg_list.h copy functions
1592 1593 1594
 * ****************************************************************
 */

1595
static Value *
1596
_copyValue(Value *from)
1597
{
1598
	Value	   *newnode = makeNode(Value);
1599 1600 1601 1602

	newnode->type = from->type;
	switch (from->type)
	{
1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613
		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;
1614 1615
	}
	return newnode;
1616 1617 1618
}

/* ----------------
1619 1620
 *		copyObject returns a copy of the node or list. If it is a list, it
 *		recursively copies its items.
1621 1622
 * ----------------
 */
1623
void *
1624 1625
copyObject(void *from)
{
1626
	void	   *retval;
1627

1628 1629 1630
	if (from == NULL)
		return NULL;
	switch (nodeTag(from))
1631
	{
1632

1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674
			/*
			 * 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_Temp:
			retval = _copyTemp(from);
			break;
		case T_Material:
			retval = _copyMaterial(from);
			break;
		case T_Sort:
			retval = _copySort(from);
			break;
V
Vadim B. Mikheev 已提交
1675 1676 1677
		case T_Group:
			retval = _copyGroup(from);
			break;
1678 1679 1680
		case T_Agg:
			retval = _copyAgg(from);
			break;
1681 1682 1683
		case T_GroupClause:
			retval = _copyGroupClause(from);
			break;
1684 1685 1686 1687 1688 1689
		case T_Unique:
			retval = _copyUnique(from);
			break;
		case T_Hash:
			retval = _copyHash(from);
			break;
V
Vadim B. Mikheev 已提交
1690 1691 1692
		case T_SubPlan:
			retval = _copySubPlan(from);
			break;
1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729

			/*
			 * 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;
		case T_Aggreg:
			retval = _copyAggreg(from);
			break;
1730 1731 1732
		case T_SubLink:
			retval = _copySubLink(from);
			break;
1733 1734 1735 1736

			/*
			 * RELATION NODES
			 */
B
Bruce Momjian 已提交
1737
		case T_RelOptInfo:
1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818
			retval = _copyRel(from);
			break;
		case T_Path:
			retval = _copyPath(from);
			break;
		case T_IndexPath:
			retval = _copyIndexPath(from);
			break;
		case T_JoinPath:
			retval = _copyJoinPath(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_CInfo:
			retval = _copyCInfo(from);
			break;
		case T_JoinMethod:
			retval = _copyJoinMethod(from);
			break;
		case T_HInfo:
			retval = _copyHInfo(from);
			break;
		case T_MInfo:
			retval = _copyMInfo(from);
			break;
		case T_JInfo:
			retval = _copyJInfo(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_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,
1819
						   *l;
1820
				List	   *newlist = NIL,
1821 1822
						   *nl = NIL;

1823
				foreach(l, list)
1824
				{
1825 1826 1827 1828 1829 1830 1831
					if (newlist == NIL)
						newlist = nl = lcons(copyObject(lfirst(l)), NIL);
					else
					{
						lnext(nl) = lcons(copyObject(lfirst(l)), NIL);
						nl = lnext(nl);
					}
1832
				}
1833
				retval = newlist;
1834
			}
1835 1836 1837 1838 1839
			break;
		default:
			elog(NOTICE, "copyObject: don't know how to copy %d", nodeTag(from));
			retval = from;
			break;
1840
	}
1841
	return retval;
1842
}