OSDN Git Service

First stage of reclaiming memory in executor by resetting short-term
[pg-rex/syncrep.git] / src / backend / nodes / copyfuncs.c
1 /*-------------------------------------------------------------------------
2  *
3  * copyfuncs.c
4  *        Copy functions for Postgres tree nodes.
5  *
6  * NOTE: a general convention when copying or comparing plan nodes is
7  * that we ignore the executor state subnode.  We do not need to look
8  * at it because no current uses of copyObject() or equal() need to
9  * deal with already-executing plan trees.  By leaving the state subnodes
10  * out, we avoid needing to write copy/compare routines for all the
11  * different executor state node types.
12  *
13  * Another class of nodes not currently handled is nodes that appear
14  * only in "raw" parsetrees (gram.y output not yet analyzed by the parser).
15  * Perhaps some day that will need to be supported.
16  *
17  *
18  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
19  * Portions Copyright (c) 1994, Regents of the University of California
20  *
21  * IDENTIFICATION
22  *        $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.116 2000/07/12 02:37:04 tgl Exp $
23  *
24  *-------------------------------------------------------------------------
25  */
26
27 #include "postgres.h"
28
29 #include "optimizer/clauses.h"
30 #include "optimizer/planmain.h"
31
32
33 /*
34  * Node_Copy
35  *        a macro to simplify calling of copyObject on the specified field
36  */
37 #define Node_Copy(from, newnode, field) \
38         ((newnode)->field = copyObject((from)->field))
39
40
41 /*
42  * listCopy
43  *        This copy function only copies the "cons-cells" of the list, not the
44  *        pointed-to objects.  (Use copyObject if you want a "deep" copy.)
45  *
46  *        We also use this function for copying lists of integers, which is
47  *        grotty but unlikely to break --- it could fail if sizeof(pointer)
48  *        is less than sizeof(int), but I don't know any such machines...
49  *
50  *        Note that copyObject will surely coredump if applied to a list
51  *        of integers!
52  */
53 List *
54 listCopy(List *list)
55 {
56         List       *newlist,
57                            *l,
58                            *nl;
59
60         /* rather ugly coding for speed... */
61         if (list == NIL)
62                 return NIL;
63
64         newlist = nl = lcons(lfirst(list), NIL);
65
66         foreach(l, lnext(list))
67         {
68                 lnext(nl) = lcons(lfirst(l), NIL);
69                 nl = lnext(nl);
70         }
71         return newlist;
72 }
73
74 /* ****************************************************************
75  *                                       plannodes.h copy functions
76  * ****************************************************************
77  */
78
79 /* ----------------
80  *              CopyPlanFields
81  *
82  *              This function copies the fields of the Plan node.  It is used by
83  *              all the copy functions for classes which inherit from Plan.
84  * ----------------
85  */
86 static void
87 CopyPlanFields(Plan *from, Plan *newnode)
88 {
89         newnode->startup_cost = from->startup_cost;
90         newnode->total_cost = from->total_cost;
91         newnode->plan_rows = from->plan_rows;
92         newnode->plan_width = from->plan_width;
93         /* state is NOT copied */
94         newnode->targetlist = copyObject(from->targetlist);
95         newnode->qual = copyObject(from->qual);
96         newnode->lefttree = copyObject(from->lefttree);
97         newnode->righttree = copyObject(from->righttree);
98         newnode->extParam = listCopy(from->extParam);
99         newnode->locParam = listCopy(from->locParam);
100         newnode->chgParam = listCopy(from->chgParam);
101         Node_Copy(from, newnode, initPlan);
102         /* subPlan list must point to subplans in the new subtree, not the old */
103         if (from->subPlan != NIL)
104                 newnode->subPlan = nconc(pull_subplans((Node *) newnode->targetlist),
105                                                                  pull_subplans((Node *) newnode->qual));
106         else
107                 newnode->subPlan = NIL;
108         newnode->nParamExec = from->nParamExec;
109 }
110
111 /* ----------------
112  *              _copyPlan
113  * ----------------
114  */
115 static Plan *
116 _copyPlan(Plan *from)
117 {
118         Plan       *newnode = makeNode(Plan);
119
120         /* ----------------
121          *      copy the node superclass fields
122          * ----------------
123          */
124         CopyPlanFields(from, newnode);
125
126         return newnode;
127 }
128
129
130 /* ----------------
131  *              _copyResult
132  * ----------------
133  */
134 static Result *
135 _copyResult(Result *from)
136 {
137         Result     *newnode = makeNode(Result);
138
139         /* ----------------
140          *      copy node superclass fields
141          * ----------------
142          */
143         CopyPlanFields((Plan *) from, (Plan *) newnode);
144
145         /* ----------------
146          *      copy remainder of node
147          * ----------------
148          */
149         Node_Copy(from, newnode, resconstantqual);
150
151         /*
152          * We must add subplans in resconstantqual to the new plan's subPlan
153          * list
154          */
155         if (from->plan.subPlan != NIL)
156                 newnode->plan.subPlan = nconc(newnode->plan.subPlan,
157                                                                 pull_subplans(newnode->resconstantqual));
158
159         return newnode;
160 }
161
162 /* ----------------
163  *              _copyAppend
164  * ----------------
165  */
166 static Append *
167 _copyAppend(Append *from)
168 {
169         Append     *newnode = makeNode(Append);
170
171         /* ----------------
172          *      copy node superclass fields
173          * ----------------
174          */
175         CopyPlanFields((Plan *) from, (Plan *) newnode);
176
177         /* ----------------
178          *      copy remainder of node
179          * ----------------
180          */
181         Node_Copy(from, newnode, appendplans);
182         Node_Copy(from, newnode, unionrtables);
183         newnode->inheritrelid = from->inheritrelid;
184         Node_Copy(from, newnode, inheritrtable);
185
186         return newnode;
187 }
188
189
190 /* ----------------
191  *              CopyScanFields
192  *
193  *              This function copies the fields of the Scan node.  It is used by
194  *              all the copy functions for classes which inherit from Scan.
195  * ----------------
196  */
197 static void
198 CopyScanFields(Scan *from, Scan *newnode)
199 {
200         newnode->scanrelid = from->scanrelid;
201         return;
202 }
203
204 /* ----------------
205  *              _copyScan
206  * ----------------
207  */
208 static Scan *
209 _copyScan(Scan *from)
210 {
211         Scan       *newnode = makeNode(Scan);
212
213         /* ----------------
214          *      copy node superclass fields
215          * ----------------
216          */
217         CopyPlanFields((Plan *) from, (Plan *) newnode);
218         CopyScanFields((Scan *) from, (Scan *) newnode);
219
220         return newnode;
221 }
222
223 /* ----------------
224  *              _copySeqScan
225  * ----------------
226  */
227 static SeqScan *
228 _copySeqScan(SeqScan *from)
229 {
230         SeqScan    *newnode = makeNode(SeqScan);
231
232         /* ----------------
233          *      copy node superclass fields
234          * ----------------
235          */
236         CopyPlanFields((Plan *) from, (Plan *) newnode);
237         CopyScanFields((Scan *) from, (Scan *) newnode);
238
239         return newnode;
240 }
241
242 /* ----------------
243  *              _copyIndexScan
244  * ----------------
245  */
246 static IndexScan *
247 _copyIndexScan(IndexScan *from)
248 {
249         IndexScan  *newnode = makeNode(IndexScan);
250
251         /* ----------------
252          *      copy node superclass fields
253          * ----------------
254          */
255         CopyPlanFields((Plan *) from, (Plan *) newnode);
256         CopyScanFields((Scan *) from, (Scan *) newnode);
257
258         /* ----------------
259          *      copy remainder of node
260          * ----------------
261          */
262         newnode->indxid = listCopy(from->indxid);
263         Node_Copy(from, newnode, indxqual);
264         Node_Copy(from, newnode, indxqualorig);
265         newnode->indxorderdir = from->indxorderdir;
266
267         /*
268          * We must add subplans in index quals to the new plan's subPlan list
269          */
270         if (from->scan.plan.subPlan != NIL)
271         {
272                 newnode->scan.plan.subPlan = nconc(newnode->scan.plan.subPlan,
273                                                           pull_subplans((Node *) newnode->indxqual));
274                 newnode->scan.plan.subPlan = nconc(newnode->scan.plan.subPlan,
275                                                   pull_subplans((Node *) newnode->indxqualorig));
276         }
277
278         return newnode;
279 }
280
281 /* ----------------
282  *                              _copyTidScan
283  * ----------------
284  */
285 static TidScan *
286 _copyTidScan(TidScan *from)
287 {
288         TidScan    *newnode = makeNode(TidScan);
289
290         /* ----------------
291          *      copy node superclass fields
292          * ----------------
293          */
294         CopyPlanFields((Plan *) from, (Plan *) newnode);
295         CopyScanFields((Scan *) from, (Scan *) newnode);
296         /* ----------------
297          *      copy remainder of node
298          * ----------------
299          */
300         newnode->needRescan = from->needRescan;
301         Node_Copy(from, newnode, tideval);
302
303         return newnode;
304 }
305
306
307 /* ----------------
308  *              CopyJoinFields
309  *
310  *              This function copies the fields of the Join node.  It is used by
311  *              all the copy functions for classes which inherit from Join.
312  * ----------------
313  */
314 static void
315 CopyJoinFields(Join *from, Join *newnode)
316 {
317         /* nothing extra */
318         return;
319 }
320
321
322 /* ----------------
323  *              _copyJoin
324  * ----------------
325  */
326 static Join *
327 _copyJoin(Join *from)
328 {
329         Join       *newnode = makeNode(Join);
330
331         /* ----------------
332          *      copy node superclass fields
333          * ----------------
334          */
335         CopyPlanFields((Plan *) from, (Plan *) newnode);
336         CopyJoinFields(from, newnode);
337
338         return newnode;
339 }
340
341
342 /* ----------------
343  *              _copyNestLoop
344  * ----------------
345  */
346 static NestLoop *
347 _copyNestLoop(NestLoop *from)
348 {
349         NestLoop   *newnode = makeNode(NestLoop);
350
351         /* ----------------
352          *      copy node superclass fields
353          * ----------------
354          */
355         CopyPlanFields((Plan *) from, (Plan *) newnode);
356         CopyJoinFields((Join *) from, (Join *) newnode);
357
358         return newnode;
359 }
360
361
362 /* ----------------
363  *              _copyMergeJoin
364  * ----------------
365  */
366 static MergeJoin *
367 _copyMergeJoin(MergeJoin *from)
368 {
369         MergeJoin  *newnode = makeNode(MergeJoin);
370
371         /* ----------------
372          *      copy node superclass fields
373          * ----------------
374          */
375         CopyPlanFields((Plan *) from, (Plan *) newnode);
376         CopyJoinFields((Join *) from, (Join *) newnode);
377
378         /* ----------------
379          *      copy remainder of node
380          * ----------------
381          */
382         Node_Copy(from, newnode, mergeclauses);
383
384         /*
385          * We must add subplans in mergeclauses to the new plan's subPlan list
386          */
387         if (from->join.subPlan != NIL)
388                 newnode->join.subPlan = nconc(newnode->join.subPlan,
389                                                   pull_subplans((Node *) newnode->mergeclauses));
390
391         return newnode;
392 }
393
394 /* ----------------
395  *              _copyHashJoin
396  * ----------------
397  */
398 static HashJoin *
399 _copyHashJoin(HashJoin *from)
400 {
401         HashJoin   *newnode = makeNode(HashJoin);
402
403         /* ----------------
404          *      copy node superclass fields
405          * ----------------
406          */
407         CopyPlanFields((Plan *) from, (Plan *) newnode);
408         CopyJoinFields((Join *) from, (Join *) newnode);
409
410         /* ----------------
411          *      copy remainder of node
412          * ----------------
413          */
414         Node_Copy(from, newnode, hashclauses);
415         newnode->hashjoinop = from->hashjoinop;
416
417         /*
418          * We must add subplans in hashclauses to the new plan's subPlan list
419          */
420         if (from->join.subPlan != NIL)
421                 newnode->join.subPlan = nconc(newnode->join.subPlan,
422                                                    pull_subplans((Node *) newnode->hashclauses));
423
424         return newnode;
425 }
426
427
428 /* ----------------
429  *              _copyMaterial
430  * ----------------
431  */
432 static Material *
433 _copyMaterial(Material *from)
434 {
435         Material   *newnode = makeNode(Material);
436
437         /* ----------------
438          *      copy node superclass fields
439          * ----------------
440          */
441         CopyPlanFields((Plan *) from, (Plan *) newnode);
442
443         return newnode;
444 }
445
446
447 /* ----------------
448  *              _copySort
449  * ----------------
450  */
451 static Sort *
452 _copySort(Sort *from)
453 {
454         Sort       *newnode = makeNode(Sort);
455
456         /* ----------------
457          *      copy node superclass fields
458          * ----------------
459          */
460         CopyPlanFields((Plan *) from, (Plan *) newnode);
461
462         newnode->keycount = from->keycount;
463
464         return newnode;
465 }
466
467
468 /* ----------------
469  *              _copyGroup
470  * ----------------
471  */
472 static Group *
473 _copyGroup(Group *from)
474 {
475         Group      *newnode = makeNode(Group);
476
477         CopyPlanFields((Plan *) from, (Plan *) newnode);
478
479         newnode->tuplePerGroup = from->tuplePerGroup;
480         newnode->numCols = from->numCols;
481         newnode->grpColIdx = palloc(from->numCols * sizeof(AttrNumber));
482         memcpy(newnode->grpColIdx, from->grpColIdx, from->numCols * sizeof(AttrNumber));
483
484         return newnode;
485 }
486
487 /* ---------------
488  *      _copyAgg
489  * --------------
490  */
491 static Agg *
492 _copyAgg(Agg *from)
493 {
494         Agg                *newnode = makeNode(Agg);
495
496         CopyPlanFields((Plan *) from, (Plan *) newnode);
497
498         return newnode;
499 }
500
501 /* ---------------
502  *      _copyGroupClause
503  * --------------
504  */
505 static GroupClause *
506 _copyGroupClause(GroupClause *from)
507 {
508         GroupClause *newnode = makeNode(GroupClause);
509
510         newnode->tleSortGroupRef = from->tleSortGroupRef;
511         newnode->sortop = from->sortop;
512
513         return newnode;
514 }
515
516
517 /* ----------------
518  *              _copyUnique
519  * ----------------
520  */
521 static Unique *
522 _copyUnique(Unique *from)
523 {
524         Unique     *newnode = makeNode(Unique);
525
526         /* ----------------
527          *      copy node superclass fields
528          * ----------------
529          */
530         CopyPlanFields((Plan *) from, (Plan *) newnode);
531
532         /* ----------------
533          *      copy remainder of node
534          * ----------------
535          */
536         newnode->numCols = from->numCols;
537         newnode->uniqColIdx = palloc(from->numCols * sizeof(AttrNumber));
538         memcpy(newnode->uniqColIdx, from->uniqColIdx, from->numCols * sizeof(AttrNumber));
539
540         return newnode;
541 }
542
543
544 /* ----------------
545  *              _copyHash
546  * ----------------
547  */
548 static Hash *
549 _copyHash(Hash *from)
550 {
551         Hash       *newnode = makeNode(Hash);
552
553         /* ----------------
554          *      copy node superclass fields
555          * ----------------
556          */
557         CopyPlanFields((Plan *) from, (Plan *) newnode);
558
559         /* ----------------
560          *      copy remainder of node
561          * ----------------
562          */
563         Node_Copy(from, newnode, hashkey);
564
565         return newnode;
566 }
567
568 static SubPlan *
569 _copySubPlan(SubPlan *from)
570 {
571         SubPlan    *newnode = makeNode(SubPlan);
572
573         Node_Copy(from, newnode, plan);
574         newnode->plan_id = from->plan_id;
575         Node_Copy(from, newnode, rtable);
576         newnode->setParam = listCopy(from->setParam);
577         newnode->parParam = listCopy(from->parParam);
578         Node_Copy(from, newnode, sublink);
579
580         /* do not copy execution state */
581         newnode->needShutdown = false;
582         newnode->curTuple = NULL;
583
584         return newnode;
585 }
586
587 /* ****************************************************************
588  *                                         primnodes.h copy functions
589  * ****************************************************************
590  */
591
592 /* ----------------
593  *              _copyResdom
594  * ----------------
595  */
596 static Resdom *
597 _copyResdom(Resdom *from)
598 {
599         Resdom     *newnode = makeNode(Resdom);
600
601         newnode->resno = from->resno;
602         newnode->restype = from->restype;
603         newnode->restypmod = from->restypmod;
604         if (from->resname != NULL)
605                 newnode->resname = pstrdup(from->resname);
606         newnode->ressortgroupref = from->ressortgroupref;
607         newnode->reskey = from->reskey;
608         newnode->reskeyop = from->reskeyop;
609         newnode->resjunk = from->resjunk;
610
611         return newnode;
612 }
613
614 static Fjoin *
615 _copyFjoin(Fjoin *from)
616 {
617         Fjoin      *newnode = makeNode(Fjoin);
618
619         /* ----------------
620          *      copy node superclass fields
621          * ----------------
622          */
623
624         newnode->fj_initialized = from->fj_initialized;
625         newnode->fj_nNodes = from->fj_nNodes;
626
627         Node_Copy(from, newnode, fj_innerNode);
628
629         newnode->fj_results = (DatumPtr)
630                 palloc((from->fj_nNodes) * sizeof(Datum));
631         memmove(from->fj_results,
632                         newnode->fj_results,
633                         (from->fj_nNodes) * sizeof(Datum));
634
635         newnode->fj_alwaysDone = (BoolPtr)
636                 palloc((from->fj_nNodes) * sizeof(bool));
637         memmove(from->fj_alwaysDone,
638                         newnode->fj_alwaysDone,
639                         (from->fj_nNodes) * sizeof(bool));
640
641
642         return newnode;
643 }
644
645 /* ----------------
646  *              _copyExpr
647  * ----------------
648  */
649 static Expr *
650 _copyExpr(Expr *from)
651 {
652         Expr       *newnode = makeNode(Expr);
653
654         /* ----------------
655          *      copy node superclass fields
656          * ----------------
657          */
658         newnode->typeOid = from->typeOid;
659         newnode->opType = from->opType;
660
661         Node_Copy(from, newnode, oper);
662         Node_Copy(from, newnode, args);
663
664         return newnode;
665 }
666
667 /* ----------------
668  *              _copyVar
669  * ----------------
670  */
671 static Var *
672 _copyVar(Var *from)
673 {
674         Var                *newnode = makeNode(Var);
675
676         /* ----------------
677          *      copy remainder of node
678          * ----------------
679          */
680         newnode->varno = from->varno;
681         newnode->varattno = from->varattno;
682         newnode->vartype = from->vartype;
683         newnode->vartypmod = from->vartypmod;
684         newnode->varlevelsup = from->varlevelsup;
685
686         newnode->varnoold = from->varnoold;
687         newnode->varoattno = from->varoattno;
688
689         return newnode;
690 }
691
692 static Attr *
693 _copyAttr(Attr *from)
694 {
695         Attr       *newnode = makeNode(Attr);
696
697         if (from->relname)
698                 newnode->relname = pstrdup(from->relname);
699         Node_Copy(from, newnode, attrs);
700
701         return newnode;
702 }
703
704 /* ----------------
705  *              _copyOper
706  * ----------------
707  */
708 static Oper *
709 _copyOper(Oper *from)
710 {
711         Oper       *newnode = makeNode(Oper);
712
713         /* ----------------
714          *      copy remainder of node
715          * ----------------
716          */
717         newnode->opno = from->opno;
718         newnode->opid = from->opid;
719         newnode->opresulttype = from->opresulttype;
720         newnode->opsize = from->opsize;
721
722         /*
723          * NOTE: shall we copy the cache structure or just the pointer ?
724          * Alternatively we can set 'op_fcache' to NULL, in which case the
725          * executor will initialize it when it needs it...
726          */
727         newnode->op_fcache = from->op_fcache;
728
729         return newnode;
730 }
731
732 /* ----------------
733  *              _copyConst
734  * ----------------
735  */
736 static Const *
737 _copyConst(Const *from)
738 {
739         Const      *newnode = makeNode(Const);
740
741         /* ----------------
742          *      copy remainder of node
743          * ----------------
744          */
745         newnode->consttype = from->consttype;
746         newnode->constlen = from->constlen;
747
748         if (from->constbyval || from->constisnull)
749         {
750                 /* ----------------
751                  *      passed by value so just copy the datum.
752                  *      Also, don't try to copy struct when value is null!
753                  * ----------------
754                  */
755                 newnode->constvalue = from->constvalue;
756         }
757         else
758         {
759                 /* ----------------
760                  *      not passed by value. datum contains a pointer.
761                  * ----------------
762                  */
763                 int                     length = from->constlen;
764
765                 if (length == -1)               /* variable-length type? */
766                         length = VARSIZE(from->constvalue);
767                 newnode->constvalue = PointerGetDatum(palloc(length));
768                 memcpy(DatumGetPointer(newnode->constvalue),
769                            DatumGetPointer(from->constvalue),
770                            length);
771         }
772
773         newnode->constisnull = from->constisnull;
774         newnode->constbyval = from->constbyval;
775         newnode->constisset = from->constisset;
776         newnode->constiscast = from->constiscast;
777
778         return newnode;
779 }
780
781 /* ----------------
782  *              _copyParam
783  * ----------------
784  */
785 static Param *
786 _copyParam(Param *from)
787 {
788         Param      *newnode = makeNode(Param);
789
790         /* ----------------
791          *      copy remainder of node
792          * ----------------
793          */
794         newnode->paramkind = from->paramkind;
795         newnode->paramid = from->paramid;
796
797         if (from->paramname != NULL)
798                 newnode->paramname = pstrdup(from->paramname);
799         newnode->paramtype = from->paramtype;
800         Node_Copy(from, newnode, param_tlist);
801
802         return newnode;
803 }
804
805 /* ----------------
806  *              _copyFunc
807  * ----------------
808  */
809 static Func *
810 _copyFunc(Func *from)
811 {
812         Func       *newnode = makeNode(Func);
813
814         /* ----------------
815          *      copy remainder of node
816          * ----------------
817          */
818         newnode->funcid = from->funcid;
819         newnode->functype = from->functype;
820         newnode->funcisindex = from->funcisindex;
821         newnode->funcsize = from->funcsize;
822         newnode->func_fcache = from->func_fcache;
823         Node_Copy(from, newnode, func_tlist);
824         Node_Copy(from, newnode, func_planlist);
825
826         return newnode;
827 }
828
829 /* ----------------
830  *              _copyAggref
831  * ----------------
832  */
833 static Aggref *
834 _copyAggref(Aggref *from)
835 {
836         Aggref     *newnode = makeNode(Aggref);
837
838         /* ----------------
839          *      copy remainder of node
840          * ----------------
841          */
842         newnode->aggname = pstrdup(from->aggname);
843         newnode->basetype = from->basetype;
844         newnode->aggtype = from->aggtype;
845         Node_Copy(from, newnode, target);
846         newnode->usenulls = from->usenulls;
847         newnode->aggstar = from->aggstar;
848         newnode->aggdistinct = from->aggdistinct;
849         newnode->aggno = from->aggno;           /* probably not needed */
850
851         return newnode;
852 }
853
854 /* ----------------
855  *              _copySubLink
856  * ----------------
857  */
858 static SubLink *
859 _copySubLink(SubLink *from)
860 {
861         SubLink    *newnode = makeNode(SubLink);
862
863         /* ----------------
864          *      copy remainder of node
865          * ----------------
866          */
867         newnode->subLinkType = from->subLinkType;
868         newnode->useor = from->useor;
869         Node_Copy(from, newnode, lefthand);
870         Node_Copy(from, newnode, oper);
871         Node_Copy(from, newnode, subselect);
872
873         return newnode;
874 }
875
876 /* ----------------
877  *              _copyRelabelType
878  * ----------------
879  */
880 static RelabelType *
881 _copyRelabelType(RelabelType *from)
882 {
883         RelabelType *newnode = makeNode(RelabelType);
884
885         /* ----------------
886          *      copy remainder of node
887          * ----------------
888          */
889         Node_Copy(from, newnode, arg);
890         newnode->resulttype = from->resulttype;
891         newnode->resulttypmod = from->resulttypmod;
892
893         return newnode;
894 }
895
896 /* ----------------
897  *              _copyCaseExpr
898  * ----------------
899  */
900 static CaseExpr *
901 _copyCaseExpr(CaseExpr *from)
902 {
903         CaseExpr   *newnode = makeNode(CaseExpr);
904
905         /* ----------------
906          *      copy remainder of node
907          * ----------------
908          */
909         newnode->casetype = from->casetype;
910
911         Node_Copy(from, newnode, arg);
912         Node_Copy(from, newnode, args);
913         Node_Copy(from, newnode, defresult);
914
915         return newnode;
916 }
917
918 /* ----------------
919  *              _copyCaseWhen
920  * ----------------
921  */
922 static CaseWhen *
923 _copyCaseWhen(CaseWhen *from)
924 {
925         CaseWhen   *newnode = makeNode(CaseWhen);
926
927         /* ----------------
928          *      copy remainder of node
929          * ----------------
930          */
931         Node_Copy(from, newnode, expr);
932         Node_Copy(from, newnode, result);
933
934         return newnode;
935 }
936
937 static Array *
938 _copyArray(Array *from)
939 {
940         Array      *newnode = makeNode(Array);
941
942         /* ----------------
943          *      copy remainder of node
944          * ----------------
945          */
946         newnode->arrayelemtype = from->arrayelemtype;
947         newnode->arrayelemlength = from->arrayelemlength;
948         newnode->arrayelembyval = from->arrayelembyval;
949         newnode->arrayndim = from->arrayndim;
950         newnode->arraylow = from->arraylow;
951         newnode->arrayhigh = from->arrayhigh;
952         newnode->arraylen = from->arraylen;
953
954         return newnode;
955 }
956
957 static ArrayRef *
958 _copyArrayRef(ArrayRef *from)
959 {
960         ArrayRef   *newnode = makeNode(ArrayRef);
961
962         /* ----------------
963          *      copy remainder of node
964          * ----------------
965          */
966         newnode->refattrlength = from->refattrlength;
967         newnode->refelemlength = from->refelemlength;
968         newnode->refelemtype = from->refelemtype;
969         newnode->refelembyval = from->refelembyval;
970
971         Node_Copy(from, newnode, refupperindexpr);
972         Node_Copy(from, newnode, reflowerindexpr);
973         Node_Copy(from, newnode, refexpr);
974         Node_Copy(from, newnode, refassgnexpr);
975
976         return newnode;
977 }
978
979 /* ****************************************************************
980  *                                              relation.h copy functions
981  * ****************************************************************
982  */
983
984 /* ----------------
985  *              _copyRelOptInfo
986  * ----------------
987  */
988 /*
989  *      when you change this, also make sure to fix up xfunc_copyRelOptInfo in
990  *      planner/path/xfunc.c accordingly!!!
991  *              -- JMH, 8/2/93
992  */
993 static RelOptInfo *
994 _copyRelOptInfo(RelOptInfo *from)
995 {
996         RelOptInfo *newnode = makeNode(RelOptInfo);
997
998         newnode->relids = listCopy(from->relids);
999
1000         newnode->rows = from->rows;
1001         newnode->width = from->width;
1002
1003         Node_Copy(from, newnode, targetlist);
1004         Node_Copy(from, newnode, pathlist);
1005         /* XXX cheapest-path fields should point to members of pathlist? */
1006         Node_Copy(from, newnode, cheapest_startup_path);
1007         Node_Copy(from, newnode, cheapest_total_path);
1008         newnode->pruneable = from->pruneable;
1009
1010         newnode->indexed = from->indexed;
1011         newnode->pages = from->pages;
1012         newnode->tuples = from->tuples;
1013
1014         Node_Copy(from, newnode, baserestrictinfo);
1015         newnode->baserestrictcost = from->baserestrictcost;
1016         Node_Copy(from, newnode, joininfo);
1017         Node_Copy(from, newnode, innerjoin);
1018
1019         return newnode;
1020 }
1021
1022 /* ----------------
1023  *              _copyIndexOptInfo
1024  * ----------------
1025  */
1026 static IndexOptInfo *
1027 _copyIndexOptInfo(IndexOptInfo *from)
1028 {
1029         IndexOptInfo *newnode = makeNode(IndexOptInfo);
1030         int                     i,
1031                                 len;
1032
1033         newnode->indexoid = from->indexoid;
1034         newnode->pages = from->pages;
1035         newnode->tuples = from->tuples;
1036
1037         if (from->classlist)
1038         {
1039                 for (len = 0; from->classlist[len] != 0; len++)
1040                         ;
1041                 newnode->classlist = (Oid *) palloc(sizeof(Oid) * (len + 1));
1042                 for (i = 0; i < len; i++)
1043                         newnode->classlist[i] = from->classlist[i];
1044                 newnode->classlist[len] = 0;
1045         }
1046
1047         if (from->indexkeys)
1048         {
1049                 for (len = 0; from->indexkeys[len] != 0; len++)
1050                         ;
1051                 newnode->indexkeys = (int *) palloc(sizeof(int) * (len + 1));
1052                 for (i = 0; i < len; i++)
1053                         newnode->indexkeys[i] = from->indexkeys[i];
1054                 newnode->indexkeys[len] = 0;
1055         }
1056
1057         if (from->ordering)
1058         {
1059                 for (len = 0; from->ordering[len] != 0; len++)
1060                         ;
1061                 newnode->ordering = (Oid *) palloc(sizeof(Oid) * (len + 1));
1062                 for (i = 0; i < len; i++)
1063                         newnode->ordering[i] = from->ordering[i];
1064                 newnode->ordering[len] = 0;
1065         }
1066
1067         newnode->relam = from->relam;
1068         newnode->amcostestimate = from->amcostestimate;
1069         newnode->indproc = from->indproc;
1070         Node_Copy(from, newnode, indpred);
1071         newnode->lossy = from->lossy;
1072
1073         return newnode;
1074 }
1075
1076 /* ----------------
1077  *              CopyPathFields
1078  *
1079  *              This function copies the fields of the Path node.  It is used by
1080  *              all the copy functions for classes which inherit from Path.
1081  * ----------------
1082  */
1083 static void
1084 CopyPathFields(Path *from, Path *newnode)
1085 {
1086
1087         /*
1088          * Modify the next line, since it causes the copying to cycle (i.e.
1089          * the parent points right back here! -- JMH, 7/7/92. Old version:
1090          * Node_Copy(from, newnode, parent);
1091          */
1092         newnode->parent = from->parent;
1093
1094         newnode->startup_cost = from->startup_cost;
1095         newnode->total_cost = from->total_cost;
1096
1097         newnode->pathtype = from->pathtype;
1098
1099         Node_Copy(from, newnode, pathkeys);
1100 }
1101
1102 /* ----------------
1103  *              _copyPath
1104  * ----------------
1105  */
1106 static Path *
1107 _copyPath(Path *from)
1108 {
1109         Path       *newnode = makeNode(Path);
1110
1111         CopyPathFields(from, newnode);
1112
1113         return newnode;
1114 }
1115
1116 /* ----------------
1117  *              _copyIndexPath
1118  * ----------------
1119  */
1120 static IndexPath *
1121 _copyIndexPath(IndexPath *from)
1122 {
1123         IndexPath  *newnode = makeNode(IndexPath);
1124
1125         /* ----------------
1126          *      copy the node superclass fields
1127          * ----------------
1128          */
1129         CopyPathFields((Path *) from, (Path *) newnode);
1130
1131         /* ----------------
1132          *      copy remainder of node
1133          * ----------------
1134          */
1135         newnode->indexid = listCopy(from->indexid);
1136         Node_Copy(from, newnode, indexqual);
1137         newnode->indexscandir = from->indexscandir;
1138         newnode->joinrelids = listCopy(from->joinrelids);
1139         newnode->rows = from->rows;
1140
1141         return newnode;
1142 }
1143
1144 /* ----------------
1145  *                              _copyTidPath
1146  * ----------------
1147  */
1148 static TidPath *
1149 _copyTidPath(TidPath *from)
1150 {
1151         TidPath    *newnode = makeNode(TidPath);
1152
1153         /* ----------------
1154          *      copy the node superclass fields
1155          * ----------------
1156          */
1157         CopyPathFields((Path *) from, (Path *) newnode);
1158
1159         /* ----------------
1160          *      copy remainder of node
1161          * ----------------
1162          */
1163         Node_Copy(from, newnode, tideval);
1164         newnode->unjoined_relids = listCopy(from->unjoined_relids);
1165
1166         return newnode;
1167 }
1168
1169 /* ----------------
1170  *              CopyJoinPathFields
1171  *
1172  *              This function copies the fields of the JoinPath node.  It is used by
1173  *              all the copy functions for classes which inherit from JoinPath.
1174  * ----------------
1175  */
1176 static void
1177 CopyJoinPathFields(JoinPath *from, JoinPath *newnode)
1178 {
1179         Node_Copy(from, newnode, outerjoinpath);
1180         Node_Copy(from, newnode, innerjoinpath);
1181         Node_Copy(from, newnode, joinrestrictinfo);
1182 }
1183
1184 /* ----------------
1185  *              _copyNestPath
1186  * ----------------
1187  */
1188 static NestPath *
1189 _copyNestPath(NestPath *from)
1190 {
1191         NestPath   *newnode = makeNode(NestPath);
1192
1193         /* ----------------
1194          *      copy the node superclass fields
1195          * ----------------
1196          */
1197         CopyPathFields((Path *) from, (Path *) newnode);
1198         CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
1199
1200         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          *      copy the node superclass fields
1214          * ----------------
1215          */
1216         CopyPathFields((Path *) from, (Path *) newnode);
1217         CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
1218
1219         /* ----------------
1220          *      copy the remainder of the node
1221          * ----------------
1222          */
1223         Node_Copy(from, newnode, path_mergeclauses);
1224         Node_Copy(from, newnode, outersortkeys);
1225         Node_Copy(from, newnode, innersortkeys);
1226
1227         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          *      copy the node superclass fields
1241          * ----------------
1242          */
1243         CopyPathFields((Path *) from, (Path *) newnode);
1244         CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
1245
1246         /* ----------------
1247          *      copy remainder of node
1248          * ----------------
1249          */
1250         Node_Copy(from, newnode, path_hashclauses);
1251
1252         return newnode;
1253 }
1254
1255 /* ----------------
1256  *              _copyPathKeyItem
1257  * ----------------
1258  */
1259 static PathKeyItem *
1260 _copyPathKeyItem(PathKeyItem *from)
1261 {
1262         PathKeyItem *newnode = makeNode(PathKeyItem);
1263
1264         /* ----------------
1265          *      copy remainder of node
1266          * ----------------
1267          */
1268         Node_Copy(from, newnode, key);
1269         newnode->sortop = from->sortop;
1270
1271         return newnode;
1272 }
1273
1274 /* ----------------
1275  *              _copyRestrictInfo
1276  * ----------------
1277  */
1278 static RestrictInfo *
1279 _copyRestrictInfo(RestrictInfo *from)
1280 {
1281         RestrictInfo *newnode = makeNode(RestrictInfo);
1282
1283         /* ----------------
1284          *      copy remainder of node
1285          * ----------------
1286          */
1287         Node_Copy(from, newnode, clause);
1288         Node_Copy(from, newnode, subclauseindices);
1289         newnode->mergejoinoperator = from->mergejoinoperator;
1290         newnode->left_sortop = from->left_sortop;
1291         newnode->right_sortop = from->right_sortop;
1292         newnode->hashjoinoperator = from->hashjoinoperator;
1293
1294         return newnode;
1295 }
1296
1297 /* ----------------
1298  *              _copyJoinInfo
1299  * ----------------
1300  */
1301 static JoinInfo *
1302 _copyJoinInfo(JoinInfo *from)
1303 {
1304         JoinInfo   *newnode = makeNode(JoinInfo);
1305
1306         /* ----------------
1307          *      copy remainder of node
1308          * ----------------
1309          */
1310         newnode->unjoined_relids = listCopy(from->unjoined_relids);
1311         Node_Copy(from, newnode, jinfo_restrictinfo);
1312
1313         return newnode;
1314 }
1315
1316 static Iter *
1317 _copyIter(Iter *from)
1318 {
1319         Iter       *newnode = makeNode(Iter);
1320
1321         Node_Copy(from, newnode, iterexpr);
1322         newnode->itertype = from->itertype;
1323
1324         return newnode;
1325 }
1326
1327 static Stream *
1328 _copyStream(Stream *from)
1329 {
1330         Stream     *newnode = makeNode(Stream);
1331
1332         newnode->pathptr = from->pathptr;
1333         newnode->cinfo = from->cinfo;
1334         newnode->clausetype = from->clausetype;
1335
1336         newnode->upstream = (StreamPtr) NULL;           /* only copy nodes
1337                                                                                                  * downwards! */
1338         Node_Copy(from, newnode, downstream);
1339         if (newnode->downstream)
1340                 ((Stream *) newnode->downstream)->upstream = (Stream *) newnode;
1341
1342         newnode->groupup = from->groupup;
1343         newnode->groupcost = from->groupcost;
1344         newnode->groupsel = from->groupsel;
1345
1346         return newnode;
1347 }
1348
1349 /* ****************************************************************
1350  *                                      parsenodes.h copy functions
1351  * ****************************************************************
1352  */
1353
1354 static TargetEntry *
1355 _copyTargetEntry(TargetEntry *from)
1356 {
1357         TargetEntry *newnode = makeNode(TargetEntry);
1358
1359         Node_Copy(from, newnode, resdom);
1360         Node_Copy(from, newnode, fjoin);
1361         Node_Copy(from, newnode, expr);
1362         return newnode;
1363 }
1364
1365 static RangeTblEntry *
1366 _copyRangeTblEntry(RangeTblEntry *from)
1367 {
1368         RangeTblEntry *newnode = makeNode(RangeTblEntry);
1369
1370         if (from->relname)
1371                 newnode->relname = pstrdup(from->relname);
1372         Node_Copy(from, newnode, ref);
1373         Node_Copy(from, newnode, eref);
1374         newnode->relid = from->relid;
1375         newnode->inh = from->inh;
1376         newnode->inFromCl = from->inFromCl;
1377         newnode->inJoinSet = from->inJoinSet;
1378         newnode->skipAcl = from->skipAcl;
1379
1380         return newnode;
1381 }
1382
1383 static RowMark *
1384 _copyRowMark(RowMark *from)
1385 {
1386         RowMark    *newnode = makeNode(RowMark);
1387
1388         newnode->rti = from->rti;
1389         newnode->info = from->info;
1390
1391         return newnode;
1392 }
1393
1394 static SortClause *
1395 _copySortClause(SortClause *from)
1396 {
1397         SortClause *newnode = makeNode(SortClause);
1398
1399         newnode->tleSortGroupRef = from->tleSortGroupRef;
1400         newnode->sortop = from->sortop;
1401
1402         return newnode;
1403 }
1404
1405 static A_Const *
1406 _copyAConst(A_Const *from)
1407 {
1408         A_Const    *newnode = makeNode(A_Const);
1409
1410         newnode->val = *((Value *) (copyObject(&(from->val))));
1411         Node_Copy(from, newnode, typename);
1412
1413         return newnode;
1414 }
1415
1416 static TypeName *
1417 _copyTypeName(TypeName *from)
1418 {
1419         TypeName   *newnode = makeNode(TypeName);
1420
1421         if (from->name)
1422                 newnode->name = pstrdup(from->name);
1423         newnode->timezone = from->timezone;
1424         newnode->setof = from->setof;
1425         newnode->typmod = from->typmod;
1426         Node_Copy(from, newnode, arrayBounds);
1427
1428         return newnode;
1429 }
1430
1431 static TypeCast *
1432 _copyTypeCast(TypeCast *from)
1433 {
1434         TypeCast   *newnode = makeNode(TypeCast);
1435
1436         Node_Copy(from, newnode, arg);
1437         Node_Copy(from, newnode, typename);
1438
1439         return newnode;
1440 }
1441
1442 static Query *
1443 _copyQuery(Query *from)
1444 {
1445         Query      *newnode = makeNode(Query);
1446
1447         newnode->commandType = from->commandType;
1448         Node_Copy(from, newnode, utilityStmt);
1449         newnode->resultRelation = from->resultRelation;
1450         if (from->into)
1451                 newnode->into = pstrdup(from->into);
1452         newnode->isPortal = from->isPortal;
1453         newnode->isBinary = from->isBinary;
1454         newnode->isTemp = from->isTemp;
1455         newnode->unionall = from->unionall;
1456         newnode->hasAggs = from->hasAggs;
1457         newnode->hasSubLinks = from->hasSubLinks;
1458
1459         Node_Copy(from, newnode, rtable);
1460         Node_Copy(from, newnode, targetList);
1461         Node_Copy(from, newnode, qual);
1462         Node_Copy(from, newnode, rowMark);
1463
1464         Node_Copy(from, newnode, distinctClause);
1465         Node_Copy(from, newnode, sortClause);
1466         Node_Copy(from, newnode, groupClause);
1467         Node_Copy(from, newnode, havingQual);
1468
1469         /* why is intersectClause missing? */
1470         Node_Copy(from, newnode, unionClause);
1471
1472         Node_Copy(from, newnode, limitOffset);
1473         Node_Copy(from, newnode, limitCount);
1474
1475         /*
1476          * We do not copy the planner internal fields: base_rel_list,
1477          * join_rel_list, equi_key_list, query_pathkeys. Not entirely clear if
1478          * this is right?
1479          */
1480
1481         return newnode;
1482 }
1483
1484 static ClosePortalStmt *
1485 _copyClosePortalStmt(ClosePortalStmt *from)
1486 {
1487         ClosePortalStmt *newnode = makeNode(ClosePortalStmt);
1488
1489         if (from->portalname)
1490                 newnode->portalname = pstrdup(from->portalname);
1491
1492         return newnode;
1493 }
1494
1495 static TruncateStmt *
1496 _copyTruncateStmt(TruncateStmt *from)
1497 {
1498         TruncateStmt *newnode = makeNode(TruncateStmt);
1499
1500         newnode->relName = pstrdup(from->relName);
1501
1502         return newnode;
1503 }
1504
1505 static NotifyStmt *
1506 _copyNotifyStmt(NotifyStmt *from)
1507 {
1508         NotifyStmt *newnode = makeNode(NotifyStmt);
1509
1510         if (from->relname)
1511                 newnode->relname = pstrdup(from->relname);
1512
1513         return newnode;
1514 }
1515
1516 static ListenStmt *
1517 _copyListenStmt(ListenStmt *from)
1518 {
1519         ListenStmt *newnode = makeNode(ListenStmt);
1520
1521         if (from->relname)
1522                 newnode->relname = pstrdup(from->relname);
1523
1524         return newnode;
1525 }
1526
1527 static UnlistenStmt *
1528 _copyUnlistenStmt(UnlistenStmt *from)
1529 {
1530         UnlistenStmt *newnode = makeNode(UnlistenStmt);
1531
1532         if (from->relname)
1533                 newnode->relname = pstrdup(from->relname);
1534
1535         return newnode;
1536 }
1537
1538 static TransactionStmt *
1539 _copyTransactionStmt(TransactionStmt *from)
1540 {
1541         TransactionStmt *newnode = makeNode(TransactionStmt);
1542
1543         newnode->command = from->command;
1544
1545         return newnode;
1546 }
1547
1548 static LoadStmt *
1549 _copyLoadStmt(LoadStmt *from)
1550 {
1551         LoadStmt   *newnode = makeNode(LoadStmt);
1552
1553         if (from->filename)
1554                 newnode->filename = pstrdup(from->filename);
1555
1556         return newnode;
1557 }
1558
1559 static VariableSetStmt *
1560 _copyVariableSetStmt(VariableSetStmt *from)
1561 {
1562         VariableSetStmt *newnode = makeNode(VariableSetStmt);
1563
1564         if (from->name)
1565                 newnode->name = pstrdup(from->name);
1566         if (from->value)
1567                 newnode->value = pstrdup(from->value);
1568
1569         return newnode;
1570 }
1571
1572 static VariableResetStmt *
1573 _copyVariableResetStmt(VariableResetStmt *from)
1574 {
1575         VariableResetStmt *newnode = makeNode(VariableResetStmt);
1576
1577         if (from->name)
1578                 newnode->name = pstrdup(from->name);
1579
1580         return newnode;
1581 }
1582
1583 static LockStmt *
1584 _copyLockStmt(LockStmt *from)
1585 {
1586         LockStmt   *newnode = makeNode(LockStmt);
1587
1588         if (from->relname)
1589                 newnode->relname = pstrdup(from->relname);
1590         newnode->mode = from->mode;
1591
1592         return newnode;
1593 }
1594
1595
1596 /* ****************************************************************
1597  *                                      pg_list.h copy functions
1598  * ****************************************************************
1599  */
1600
1601 static Value *
1602 _copyValue(Value *from)
1603 {
1604         Value      *newnode = makeNode(Value);
1605
1606         newnode->type = from->type;
1607         switch (from->type)
1608         {
1609                 case T_Integer:
1610                         newnode->val.ival = from->val.ival;
1611                         break;
1612                 case T_Float:
1613                 case T_String:
1614                         newnode->val.str = pstrdup(from->val.str);
1615                         break;
1616                 default:
1617                         break;
1618         }
1619         return newnode;
1620 }
1621
1622 /* ----------------
1623  *              copyObject returns a copy of the node or list. If it is a list, it
1624  *              recursively copies its items.
1625  * ----------------
1626  */
1627 void *
1628 copyObject(void *from)
1629 {
1630         void       *retval;
1631
1632         if (from == NULL)
1633                 return NULL;
1634         switch (nodeTag(from))
1635         {
1636
1637                         /*
1638                          * PLAN NODES
1639                          */
1640                 case T_Plan:
1641                         retval = _copyPlan(from);
1642                         break;
1643                 case T_Result:
1644                         retval = _copyResult(from);
1645                         break;
1646                 case T_Append:
1647                         retval = _copyAppend(from);
1648                         break;
1649                 case T_Scan:
1650                         retval = _copyScan(from);
1651                         break;
1652                 case T_SeqScan:
1653                         retval = _copySeqScan(from);
1654                         break;
1655                 case T_IndexScan:
1656                         retval = _copyIndexScan(from);
1657                         break;
1658                 case T_TidScan:
1659                         retval = _copyTidScan(from);
1660                         break;
1661                 case T_Join:
1662                         retval = _copyJoin(from);
1663                         break;
1664                 case T_NestLoop:
1665                         retval = _copyNestLoop(from);
1666                         break;
1667                 case T_MergeJoin:
1668                         retval = _copyMergeJoin(from);
1669                         break;
1670                 case T_HashJoin:
1671                         retval = _copyHashJoin(from);
1672                         break;
1673                 case T_Material:
1674                         retval = _copyMaterial(from);
1675                         break;
1676                 case T_Sort:
1677                         retval = _copySort(from);
1678                         break;
1679                 case T_Group:
1680                         retval = _copyGroup(from);
1681                         break;
1682                 case T_Agg:
1683                         retval = _copyAgg(from);
1684                         break;
1685                 case T_Unique:
1686                         retval = _copyUnique(from);
1687                         break;
1688                 case T_Hash:
1689                         retval = _copyHash(from);
1690                         break;
1691                 case T_SubPlan:
1692                         retval = _copySubPlan(from);
1693                         break;
1694
1695                         /*
1696                          * PRIMITIVE NODES
1697                          */
1698                 case T_Resdom:
1699                         retval = _copyResdom(from);
1700                         break;
1701                 case T_Fjoin:
1702                         retval = _copyFjoin(from);
1703                         break;
1704                 case T_Expr:
1705                         retval = _copyExpr(from);
1706                         break;
1707                 case T_Var:
1708                         retval = _copyVar(from);
1709                         break;
1710                 case T_Oper:
1711                         retval = _copyOper(from);
1712                         break;
1713                 case T_Const:
1714                         retval = _copyConst(from);
1715                         break;
1716                 case T_Param:
1717                         retval = _copyParam(from);
1718                         break;
1719                 case T_Aggref:
1720                         retval = _copyAggref(from);
1721                         break;
1722                 case T_SubLink:
1723                         retval = _copySubLink(from);
1724                         break;
1725                 case T_Func:
1726                         retval = _copyFunc(from);
1727                         break;
1728                 case T_Array:
1729                         retval = _copyArray(from);
1730                         break;
1731                 case T_ArrayRef:
1732                         retval = _copyArrayRef(from);
1733                         break;
1734                 case T_Iter:
1735                         retval = _copyIter(from);
1736                         break;
1737                 case T_RelabelType:
1738                         retval = _copyRelabelType(from);
1739                         break;
1740
1741                         /*
1742                          * RELATION NODES
1743                          */
1744                 case T_RelOptInfo:
1745                         retval = _copyRelOptInfo(from);
1746                         break;
1747                 case T_Path:
1748                         retval = _copyPath(from);
1749                         break;
1750                 case T_IndexPath:
1751                         retval = _copyIndexPath(from);
1752                         break;
1753                 case T_TidPath:
1754                         retval = _copyTidPath(from);
1755                         break;
1756                 case T_NestPath:
1757                         retval = _copyNestPath(from);
1758                         break;
1759                 case T_MergePath:
1760                         retval = _copyMergePath(from);
1761                         break;
1762                 case T_HashPath:
1763                         retval = _copyHashPath(from);
1764                         break;
1765                 case T_PathKeyItem:
1766                         retval = _copyPathKeyItem(from);
1767                         break;
1768                 case T_RestrictInfo:
1769                         retval = _copyRestrictInfo(from);
1770                         break;
1771                 case T_JoinInfo:
1772                         retval = _copyJoinInfo(from);
1773                         break;
1774                 case T_Stream:
1775                         retval = _copyStream(from);
1776                         break;
1777                 case T_IndexOptInfo:
1778                         retval = _copyIndexOptInfo(from);
1779                         break;
1780
1781                         /*
1782                          * VALUE NODES
1783                          */
1784                 case T_Integer:
1785                 case T_Float:
1786                 case T_String:
1787                         retval = _copyValue(from);
1788                         break;
1789                 case T_List:
1790                         {
1791                                 List       *list = from,
1792                                                    *l,
1793                                                    *nl;
1794
1795                                 /* rather ugly coding for speed... */
1796                                 /* Note the input list cannot be NIL if we got here. */
1797                                 nl = lcons(copyObject(lfirst(list)), NIL);
1798                                 retval = nl;
1799
1800                                 foreach(l, lnext(list))
1801                                 {
1802                                         lnext(nl) = lcons(copyObject(lfirst(l)), NIL);
1803                                         nl = lnext(nl);
1804                                 }
1805                         }
1806                         break;
1807
1808                         /*
1809                          * PARSE NODES
1810                          */
1811                 case T_Query:
1812                         retval = _copyQuery(from);
1813                         break;
1814                 case T_ClosePortalStmt:
1815                         retval = _copyClosePortalStmt(from);
1816                         break;
1817                 case T_TruncateStmt:
1818                         retval = _copyTruncateStmt(from);
1819                         break;
1820                 case T_NotifyStmt:
1821                         retval = _copyNotifyStmt(from);
1822                         break;
1823                 case T_ListenStmt:
1824                         retval = _copyListenStmt(from);
1825                         break;
1826                 case T_UnlistenStmt:
1827                         retval = _copyUnlistenStmt(from);
1828                         break;
1829                 case T_TransactionStmt:
1830                         retval = _copyTransactionStmt(from);
1831                         break;
1832                 case T_LoadStmt:
1833                         retval = _copyLoadStmt(from);
1834                         break;
1835                 case T_VariableSetStmt:
1836                         retval = _copyVariableSetStmt(from);
1837                         break;
1838                 case T_VariableResetStmt:
1839                         retval = _copyVariableResetStmt(from);
1840                         break;
1841                 case T_LockStmt:
1842                         retval = _copyLockStmt(from);
1843                         break;
1844
1845                 case T_Attr:
1846                         retval = _copyAttr(from);
1847                         break;
1848                 case T_A_Const:
1849                         retval = _copyAConst(from);
1850                         break;
1851                 case T_TypeCast:
1852                         retval = _copyTypeCast(from);
1853                         break;
1854                 case T_TypeName:
1855                         retval = _copyTypeName(from);
1856                         break;
1857                 case T_TargetEntry:
1858                         retval = _copyTargetEntry(from);
1859                         break;
1860                 case T_RangeTblEntry:
1861                         retval = _copyRangeTblEntry(from);
1862                         break;
1863                 case T_SortClause:
1864                         retval = _copySortClause(from);
1865                         break;
1866                 case T_GroupClause:
1867                         retval = _copyGroupClause(from);
1868                         break;
1869                 case T_CaseExpr:
1870                         retval = _copyCaseExpr(from);
1871                         break;
1872                 case T_CaseWhen:
1873                         retval = _copyCaseWhen(from);
1874                         break;
1875                 case T_RowMark:
1876                         retval = _copyRowMark(from);
1877                         break;
1878
1879                 default:
1880                         elog(ERROR, "copyObject: don't know how to copy node type %d",
1881                                  nodeTag(from));
1882                         retval = from;          /* keep compiler quiet */
1883                         break;
1884         }
1885         return retval;
1886 }