OSDN Git Service

Redesign DISTINCT ON as discussed in pgsql-sql 1/25/00: syntax is now
[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.103 2000/01/27 18:11:27 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->cost = from->cost;
79         newnode->plan_rows = from->plan_rows;
80         newnode->plan_width = from->plan_width;
81         /* state is NOT copied */
82         newnode->targetlist = copyObject(from->targetlist);
83         newnode->qual = copyObject(from->qual);
84         newnode->lefttree = copyObject(from->lefttree);
85         newnode->righttree = copyObject(from->righttree);
86         newnode->extParam = listCopy(from->extParam);
87         newnode->locParam = listCopy(from->locParam);
88         newnode->chgParam = listCopy(from->chgParam);
89         Node_Copy(from, newnode, initPlan);
90         if (from->subPlan != NIL)
91                 newnode->subPlan = nconc(SS_pull_subplan((Node *) newnode->targetlist),
92                                                                  SS_pull_subplan((Node *) newnode->qual));
93         else
94                 newnode->subPlan = NIL;
95         newnode->nParamExec = from->nParamExec;
96 }
97
98 /* ----------------
99  *              _copyPlan
100  * ----------------
101  */
102 static Plan *
103 _copyPlan(Plan *from)
104 {
105         Plan       *newnode = makeNode(Plan);
106
107         /* ----------------
108          *      copy the node superclass fields
109          * ----------------
110          */
111         CopyPlanFields(from, newnode);
112
113         return newnode;
114 }
115
116
117 /* ----------------
118  *              _copyResult
119  * ----------------
120  */
121 static Result *
122 _copyResult(Result *from)
123 {
124         Result     *newnode = makeNode(Result);
125
126         /* ----------------
127          *      copy node superclass fields
128          * ----------------
129          */
130         CopyPlanFields((Plan *) from, (Plan *) newnode);
131
132         /* ----------------
133          *      copy remainder of node
134          * ----------------
135          */
136         Node_Copy(from, newnode, resconstantqual);
137
138         /*
139          * We must add subplans in resconstantqual to the new plan's subPlan
140          * list
141          */
142         if (from->plan.subPlan != NIL)
143                 newnode->plan.subPlan = nconc(newnode->plan.subPlan,
144                                                                           SS_pull_subplan(newnode->resconstantqual));
145
146         return newnode;
147 }
148
149 /* ----------------
150  *              _copyAppend
151  * ----------------
152  */
153 static Append *
154 _copyAppend(Append *from)
155 {
156         Append     *newnode = makeNode(Append);
157
158         /* ----------------
159          *      copy node superclass fields
160          * ----------------
161          */
162         CopyPlanFields((Plan *) from, (Plan *) newnode);
163
164         /* ----------------
165          *      copy remainder of node
166          * ----------------
167          */
168         Node_Copy(from, newnode, appendplans);
169         Node_Copy(from, newnode, unionrtables);
170         newnode->inheritrelid = from->inheritrelid;
171         Node_Copy(from, newnode, inheritrtable);
172
173         return newnode;
174 }
175
176
177 /* ----------------
178  *              CopyScanFields
179  *
180  *              This function copies the fields of the Scan node.  It is used by
181  *              all the copy functions for classes which inherit from Scan.
182  * ----------------
183  */
184 static void
185 CopyScanFields(Scan *from, Scan *newnode)
186 {
187         newnode->scanrelid = from->scanrelid;
188         return;
189 }
190
191 /* ----------------
192  *              _copyScan
193  * ----------------
194  */
195 static Scan *
196 _copyScan(Scan *from)
197 {
198         Scan       *newnode = makeNode(Scan);
199
200         /* ----------------
201          *      copy node superclass fields
202          * ----------------
203          */
204         CopyPlanFields((Plan *) from, (Plan *) newnode);
205         CopyScanFields((Scan *) from, (Scan *) newnode);
206
207         return newnode;
208 }
209
210 /* ----------------
211  *              _copySeqScan
212  * ----------------
213  */
214 static SeqScan *
215 _copySeqScan(SeqScan *from)
216 {
217         SeqScan    *newnode = makeNode(SeqScan);
218
219         /* ----------------
220          *      copy node superclass fields
221          * ----------------
222          */
223         CopyPlanFields((Plan *) from, (Plan *) newnode);
224         CopyScanFields((Scan *) from, (Scan *) newnode);
225
226         return newnode;
227 }
228
229 /* ----------------
230  *              _copyIndexScan
231  * ----------------
232  */
233 static IndexScan *
234 _copyIndexScan(IndexScan *from)
235 {
236         IndexScan  *newnode = makeNode(IndexScan);
237
238         /* ----------------
239          *      copy node superclass fields
240          * ----------------
241          */
242         CopyPlanFields((Plan *) from, (Plan *) newnode);
243         CopyScanFields((Scan *) from, (Scan *) newnode);
244
245         /* ----------------
246          *      copy remainder of node
247          * ----------------
248          */
249         newnode->indxid = listCopy(from->indxid);
250         Node_Copy(from, newnode, indxqual);
251         Node_Copy(from, newnode, indxqualorig);
252         newnode->indxorderdir = from->indxorderdir;
253
254         return newnode;
255 }
256
257 /* ----------------
258  *              _copyTidScan
259  * ----------------
260  */
261 static TidScan *
262 _copyTidScan(TidScan *from)
263 {
264         TidScan *newnode = makeNode(TidScan);
265
266         /* ----------------
267          *      copy node superclass fields
268          * ----------------
269          */
270         CopyPlanFields((Plan *) from, (Plan *) newnode);
271         CopyScanFields((Scan *) from, (Scan *) newnode);
272         /* ----------------
273          *      copy remainder of node
274          * ----------------
275          */
276         newnode->needRescan = from->needRescan;
277         Node_Copy(from, newnode, tideval);
278
279         return newnode;
280 }
281
282     
283 /* ----------------
284  *              CopyJoinFields
285  *
286  *              This function copies the fields of the Join node.  It is used by
287  *              all the copy functions for classes which inherit from Join.
288  * ----------------
289  */
290 static void
291 CopyJoinFields(Join *from, Join *newnode)
292 {
293         /* nothing extra */
294         return;
295 }
296
297
298 /* ----------------
299  *              _copyJoin
300  * ----------------
301  */
302 static Join *
303 _copyJoin(Join *from)
304 {
305         Join       *newnode = makeNode(Join);
306
307         /* ----------------
308          *      copy node superclass fields
309          * ----------------
310          */
311         CopyPlanFields((Plan *) from, (Plan *) newnode);
312         CopyJoinFields(from, newnode);
313
314         return newnode;
315 }
316
317
318 /* ----------------
319  *              _copyNestLoop
320  * ----------------
321  */
322 static NestLoop *
323 _copyNestLoop(NestLoop *from)
324 {
325         NestLoop   *newnode = makeNode(NestLoop);
326
327         /* ----------------
328          *      copy node superclass fields
329          * ----------------
330          */
331         CopyPlanFields((Plan *) from, (Plan *) newnode);
332         CopyJoinFields((Join *) from, (Join *) newnode);
333
334         return newnode;
335 }
336
337
338 /* ----------------
339  *              _copyMergeJoin
340  * ----------------
341  */
342 static MergeJoin *
343 _copyMergeJoin(MergeJoin *from)
344 {
345         MergeJoin  *newnode = makeNode(MergeJoin);
346
347         /* ----------------
348          *      copy node superclass fields
349          * ----------------
350          */
351         CopyPlanFields((Plan *) from, (Plan *) newnode);
352         CopyJoinFields((Join *) from, (Join *) newnode);
353
354         /* ----------------
355          *      copy remainder of node
356          * ----------------
357          */
358         Node_Copy(from, newnode, mergeclauses);
359
360         return newnode;
361 }
362
363 /* ----------------
364  *              _copyHashJoin
365  * ----------------
366  */
367 static HashJoin *
368 _copyHashJoin(HashJoin *from)
369 {
370         HashJoin   *newnode = makeNode(HashJoin);
371
372         /* ----------------
373          *      copy node superclass fields
374          * ----------------
375          */
376         CopyPlanFields((Plan *) from, (Plan *) newnode);
377         CopyJoinFields((Join *) from, (Join *) newnode);
378
379         /* ----------------
380          *      copy remainder of node
381          * ----------------
382          */
383         Node_Copy(from, newnode, hashclauses);
384
385         newnode->hashjoinop = from->hashjoinop;
386
387         return newnode;
388 }
389
390
391 /* ----------------
392  *              CopyNonameFields
393  *
394  *              This function copies the fields of the Noname node.  It is used by
395  *              all the copy functions for classes which inherit from Noname.
396  * ----------------
397  */
398 static void
399 CopyNonameFields(Noname *from, Noname *newnode)
400 {
401         newnode->nonameid = from->nonameid;
402         newnode->keycount = from->keycount;
403         return;
404 }
405
406
407 /* ----------------
408  *              _copyNoname
409  * ----------------
410  */
411 static Noname *
412 _copyNoname(Noname *from)
413 {
414         Noname     *newnode = makeNode(Noname);
415
416         /* ----------------
417          *      copy node superclass fields
418          * ----------------
419          */
420         CopyPlanFields((Plan *) from, (Plan *) newnode);
421         CopyNonameFields(from, newnode);
422
423         return newnode;
424 }
425
426 /* ----------------
427  *              _copyMaterial
428  * ----------------
429  */
430 static Material *
431 _copyMaterial(Material *from)
432 {
433         Material   *newnode = makeNode(Material);
434
435         /* ----------------
436          *      copy node superclass fields
437          * ----------------
438          */
439         CopyPlanFields((Plan *) from, (Plan *) newnode);
440         CopyNonameFields((Noname *) from, (Noname *) newnode);
441
442         return newnode;
443 }
444
445
446 /* ----------------
447  *              _copySort
448  * ----------------
449  */
450 static Sort *
451 _copySort(Sort *from)
452 {
453         Sort       *newnode = makeNode(Sort);
454
455         /* ----------------
456          *      copy node superclass fields
457          * ----------------
458          */
459         CopyPlanFields((Plan *) from, (Plan *) newnode);
460         CopyNonameFields((Noname *) from, (Noname *) newnode);
461
462         return newnode;
463 }
464
465
466 /* ----------------
467  *              _copyGroup
468  * ----------------
469  */
470 static Group *
471 _copyGroup(Group *from)
472 {
473         Group      *newnode = makeNode(Group);
474
475         CopyPlanFields((Plan *) from, (Plan *) newnode);
476
477         newnode->tuplePerGroup = from->tuplePerGroup;
478         newnode->numCols = from->numCols;
479         newnode->grpColIdx = palloc(from->numCols * sizeof(AttrNumber));
480         memcpy(newnode->grpColIdx, from->grpColIdx, from->numCols * sizeof(AttrNumber));
481
482         return newnode;
483 }
484
485 /* ---------------
486  *      _copyAgg
487  * --------------
488  */
489 static Agg *
490 _copyAgg(Agg *from)
491 {
492         Agg                *newnode = makeNode(Agg);
493
494         CopyPlanFields((Plan *) from, (Plan *) newnode);
495
496         return newnode;
497 }
498
499 /* ---------------
500  *      _copyGroupClause
501  * --------------
502  */
503 static GroupClause *
504 _copyGroupClause(GroupClause *from)
505 {
506         GroupClause *newnode = makeNode(GroupClause);
507
508         newnode->tleSortGroupRef = from->tleSortGroupRef;
509         newnode->sortop = from->sortop;
510
511         return newnode;
512 }
513
514
515 /* ----------------
516  *              _copyUnique
517  * ----------------
518  */
519 static Unique *
520 _copyUnique(Unique *from)
521 {
522         Unique     *newnode = makeNode(Unique);
523
524         /* ----------------
525          *      copy node superclass fields
526          * ----------------
527          */
528         CopyPlanFields((Plan *) from, (Plan *) newnode);
529         CopyNonameFields((Noname *) from, (Noname *) newnode);
530
531         /* ----------------
532          *      copy remainder of node
533          * ----------------
534          */
535         newnode->numCols = from->numCols;
536         newnode->uniqColIdx = palloc(from->numCols * sizeof(AttrNumber));
537         memcpy(newnode->uniqColIdx, from->uniqColIdx, from->numCols * sizeof(AttrNumber));
538
539         return newnode;
540 }
541
542
543 /* ----------------
544  *              _copyHash
545  * ----------------
546  */
547 static Hash *
548 _copyHash(Hash *from)
549 {
550         Hash       *newnode = makeNode(Hash);
551
552         /* ----------------
553          *      copy node superclass fields
554          * ----------------
555          */
556         CopyPlanFields((Plan *) from, (Plan *) newnode);
557
558         /* ----------------
559          *      copy remainder of node
560          * ----------------
561          */
562         Node_Copy(from, newnode, hashkey);
563
564         return newnode;
565 }
566
567 static SubPlan *
568 _copySubPlan(SubPlan *from)
569 {
570         SubPlan    *newnode = makeNode(SubPlan);
571
572         Node_Copy(from, newnode, plan);
573         newnode->plan_id = from->plan_id;
574         Node_Copy(from, newnode, rtable);
575         newnode->setParam = listCopy(from->setParam);
576         newnode->parParam = listCopy(from->parParam);
577         Node_Copy(from, newnode, sublink);
578
579         /* do not copy execution state */
580         newnode->shutdown = false;
581         newnode->curTuple = NULL;
582
583         return newnode;
584 }
585
586 /* ****************************************************************
587  *                                         primnodes.h copy functions
588  * ****************************************************************
589  */
590
591 /* ----------------
592  *              _copyResdom
593  * ----------------
594  */
595 static Resdom *
596 _copyResdom(Resdom *from)
597 {
598         Resdom     *newnode = makeNode(Resdom);
599
600         newnode->resno = from->resno;
601         newnode->restype = from->restype;
602         newnode->restypmod = from->restypmod;
603         if (from->resname != NULL)
604                 newnode->resname = pstrdup(from->resname);
605         newnode->ressortgroupref = from->ressortgroupref;
606         newnode->reskey = from->reskey;
607         newnode->reskeyop = from->reskeyop;
608         newnode->resjunk = from->resjunk;
609
610         return newnode;
611 }
612
613 static Fjoin *
614 _copyFjoin(Fjoin *from)
615 {
616         Fjoin      *newnode = makeNode(Fjoin);
617
618         /* ----------------
619          *      copy node superclass fields
620          * ----------------
621          */
622
623         newnode->fj_initialized = from->fj_initialized;
624         newnode->fj_nNodes = from->fj_nNodes;
625
626         Node_Copy(from, newnode, fj_innerNode);
627
628         newnode->fj_results = (DatumPtr)
629                 palloc((from->fj_nNodes) * sizeof(Datum));
630         memmove(from->fj_results,
631                         newnode->fj_results,
632                         (from->fj_nNodes) * sizeof(Datum));
633
634         newnode->fj_alwaysDone = (BoolPtr)
635                 palloc((from->fj_nNodes) * sizeof(bool));
636         memmove(from->fj_alwaysDone,
637                         newnode->fj_alwaysDone,
638                         (from->fj_nNodes) * sizeof(bool));
639
640
641         return newnode;
642 }
643
644 /* ----------------
645  *              _copyExpr
646  * ----------------
647  */
648 static Expr *
649 _copyExpr(Expr *from)
650 {
651         Expr       *newnode = makeNode(Expr);
652
653         /* ----------------
654          *      copy node superclass fields
655          * ----------------
656          */
657         newnode->typeOid = from->typeOid;
658         newnode->opType = from->opType;
659
660         Node_Copy(from, newnode, oper);
661         Node_Copy(from, newnode, args);
662
663         return newnode;
664 }
665
666 /* ----------------
667  *              _copyVar
668  * ----------------
669  */
670 static Var *
671 _copyVar(Var *from)
672 {
673         Var                *newnode = makeNode(Var);
674
675         /* ----------------
676          *      copy remainder of node
677          * ----------------
678          */
679         newnode->varno = from->varno;
680         newnode->varattno = from->varattno;
681         newnode->vartype = from->vartype;
682         newnode->vartypmod = from->vartypmod;
683         newnode->varlevelsup = from->varlevelsup;
684
685         newnode->varnoold = from->varnoold;
686         newnode->varoattno = from->varoattno;
687
688         return newnode;
689 }
690
691 /* ----------------
692  *              _copyOper
693  * ----------------
694  */
695 static Oper *
696 _copyOper(Oper *from)
697 {
698         Oper       *newnode = makeNode(Oper);
699
700         /* ----------------
701          *      copy remainder of node
702          * ----------------
703          */
704         newnode->opno = from->opno;
705         newnode->opid = from->opid;
706         newnode->opresulttype = from->opresulttype;
707         newnode->opsize = from->opsize;
708
709         /*
710          * NOTE: shall we copy the cache structure or just the pointer ?
711          * Alternatively we can set 'op_fcache' to NULL, in which case the
712          * executor will initialize it when it needs it...
713          */
714         newnode->op_fcache = from->op_fcache;
715
716         return newnode;
717 }
718
719 /* ----------------
720  *              _copyConst
721  * ----------------
722  */
723 static Const *
724 _copyConst(Const *from)
725 {
726         Const      *newnode = makeNode(Const);
727
728         /* ----------------
729          *      copy remainder of node
730          * ----------------
731          */
732         newnode->consttype = from->consttype;
733         newnode->constlen = from->constlen;
734
735         if (from->constbyval || from->constisnull)
736         {
737                 /* ----------------
738                  *      passed by value so just copy the datum.
739                  *      Also, don't try to copy struct when value is null!
740                  * ----------------
741                  */
742                 newnode->constvalue = from->constvalue;
743         }
744         else
745         {
746                 /* ----------------
747                  *      not passed by value. datum contains a pointer.
748                  * ----------------
749                  */
750                 int                     length = from->constlen;
751
752                 if (length == -1)               /* variable-length type? */
753                         length = VARSIZE(from->constvalue);
754                 newnode->constvalue = PointerGetDatum(palloc(length));
755                 memcpy(DatumGetPointer(newnode->constvalue),
756                            DatumGetPointer(from->constvalue),
757                            length);
758         }
759
760         newnode->constisnull = from->constisnull;
761         newnode->constbyval = from->constbyval;
762         newnode->constisset = from->constisset;
763         newnode->constiscast = from->constiscast;
764
765         return newnode;
766 }
767
768 /* ----------------
769  *              _copyParam
770  * ----------------
771  */
772 static Param *
773 _copyParam(Param *from)
774 {
775         Param      *newnode = makeNode(Param);
776
777         /* ----------------
778          *      copy remainder of node
779          * ----------------
780          */
781         newnode->paramkind = from->paramkind;
782         newnode->paramid = from->paramid;
783
784         if (from->paramname != NULL)
785                 newnode->paramname = pstrdup(from->paramname);
786         newnode->paramtype = from->paramtype;
787         Node_Copy(from, newnode, param_tlist);
788
789         return newnode;
790 }
791
792 /* ----------------
793  *              _copyFunc
794  * ----------------
795  */
796 static Func *
797 _copyFunc(Func *from)
798 {
799         Func       *newnode = makeNode(Func);
800
801         /* ----------------
802          *      copy remainder of node
803          * ----------------
804          */
805         newnode->funcid = from->funcid;
806         newnode->functype = from->functype;
807         newnode->funcisindex = from->funcisindex;
808         newnode->funcsize = from->funcsize;
809         newnode->func_fcache = from->func_fcache;
810         Node_Copy(from, newnode, func_tlist);
811         Node_Copy(from, newnode, func_planlist);
812
813         return newnode;
814 }
815
816 /* ----------------
817  *              _copyAggref
818  * ----------------
819  */
820 static Aggref *
821 _copyAggref(Aggref *from)
822 {
823         Aggref     *newnode = makeNode(Aggref);
824
825         /* ----------------
826          *      copy remainder of node
827          * ----------------
828          */
829         newnode->aggname = pstrdup(from->aggname);
830         newnode->basetype = from->basetype;
831         newnode->aggtype = from->aggtype;
832         Node_Copy(from, newnode, target);
833         newnode->usenulls = from->usenulls;
834         newnode->aggstar = from->aggstar;
835         newnode->aggdistinct = from->aggdistinct;
836         newnode->aggno = from->aggno; /* probably not needed */
837
838         return newnode;
839 }
840
841 /* ----------------
842  *              _copySubLink
843  * ----------------
844  */
845 static SubLink *
846 _copySubLink(SubLink *from)
847 {
848         SubLink    *newnode = makeNode(SubLink);
849
850         /* ----------------
851          *      copy remainder of node
852          * ----------------
853          */
854         newnode->subLinkType = from->subLinkType;
855         newnode->useor = from->useor;
856         Node_Copy(from, newnode, lefthand);
857         Node_Copy(from, newnode, oper);
858         Node_Copy(from, newnode, subselect);
859
860         return newnode;
861 }
862
863 /* ----------------
864  *              _copyCaseExpr
865  * ----------------
866  */
867 static CaseExpr *
868 _copyCaseExpr(CaseExpr *from)
869 {
870         CaseExpr   *newnode = makeNode(CaseExpr);
871
872         /* ----------------
873          *      copy remainder of node
874          * ----------------
875          */
876         newnode->casetype = from->casetype;
877
878         Node_Copy(from, newnode, arg);
879         Node_Copy(from, newnode, args);
880         Node_Copy(from, newnode, defresult);
881
882         return newnode;
883 }
884
885 /* ----------------
886  *              _copyCaseWhen
887  * ----------------
888  */
889 static CaseWhen *
890 _copyCaseWhen(CaseWhen *from)
891 {
892         CaseWhen   *newnode = makeNode(CaseWhen);
893
894         /* ----------------
895          *      copy remainder of node
896          * ----------------
897          */
898         Node_Copy(from, newnode, expr);
899         Node_Copy(from, newnode, result);
900
901         return newnode;
902 }
903
904 static Array *
905 _copyArray(Array *from)
906 {
907         Array      *newnode = makeNode(Array);
908
909         /* ----------------
910          *      copy remainder of node
911          * ----------------
912          */
913         newnode->arrayelemtype = from->arrayelemtype;
914         newnode->arrayelemlength = from->arrayelemlength;
915         newnode->arrayelembyval = from->arrayelembyval;
916         newnode->arrayndim = from->arrayndim;
917         newnode->arraylow = from->arraylow;
918         newnode->arrayhigh = from->arrayhigh;
919         newnode->arraylen = from->arraylen;
920
921         return newnode;
922 }
923
924 static ArrayRef *
925 _copyArrayRef(ArrayRef *from)
926 {
927         ArrayRef   *newnode = makeNode(ArrayRef);
928
929         /* ----------------
930          *      copy remainder of node
931          * ----------------
932          */
933         newnode->refattrlength = from->refattrlength;
934         newnode->refelemlength = from->refelemlength;
935         newnode->refelemtype = from->refelemtype;
936         newnode->refelembyval = from->refelembyval;
937
938         Node_Copy(from, newnode, refupperindexpr);
939         Node_Copy(from, newnode, reflowerindexpr);
940         Node_Copy(from, newnode, refexpr);
941         Node_Copy(from, newnode, refassgnexpr);
942
943         return newnode;
944 }
945
946 /* ****************************************************************
947  *                                              relation.h copy functions
948  * ****************************************************************
949  */
950
951 /* ----------------
952  *              _copyRelOptInfo
953  * ----------------
954  */
955 /*
956  *      when you change this, also make sure to fix up xfunc_copyRelOptInfo in
957  *      planner/path/xfunc.c accordingly!!!
958  *              -- JMH, 8/2/93
959  */
960 static RelOptInfo *
961 _copyRelOptInfo(RelOptInfo *from)
962 {
963         RelOptInfo *newnode = makeNode(RelOptInfo);
964
965         newnode->relids = listCopy(from->relids);
966
967         newnode->rows = from->rows;
968         newnode->width = from->width;
969
970         Node_Copy(from, newnode, targetlist);
971         Node_Copy(from, newnode, pathlist);
972         /* XXX cheapestpath should point to a member of pathlist? */
973         Node_Copy(from, newnode, cheapestpath);
974         newnode->pruneable = from->pruneable;
975
976         newnode->indexed = from->indexed;
977         newnode->pages = from->pages;
978         newnode->tuples = from->tuples;
979
980         Node_Copy(from, newnode, restrictinfo);
981         Node_Copy(from, newnode, joininfo);
982         Node_Copy(from, newnode, innerjoin);
983
984         return newnode;
985 }
986
987 /* ----------------
988  *              _copyIndexOptInfo
989  * ----------------
990  */
991 static IndexOptInfo *
992 _copyIndexOptInfo(IndexOptInfo *from)
993 {
994         IndexOptInfo *newnode = makeNode(IndexOptInfo);
995         int                     i,
996                                 len;
997
998         newnode->indexoid = from->indexoid;
999         newnode->pages = from->pages;
1000         newnode->tuples = from->tuples;
1001
1002         if (from->classlist)
1003         {
1004                 for (len = 0; from->classlist[len] != 0; len++)
1005                         ;
1006                 newnode->classlist = (Oid *) palloc(sizeof(Oid) * (len + 1));
1007                 for (i = 0; i < len; i++)
1008                         newnode->classlist[i] = from->classlist[i];
1009                 newnode->classlist[len] = 0;
1010         }
1011
1012         if (from->indexkeys)
1013         {
1014                 for (len = 0; from->indexkeys[len] != 0; len++)
1015                         ;
1016                 newnode->indexkeys = (int *) palloc(sizeof(int) * (len + 1));
1017                 for (i = 0; i < len; i++)
1018                         newnode->indexkeys[i] = from->indexkeys[i];
1019                 newnode->indexkeys[len] = 0;
1020         }
1021
1022         if (from->ordering)
1023         {
1024                 for (len = 0; from->ordering[len] != 0; len++)
1025                         ;
1026                 newnode->ordering = (Oid *) palloc(sizeof(Oid) * (len + 1));
1027                 for (i = 0; i < len; i++)
1028                         newnode->ordering[i] = from->ordering[i];
1029                 newnode->ordering[len] = 0;
1030         }
1031
1032         newnode->relam = from->relam;
1033         newnode->amcostestimate = from->amcostestimate;
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         Node_Copy(from, newnode, distinctClause);
1429         Node_Copy(from, newnode, sortClause);
1430         Node_Copy(from, newnode, groupClause);
1431         Node_Copy(from, newnode, havingQual);
1432
1433         /* why is intersectClause missing? */
1434         Node_Copy(from, newnode, unionClause);
1435
1436         Node_Copy(from, newnode, limitOffset);
1437         Node_Copy(from, newnode, limitCount);
1438
1439         /* we do not copy the planner internal fields: base_rel_list,
1440          * join_rel_list, query_pathkeys.  Not entirely clear if this is right?
1441          */
1442
1443         return newnode;
1444 }
1445
1446
1447 /*
1448  *      mnodes.h routines have no copy functions
1449  */
1450
1451 /* ****************************************************************
1452  *                                      pg_list.h copy functions
1453  * ****************************************************************
1454  */
1455
1456 static Value *
1457 _copyValue(Value *from)
1458 {
1459         Value      *newnode = makeNode(Value);
1460
1461         newnode->type = from->type;
1462         switch (from->type)
1463         {
1464                 case T_String:
1465                         newnode->val.str = pstrdup(from->val.str);
1466                         break;
1467                 case T_Integer:
1468                         newnode->val.ival = from->val.ival;
1469                         break;
1470                 case T_Float:
1471                         newnode->val.dval = from->val.dval;
1472                         break;
1473                 default:
1474                         break;
1475         }
1476         return newnode;
1477 }
1478
1479 /* ----------------
1480  *              copyObject returns a copy of the node or list. If it is a list, it
1481  *              recursively copies its items.
1482  * ----------------
1483  */
1484 void *
1485 copyObject(void *from)
1486 {
1487         void       *retval;
1488
1489         if (from == NULL)
1490                 return NULL;
1491         switch (nodeTag(from))
1492         {
1493
1494                         /*
1495                          * PLAN NODES
1496                          */
1497                 case T_Plan:
1498                         retval = _copyPlan(from);
1499                         break;
1500                 case T_Result:
1501                         retval = _copyResult(from);
1502                         break;
1503                 case T_Append:
1504                         retval = _copyAppend(from);
1505                         break;
1506                 case T_Scan:
1507                         retval = _copyScan(from);
1508                         break;
1509                 case T_SeqScan:
1510                         retval = _copySeqScan(from);
1511                         break;
1512                 case T_IndexScan:
1513                         retval = _copyIndexScan(from);
1514                         break;
1515                 case T_TidScan:
1516                         retval = _copyTidScan(from);
1517                         break;
1518                 case T_Join:
1519                         retval = _copyJoin(from);
1520                         break;
1521                 case T_NestLoop:
1522                         retval = _copyNestLoop(from);
1523                         break;
1524                 case T_MergeJoin:
1525                         retval = _copyMergeJoin(from);
1526                         break;
1527                 case T_HashJoin:
1528                         retval = _copyHashJoin(from);
1529                         break;
1530                 case T_Noname:
1531                         retval = _copyNoname(from);
1532                         break;
1533                 case T_Material:
1534                         retval = _copyMaterial(from);
1535                         break;
1536                 case T_Sort:
1537                         retval = _copySort(from);
1538                         break;
1539                 case T_Group:
1540                         retval = _copyGroup(from);
1541                         break;
1542                 case T_Agg:
1543                         retval = _copyAgg(from);
1544                         break;
1545                 case T_GroupClause:
1546                         retval = _copyGroupClause(from);
1547                         break;
1548                 case T_Unique:
1549                         retval = _copyUnique(from);
1550                         break;
1551                 case T_Hash:
1552                         retval = _copyHash(from);
1553                         break;
1554                 case T_SubPlan:
1555                         retval = _copySubPlan(from);
1556                         break;
1557
1558                         /*
1559                          * PRIMITIVE NODES
1560                          */
1561                 case T_Resdom:
1562                         retval = _copyResdom(from);
1563                         break;
1564                 case T_Fjoin:
1565                         retval = _copyFjoin(from);
1566                         break;
1567                 case T_Expr:
1568                         retval = _copyExpr(from);
1569                         break;
1570                 case T_Var:
1571                         retval = _copyVar(from);
1572                         break;
1573                 case T_Oper:
1574                         retval = _copyOper(from);
1575                         break;
1576                 case T_Const:
1577                         retval = _copyConst(from);
1578                         break;
1579                 case T_Param:
1580                         retval = _copyParam(from);
1581                         break;
1582                 case T_Func:
1583                         retval = _copyFunc(from);
1584                         break;
1585                 case T_Array:
1586                         retval = _copyArray(from);
1587                         break;
1588                 case T_ArrayRef:
1589                         retval = _copyArrayRef(from);
1590                         break;
1591                 case T_Aggref:
1592                         retval = _copyAggref(from);
1593                         break;
1594                 case T_SubLink:
1595                         retval = _copySubLink(from);
1596                         break;
1597                 case T_CaseExpr:
1598                         retval = _copyCaseExpr(from);
1599                         break;
1600                 case T_CaseWhen:
1601                         retval = _copyCaseWhen(from);
1602                         break;
1603
1604                         /*
1605                          * RELATION NODES
1606                          */
1607                 case T_RelOptInfo:
1608                         retval = _copyRelOptInfo(from);
1609                         break;
1610                 case T_Path:
1611                         retval = _copyPath(from);
1612                         break;
1613                 case T_IndexPath:
1614                         retval = _copyIndexPath(from);
1615                         break;
1616                 case T_TidPath:
1617                         retval = _copyTidPath(from);
1618                         break;
1619                 case T_NestPath:
1620                         retval = _copyNestPath(from);
1621                         break;
1622                 case T_MergePath:
1623                         retval = _copyMergePath(from);
1624                         break;
1625                 case T_HashPath:
1626                         retval = _copyHashPath(from);
1627                         break;
1628                 case T_PathKeyItem:
1629                         retval = _copyPathKeyItem(from);
1630                         break;
1631                 case T_RestrictInfo:
1632                         retval = _copyRestrictInfo(from);
1633                         break;
1634                 case T_JoinInfo:
1635                         retval = _copyJoinInfo(from);
1636                         break;
1637                 case T_Iter:
1638                         retval = _copyIter(from);
1639                         break;
1640                 case T_Stream:
1641                         retval = _copyStream(from);
1642                         break;
1643                 case T_IndexOptInfo:
1644                         retval = _copyIndexOptInfo(from);
1645                         break;
1646
1647                         /*
1648                          * PARSE NODES
1649                          */
1650                 case T_Query:
1651                         retval = _copyQuery(from);
1652                         break;
1653                 case T_TargetEntry:
1654                         retval = _copyTargetEntry(from);
1655                         break;
1656                 case T_RangeTblEntry:
1657                         retval = _copyRangeTblEntry(from);
1658                         break;
1659                 case T_RowMark:
1660                         retval = _copyRowMark(from);
1661                         break;
1662                 case T_SortClause:
1663                         retval = _copySortClause(from);
1664                         break;
1665                 case T_A_Const:
1666                         retval = _copyAConst(from);
1667                         break;
1668                 case T_TypeName:
1669                         retval = _copyTypeName(from);
1670                         break;
1671                 case T_TypeCast:
1672                         retval = _copyTypeCast(from);
1673                         break;
1674
1675                         /*
1676                          * VALUE NODES
1677                          */
1678                 case T_Integer:
1679                 case T_String:
1680                 case T_Float:
1681                         retval = _copyValue(from);
1682                         break;
1683                 case T_List:
1684                         {
1685                                 List       *list = from,
1686                                                    *l,
1687                                                    *nl;
1688
1689                                 /* rather ugly coding for speed... */
1690                                 /* Note the input list cannot be NIL if we got here. */
1691                                 nl = lcons(copyObject(lfirst(list)), NIL);
1692                                 retval = nl;
1693
1694                                 foreach(l, lnext(list))
1695                                 {
1696                                         lnext(nl) = lcons(copyObject(lfirst(l)), NIL);
1697                                         nl = lnext(nl);
1698                                 }
1699                         }
1700                         break;
1701                 default:
1702                         elog(ERROR, "copyObject: don't know how to copy %d", nodeTag(from));
1703                         retval = from;
1704                         break;
1705         }
1706         return retval;
1707 }