OSDN Git Service

Create a new expression node type RelabelType, which exists solely to
[pg-rex/syncrep.git] / src / backend / nodes / copyfuncs.c
1 /*-------------------------------------------------------------------------
2  *
3  * copyfuncs.c
4  *        Copy functions for Postgres tree nodes.
5  *
6  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.107 2000/02/20 21:32:05 tgl Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15
16 #include "postgres.h"
17
18 #include "optimizer/planmain.h"
19 #include "optimizer/subselect.h"
20
21
22 /*
23  * Node_Copy
24  *        a macro to simplify calling of copyObject on the specified field
25  */
26 #define Node_Copy(from, newnode, field) \
27         ((newnode)->field = copyObject((from)->field))
28
29
30 /*
31  * listCopy
32  *        This copy function only copies the "cons-cells" of the list, not the
33  *        pointed-to objects.  (Use copyObject if you want a "deep" copy.)
34  *
35  *        We also use this function for copying lists of integers, which is
36  *        grotty but unlikely to break --- it could fail if sizeof(pointer)
37  *        is less than sizeof(int), but I don't know any such machines...
38  *
39  *        Note that copyObject will surely coredump if applied to a list
40  *        of integers!
41  */
42 List *
43 listCopy(List *list)
44 {
45         List       *newlist,
46                            *l,
47                            *nl;
48
49         /* rather ugly coding for speed... */
50         if (list == NIL)
51                 return NIL;
52
53         newlist = nl = lcons(lfirst(list), NIL);
54
55         foreach(l, lnext(list))
56         {
57                 lnext(nl) = lcons(lfirst(l), NIL);
58                 nl = lnext(nl);
59         }
60         return newlist;
61 }
62
63 /* ****************************************************************
64  *                                       plannodes.h copy functions
65  * ****************************************************************
66  */
67
68 /* ----------------
69  *              CopyPlanFields
70  *
71  *              This function copies the fields of the Plan node.  It is used by
72  *              all the copy functions for classes which inherit from Plan.
73  * ----------------
74  */
75 static void
76 CopyPlanFields(Plan *from, Plan *newnode)
77 {
78         newnode->startup_cost = from->startup_cost;
79         newnode->total_cost = from->total_cost;
80         newnode->plan_rows = from->plan_rows;
81         newnode->plan_width = from->plan_width;
82         /* state is NOT copied */
83         newnode->targetlist = copyObject(from->targetlist);
84         newnode->qual = copyObject(from->qual);
85         newnode->lefttree = copyObject(from->lefttree);
86         newnode->righttree = copyObject(from->righttree);
87         newnode->extParam = listCopy(from->extParam);
88         newnode->locParam = listCopy(from->locParam);
89         newnode->chgParam = listCopy(from->chgParam);
90         Node_Copy(from, newnode, initPlan);
91         if (from->subPlan != NIL)
92                 newnode->subPlan = nconc(SS_pull_subplan((Node *) newnode->targetlist),
93                                                                  SS_pull_subplan((Node *) newnode->qual));
94         else
95                 newnode->subPlan = NIL;
96         newnode->nParamExec = from->nParamExec;
97 }
98
99 /* ----------------
100  *              _copyPlan
101  * ----------------
102  */
103 static Plan *
104 _copyPlan(Plan *from)
105 {
106         Plan       *newnode = makeNode(Plan);
107
108         /* ----------------
109          *      copy the node superclass fields
110          * ----------------
111          */
112         CopyPlanFields(from, newnode);
113
114         return newnode;
115 }
116
117
118 /* ----------------
119  *              _copyResult
120  * ----------------
121  */
122 static Result *
123 _copyResult(Result *from)
124 {
125         Result     *newnode = makeNode(Result);
126
127         /* ----------------
128          *      copy node superclass fields
129          * ----------------
130          */
131         CopyPlanFields((Plan *) from, (Plan *) newnode);
132
133         /* ----------------
134          *      copy remainder of node
135          * ----------------
136          */
137         Node_Copy(from, newnode, resconstantqual);
138
139         /*
140          * We must add subplans in resconstantqual to the new plan's subPlan
141          * list
142          */
143         if (from->plan.subPlan != NIL)
144                 newnode->plan.subPlan = nconc(newnode->plan.subPlan,
145                                                                           SS_pull_subplan(newnode->resconstantqual));
146
147         return newnode;
148 }
149
150 /* ----------------
151  *              _copyAppend
152  * ----------------
153  */
154 static Append *
155 _copyAppend(Append *from)
156 {
157         Append     *newnode = makeNode(Append);
158
159         /* ----------------
160          *      copy node superclass fields
161          * ----------------
162          */
163         CopyPlanFields((Plan *) from, (Plan *) newnode);
164
165         /* ----------------
166          *      copy remainder of node
167          * ----------------
168          */
169         Node_Copy(from, newnode, appendplans);
170         Node_Copy(from, newnode, unionrtables);
171         newnode->inheritrelid = from->inheritrelid;
172         Node_Copy(from, newnode, inheritrtable);
173
174         return newnode;
175 }
176
177
178 /* ----------------
179  *              CopyScanFields
180  *
181  *              This function copies the fields of the Scan node.  It is used by
182  *              all the copy functions for classes which inherit from Scan.
183  * ----------------
184  */
185 static void
186 CopyScanFields(Scan *from, Scan *newnode)
187 {
188         newnode->scanrelid = from->scanrelid;
189         return;
190 }
191
192 /* ----------------
193  *              _copyScan
194  * ----------------
195  */
196 static Scan *
197 _copyScan(Scan *from)
198 {
199         Scan       *newnode = makeNode(Scan);
200
201         /* ----------------
202          *      copy node superclass fields
203          * ----------------
204          */
205         CopyPlanFields((Plan *) from, (Plan *) newnode);
206         CopyScanFields((Scan *) from, (Scan *) newnode);
207
208         return newnode;
209 }
210
211 /* ----------------
212  *              _copySeqScan
213  * ----------------
214  */
215 static SeqScan *
216 _copySeqScan(SeqScan *from)
217 {
218         SeqScan    *newnode = makeNode(SeqScan);
219
220         /* ----------------
221          *      copy node superclass fields
222          * ----------------
223          */
224         CopyPlanFields((Plan *) from, (Plan *) newnode);
225         CopyScanFields((Scan *) from, (Scan *) newnode);
226
227         return newnode;
228 }
229
230 /* ----------------
231  *              _copyIndexScan
232  * ----------------
233  */
234 static IndexScan *
235 _copyIndexScan(IndexScan *from)
236 {
237         IndexScan  *newnode = makeNode(IndexScan);
238
239         /* ----------------
240          *      copy node superclass fields
241          * ----------------
242          */
243         CopyPlanFields((Plan *) from, (Plan *) newnode);
244         CopyScanFields((Scan *) from, (Scan *) newnode);
245
246         /* ----------------
247          *      copy remainder of node
248          * ----------------
249          */
250         newnode->indxid = listCopy(from->indxid);
251         Node_Copy(from, newnode, indxqual);
252         Node_Copy(from, newnode, indxqualorig);
253         newnode->indxorderdir = from->indxorderdir;
254
255         return newnode;
256 }
257
258 /* ----------------
259  *              _copyTidScan
260  * ----------------
261  */
262 static TidScan *
263 _copyTidScan(TidScan *from)
264 {
265         TidScan *newnode = makeNode(TidScan);
266
267         /* ----------------
268          *      copy node superclass fields
269          * ----------------
270          */
271         CopyPlanFields((Plan *) from, (Plan *) newnode);
272         CopyScanFields((Scan *) from, (Scan *) newnode);
273         /* ----------------
274          *      copy remainder of node
275          * ----------------
276          */
277         newnode->needRescan = from->needRescan;
278         Node_Copy(from, newnode, tideval);
279
280         return newnode;
281 }
282
283     
284 /* ----------------
285  *              CopyJoinFields
286  *
287  *              This function copies the fields of the Join node.  It is used by
288  *              all the copy functions for classes which inherit from Join.
289  * ----------------
290  */
291 static void
292 CopyJoinFields(Join *from, Join *newnode)
293 {
294         /* nothing extra */
295         return;
296 }
297
298
299 /* ----------------
300  *              _copyJoin
301  * ----------------
302  */
303 static Join *
304 _copyJoin(Join *from)
305 {
306         Join       *newnode = makeNode(Join);
307
308         /* ----------------
309          *      copy node superclass fields
310          * ----------------
311          */
312         CopyPlanFields((Plan *) from, (Plan *) newnode);
313         CopyJoinFields(from, newnode);
314
315         return newnode;
316 }
317
318
319 /* ----------------
320  *              _copyNestLoop
321  * ----------------
322  */
323 static NestLoop *
324 _copyNestLoop(NestLoop *from)
325 {
326         NestLoop   *newnode = makeNode(NestLoop);
327
328         /* ----------------
329          *      copy node superclass fields
330          * ----------------
331          */
332         CopyPlanFields((Plan *) from, (Plan *) newnode);
333         CopyJoinFields((Join *) from, (Join *) newnode);
334
335         return newnode;
336 }
337
338
339 /* ----------------
340  *              _copyMergeJoin
341  * ----------------
342  */
343 static MergeJoin *
344 _copyMergeJoin(MergeJoin *from)
345 {
346         MergeJoin  *newnode = makeNode(MergeJoin);
347
348         /* ----------------
349          *      copy node superclass fields
350          * ----------------
351          */
352         CopyPlanFields((Plan *) from, (Plan *) newnode);
353         CopyJoinFields((Join *) from, (Join *) newnode);
354
355         /* ----------------
356          *      copy remainder of node
357          * ----------------
358          */
359         Node_Copy(from, newnode, mergeclauses);
360
361         return newnode;
362 }
363
364 /* ----------------
365  *              _copyHashJoin
366  * ----------------
367  */
368 static HashJoin *
369 _copyHashJoin(HashJoin *from)
370 {
371         HashJoin   *newnode = makeNode(HashJoin);
372
373         /* ----------------
374          *      copy node superclass fields
375          * ----------------
376          */
377         CopyPlanFields((Plan *) from, (Plan *) newnode);
378         CopyJoinFields((Join *) from, (Join *) newnode);
379
380         /* ----------------
381          *      copy remainder of node
382          * ----------------
383          */
384         Node_Copy(from, newnode, hashclauses);
385
386         newnode->hashjoinop = from->hashjoinop;
387
388         return newnode;
389 }
390
391
392 /* ----------------
393  *              CopyNonameFields
394  *
395  *              This function copies the fields of the Noname node.  It is used by
396  *              all the copy functions for classes which inherit from Noname.
397  * ----------------
398  */
399 static void
400 CopyNonameFields(Noname *from, Noname *newnode)
401 {
402         newnode->nonameid = from->nonameid;
403         newnode->keycount = from->keycount;
404         return;
405 }
406
407
408 /* ----------------
409  *              _copyNoname
410  * ----------------
411  */
412 static Noname *
413 _copyNoname(Noname *from)
414 {
415         Noname     *newnode = makeNode(Noname);
416
417         /* ----------------
418          *      copy node superclass fields
419          * ----------------
420          */
421         CopyPlanFields((Plan *) from, (Plan *) newnode);
422         CopyNonameFields(from, newnode);
423
424         return newnode;
425 }
426
427 /* ----------------
428  *              _copyMaterial
429  * ----------------
430  */
431 static Material *
432 _copyMaterial(Material *from)
433 {
434         Material   *newnode = makeNode(Material);
435
436         /* ----------------
437          *      copy node superclass fields
438          * ----------------
439          */
440         CopyPlanFields((Plan *) from, (Plan *) newnode);
441         CopyNonameFields((Noname *) from, (Noname *) 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         CopyNonameFields((Noname *) from, (Noname *) newnode);
462
463         return newnode;
464 }
465
466
467 /* ----------------
468  *              _copyGroup
469  * ----------------
470  */
471 static Group *
472 _copyGroup(Group *from)
473 {
474         Group      *newnode = makeNode(Group);
475
476         CopyPlanFields((Plan *) from, (Plan *) newnode);
477
478         newnode->tuplePerGroup = from->tuplePerGroup;
479         newnode->numCols = from->numCols;
480         newnode->grpColIdx = palloc(from->numCols * sizeof(AttrNumber));
481         memcpy(newnode->grpColIdx, from->grpColIdx, from->numCols * sizeof(AttrNumber));
482
483         return newnode;
484 }
485
486 /* ---------------
487  *      _copyAgg
488  * --------------
489  */
490 static Agg *
491 _copyAgg(Agg *from)
492 {
493         Agg                *newnode = makeNode(Agg);
494
495         CopyPlanFields((Plan *) from, (Plan *) newnode);
496
497         return newnode;
498 }
499
500 /* ---------------
501  *      _copyGroupClause
502  * --------------
503  */
504 static GroupClause *
505 _copyGroupClause(GroupClause *from)
506 {
507         GroupClause *newnode = makeNode(GroupClause);
508
509         newnode->tleSortGroupRef = from->tleSortGroupRef;
510         newnode->sortop = from->sortop;
511
512         return newnode;
513 }
514
515
516 /* ----------------
517  *              _copyUnique
518  * ----------------
519  */
520 static Unique *
521 _copyUnique(Unique *from)
522 {
523         Unique     *newnode = makeNode(Unique);
524
525         /* ----------------
526          *      copy node superclass fields
527          * ----------------
528          */
529         CopyPlanFields((Plan *) from, (Plan *) newnode);
530         CopyNonameFields((Noname *) from, (Noname *) 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->shutdown = 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          * Modify the next line, since it causes the copying to cycle (i.e.
1088          * the parent points right back here! -- JMH, 7/7/92. Old version:
1089          * Node_Copy(from, newnode, parent);
1090          */
1091         newnode->parent = from->parent;
1092
1093         newnode->startup_cost = from->startup_cost;
1094         newnode->total_cost = from->total_cost;
1095
1096         newnode->pathtype = from->pathtype;
1097
1098         Node_Copy(from, newnode, pathkeys);
1099 }
1100
1101 /* ----------------
1102  *              _copyPath
1103  * ----------------
1104  */
1105 static Path *
1106 _copyPath(Path *from)
1107 {
1108         Path       *newnode = makeNode(Path);
1109
1110         CopyPathFields(from, newnode);
1111
1112         return newnode;
1113 }
1114
1115 /* ----------------
1116  *              _copyIndexPath
1117  * ----------------
1118  */
1119 static IndexPath *
1120 _copyIndexPath(IndexPath *from)
1121 {
1122         IndexPath  *newnode = makeNode(IndexPath);
1123
1124         /* ----------------
1125          *      copy the node superclass fields
1126          * ----------------
1127          */
1128         CopyPathFields((Path *) from, (Path *) newnode);
1129
1130         /* ----------------
1131          *      copy remainder of node
1132          * ----------------
1133          */
1134         newnode->indexid = listCopy(from->indexid);
1135         Node_Copy(from, newnode, indexqual);
1136         newnode->indexscandir = from->indexscandir;
1137         newnode->joinrelids = listCopy(from->joinrelids);
1138
1139         return newnode;
1140 }
1141
1142 /* ----------------
1143  *              _copyTidPath
1144  * ----------------
1145  */
1146 static TidPath *
1147 _copyTidPath(TidPath *from)
1148 {
1149         TidPath *newnode = makeNode(TidPath);
1150
1151         /* ----------------
1152          *      copy the node superclass fields
1153          * ----------------
1154          */
1155         CopyPathFields((Path *) from, (Path *) newnode);
1156
1157         /* ----------------
1158          *      copy remainder of node
1159          * ----------------
1160          */
1161         Node_Copy(from, newnode, tideval);
1162         newnode->unjoined_relids = listCopy(from->unjoined_relids);
1163
1164         return newnode;
1165 }
1166 /* ----------------
1167  *              CopyJoinPathFields
1168  *
1169  *              This function copies the fields of the JoinPath node.  It is used by
1170  *              all the copy functions for classes which inherit from JoinPath.
1171  * ----------------
1172  */
1173 static void
1174 CopyJoinPathFields(JoinPath *from, JoinPath *newnode)
1175 {
1176         Node_Copy(from, newnode, outerjoinpath);
1177         Node_Copy(from, newnode, innerjoinpath);
1178         Node_Copy(from, newnode, joinrestrictinfo);
1179 }
1180
1181 /* ----------------
1182  *              _copyNestPath
1183  * ----------------
1184  */
1185 static NestPath *
1186 _copyNestPath(NestPath *from)
1187 {
1188         NestPath   *newnode = makeNode(NestPath);
1189
1190         /* ----------------
1191          *      copy the node superclass fields
1192          * ----------------
1193          */
1194         CopyPathFields((Path *) from, (Path *) newnode);
1195         CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
1196
1197         return newnode;
1198 }
1199
1200 /* ----------------
1201  *              _copyMergePath
1202  * ----------------
1203  */
1204 static MergePath *
1205 _copyMergePath(MergePath *from)
1206 {
1207         MergePath  *newnode = makeNode(MergePath);
1208
1209         /* ----------------
1210          *      copy the node superclass fields
1211          * ----------------
1212          */
1213         CopyPathFields((Path *) from, (Path *) newnode);
1214         CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
1215
1216         /* ----------------
1217          *      copy the remainder of the node
1218          * ----------------
1219          */
1220         Node_Copy(from, newnode, path_mergeclauses);
1221         Node_Copy(from, newnode, outersortkeys);
1222         Node_Copy(from, newnode, innersortkeys);
1223
1224         return newnode;
1225 }
1226
1227 /* ----------------
1228  *              _copyHashPath
1229  * ----------------
1230  */
1231 static HashPath *
1232 _copyHashPath(HashPath *from)
1233 {
1234         HashPath   *newnode = makeNode(HashPath);
1235
1236         /* ----------------
1237          *      copy the node superclass fields
1238          * ----------------
1239          */
1240         CopyPathFields((Path *) from, (Path *) newnode);
1241         CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
1242
1243         /* ----------------
1244          *      copy remainder of node
1245          * ----------------
1246          */
1247         Node_Copy(from, newnode, path_hashclauses);
1248
1249         return newnode;
1250 }
1251
1252 /* ----------------
1253  *              _copyPathKeyItem
1254  * ----------------
1255  */
1256 static PathKeyItem *
1257 _copyPathKeyItem(PathKeyItem *from)
1258 {
1259         PathKeyItem   *newnode = makeNode(PathKeyItem);
1260
1261         /* ----------------
1262          *      copy remainder of node
1263          * ----------------
1264          */
1265         Node_Copy(from, newnode, key);
1266         newnode->sortop = from->sortop;
1267
1268         return newnode;
1269 }
1270
1271 /* ----------------
1272  *              _copyRestrictInfo
1273  * ----------------
1274  */
1275 static RestrictInfo *
1276 _copyRestrictInfo(RestrictInfo *from)
1277 {
1278         RestrictInfo *newnode = makeNode(RestrictInfo);
1279
1280         /* ----------------
1281          *      copy remainder of node
1282          * ----------------
1283          */
1284         Node_Copy(from, newnode, clause);
1285         Node_Copy(from, newnode, subclauseindices);
1286         newnode->mergejoinoperator = from->mergejoinoperator;
1287         newnode->left_sortop = from->left_sortop;
1288         newnode->right_sortop = from->right_sortop;
1289         newnode->hashjoinoperator = from->hashjoinoperator;
1290
1291         return newnode;
1292 }
1293
1294 /* ----------------
1295  *              _copyJoinInfo
1296  * ----------------
1297  */
1298 static JoinInfo *
1299 _copyJoinInfo(JoinInfo *from)
1300 {
1301         JoinInfo   *newnode = makeNode(JoinInfo);
1302
1303         /* ----------------
1304          *      copy remainder of node
1305          * ----------------
1306          */
1307         newnode->unjoined_relids = listCopy(from->unjoined_relids);
1308         Node_Copy(from, newnode, jinfo_restrictinfo);
1309
1310         return newnode;
1311 }
1312
1313 static Iter *
1314 _copyIter(Iter *from)
1315 {
1316         Iter       *newnode = makeNode(Iter);
1317
1318         Node_Copy(from, newnode, iterexpr);
1319         newnode->itertype = from->itertype;
1320
1321         return newnode;
1322 }
1323
1324 static Stream *
1325 _copyStream(Stream *from)
1326 {
1327         Stream     *newnode = makeNode(Stream);
1328
1329         newnode->pathptr = from->pathptr;
1330         newnode->cinfo = from->cinfo;
1331         newnode->clausetype = from->clausetype;
1332
1333         newnode->upstream = (StreamPtr) NULL;           /* only copy nodes
1334                                                                                                  * downwards! */
1335         Node_Copy(from, newnode, downstream);
1336         if (newnode->downstream)
1337                 ((Stream *) newnode->downstream)->upstream = (Stream *) newnode;
1338
1339         newnode->groupup = from->groupup;
1340         newnode->groupcost = from->groupcost;
1341         newnode->groupsel = from->groupsel;
1342
1343         return newnode;
1344 }
1345
1346 /*
1347  *      parsenodes.h routines have no copy functions
1348  */
1349
1350 static TargetEntry *
1351 _copyTargetEntry(TargetEntry *from)
1352 {
1353         TargetEntry *newnode = makeNode(TargetEntry);
1354
1355         Node_Copy(from, newnode, resdom);
1356         Node_Copy(from, newnode, fjoin);
1357         Node_Copy(from, newnode, expr);
1358         return newnode;
1359 }
1360
1361 static RangeTblEntry *
1362 _copyRangeTblEntry(RangeTblEntry *from)
1363 {
1364         RangeTblEntry *newnode = makeNode(RangeTblEntry);
1365
1366         if (from->relname)
1367                 newnode->relname = pstrdup(from->relname);
1368         Node_Copy(from, newnode, ref);
1369         newnode->relid = from->relid;
1370         newnode->inh = from->inh;
1371         newnode->inFromCl = from->inFromCl;
1372         newnode->inJoinSet = from->inJoinSet;
1373         newnode->skipAcl = from->skipAcl;
1374
1375         return newnode;
1376 }
1377
1378 static RowMark *
1379 _copyRowMark(RowMark *from)
1380 {
1381         RowMark    *newnode = makeNode(RowMark);
1382
1383         newnode->rti = from->rti;
1384         newnode->info = from->info;
1385
1386         return newnode;
1387 }
1388
1389 static SortClause *
1390 _copySortClause(SortClause *from)
1391 {
1392         SortClause *newnode = makeNode(SortClause);
1393
1394         newnode->tleSortGroupRef = from->tleSortGroupRef;
1395         newnode->sortop = from->sortop;
1396
1397         return newnode;
1398 }
1399
1400 static A_Const *
1401 _copyAConst(A_Const *from)
1402 {
1403         A_Const    *newnode = makeNode(A_Const);
1404
1405         newnode->val = *((Value *) (copyObject(&(from->val))));
1406         Node_Copy(from, newnode, typename);
1407
1408         return newnode;
1409 }
1410
1411 static TypeName *
1412 _copyTypeName(TypeName *from)
1413 {
1414         TypeName   *newnode = makeNode(TypeName);
1415
1416         if (from->name)
1417                 newnode->name = pstrdup(from->name);
1418         newnode->timezone = from->timezone;
1419         newnode->setof = from->setof;
1420         newnode->typmod = from->typmod;
1421         Node_Copy(from, newnode, arrayBounds);
1422
1423         return newnode;
1424 }
1425
1426 static TypeCast *
1427 _copyTypeCast(TypeCast *from)
1428 {
1429         TypeCast   *newnode = makeNode(TypeCast);
1430
1431         Node_Copy(from, newnode, arg);
1432         Node_Copy(from, newnode, typename);
1433
1434         return newnode;
1435 }
1436
1437 static Query *
1438 _copyQuery(Query *from)
1439 {
1440         Query      *newnode = makeNode(Query);
1441
1442         newnode->commandType = from->commandType;
1443         if (from->utilityStmt && nodeTag(from->utilityStmt) == T_NotifyStmt)
1444         {
1445                 NotifyStmt *from_notify = (NotifyStmt *) from->utilityStmt;
1446                 NotifyStmt *n = makeNode(NotifyStmt);
1447
1448                 n->relname = pstrdup(from_notify->relname);
1449                 newnode->utilityStmt = (Node *) n;
1450         }
1451         newnode->resultRelation = from->resultRelation;
1452         if (from->into)
1453                 newnode->into = pstrdup(from->into);
1454         newnode->isPortal = from->isPortal;
1455         newnode->isBinary = from->isBinary;
1456         newnode->isTemp = from->isTemp;
1457         newnode->unionall = from->unionall;
1458         newnode->hasAggs = from->hasAggs;
1459         newnode->hasSubLinks = from->hasSubLinks;
1460
1461         Node_Copy(from, newnode, rtable);
1462         Node_Copy(from, newnode, targetList);
1463         Node_Copy(from, newnode, qual);
1464         Node_Copy(from, newnode, rowMark);
1465
1466         Node_Copy(from, newnode, distinctClause);
1467         Node_Copy(from, newnode, sortClause);
1468         Node_Copy(from, newnode, groupClause);
1469         Node_Copy(from, newnode, havingQual);
1470
1471         /* why is intersectClause missing? */
1472         Node_Copy(from, newnode, unionClause);
1473
1474         Node_Copy(from, newnode, limitOffset);
1475         Node_Copy(from, newnode, limitCount);
1476
1477         /*
1478          * We do not copy the planner internal fields: base_rel_list,
1479          * join_rel_list, equi_key_list, query_pathkeys.
1480          * Not entirely clear if this is right?
1481          */
1482
1483         return newnode;
1484 }
1485
1486
1487 /*
1488  *      mnodes.h routines have no copy functions
1489  */
1490
1491 /* ****************************************************************
1492  *                                      pg_list.h copy functions
1493  * ****************************************************************
1494  */
1495
1496 static Value *
1497 _copyValue(Value *from)
1498 {
1499         Value      *newnode = makeNode(Value);
1500
1501         newnode->type = from->type;
1502         switch (from->type)
1503         {
1504                 case T_String:
1505                         newnode->val.str = pstrdup(from->val.str);
1506                         break;
1507                 case T_Integer:
1508                         newnode->val.ival = from->val.ival;
1509                         break;
1510                 case T_Float:
1511                         newnode->val.dval = from->val.dval;
1512                         break;
1513                 default:
1514                         break;
1515         }
1516         return newnode;
1517 }
1518
1519 /* ----------------
1520  *              copyObject returns a copy of the node or list. If it is a list, it
1521  *              recursively copies its items.
1522  * ----------------
1523  */
1524 void *
1525 copyObject(void *from)
1526 {
1527         void       *retval;
1528
1529         if (from == NULL)
1530                 return NULL;
1531         switch (nodeTag(from))
1532         {
1533
1534                         /*
1535                          * PLAN NODES
1536                          */
1537                 case T_Plan:
1538                         retval = _copyPlan(from);
1539                         break;
1540                 case T_Result:
1541                         retval = _copyResult(from);
1542                         break;
1543                 case T_Append:
1544                         retval = _copyAppend(from);
1545                         break;
1546                 case T_Scan:
1547                         retval = _copyScan(from);
1548                         break;
1549                 case T_SeqScan:
1550                         retval = _copySeqScan(from);
1551                         break;
1552                 case T_IndexScan:
1553                         retval = _copyIndexScan(from);
1554                         break;
1555                 case T_TidScan:
1556                         retval = _copyTidScan(from);
1557                         break;
1558                 case T_Join:
1559                         retval = _copyJoin(from);
1560                         break;
1561                 case T_NestLoop:
1562                         retval = _copyNestLoop(from);
1563                         break;
1564                 case T_MergeJoin:
1565                         retval = _copyMergeJoin(from);
1566                         break;
1567                 case T_HashJoin:
1568                         retval = _copyHashJoin(from);
1569                         break;
1570                 case T_Noname:
1571                         retval = _copyNoname(from);
1572                         break;
1573                 case T_Material:
1574                         retval = _copyMaterial(from);
1575                         break;
1576                 case T_Sort:
1577                         retval = _copySort(from);
1578                         break;
1579                 case T_Group:
1580                         retval = _copyGroup(from);
1581                         break;
1582                 case T_Agg:
1583                         retval = _copyAgg(from);
1584                         break;
1585                 case T_GroupClause:
1586                         retval = _copyGroupClause(from);
1587                         break;
1588                 case T_Unique:
1589                         retval = _copyUnique(from);
1590                         break;
1591                 case T_Hash:
1592                         retval = _copyHash(from);
1593                         break;
1594                 case T_SubPlan:
1595                         retval = _copySubPlan(from);
1596                         break;
1597
1598                         /*
1599                          * PRIMITIVE NODES
1600                          */
1601                 case T_Resdom:
1602                         retval = _copyResdom(from);
1603                         break;
1604                 case T_Fjoin:
1605                         retval = _copyFjoin(from);
1606                         break;
1607                 case T_Expr:
1608                         retval = _copyExpr(from);
1609                         break;
1610                 case T_Var:
1611                         retval = _copyVar(from);
1612                         break;
1613                 case T_Attr:
1614                         retval = _copyAttr(from);
1615                         break;
1616                 case T_Oper:
1617                         retval = _copyOper(from);
1618                         break;
1619                 case T_Const:
1620                         retval = _copyConst(from);
1621                         break;
1622                 case T_Param:
1623                         retval = _copyParam(from);
1624                         break;
1625                 case T_Func:
1626                         retval = _copyFunc(from);
1627                         break;
1628                 case T_Array:
1629                         retval = _copyArray(from);
1630                         break;
1631                 case T_ArrayRef:
1632                         retval = _copyArrayRef(from);
1633                         break;
1634                 case T_Aggref:
1635                         retval = _copyAggref(from);
1636                         break;
1637                 case T_SubLink:
1638                         retval = _copySubLink(from);
1639                         break;
1640                 case T_RelabelType:
1641                         retval = _copyRelabelType(from);
1642                         break;
1643                 case T_CaseExpr:
1644                         retval = _copyCaseExpr(from);
1645                         break;
1646                 case T_CaseWhen:
1647                         retval = _copyCaseWhen(from);
1648                         break;
1649
1650                         /*
1651                          * RELATION NODES
1652                          */
1653                 case T_RelOptInfo:
1654                         retval = _copyRelOptInfo(from);
1655                         break;
1656                 case T_Path:
1657                         retval = _copyPath(from);
1658                         break;
1659                 case T_IndexPath:
1660                         retval = _copyIndexPath(from);
1661                         break;
1662                 case T_TidPath:
1663                         retval = _copyTidPath(from);
1664                         break;
1665                 case T_NestPath:
1666                         retval = _copyNestPath(from);
1667                         break;
1668                 case T_MergePath:
1669                         retval = _copyMergePath(from);
1670                         break;
1671                 case T_HashPath:
1672                         retval = _copyHashPath(from);
1673                         break;
1674                 case T_PathKeyItem:
1675                         retval = _copyPathKeyItem(from);
1676                         break;
1677                 case T_RestrictInfo:
1678                         retval = _copyRestrictInfo(from);
1679                         break;
1680                 case T_JoinInfo:
1681                         retval = _copyJoinInfo(from);
1682                         break;
1683                 case T_Iter:
1684                         retval = _copyIter(from);
1685                         break;
1686                 case T_Stream:
1687                         retval = _copyStream(from);
1688                         break;
1689                 case T_IndexOptInfo:
1690                         retval = _copyIndexOptInfo(from);
1691                         break;
1692
1693                         /*
1694                          * PARSE NODES
1695                          */
1696                 case T_Query:
1697                         retval = _copyQuery(from);
1698                         break;
1699                 case T_TargetEntry:
1700                         retval = _copyTargetEntry(from);
1701                         break;
1702                 case T_RangeTblEntry:
1703                         retval = _copyRangeTblEntry(from);
1704                         break;
1705                 case T_RowMark:
1706                         retval = _copyRowMark(from);
1707                         break;
1708                 case T_SortClause:
1709                         retval = _copySortClause(from);
1710                         break;
1711                 case T_A_Const:
1712                         retval = _copyAConst(from);
1713                         break;
1714                 case T_TypeName:
1715                         retval = _copyTypeName(from);
1716                         break;
1717                 case T_TypeCast:
1718                         retval = _copyTypeCast(from);
1719                         break;
1720
1721                         /*
1722                          * VALUE NODES
1723                          */
1724                 case T_Integer:
1725                 case T_String:
1726                 case T_Float:
1727                         retval = _copyValue(from);
1728                         break;
1729                 case T_List:
1730                         {
1731                                 List       *list = from,
1732                                                    *l,
1733                                                    *nl;
1734
1735                                 /* rather ugly coding for speed... */
1736                                 /* Note the input list cannot be NIL if we got here. */
1737                                 nl = lcons(copyObject(lfirst(list)), NIL);
1738                                 retval = nl;
1739
1740                                 foreach(l, lnext(list))
1741                                 {
1742                                         lnext(nl) = lcons(copyObject(lfirst(l)), NIL);
1743                                         nl = lnext(nl);
1744                                 }
1745                         }
1746                         break;
1747                 default:
1748                         elog(ERROR, "copyObject: don't know how to copy %d", nodeTag(from));
1749                         retval = from;
1750                         break;
1751         }
1752         return retval;
1753 }