OSDN Git Service

Create a new parsetree node type, TypeCast, so that transformation of
[pg-rex/syncrep.git] / src / backend / nodes / copyfuncs.c
1 /*-------------------------------------------------------------------------
2  *
3  * copyfuncs.c
4  *        Copy functions for Postgres tree nodes.
5  *
6  * Copyright (c) 1994, Regents of the University of California
7  *
8  *
9  * IDENTIFICATION
10  *        $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.100 2000/01/17 00:14:46 tgl Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14
15 #include "postgres.h"
16
17 #include "optimizer/planmain.h"
18 #include "optimizer/subselect.h"
19
20
21 /*
22  * Node_Copy
23  *        a macro to simplify calling of copyObject on the specified field
24  */
25 #define Node_Copy(from, newnode, field) \
26         ((newnode)->field = copyObject((from)->field))
27
28
29 /*
30  * listCopy
31  *        This copy function only copies the "cons-cells" of the list, not the
32  *        pointed-to objects.  (Use copyObject if you want a "deep" copy.)
33  *
34  *        We also use this function for copying lists of integers, which is
35  *        grotty but unlikely to break --- it could fail if sizeof(pointer)
36  *        is less than sizeof(int), but I don't know any such machines...
37  *
38  *        Note that copyObject will surely coredump if applied to a list
39  *        of integers!
40  */
41 List *
42 listCopy(List *list)
43 {
44         List       *newlist,
45                            *l,
46                            *nl;
47
48         /* rather ugly coding for speed... */
49         if (list == NIL)
50                 return NIL;
51
52         newlist = nl = lcons(lfirst(list), NIL);
53
54         foreach(l, lnext(list))
55         {
56                 lnext(nl) = lcons(lfirst(l), NIL);
57                 nl = lnext(nl);
58         }
59         return newlist;
60 }
61
62 /* ****************************************************************
63  *                                       plannodes.h copy functions
64  * ****************************************************************
65  */
66
67 /* ----------------
68  *              CopyPlanFields
69  *
70  *              This function copies the fields of the Plan node.  It is used by
71  *              all the copy functions for classes which inherit from Plan.
72  * ----------------
73  */
74 static void
75 CopyPlanFields(Plan *from, Plan *newnode)
76 {
77         newnode->cost = from->cost;
78         newnode->plan_rows = from->plan_rows;
79         newnode->plan_width = from->plan_width;
80         /* state is NOT copied */
81         newnode->targetlist = copyObject(from->targetlist);
82         newnode->qual = copyObject(from->qual);
83         newnode->lefttree = copyObject(from->lefttree);
84         newnode->righttree = copyObject(from->righttree);
85         newnode->extParam = listCopy(from->extParam);
86         newnode->locParam = listCopy(from->locParam);
87         newnode->chgParam = listCopy(from->chgParam);
88         Node_Copy(from, newnode, initPlan);
89         if (from->subPlan != NIL)
90                 newnode->subPlan = nconc(SS_pull_subplan((Node *) newnode->targetlist),
91                                                                  SS_pull_subplan((Node *) newnode->qual));
92         else
93                 newnode->subPlan = NIL;
94         newnode->nParamExec = from->nParamExec;
95 }
96
97 /* ----------------
98  *              _copyPlan
99  * ----------------
100  */
101 static Plan *
102 _copyPlan(Plan *from)
103 {
104         Plan       *newnode = makeNode(Plan);
105
106         /* ----------------
107          *      copy the node superclass fields
108          * ----------------
109          */
110         CopyPlanFields(from, newnode);
111
112         return newnode;
113 }
114
115
116 /* ----------------
117  *              _copyResult
118  * ----------------
119  */
120 static Result *
121 _copyResult(Result *from)
122 {
123         Result     *newnode = makeNode(Result);
124
125         /* ----------------
126          *      copy node superclass fields
127          * ----------------
128          */
129         CopyPlanFields((Plan *) from, (Plan *) newnode);
130
131         /* ----------------
132          *      copy remainder of node
133          * ----------------
134          */
135         Node_Copy(from, newnode, resconstantqual);
136
137         /*
138          * We must add subplans in resconstantqual to the new plan's subPlan
139          * list
140          */
141         if (from->plan.subPlan != NIL)
142                 newnode->plan.subPlan = nconc(newnode->plan.subPlan,
143                                                                           SS_pull_subplan(newnode->resconstantqual));
144
145         return newnode;
146 }
147
148 /* ----------------
149  *              _copyAppend
150  * ----------------
151  */
152 static Append *
153 _copyAppend(Append *from)
154 {
155         Append     *newnode = makeNode(Append);
156
157         /* ----------------
158          *      copy node superclass fields
159          * ----------------
160          */
161         CopyPlanFields((Plan *) from, (Plan *) newnode);
162
163         /* ----------------
164          *      copy remainder of node
165          * ----------------
166          */
167         Node_Copy(from, newnode, appendplans);
168         Node_Copy(from, newnode, unionrtables);
169         newnode->inheritrelid = from->inheritrelid;
170         Node_Copy(from, newnode, inheritrtable);
171
172         return newnode;
173 }
174
175
176 /* ----------------
177  *              CopyScanFields
178  *
179  *              This function copies the fields of the Scan node.  It is used by
180  *              all the copy functions for classes which inherit from Scan.
181  * ----------------
182  */
183 static void
184 CopyScanFields(Scan *from, Scan *newnode)
185 {
186         newnode->scanrelid = from->scanrelid;
187         return;
188 }
189
190 /* ----------------
191  *              _copyScan
192  * ----------------
193  */
194 static Scan *
195 _copyScan(Scan *from)
196 {
197         Scan       *newnode = makeNode(Scan);
198
199         /* ----------------
200          *      copy node superclass fields
201          * ----------------
202          */
203         CopyPlanFields((Plan *) from, (Plan *) newnode);
204         CopyScanFields((Scan *) from, (Scan *) newnode);
205
206         return newnode;
207 }
208
209 /* ----------------
210  *              _copySeqScan
211  * ----------------
212  */
213 static SeqScan *
214 _copySeqScan(SeqScan *from)
215 {
216         SeqScan    *newnode = makeNode(SeqScan);
217
218         /* ----------------
219          *      copy node superclass fields
220          * ----------------
221          */
222         CopyPlanFields((Plan *) from, (Plan *) newnode);
223         CopyScanFields((Scan *) from, (Scan *) newnode);
224
225         return newnode;
226 }
227
228 /* ----------------
229  *              _copyIndexScan
230  * ----------------
231  */
232 static IndexScan *
233 _copyIndexScan(IndexScan *from)
234 {
235         IndexScan  *newnode = makeNode(IndexScan);
236
237         /* ----------------
238          *      copy node superclass fields
239          * ----------------
240          */
241         CopyPlanFields((Plan *) from, (Plan *) newnode);
242         CopyScanFields((Scan *) from, (Scan *) newnode);
243
244         /* ----------------
245          *      copy remainder of node
246          * ----------------
247          */
248         newnode->indxid = listCopy(from->indxid);
249         Node_Copy(from, newnode, indxqual);
250         Node_Copy(from, newnode, indxqualorig);
251         newnode->indxorderdir = from->indxorderdir;
252
253         return newnode;
254 }
255
256 /* ----------------
257  *              _copyTidScan
258  * ----------------
259  */
260 static TidScan *
261 _copyTidScan(TidScan *from)
262 {
263         TidScan *newnode = makeNode(TidScan);
264
265         /* ----------------
266          *      copy node superclass fields
267          * ----------------
268          */
269         CopyPlanFields((Plan *) from, (Plan *) newnode);
270         CopyScanFields((Scan *) from, (Scan *) newnode);
271         /* ----------------
272          *      copy remainder of node
273          * ----------------
274          */
275         newnode->needRescan = from->needRescan;
276         Node_Copy(from, newnode, tideval);
277
278         return newnode;
279 }
280
281     
282 /* ----------------
283  *              CopyJoinFields
284  *
285  *              This function copies the fields of the Join node.  It is used by
286  *              all the copy functions for classes which inherit from Join.
287  * ----------------
288  */
289 static void
290 CopyJoinFields(Join *from, Join *newnode)
291 {
292         /* nothing extra */
293         return;
294 }
295
296
297 /* ----------------
298  *              _copyJoin
299  * ----------------
300  */
301 static Join *
302 _copyJoin(Join *from)
303 {
304         Join       *newnode = makeNode(Join);
305
306         /* ----------------
307          *      copy node superclass fields
308          * ----------------
309          */
310         CopyPlanFields((Plan *) from, (Plan *) newnode);
311         CopyJoinFields(from, newnode);
312
313         return newnode;
314 }
315
316
317 /* ----------------
318  *              _copyNestLoop
319  * ----------------
320  */
321 static NestLoop *
322 _copyNestLoop(NestLoop *from)
323 {
324         NestLoop   *newnode = makeNode(NestLoop);
325
326         /* ----------------
327          *      copy node superclass fields
328          * ----------------
329          */
330         CopyPlanFields((Plan *) from, (Plan *) newnode);
331         CopyJoinFields((Join *) from, (Join *) newnode);
332
333         return newnode;
334 }
335
336
337 /* ----------------
338  *              _copyMergeJoin
339  * ----------------
340  */
341 static MergeJoin *
342 _copyMergeJoin(MergeJoin *from)
343 {
344         MergeJoin  *newnode = makeNode(MergeJoin);
345
346         /* ----------------
347          *      copy node superclass fields
348          * ----------------
349          */
350         CopyPlanFields((Plan *) from, (Plan *) newnode);
351         CopyJoinFields((Join *) from, (Join *) newnode);
352
353         /* ----------------
354          *      copy remainder of node
355          * ----------------
356          */
357         Node_Copy(from, newnode, mergeclauses);
358
359         return newnode;
360 }
361
362 /* ----------------
363  *              _copyHashJoin
364  * ----------------
365  */
366 static HashJoin *
367 _copyHashJoin(HashJoin *from)
368 {
369         HashJoin   *newnode = makeNode(HashJoin);
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, hashclauses);
383
384         newnode->hashjoinop = from->hashjoinop;
385
386         return newnode;
387 }
388
389
390 /* ----------------
391  *              CopyNonameFields
392  *
393  *              This function copies the fields of the Noname node.  It is used by
394  *              all the copy functions for classes which inherit from Noname.
395  * ----------------
396  */
397 static void
398 CopyNonameFields(Noname *from, Noname *newnode)
399 {
400         newnode->nonameid = from->nonameid;
401         newnode->keycount = from->keycount;
402         return;
403 }
404
405
406 /* ----------------
407  *              _copyNoname
408  * ----------------
409  */
410 static Noname *
411 _copyNoname(Noname *from)
412 {
413         Noname     *newnode = makeNode(Noname);
414
415         /* ----------------
416          *      copy node superclass fields
417          * ----------------
418          */
419         CopyPlanFields((Plan *) from, (Plan *) newnode);
420         CopyNonameFields(from, newnode);
421
422         return newnode;
423 }
424
425 /* ----------------
426  *              _copyMaterial
427  * ----------------
428  */
429 static Material *
430 _copyMaterial(Material *from)
431 {
432         Material   *newnode = makeNode(Material);
433
434         /* ----------------
435          *      copy node superclass fields
436          * ----------------
437          */
438         CopyPlanFields((Plan *) from, (Plan *) newnode);
439         CopyNonameFields((Noname *) from, (Noname *) newnode);
440
441         return newnode;
442 }
443
444
445 /* ----------------
446  *              _copySort
447  * ----------------
448  */
449 static Sort *
450 _copySort(Sort *from)
451 {
452         Sort       *newnode = makeNode(Sort);
453
454         /* ----------------
455          *      copy node superclass fields
456          * ----------------
457          */
458         CopyPlanFields((Plan *) from, (Plan *) newnode);
459         CopyNonameFields((Noname *) from, (Noname *) newnode);
460
461         return newnode;
462 }
463
464
465 /* ----------------
466  *              _copyGroup
467  * ----------------
468  */
469 static Group *
470 _copyGroup(Group *from)
471 {
472         Group      *newnode = makeNode(Group);
473
474         CopyPlanFields((Plan *) from, (Plan *) newnode);
475
476         newnode->tuplePerGroup = from->tuplePerGroup;
477         newnode->numCols = from->numCols;
478         newnode->grpColIdx = palloc(from->numCols * sizeof(AttrNumber));
479         memcpy(newnode->grpColIdx, from->grpColIdx, from->numCols * sizeof(AttrNumber));
480
481         return newnode;
482 }
483
484 /* ---------------
485  *      _copyAgg
486  * --------------
487  */
488 static Agg *
489 _copyAgg(Agg *from)
490 {
491         Agg                *newnode = makeNode(Agg);
492
493         CopyPlanFields((Plan *) from, (Plan *) newnode);
494
495         return newnode;
496 }
497
498 /* ---------------
499  *      _copyGroupClause
500  * --------------
501  */
502 static GroupClause *
503 _copyGroupClause(GroupClause *from)
504 {
505         GroupClause *newnode = makeNode(GroupClause);
506
507         newnode->tleSortGroupRef = from->tleSortGroupRef;
508         newnode->sortop = from->sortop;
509
510         return newnode;
511 }
512
513
514 /* ----------------
515  *              _copyUnique
516  * ----------------
517  */
518 static Unique *
519 _copyUnique(Unique *from)
520 {
521         Unique     *newnode = makeNode(Unique);
522
523         /* ----------------
524          *      copy node superclass fields
525          * ----------------
526          */
527         CopyPlanFields((Plan *) from, (Plan *) newnode);
528         CopyNonameFields((Noname *) from, (Noname *) newnode);
529
530         /* ----------------
531          *      copy remainder of node
532          * ----------------
533          */
534         if (from->uniqueAttr)
535                 newnode->uniqueAttr = pstrdup(from->uniqueAttr);
536         else
537                 newnode->uniqueAttr = NULL;
538         newnode->uniqueAttrNum = from->uniqueAttrNum;
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 /* ----------------
693  *              _copyOper
694  * ----------------
695  */
696 static Oper *
697 _copyOper(Oper *from)
698 {
699         Oper       *newnode = makeNode(Oper);
700
701         /* ----------------
702          *      copy remainder of node
703          * ----------------
704          */
705         newnode->opno = from->opno;
706         newnode->opid = from->opid;
707         newnode->opresulttype = from->opresulttype;
708         newnode->opsize = from->opsize;
709
710         /*
711          * NOTE: shall we copy the cache structure or just the pointer ?
712          * Alternatively we can set 'op_fcache' to NULL, in which case the
713          * executor will initialize it when it needs it...
714          */
715         newnode->op_fcache = from->op_fcache;
716
717         return newnode;
718 }
719
720 /* ----------------
721  *              _copyConst
722  * ----------------
723  */
724 static Const *
725 _copyConst(Const *from)
726 {
727         Const      *newnode = makeNode(Const);
728
729         /* ----------------
730          *      copy remainder of node
731          * ----------------
732          */
733         newnode->consttype = from->consttype;
734         newnode->constlen = from->constlen;
735
736         if (from->constbyval || from->constisnull)
737         {
738                 /* ----------------
739                  *      passed by value so just copy the datum.
740                  *      Also, don't try to copy struct when value is null!
741                  * ----------------
742                  */
743                 newnode->constvalue = from->constvalue;
744         }
745         else
746         {
747                 /* ----------------
748                  *      not passed by value. datum contains a pointer.
749                  * ----------------
750                  */
751                 int                     length = from->constlen;
752
753                 if (length == -1)               /* variable-length type? */
754                         length = VARSIZE(from->constvalue);
755                 newnode->constvalue = PointerGetDatum(palloc(length));
756                 memcpy(DatumGetPointer(newnode->constvalue),
757                            DatumGetPointer(from->constvalue),
758                            length);
759         }
760
761         newnode->constisnull = from->constisnull;
762         newnode->constbyval = from->constbyval;
763         newnode->constisset = from->constisset;
764         newnode->constiscast = from->constiscast;
765
766         return newnode;
767 }
768
769 /* ----------------
770  *              _copyParam
771  * ----------------
772  */
773 static Param *
774 _copyParam(Param *from)
775 {
776         Param      *newnode = makeNode(Param);
777
778         /* ----------------
779          *      copy remainder of node
780          * ----------------
781          */
782         newnode->paramkind = from->paramkind;
783         newnode->paramid = from->paramid;
784
785         if (from->paramname != NULL)
786                 newnode->paramname = pstrdup(from->paramname);
787         newnode->paramtype = from->paramtype;
788         Node_Copy(from, newnode, param_tlist);
789
790         return newnode;
791 }
792
793 /* ----------------
794  *              _copyFunc
795  * ----------------
796  */
797 static Func *
798 _copyFunc(Func *from)
799 {
800         Func       *newnode = makeNode(Func);
801
802         /* ----------------
803          *      copy remainder of node
804          * ----------------
805          */
806         newnode->funcid = from->funcid;
807         newnode->functype = from->functype;
808         newnode->funcisindex = from->funcisindex;
809         newnode->funcsize = from->funcsize;
810         newnode->func_fcache = from->func_fcache;
811         Node_Copy(from, newnode, func_tlist);
812         Node_Copy(from, newnode, func_planlist);
813
814         return newnode;
815 }
816
817 /* ----------------
818  *              _copyAggref
819  * ----------------
820  */
821 static Aggref *
822 _copyAggref(Aggref *from)
823 {
824         Aggref     *newnode = makeNode(Aggref);
825
826         /* ----------------
827          *      copy remainder of node
828          * ----------------
829          */
830         newnode->aggname = pstrdup(from->aggname);
831         newnode->basetype = from->basetype;
832         newnode->aggtype = from->aggtype;
833         Node_Copy(from, newnode, target);
834         newnode->usenulls = from->usenulls;
835         newnode->aggstar = from->aggstar;
836         newnode->aggdistinct = from->aggdistinct;
837         newnode->aggno = from->aggno; /* probably not needed */
838
839         return newnode;
840 }
841
842 /* ----------------
843  *              _copySubLink
844  * ----------------
845  */
846 static SubLink *
847 _copySubLink(SubLink *from)
848 {
849         SubLink    *newnode = makeNode(SubLink);
850
851         /* ----------------
852          *      copy remainder of node
853          * ----------------
854          */
855         newnode->subLinkType = from->subLinkType;
856         newnode->useor = from->useor;
857         Node_Copy(from, newnode, lefthand);
858         Node_Copy(from, newnode, oper);
859         Node_Copy(from, newnode, subselect);
860
861         return newnode;
862 }
863
864 /* ----------------
865  *              _copyCaseExpr
866  * ----------------
867  */
868 static CaseExpr *
869 _copyCaseExpr(CaseExpr *from)
870 {
871         CaseExpr   *newnode = makeNode(CaseExpr);
872
873         /* ----------------
874          *      copy remainder of node
875          * ----------------
876          */
877         newnode->casetype = from->casetype;
878
879         Node_Copy(from, newnode, arg);
880         Node_Copy(from, newnode, args);
881         Node_Copy(from, newnode, defresult);
882
883         return newnode;
884 }
885
886 /* ----------------
887  *              _copyCaseWhen
888  * ----------------
889  */
890 static CaseWhen *
891 _copyCaseWhen(CaseWhen *from)
892 {
893         CaseWhen   *newnode = makeNode(CaseWhen);
894
895         /* ----------------
896          *      copy remainder of node
897          * ----------------
898          */
899         Node_Copy(from, newnode, expr);
900         Node_Copy(from, newnode, result);
901
902         return newnode;
903 }
904
905 static Array *
906 _copyArray(Array *from)
907 {
908         Array      *newnode = makeNode(Array);
909
910         /* ----------------
911          *      copy remainder of node
912          * ----------------
913          */
914         newnode->arrayelemtype = from->arrayelemtype;
915         newnode->arrayelemlength = from->arrayelemlength;
916         newnode->arrayelembyval = from->arrayelembyval;
917         newnode->arrayndim = from->arrayndim;
918         newnode->arraylow = from->arraylow;
919         newnode->arrayhigh = from->arrayhigh;
920         newnode->arraylen = from->arraylen;
921
922         return newnode;
923 }
924
925 static ArrayRef *
926 _copyArrayRef(ArrayRef *from)
927 {
928         ArrayRef   *newnode = makeNode(ArrayRef);
929
930         /* ----------------
931          *      copy remainder of node
932          * ----------------
933          */
934         newnode->refattrlength = from->refattrlength;
935         newnode->refelemlength = from->refelemlength;
936         newnode->refelemtype = from->refelemtype;
937         newnode->refelembyval = from->refelembyval;
938
939         Node_Copy(from, newnode, refupperindexpr);
940         Node_Copy(from, newnode, reflowerindexpr);
941         Node_Copy(from, newnode, refexpr);
942         Node_Copy(from, newnode, refassgnexpr);
943
944         return newnode;
945 }
946
947 /* ****************************************************************
948  *                                              relation.h copy functions
949  * ****************************************************************
950  */
951
952 /* ----------------
953  *              _copyRelOptInfo
954  * ----------------
955  */
956 /*
957  *      when you change this, also make sure to fix up xfunc_copyRelOptInfo in
958  *      planner/path/xfunc.c accordingly!!!
959  *              -- JMH, 8/2/93
960  */
961 static RelOptInfo *
962 _copyRelOptInfo(RelOptInfo *from)
963 {
964         RelOptInfo *newnode = makeNode(RelOptInfo);
965
966         newnode->relids = listCopy(from->relids);
967
968         newnode->rows = from->rows;
969         newnode->width = from->width;
970
971         Node_Copy(from, newnode, targetlist);
972         Node_Copy(from, newnode, pathlist);
973         /* XXX cheapestpath should point to a member of pathlist? */
974         Node_Copy(from, newnode, cheapestpath);
975         newnode->pruneable = from->pruneable;
976
977         newnode->indexed = from->indexed;
978         newnode->pages = from->pages;
979         newnode->tuples = from->tuples;
980
981         Node_Copy(from, newnode, restrictinfo);
982         Node_Copy(from, newnode, joininfo);
983         Node_Copy(from, newnode, innerjoin);
984
985         return newnode;
986 }
987
988 /* ----------------
989  *              _copyIndexOptInfo
990  * ----------------
991  */
992 static IndexOptInfo *
993 _copyIndexOptInfo(IndexOptInfo *from)
994 {
995         IndexOptInfo *newnode = makeNode(IndexOptInfo);
996         int                     i,
997                                 len;
998
999         newnode->indexoid = from->indexoid;
1000         newnode->pages = from->pages;
1001         newnode->tuples = from->tuples;
1002
1003         if (from->classlist)
1004         {
1005                 for (len = 0; from->classlist[len] != 0; len++)
1006                         ;
1007                 newnode->classlist = (Oid *) palloc(sizeof(Oid) * (len + 1));
1008                 for (i = 0; i < len; i++)
1009                         newnode->classlist[i] = from->classlist[i];
1010                 newnode->classlist[len] = 0;
1011         }
1012
1013         if (from->indexkeys)
1014         {
1015                 for (len = 0; from->indexkeys[len] != 0; len++)
1016                         ;
1017                 newnode->indexkeys = (int *) palloc(sizeof(int) * (len + 1));
1018                 for (i = 0; i < len; i++)
1019                         newnode->indexkeys[i] = from->indexkeys[i];
1020                 newnode->indexkeys[len] = 0;
1021         }
1022
1023         if (from->ordering)
1024         {
1025                 for (len = 0; from->ordering[len] != 0; len++)
1026                         ;
1027                 newnode->ordering = (Oid *) palloc(sizeof(Oid) * (len + 1));
1028                 for (i = 0; i < len; i++)
1029                         newnode->ordering[i] = from->ordering[i];
1030                 newnode->ordering[len] = 0;
1031         }
1032
1033         newnode->relam = from->relam;
1034         newnode->indproc = from->indproc;
1035         Node_Copy(from, newnode, indpred);
1036
1037         return newnode;
1038 }
1039
1040 /* ----------------
1041  *              CopyPathFields
1042  *
1043  *              This function copies the fields of the Path node.  It is used by
1044  *              all the copy functions for classes which inherit from Path.
1045  * ----------------
1046  */
1047 static void
1048 CopyPathFields(Path *from, Path *newnode)
1049 {
1050         /*
1051          * Modify the next line, since it causes the copying to cycle (i.e.
1052          * the parent points right back here! -- JMH, 7/7/92. Old version:
1053          * Node_Copy(from, newnode, parent);
1054          */
1055         newnode->parent = from->parent;
1056
1057         newnode->path_cost = from->path_cost;
1058
1059         newnode->pathtype = from->pathtype;
1060
1061         Node_Copy(from, newnode, pathkeys);
1062 }
1063
1064 /* ----------------
1065  *              _copyPath
1066  * ----------------
1067  */
1068 static Path *
1069 _copyPath(Path *from)
1070 {
1071         Path       *newnode = makeNode(Path);
1072
1073         CopyPathFields(from, newnode);
1074
1075         return newnode;
1076 }
1077
1078 /* ----------------
1079  *              _copyIndexPath
1080  * ----------------
1081  */
1082 static IndexPath *
1083 _copyIndexPath(IndexPath *from)
1084 {
1085         IndexPath  *newnode = makeNode(IndexPath);
1086
1087         /* ----------------
1088          *      copy the node superclass fields
1089          * ----------------
1090          */
1091         CopyPathFields((Path *) from, (Path *) newnode);
1092
1093         /* ----------------
1094          *      copy remainder of node
1095          * ----------------
1096          */
1097         newnode->indexid = listCopy(from->indexid);
1098         Node_Copy(from, newnode, indexqual);
1099         newnode->joinrelids = listCopy(from->joinrelids);
1100
1101         return newnode;
1102 }
1103
1104 /* ----------------
1105  *              _copyTidPath
1106  * ----------------
1107  */
1108 static TidPath *
1109 _copyTidPath(TidPath *from)
1110 {
1111         TidPath *newnode = makeNode(TidPath);
1112
1113         /* ----------------
1114          *      copy the node superclass fields
1115          * ----------------
1116          */
1117         CopyPathFields((Path *) from, (Path *) newnode);
1118
1119         /* ----------------
1120          *      copy remainder of node
1121          * ----------------
1122          */
1123         Node_Copy(from, newnode, tideval);
1124         newnode->unjoined_relids = listCopy(from->unjoined_relids);
1125
1126         return newnode;
1127 }
1128 /* ----------------
1129  *              CopyJoinPathFields
1130  *
1131  *              This function copies the fields of the JoinPath node.  It is used by
1132  *              all the copy functions for classes which inherit from JoinPath.
1133  * ----------------
1134  */
1135 static void
1136 CopyJoinPathFields(JoinPath *from, JoinPath *newnode)
1137 {
1138         Node_Copy(from, newnode, outerjoinpath);
1139         Node_Copy(from, newnode, innerjoinpath);
1140 }
1141
1142 /* ----------------
1143  *              _copyNestPath
1144  * ----------------
1145  */
1146 static NestPath *
1147 _copyNestPath(NestPath *from)
1148 {
1149         NestPath   *newnode = makeNode(NestPath);
1150
1151         /* ----------------
1152          *      copy the node superclass fields
1153          * ----------------
1154          */
1155         CopyPathFields((Path *) from, (Path *) newnode);
1156         CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
1157
1158         return newnode;
1159 }
1160
1161 /* ----------------
1162  *              _copyMergePath
1163  * ----------------
1164  */
1165 static MergePath *
1166 _copyMergePath(MergePath *from)
1167 {
1168         MergePath  *newnode = makeNode(MergePath);
1169
1170         /* ----------------
1171          *      copy the node superclass fields
1172          * ----------------
1173          */
1174         CopyPathFields((Path *) from, (Path *) newnode);
1175         CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
1176
1177         /* ----------------
1178          *      copy the remainder of the node
1179          * ----------------
1180          */
1181         Node_Copy(from, newnode, path_mergeclauses);
1182         Node_Copy(from, newnode, outersortkeys);
1183         Node_Copy(from, newnode, innersortkeys);
1184
1185         return newnode;
1186 }
1187
1188 /* ----------------
1189  *              _copyHashPath
1190  * ----------------
1191  */
1192 static HashPath *
1193 _copyHashPath(HashPath *from)
1194 {
1195         HashPath   *newnode = makeNode(HashPath);
1196
1197         /* ----------------
1198          *      copy the node superclass fields
1199          * ----------------
1200          */
1201         CopyPathFields((Path *) from, (Path *) newnode);
1202         CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
1203
1204         /* ----------------
1205          *      copy remainder of node
1206          * ----------------
1207          */
1208         Node_Copy(from, newnode, path_hashclauses);
1209
1210         return newnode;
1211 }
1212
1213 /* ----------------
1214  *              _copyPathKeyItem
1215  * ----------------
1216  */
1217 static PathKeyItem *
1218 _copyPathKeyItem(PathKeyItem *from)
1219 {
1220         PathKeyItem   *newnode = makeNode(PathKeyItem);
1221
1222         /* ----------------
1223          *      copy remainder of node
1224          * ----------------
1225          */
1226         Node_Copy(from, newnode, key);
1227         newnode->sortop = from->sortop;
1228
1229         return newnode;
1230 }
1231
1232 /* ----------------
1233  *              _copyRestrictInfo
1234  * ----------------
1235  */
1236 static RestrictInfo *
1237 _copyRestrictInfo(RestrictInfo *from)
1238 {
1239         RestrictInfo *newnode = makeNode(RestrictInfo);
1240
1241         /* ----------------
1242          *      copy remainder of node
1243          * ----------------
1244          */
1245         Node_Copy(from, newnode, clause);
1246         Node_Copy(from, newnode, subclauseindices);
1247         newnode->mergejoinoperator = from->mergejoinoperator;
1248         newnode->left_sortop = from->left_sortop;
1249         newnode->right_sortop = from->right_sortop;
1250         newnode->hashjoinoperator = from->hashjoinoperator;
1251
1252         return newnode;
1253 }
1254
1255 /* ----------------
1256  *              _copyJoinInfo
1257  * ----------------
1258  */
1259 static JoinInfo *
1260 _copyJoinInfo(JoinInfo *from)
1261 {
1262         JoinInfo   *newnode = makeNode(JoinInfo);
1263
1264         /* ----------------
1265          *      copy remainder of node
1266          * ----------------
1267          */
1268         newnode->unjoined_relids = listCopy(from->unjoined_relids);
1269         Node_Copy(from, newnode, jinfo_restrictinfo);
1270
1271         return newnode;
1272 }
1273
1274 static Iter *
1275 _copyIter(Iter *from)
1276 {
1277         Iter       *newnode = makeNode(Iter);
1278
1279         Node_Copy(from, newnode, iterexpr);
1280         newnode->itertype = from->itertype;
1281
1282         return newnode;
1283 }
1284
1285 static Stream *
1286 _copyStream(Stream *from)
1287 {
1288         Stream     *newnode = makeNode(Stream);
1289
1290         newnode->pathptr = from->pathptr;
1291         newnode->cinfo = from->cinfo;
1292         newnode->clausetype = from->clausetype;
1293
1294         newnode->upstream = (StreamPtr) NULL;           /* only copy nodes
1295                                                                                                  * downwards! */
1296         Node_Copy(from, newnode, downstream);
1297         if (newnode->downstream)
1298                 ((Stream *) newnode->downstream)->upstream = (Stream *) newnode;
1299
1300         newnode->groupup = from->groupup;
1301         newnode->groupcost = from->groupcost;
1302         newnode->groupsel = from->groupsel;
1303
1304         return newnode;
1305 }
1306
1307 /*
1308  *      parsenodes.h routines have no copy functions
1309  */
1310
1311 static TargetEntry *
1312 _copyTargetEntry(TargetEntry *from)
1313 {
1314         TargetEntry *newnode = makeNode(TargetEntry);
1315
1316         Node_Copy(from, newnode, resdom);
1317         Node_Copy(from, newnode, fjoin);
1318         Node_Copy(from, newnode, expr);
1319         return newnode;
1320 }
1321
1322 static RangeTblEntry *
1323 _copyRangeTblEntry(RangeTblEntry *from)
1324 {
1325         RangeTblEntry *newnode = makeNode(RangeTblEntry);
1326
1327         if (from->relname)
1328                 newnode->relname = pstrdup(from->relname);
1329         if (from->refname)
1330                 newnode->refname = pstrdup(from->refname);
1331         newnode->relid = from->relid;
1332         newnode->inh = from->inh;
1333         newnode->inFromCl = from->inFromCl;
1334         newnode->inJoinSet = from->inJoinSet;
1335         newnode->skipAcl = from->skipAcl;
1336
1337         return newnode;
1338 }
1339
1340 static RowMark *
1341 _copyRowMark(RowMark *from)
1342 {
1343         RowMark    *newnode = makeNode(RowMark);
1344
1345         newnode->rti = from->rti;
1346         newnode->info = from->info;
1347
1348         return newnode;
1349 }
1350
1351 static SortClause *
1352 _copySortClause(SortClause *from)
1353 {
1354         SortClause *newnode = makeNode(SortClause);
1355
1356         newnode->tleSortGroupRef = from->tleSortGroupRef;
1357         newnode->sortop = from->sortop;
1358
1359         return newnode;
1360 }
1361
1362 static A_Const *
1363 _copyAConst(A_Const *from)
1364 {
1365         A_Const    *newnode = makeNode(A_Const);
1366
1367         newnode->val = *((Value *) (copyObject(&(from->val))));
1368         Node_Copy(from, newnode, typename);
1369
1370         return newnode;
1371 }
1372
1373 static TypeName *
1374 _copyTypeName(TypeName *from)
1375 {
1376         TypeName   *newnode = makeNode(TypeName);
1377
1378         if (from->name)
1379                 newnode->name = pstrdup(from->name);
1380         newnode->timezone = from->timezone;
1381         newnode->setof = from->setof;
1382         newnode->typmod = from->typmod;
1383         Node_Copy(from, newnode, arrayBounds);
1384
1385         return newnode;
1386 }
1387
1388 static TypeCast *
1389 _copyTypeCast(TypeCast *from)
1390 {
1391         TypeCast   *newnode = makeNode(TypeCast);
1392
1393         Node_Copy(from, newnode, arg);
1394         Node_Copy(from, newnode, typename);
1395
1396         return newnode;
1397 }
1398
1399 static Query *
1400 _copyQuery(Query *from)
1401 {
1402         Query      *newnode = makeNode(Query);
1403
1404         newnode->commandType = from->commandType;
1405         if (from->utilityStmt && nodeTag(from->utilityStmt) == T_NotifyStmt)
1406         {
1407                 NotifyStmt *from_notify = (NotifyStmt *) from->utilityStmt;
1408                 NotifyStmt *n = makeNode(NotifyStmt);
1409
1410                 n->relname = pstrdup(from_notify->relname);
1411                 newnode->utilityStmt = (Node *) n;
1412         }
1413         newnode->resultRelation = from->resultRelation;
1414         if (from->into)
1415                 newnode->into = pstrdup(from->into);
1416         newnode->isPortal = from->isPortal;
1417         newnode->isBinary = from->isBinary;
1418         newnode->isTemp = from->isTemp;
1419         newnode->unionall = from->unionall;
1420         newnode->hasAggs = from->hasAggs;
1421         newnode->hasSubLinks = from->hasSubLinks;
1422
1423         Node_Copy(from, newnode, rtable);
1424         Node_Copy(from, newnode, targetList);
1425         Node_Copy(from, newnode, qual);
1426         Node_Copy(from, newnode, rowMark);
1427
1428         if (from->uniqueFlag)
1429                 newnode->uniqueFlag = pstrdup(from->uniqueFlag);
1430         Node_Copy(from, newnode, sortClause);
1431         Node_Copy(from, newnode, groupClause);
1432         Node_Copy(from, newnode, havingQual);
1433
1434         /* why is intersectClause missing? */
1435         Node_Copy(from, newnode, unionClause);
1436
1437         Node_Copy(from, newnode, limitOffset);
1438         Node_Copy(from, newnode, limitCount);
1439
1440         /* we do not copy the planner internal fields: base_rel_list,
1441          * join_rel_list, query_pathkeys.  Not entirely clear if this is right?
1442          */
1443
1444         return newnode;
1445 }
1446
1447
1448 /*
1449  *      mnodes.h routines have no copy functions
1450  */
1451
1452 /* ****************************************************************
1453  *                                      pg_list.h copy functions
1454  * ****************************************************************
1455  */
1456
1457 static Value *
1458 _copyValue(Value *from)
1459 {
1460         Value      *newnode = makeNode(Value);
1461
1462         newnode->type = from->type;
1463         switch (from->type)
1464         {
1465                 case T_String:
1466                         newnode->val.str = pstrdup(from->val.str);
1467                         break;
1468                 case T_Integer:
1469                         newnode->val.ival = from->val.ival;
1470                         break;
1471                 case T_Float:
1472                         newnode->val.dval = from->val.dval;
1473                         break;
1474                 default:
1475                         break;
1476         }
1477         return newnode;
1478 }
1479
1480 /* ----------------
1481  *              copyObject returns a copy of the node or list. If it is a list, it
1482  *              recursively copies its items.
1483  * ----------------
1484  */
1485 void *
1486 copyObject(void *from)
1487 {
1488         void       *retval;
1489
1490         if (from == NULL)
1491                 return NULL;
1492         switch (nodeTag(from))
1493         {
1494
1495                         /*
1496                          * PLAN NODES
1497                          */
1498                 case T_Plan:
1499                         retval = _copyPlan(from);
1500                         break;
1501                 case T_Result:
1502                         retval = _copyResult(from);
1503                         break;
1504                 case T_Append:
1505                         retval = _copyAppend(from);
1506                         break;
1507                 case T_Scan:
1508                         retval = _copyScan(from);
1509                         break;
1510                 case T_SeqScan:
1511                         retval = _copySeqScan(from);
1512                         break;
1513                 case T_IndexScan:
1514                         retval = _copyIndexScan(from);
1515                         break;
1516                 case T_TidScan:
1517                         retval = _copyTidScan(from);
1518                         break;
1519                 case T_Join:
1520                         retval = _copyJoin(from);
1521                         break;
1522                 case T_NestLoop:
1523                         retval = _copyNestLoop(from);
1524                         break;
1525                 case T_MergeJoin:
1526                         retval = _copyMergeJoin(from);
1527                         break;
1528                 case T_HashJoin:
1529                         retval = _copyHashJoin(from);
1530                         break;
1531                 case T_Noname:
1532                         retval = _copyNoname(from);
1533                         break;
1534                 case T_Material:
1535                         retval = _copyMaterial(from);
1536                         break;
1537                 case T_Sort:
1538                         retval = _copySort(from);
1539                         break;
1540                 case T_Group:
1541                         retval = _copyGroup(from);
1542                         break;
1543                 case T_Agg:
1544                         retval = _copyAgg(from);
1545                         break;
1546                 case T_GroupClause:
1547                         retval = _copyGroupClause(from);
1548                         break;
1549                 case T_Unique:
1550                         retval = _copyUnique(from);
1551                         break;
1552                 case T_Hash:
1553                         retval = _copyHash(from);
1554                         break;
1555                 case T_SubPlan:
1556                         retval = _copySubPlan(from);
1557                         break;
1558
1559                         /*
1560                          * PRIMITIVE NODES
1561                          */
1562                 case T_Resdom:
1563                         retval = _copyResdom(from);
1564                         break;
1565                 case T_Fjoin:
1566                         retval = _copyFjoin(from);
1567                         break;
1568                 case T_Expr:
1569                         retval = _copyExpr(from);
1570                         break;
1571                 case T_Var:
1572                         retval = _copyVar(from);
1573                         break;
1574                 case T_Oper:
1575                         retval = _copyOper(from);
1576                         break;
1577                 case T_Const:
1578                         retval = _copyConst(from);
1579                         break;
1580                 case T_Param:
1581                         retval = _copyParam(from);
1582                         break;
1583                 case T_Func:
1584                         retval = _copyFunc(from);
1585                         break;
1586                 case T_Array:
1587                         retval = _copyArray(from);
1588                         break;
1589                 case T_ArrayRef:
1590                         retval = _copyArrayRef(from);
1591                         break;
1592                 case T_Aggref:
1593                         retval = _copyAggref(from);
1594                         break;
1595                 case T_SubLink:
1596                         retval = _copySubLink(from);
1597                         break;
1598                 case T_CaseExpr:
1599                         retval = _copyCaseExpr(from);
1600                         break;
1601                 case T_CaseWhen:
1602                         retval = _copyCaseWhen(from);
1603                         break;
1604
1605                         /*
1606                          * RELATION NODES
1607                          */
1608                 case T_RelOptInfo:
1609                         retval = _copyRelOptInfo(from);
1610                         break;
1611                 case T_Path:
1612                         retval = _copyPath(from);
1613                         break;
1614                 case T_IndexPath:
1615                         retval = _copyIndexPath(from);
1616                         break;
1617                 case T_TidPath:
1618                         retval = _copyTidPath(from);
1619                         break;
1620                 case T_NestPath:
1621                         retval = _copyNestPath(from);
1622                         break;
1623                 case T_MergePath:
1624                         retval = _copyMergePath(from);
1625                         break;
1626                 case T_HashPath:
1627                         retval = _copyHashPath(from);
1628                         break;
1629                 case T_PathKeyItem:
1630                         retval = _copyPathKeyItem(from);
1631                         break;
1632                 case T_RestrictInfo:
1633                         retval = _copyRestrictInfo(from);
1634                         break;
1635                 case T_JoinInfo:
1636                         retval = _copyJoinInfo(from);
1637                         break;
1638                 case T_Iter:
1639                         retval = _copyIter(from);
1640                         break;
1641                 case T_Stream:
1642                         retval = _copyStream(from);
1643                         break;
1644                 case T_IndexOptInfo:
1645                         retval = _copyIndexOptInfo(from);
1646                         break;
1647
1648                         /*
1649                          * PARSE NODES
1650                          */
1651                 case T_Query:
1652                         retval = _copyQuery(from);
1653                         break;
1654                 case T_TargetEntry:
1655                         retval = _copyTargetEntry(from);
1656                         break;
1657                 case T_RangeTblEntry:
1658                         retval = _copyRangeTblEntry(from);
1659                         break;
1660                 case T_RowMark:
1661                         retval = _copyRowMark(from);
1662                         break;
1663                 case T_SortClause:
1664                         retval = _copySortClause(from);
1665                         break;
1666                 case T_A_Const:
1667                         retval = _copyAConst(from);
1668                         break;
1669                 case T_TypeName:
1670                         retval = _copyTypeName(from);
1671                         break;
1672                 case T_TypeCast:
1673                         retval = _copyTypeCast(from);
1674                         break;
1675
1676                         /*
1677                          * VALUE NODES
1678                          */
1679                 case T_Integer:
1680                 case T_String:
1681                 case T_Float:
1682                         retval = _copyValue(from);
1683                         break;
1684                 case T_List:
1685                         {
1686                                 List       *list = from,
1687                                                    *l,
1688                                                    *nl;
1689
1690                                 /* rather ugly coding for speed... */
1691                                 /* Note the input list cannot be NIL if we got here. */
1692                                 nl = lcons(copyObject(lfirst(list)), NIL);
1693                                 retval = nl;
1694
1695                                 foreach(l, lnext(list))
1696                                 {
1697                                         lnext(nl) = lcons(copyObject(lfirst(l)), NIL);
1698                                         nl = lnext(nl);
1699                                 }
1700                         }
1701                         break;
1702                 default:
1703                         elog(ERROR, "copyObject: don't know how to copy %d", nodeTag(from));
1704                         retval = from;
1705                         break;
1706         }
1707         return retval;
1708 }