]> granicus.if.org Git - postgresql/blob - src/backend/nodes/copyfuncs.c
Implement subselects in target lists. Also, relax requirement that
[postgresql] / 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.95 1999/11/15 02:00:01 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_size = from->plan_size;
79         newnode->plan_width = from->plan_width;
80         newnode->plan_tupperpage = from->plan_tupperpage;
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  *              CopyJoinFields
258  *
259  *              This function copies the fields of the Join node.  It is used by
260  *              all the copy functions for classes which inherit from Join.
261  * ----------------
262  */
263 static void
264 CopyJoinFields(Join *from, Join *newnode)
265 {
266         /* nothing extra */
267         return;
268 }
269
270
271 /* ----------------
272  *              _copyJoin
273  * ----------------
274  */
275 static Join *
276 _copyJoin(Join *from)
277 {
278         Join       *newnode = makeNode(Join);
279
280         /* ----------------
281          *      copy node superclass fields
282          * ----------------
283          */
284         CopyPlanFields((Plan *) from, (Plan *) newnode);
285         CopyJoinFields(from, newnode);
286
287         return newnode;
288 }
289
290
291 /* ----------------
292  *              _copyNestLoop
293  * ----------------
294  */
295 static NestLoop *
296 _copyNestLoop(NestLoop *from)
297 {
298         NestLoop   *newnode = makeNode(NestLoop);
299
300         /* ----------------
301          *      copy node superclass fields
302          * ----------------
303          */
304         CopyPlanFields((Plan *) from, (Plan *) newnode);
305         CopyJoinFields((Join *) from, (Join *) newnode);
306
307         return newnode;
308 }
309
310
311 /* ----------------
312  *              _copyMergeJoin
313  * ----------------
314  */
315 static MergeJoin *
316 _copyMergeJoin(MergeJoin *from)
317 {
318         MergeJoin  *newnode = makeNode(MergeJoin);
319
320         /* ----------------
321          *      copy node superclass fields
322          * ----------------
323          */
324         CopyPlanFields((Plan *) from, (Plan *) newnode);
325         CopyJoinFields((Join *) from, (Join *) newnode);
326
327         /* ----------------
328          *      copy remainder of node
329          * ----------------
330          */
331         Node_Copy(from, newnode, mergeclauses);
332
333         return newnode;
334 }
335
336 /* ----------------
337  *              _copyHashJoin
338  * ----------------
339  */
340 static HashJoin *
341 _copyHashJoin(HashJoin *from)
342 {
343         HashJoin   *newnode = makeNode(HashJoin);
344
345         /* ----------------
346          *      copy node superclass fields
347          * ----------------
348          */
349         CopyPlanFields((Plan *) from, (Plan *) newnode);
350         CopyJoinFields((Join *) from, (Join *) newnode);
351
352         /* ----------------
353          *      copy remainder of node
354          * ----------------
355          */
356         Node_Copy(from, newnode, hashclauses);
357
358         newnode->hashjoinop = from->hashjoinop;
359
360         return newnode;
361 }
362
363
364 /* ----------------
365  *              CopyNonameFields
366  *
367  *              This function copies the fields of the Noname node.  It is used by
368  *              all the copy functions for classes which inherit from Noname.
369  * ----------------
370  */
371 static void
372 CopyNonameFields(Noname *from, Noname *newnode)
373 {
374         newnode->nonameid = from->nonameid;
375         newnode->keycount = from->keycount;
376         return;
377 }
378
379
380 /* ----------------
381  *              _copyNoname
382  * ----------------
383  */
384 static Noname *
385 _copyNoname(Noname *from)
386 {
387         Noname     *newnode = makeNode(Noname);
388
389         /* ----------------
390          *      copy node superclass fields
391          * ----------------
392          */
393         CopyPlanFields((Plan *) from, (Plan *) newnode);
394         CopyNonameFields(from, newnode);
395
396         return newnode;
397 }
398
399 /* ----------------
400  *              _copyMaterial
401  * ----------------
402  */
403 static Material *
404 _copyMaterial(Material *from)
405 {
406         Material   *newnode = makeNode(Material);
407
408         /* ----------------
409          *      copy node superclass fields
410          * ----------------
411          */
412         CopyPlanFields((Plan *) from, (Plan *) newnode);
413         CopyNonameFields((Noname *) from, (Noname *) newnode);
414
415         return newnode;
416 }
417
418
419 /* ----------------
420  *              _copySort
421  * ----------------
422  */
423 static Sort *
424 _copySort(Sort *from)
425 {
426         Sort       *newnode = makeNode(Sort);
427
428         /* ----------------
429          *      copy node superclass fields
430          * ----------------
431          */
432         CopyPlanFields((Plan *) from, (Plan *) newnode);
433         CopyNonameFields((Noname *) from, (Noname *) newnode);
434
435         return newnode;
436 }
437
438
439 /* ----------------
440  *              _copyGroup
441  * ----------------
442  */
443 static Group *
444 _copyGroup(Group *from)
445 {
446         Group      *newnode = makeNode(Group);
447
448         CopyPlanFields((Plan *) from, (Plan *) newnode);
449
450         newnode->tuplePerGroup = from->tuplePerGroup;
451         newnode->numCols = from->numCols;
452         newnode->grpColIdx = palloc(from->numCols * sizeof(AttrNumber));
453         memcpy(newnode->grpColIdx, from->grpColIdx, from->numCols * sizeof(AttrNumber));
454
455         return newnode;
456 }
457
458 /* ---------------
459  *      _copyAgg
460  * --------------
461  */
462 static Agg *
463 _copyAgg(Agg *from)
464 {
465         Agg                *newnode = makeNode(Agg);
466
467         CopyPlanFields((Plan *) from, (Plan *) newnode);
468
469         return newnode;
470 }
471
472 /* ---------------
473  *      _copyGroupClause
474  * --------------
475  */
476 static GroupClause *
477 _copyGroupClause(GroupClause *from)
478 {
479         GroupClause *newnode = makeNode(GroupClause);
480
481         newnode->tleSortGroupRef = from->tleSortGroupRef;
482         newnode->sortop = from->sortop;
483
484         return newnode;
485 }
486
487
488 /* ----------------
489  *              _copyUnique
490  * ----------------
491  */
492 static Unique *
493 _copyUnique(Unique *from)
494 {
495         Unique     *newnode = makeNode(Unique);
496
497         /* ----------------
498          *      copy node superclass fields
499          * ----------------
500          */
501         CopyPlanFields((Plan *) from, (Plan *) newnode);
502         CopyNonameFields((Noname *) from, (Noname *) newnode);
503
504         /* ----------------
505          *      copy remainder of node
506          * ----------------
507          */
508         if (from->uniqueAttr)
509                 newnode->uniqueAttr = pstrdup(from->uniqueAttr);
510         else
511                 newnode->uniqueAttr = NULL;
512         newnode->uniqueAttrNum = from->uniqueAttrNum;
513
514         return newnode;
515 }
516
517
518 /* ----------------
519  *              _copyHash
520  * ----------------
521  */
522 static Hash *
523 _copyHash(Hash *from)
524 {
525         Hash       *newnode = makeNode(Hash);
526
527         /* ----------------
528          *      copy node superclass fields
529          * ----------------
530          */
531         CopyPlanFields((Plan *) from, (Plan *) newnode);
532
533         /* ----------------
534          *      copy remainder of node
535          * ----------------
536          */
537         Node_Copy(from, newnode, hashkey);
538
539         return newnode;
540 }
541
542 static SubPlan *
543 _copySubPlan(SubPlan *from)
544 {
545         SubPlan    *newnode = makeNode(SubPlan);
546
547         Node_Copy(from, newnode, plan);
548         newnode->plan_id = from->plan_id;
549         Node_Copy(from, newnode, rtable);
550         newnode->setParam = listCopy(from->setParam);
551         newnode->parParam = listCopy(from->parParam);
552         Node_Copy(from, newnode, sublink);
553
554         return newnode;
555 }
556
557 /* ****************************************************************
558  *                                         primnodes.h copy functions
559  * ****************************************************************
560  */
561
562 /* ----------------
563  *              _copyResdom
564  * ----------------
565  */
566 static Resdom *
567 _copyResdom(Resdom *from)
568 {
569         Resdom     *newnode = makeNode(Resdom);
570
571         newnode->resno = from->resno;
572         newnode->restype = from->restype;
573         newnode->restypmod = from->restypmod;
574         if (from->resname != NULL)
575                 newnode->resname = pstrdup(from->resname);
576         newnode->ressortgroupref = from->ressortgroupref;
577         newnode->reskey = from->reskey;
578         newnode->reskeyop = from->reskeyop;
579         newnode->resjunk = from->resjunk;
580
581         return newnode;
582 }
583
584 static Fjoin *
585 _copyFjoin(Fjoin *from)
586 {
587         Fjoin      *newnode = makeNode(Fjoin);
588
589         /* ----------------
590          *      copy node superclass fields
591          * ----------------
592          */
593
594         newnode->fj_initialized = from->fj_initialized;
595         newnode->fj_nNodes = from->fj_nNodes;
596
597         Node_Copy(from, newnode, fj_innerNode);
598
599         newnode->fj_results = (DatumPtr)
600                 palloc((from->fj_nNodes) * sizeof(Datum));
601         memmove(from->fj_results,
602                         newnode->fj_results,
603                         (from->fj_nNodes) * sizeof(Datum));
604
605         newnode->fj_alwaysDone = (BoolPtr)
606                 palloc((from->fj_nNodes) * sizeof(bool));
607         memmove(from->fj_alwaysDone,
608                         newnode->fj_alwaysDone,
609                         (from->fj_nNodes) * sizeof(bool));
610
611
612         return newnode;
613 }
614
615 /* ----------------
616  *              _copyExpr
617  * ----------------
618  */
619 static Expr *
620 _copyExpr(Expr *from)
621 {
622         Expr       *newnode = makeNode(Expr);
623
624         /* ----------------
625          *      copy node superclass fields
626          * ----------------
627          */
628         newnode->typeOid = from->typeOid;
629         newnode->opType = from->opType;
630
631         Node_Copy(from, newnode, oper);
632         Node_Copy(from, newnode, args);
633
634         return newnode;
635 }
636
637 /* ----------------
638  *              _copyVar
639  * ----------------
640  */
641 static Var *
642 _copyVar(Var *from)
643 {
644         Var                *newnode = makeNode(Var);
645
646         /* ----------------
647          *      copy remainder of node
648          * ----------------
649          */
650         newnode->varno = from->varno;
651         newnode->varattno = from->varattno;
652         newnode->vartype = from->vartype;
653         newnode->vartypmod = from->vartypmod;
654         newnode->varlevelsup = from->varlevelsup;
655
656         newnode->varnoold = from->varnoold;
657         newnode->varoattno = from->varoattno;
658
659         return newnode;
660 }
661
662 /* ----------------
663  *              _copyOper
664  * ----------------
665  */
666 static Oper *
667 _copyOper(Oper *from)
668 {
669         Oper       *newnode = makeNode(Oper);
670
671         /* ----------------
672          *      copy remainder of node
673          * ----------------
674          */
675         newnode->opno = from->opno;
676         newnode->opid = from->opid;
677         newnode->opresulttype = from->opresulttype;
678         newnode->opsize = from->opsize;
679
680         /*
681          * NOTE: shall we copy the cache structure or just the pointer ?
682          * Alternatively we can set 'op_fcache' to NULL, in which case the
683          * executor will initialize it when it needs it...
684          */
685         newnode->op_fcache = from->op_fcache;
686
687         return newnode;
688 }
689
690 /* ----------------
691  *              _copyConst
692  * ----------------
693  */
694 static Const *
695 _copyConst(Const *from)
696 {
697         Const      *newnode = makeNode(Const);
698
699         /* ----------------
700          *      copy remainder of node
701          * ----------------
702          */
703         newnode->consttype = from->consttype;
704         newnode->constlen = from->constlen;
705
706         if (from->constbyval || from->constisnull)
707         {
708                 /* ----------------
709                  *      passed by value so just copy the datum.
710                  *      Also, don't try to copy struct when value is null!
711                  * ----------------
712                  */
713                 newnode->constvalue = from->constvalue;
714         }
715         else
716         {
717                 /* ----------------
718                  *      not passed by value. datum contains a pointer.
719                  * ----------------
720                  */
721                 int                     length = from->constlen;
722
723                 if (length == -1)               /* variable-length type? */
724                         length = VARSIZE(from->constvalue);
725                 newnode->constvalue = PointerGetDatum(palloc(length));
726                 memcpy(DatumGetPointer(newnode->constvalue),
727                            DatumGetPointer(from->constvalue),
728                            length);
729         }
730
731         newnode->constisnull = from->constisnull;
732         newnode->constbyval = from->constbyval;
733         newnode->constisset = from->constisset;
734         newnode->constiscast = from->constiscast;
735
736         return newnode;
737 }
738
739 /* ----------------
740  *              _copyParam
741  * ----------------
742  */
743 static Param *
744 _copyParam(Param *from)
745 {
746         Param      *newnode = makeNode(Param);
747
748         /* ----------------
749          *      copy remainder of node
750          * ----------------
751          */
752         newnode->paramkind = from->paramkind;
753         newnode->paramid = from->paramid;
754
755         if (from->paramname != NULL)
756                 newnode->paramname = pstrdup(from->paramname);
757         newnode->paramtype = from->paramtype;
758         Node_Copy(from, newnode, param_tlist);
759
760         return newnode;
761 }
762
763 /* ----------------
764  *              _copyFunc
765  * ----------------
766  */
767 static Func *
768 _copyFunc(Func *from)
769 {
770         Func       *newnode = makeNode(Func);
771
772         /* ----------------
773          *      copy remainder of node
774          * ----------------
775          */
776         newnode->funcid = from->funcid;
777         newnode->functype = from->functype;
778         newnode->funcisindex = from->funcisindex;
779         newnode->funcsize = from->funcsize;
780         newnode->func_fcache = from->func_fcache;
781         Node_Copy(from, newnode, func_tlist);
782         Node_Copy(from, newnode, func_planlist);
783
784         return newnode;
785 }
786
787 /* ----------------
788  *              _copyAggref
789  * ----------------
790  */
791 static Aggref *
792 _copyAggref(Aggref *from)
793 {
794         Aggref     *newnode = makeNode(Aggref);
795
796         /* ----------------
797          *      copy remainder of node
798          * ----------------
799          */
800         newnode->aggname = pstrdup(from->aggname);
801         newnode->basetype = from->basetype;
802         newnode->aggtype = from->aggtype;
803         Node_Copy(from, newnode, target);
804         newnode->usenulls = from->usenulls;
805         newnode->aggno = from->aggno; /* probably not needed */
806
807         return newnode;
808 }
809
810 /* ----------------
811  *              _copySubLink
812  * ----------------
813  */
814 static SubLink *
815 _copySubLink(SubLink *from)
816 {
817         SubLink    *newnode = makeNode(SubLink);
818
819         /* ----------------
820          *      copy remainder of node
821          * ----------------
822          */
823         newnode->subLinkType = from->subLinkType;
824         newnode->useor = from->useor;
825         Node_Copy(from, newnode, lefthand);
826         Node_Copy(from, newnode, oper);
827         Node_Copy(from, newnode, subselect);
828
829         return newnode;
830 }
831
832 /* ----------------
833  *              _copyCaseExpr
834  * ----------------
835  */
836 static CaseExpr *
837 _copyCaseExpr(CaseExpr *from)
838 {
839         CaseExpr   *newnode = makeNode(CaseExpr);
840
841         /* ----------------
842          *      copy remainder of node
843          * ----------------
844          */
845         newnode->casetype = from->casetype;
846
847         Node_Copy(from, newnode, arg);
848         Node_Copy(from, newnode, args);
849         Node_Copy(from, newnode, defresult);
850
851         return newnode;
852 }
853
854 /* ----------------
855  *              _copyCaseWhen
856  * ----------------
857  */
858 static CaseWhen *
859 _copyCaseWhen(CaseWhen *from)
860 {
861         CaseWhen   *newnode = makeNode(CaseWhen);
862
863         /* ----------------
864          *      copy remainder of node
865          * ----------------
866          */
867         Node_Copy(from, newnode, expr);
868         Node_Copy(from, newnode, result);
869
870         return newnode;
871 }
872
873 static Array *
874 _copyArray(Array *from)
875 {
876         Array      *newnode = makeNode(Array);
877
878         /* ----------------
879          *      copy remainder of node
880          * ----------------
881          */
882         newnode->arrayelemtype = from->arrayelemtype;
883         newnode->arrayelemlength = from->arrayelemlength;
884         newnode->arrayelembyval = from->arrayelembyval;
885         newnode->arrayndim = from->arrayndim;
886         newnode->arraylow = from->arraylow;
887         newnode->arrayhigh = from->arrayhigh;
888         newnode->arraylen = from->arraylen;
889
890         return newnode;
891 }
892
893 static ArrayRef *
894 _copyArrayRef(ArrayRef *from)
895 {
896         ArrayRef   *newnode = makeNode(ArrayRef);
897
898         /* ----------------
899          *      copy remainder of node
900          * ----------------
901          */
902         newnode->refattrlength = from->refattrlength;
903         newnode->refelemlength = from->refelemlength;
904         newnode->refelemtype = from->refelemtype;
905         newnode->refelembyval = from->refelembyval;
906
907         Node_Copy(from, newnode, refupperindexpr);
908         Node_Copy(from, newnode, reflowerindexpr);
909         Node_Copy(from, newnode, refexpr);
910         Node_Copy(from, newnode, refassgnexpr);
911
912         return newnode;
913 }
914
915 /* ****************************************************************
916  *                                              relation.h copy functions
917  * ****************************************************************
918  */
919
920 /* ----------------
921  *              _copyRelOptInfo
922  * ----------------
923  */
924 /*
925  *      when you change this, also make sure to fix up xfunc_copyRelOptInfo in
926  *      planner/path/xfunc.c accordingly!!!
927  *              -- JMH, 8/2/93
928  */
929 static RelOptInfo *
930 _copyRelOptInfo(RelOptInfo *from)
931 {
932         RelOptInfo *newnode = makeNode(RelOptInfo);
933         int                     i,
934                                 len;
935
936         /* ----------------
937          *      copy remainder of node
938          * ----------------
939          */
940         newnode->relids = listCopy(from->relids);
941
942         newnode->indexed = from->indexed;
943         newnode->pages = from->pages;
944         newnode->tuples = from->tuples;
945         newnode->size = from->size;
946         newnode->width = from->width;
947         Node_Copy(from, newnode, targetlist);
948         Node_Copy(from, newnode, pathlist);
949         Node_Copy(from, newnode, cheapestpath);
950         newnode->pruneable = from->pruneable;
951
952         if (from->classlist)
953         {
954                 for (len = 0; from->classlist[len] != 0; len++)
955                         ;
956                 newnode->classlist = (Oid *) palloc(sizeof(Oid) * (len + 1));
957                 for (i = 0; i < len; i++)
958                         newnode->classlist[i] = from->classlist[i];
959                 newnode->classlist[len] = 0;
960         }
961
962         if (from->indexkeys)
963         {
964                 for (len = 0; from->indexkeys[len] != 0; len++)
965                         ;
966                 newnode->indexkeys = (int *) palloc(sizeof(int) * (len + 1));
967                 for (i = 0; i < len; i++)
968                         newnode->indexkeys[i] = from->indexkeys[i];
969                 newnode->indexkeys[len] = 0;
970         }
971
972         if (from->ordering)
973         {
974                 for (len = 0; from->ordering[len] != 0; len++)
975                         ;
976                 newnode->ordering = (Oid *) palloc(sizeof(Oid) * (len + 1));
977                 for (i = 0; i < len; i++)
978                         newnode->ordering[i] = from->ordering[i];
979                 newnode->ordering[len] = 0;
980         }
981
982         newnode->relam = from->relam;
983         newnode->indproc = from->indproc;
984         Node_Copy(from, newnode, indpred);
985
986         Node_Copy(from, newnode, restrictinfo);
987         Node_Copy(from, newnode, joininfo);
988         Node_Copy(from, newnode, innerjoin);
989
990         return newnode;
991 }
992
993 /* ----------------
994  *              CopyPathFields
995  *
996  *              This function copies the fields of the Path node.  It is used by
997  *              all the copy functions for classes which inherit from Path.
998  * ----------------
999  */
1000 static void
1001 CopyPathFields(Path *from, Path *newnode)
1002 {
1003         /*
1004          * Modify the next line, since it causes the copying to cycle (i.e.
1005          * the parent points right back here! -- JMH, 7/7/92. Old version:
1006          * Node_Copy(from, newnode, parent);
1007          */
1008         newnode->parent = from->parent;
1009
1010         newnode->path_cost = from->path_cost;
1011
1012         newnode->pathtype = from->pathtype;
1013
1014         Node_Copy(from, newnode, pathkeys);
1015 }
1016
1017 /* ----------------
1018  *              _copyPath
1019  * ----------------
1020  */
1021 static Path *
1022 _copyPath(Path *from)
1023 {
1024         Path       *newnode = makeNode(Path);
1025
1026         CopyPathFields(from, newnode);
1027
1028         return newnode;
1029 }
1030
1031 /* ----------------
1032  *              _copyIndexPath
1033  * ----------------
1034  */
1035 static IndexPath *
1036 _copyIndexPath(IndexPath *from)
1037 {
1038         IndexPath  *newnode = makeNode(IndexPath);
1039
1040         /* ----------------
1041          *      copy the node superclass fields
1042          * ----------------
1043          */
1044         CopyPathFields((Path *) from, (Path *) newnode);
1045
1046         /* ----------------
1047          *      copy remainder of node
1048          * ----------------
1049          */
1050         newnode->indexid = listCopy(from->indexid);
1051         Node_Copy(from, newnode, indexqual);
1052         newnode->joinrelids = listCopy(from->joinrelids);
1053
1054         return newnode;
1055 }
1056
1057 /* ----------------
1058  *              CopyJoinPathFields
1059  *
1060  *              This function copies the fields of the JoinPath node.  It is used by
1061  *              all the copy functions for classes which inherit from JoinPath.
1062  * ----------------
1063  */
1064 static void
1065 CopyJoinPathFields(JoinPath *from, JoinPath *newnode)
1066 {
1067         Node_Copy(from, newnode, pathinfo);
1068         Node_Copy(from, newnode, outerjoinpath);
1069         Node_Copy(from, newnode, innerjoinpath);
1070 }
1071
1072 /* ----------------
1073  *              _copyNestPath
1074  * ----------------
1075  */
1076 static NestPath *
1077 _copyNestPath(NestPath *from)
1078 {
1079         NestPath   *newnode = makeNode(NestPath);
1080
1081         /* ----------------
1082          *      copy the node superclass fields
1083          * ----------------
1084          */
1085         CopyPathFields((Path *) from, (Path *) newnode);
1086         CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
1087
1088         return newnode;
1089 }
1090
1091 /* ----------------
1092  *              _copyMergePath
1093  * ----------------
1094  */
1095 static MergePath *
1096 _copyMergePath(MergePath *from)
1097 {
1098         MergePath  *newnode = makeNode(MergePath);
1099
1100         /* ----------------
1101          *      copy the node superclass fields
1102          * ----------------
1103          */
1104         CopyPathFields((Path *) from, (Path *) newnode);
1105         CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
1106
1107         /* ----------------
1108          *      copy the remainder of the node
1109          * ----------------
1110          */
1111         Node_Copy(from, newnode, path_mergeclauses);
1112         Node_Copy(from, newnode, outersortkeys);
1113         Node_Copy(from, newnode, innersortkeys);
1114
1115         return newnode;
1116 }
1117
1118 /* ----------------
1119  *              _copyHashPath
1120  * ----------------
1121  */
1122 static HashPath *
1123 _copyHashPath(HashPath *from)
1124 {
1125         HashPath   *newnode = makeNode(HashPath);
1126
1127         /* ----------------
1128          *      copy the node superclass fields
1129          * ----------------
1130          */
1131         CopyPathFields((Path *) from, (Path *) newnode);
1132         CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
1133
1134         /* ----------------
1135          *      copy remainder of node
1136          * ----------------
1137          */
1138         Node_Copy(from, newnode, path_hashclauses);
1139
1140         return newnode;
1141 }
1142
1143 /* ----------------
1144  *              _copyPathKeyItem
1145  * ----------------
1146  */
1147 static PathKeyItem *
1148 _copyPathKeyItem(PathKeyItem *from)
1149 {
1150         PathKeyItem   *newnode = makeNode(PathKeyItem);
1151
1152         /* ----------------
1153          *      copy remainder of node
1154          * ----------------
1155          */
1156         Node_Copy(from, newnode, key);
1157         newnode->sortop = from->sortop;
1158
1159         return newnode;
1160 }
1161
1162 /* ----------------
1163  *              _copyRestrictInfo
1164  * ----------------
1165  */
1166 static RestrictInfo *
1167 _copyRestrictInfo(RestrictInfo *from)
1168 {
1169         RestrictInfo *newnode = makeNode(RestrictInfo);
1170
1171         /* ----------------
1172          *      copy remainder of node
1173          * ----------------
1174          */
1175         Node_Copy(from, newnode, clause);
1176         newnode->selectivity = from->selectivity;
1177         Node_Copy(from, newnode, subclauseindices);
1178         newnode->mergejoinoperator = from->mergejoinoperator;
1179         newnode->left_sortop = from->left_sortop;
1180         newnode->right_sortop = from->right_sortop;
1181         newnode->hashjoinoperator = from->hashjoinoperator;
1182
1183         return newnode;
1184 }
1185
1186 /* ----------------
1187  *              _copyJoinInfo
1188  * ----------------
1189  */
1190 static JoinInfo *
1191 _copyJoinInfo(JoinInfo *from)
1192 {
1193         JoinInfo   *newnode = makeNode(JoinInfo);
1194
1195         /* ----------------
1196          *      copy remainder of node
1197          * ----------------
1198          */
1199         newnode->unjoined_relids = listCopy(from->unjoined_relids);
1200         Node_Copy(from, newnode, jinfo_restrictinfo);
1201
1202         return newnode;
1203 }
1204
1205 static Iter *
1206 _copyIter(Iter *from)
1207 {
1208         Iter       *newnode = makeNode(Iter);
1209
1210         Node_Copy(from, newnode, iterexpr);
1211         newnode->itertype = from->itertype;
1212
1213         return newnode;
1214 }
1215
1216 static Stream *
1217 _copyStream(Stream *from)
1218 {
1219         Stream     *newnode = makeNode(Stream);
1220
1221         newnode->pathptr = from->pathptr;
1222         newnode->cinfo = from->cinfo;
1223         newnode->clausetype = from->clausetype;
1224
1225         newnode->upstream = (StreamPtr) NULL;           /* only copy nodes
1226                                                                                                  * downwards! */
1227         Node_Copy(from, newnode, downstream);
1228         if (newnode->downstream)
1229                 ((Stream *) newnode->downstream)->upstream = (Stream *) newnode;
1230
1231         newnode->groupup = from->groupup;
1232         newnode->groupcost = from->groupcost;
1233         newnode->groupsel = from->groupsel;
1234
1235         return newnode;
1236 }
1237
1238 /*
1239  *      parsenodes.h routines have no copy functions
1240  */
1241
1242 static TargetEntry *
1243 _copyTargetEntry(TargetEntry *from)
1244 {
1245         TargetEntry *newnode = makeNode(TargetEntry);
1246
1247         Node_Copy(from, newnode, resdom);
1248         Node_Copy(from, newnode, fjoin);
1249         Node_Copy(from, newnode, expr);
1250         return newnode;
1251 }
1252
1253 static RangeTblEntry *
1254 _copyRangeTblEntry(RangeTblEntry *from)
1255 {
1256         RangeTblEntry *newnode = makeNode(RangeTblEntry);
1257
1258         if (from->relname)
1259                 newnode->relname = pstrdup(from->relname);
1260         if (from->refname)
1261                 newnode->refname = pstrdup(from->refname);
1262         newnode->relid = from->relid;
1263         newnode->inh = from->inh;
1264         newnode->inFromCl = from->inFromCl;
1265         newnode->inJoinSet = from->inJoinSet;
1266         newnode->skipAcl = from->skipAcl;
1267
1268         return newnode;
1269 }
1270
1271 static RowMark *
1272 _copyRowMark(RowMark *from)
1273 {
1274         RowMark    *newnode = makeNode(RowMark);
1275
1276         newnode->rti = from->rti;
1277         newnode->info = from->info;
1278
1279         return newnode;
1280 }
1281
1282 static SortClause *
1283 _copySortClause(SortClause *from)
1284 {
1285         SortClause *newnode = makeNode(SortClause);
1286
1287         newnode->tleSortGroupRef = from->tleSortGroupRef;
1288         newnode->sortop = from->sortop;
1289
1290         return newnode;
1291 }
1292
1293 static A_Const *
1294 _copyAConst(A_Const *from)
1295 {
1296         A_Const    *newnode = makeNode(A_Const);
1297
1298         newnode->val = *((Value *) (copyObject(&(from->val))));
1299         Node_Copy(from, newnode, typename);
1300
1301         return newnode;
1302 }
1303
1304 static TypeName *
1305 _copyTypeName(TypeName *from)
1306 {
1307         TypeName   *newnode = makeNode(TypeName);
1308
1309         if (from->name)
1310                 newnode->name = pstrdup(from->name);
1311         newnode->timezone = from->timezone;
1312         newnode->setof = from->setof;
1313         newnode->typmod = from->typmod;
1314         Node_Copy(from, newnode, arrayBounds);
1315
1316         return newnode;
1317 }
1318
1319 static Query *
1320 _copyQuery(Query *from)
1321 {
1322         Query      *newnode = makeNode(Query);
1323
1324         newnode->commandType = from->commandType;
1325         if (from->utilityStmt && nodeTag(from->utilityStmt) == T_NotifyStmt)
1326         {
1327                 NotifyStmt *from_notify = (NotifyStmt *) from->utilityStmt;
1328                 NotifyStmt *n = makeNode(NotifyStmt);
1329
1330                 n->relname = pstrdup(from_notify->relname);
1331                 newnode->utilityStmt = (Node *) n;
1332         }
1333         newnode->resultRelation = from->resultRelation;
1334         if (from->into)
1335                 newnode->into = pstrdup(from->into);
1336         newnode->isPortal = from->isPortal;
1337         newnode->isBinary = from->isBinary;
1338         newnode->isTemp = from->isTemp;
1339         newnode->unionall = from->unionall;
1340         newnode->hasAggs = from->hasAggs;
1341         newnode->hasSubLinks = from->hasSubLinks;
1342
1343         Node_Copy(from, newnode, rtable);
1344         Node_Copy(from, newnode, targetList);
1345         Node_Copy(from, newnode, qual);
1346         Node_Copy(from, newnode, rowMark);
1347
1348         if (from->uniqueFlag)
1349                 newnode->uniqueFlag = pstrdup(from->uniqueFlag);
1350         Node_Copy(from, newnode, sortClause);
1351         Node_Copy(from, newnode, groupClause);
1352         Node_Copy(from, newnode, havingQual);
1353
1354         /* why is intersectClause missing? */
1355         Node_Copy(from, newnode, unionClause);
1356
1357         Node_Copy(from, newnode, limitOffset);
1358         Node_Copy(from, newnode, limitCount);
1359
1360         /* we do not copy the planner internal fields: base_rel_list,
1361          * join_rel_list, query_pathkeys.  Not entirely clear if this is right?
1362          */
1363
1364         return newnode;
1365 }
1366
1367
1368 /*
1369  *      mnodes.h routines have no copy functions
1370  */
1371
1372 /* ****************************************************************
1373  *                                      pg_list.h copy functions
1374  * ****************************************************************
1375  */
1376
1377 static Value *
1378 _copyValue(Value *from)
1379 {
1380         Value      *newnode = makeNode(Value);
1381
1382         newnode->type = from->type;
1383         switch (from->type)
1384         {
1385                 case T_String:
1386                         newnode->val.str = pstrdup(from->val.str);
1387                         break;
1388                 case T_Integer:
1389                         newnode->val.ival = from->val.ival;
1390                         break;
1391                 case T_Float:
1392                         newnode->val.dval = from->val.dval;
1393                         break;
1394                 default:
1395                         break;
1396         }
1397         return newnode;
1398 }
1399
1400 /* ----------------
1401  *              copyObject returns a copy of the node or list. If it is a list, it
1402  *              recursively copies its items.
1403  * ----------------
1404  */
1405 void *
1406 copyObject(void *from)
1407 {
1408         void       *retval;
1409
1410         if (from == NULL)
1411                 return NULL;
1412         switch (nodeTag(from))
1413         {
1414
1415                         /*
1416                          * PLAN NODES
1417                          */
1418                 case T_Plan:
1419                         retval = _copyPlan(from);
1420                         break;
1421                 case T_Result:
1422                         retval = _copyResult(from);
1423                         break;
1424                 case T_Append:
1425                         retval = _copyAppend(from);
1426                         break;
1427                 case T_Scan:
1428                         retval = _copyScan(from);
1429                         break;
1430                 case T_SeqScan:
1431                         retval = _copySeqScan(from);
1432                         break;
1433                 case T_IndexScan:
1434                         retval = _copyIndexScan(from);
1435                         break;
1436                 case T_Join:
1437                         retval = _copyJoin(from);
1438                         break;
1439                 case T_NestLoop:
1440                         retval = _copyNestLoop(from);
1441                         break;
1442                 case T_MergeJoin:
1443                         retval = _copyMergeJoin(from);
1444                         break;
1445                 case T_HashJoin:
1446                         retval = _copyHashJoin(from);
1447                         break;
1448                 case T_Noname:
1449                         retval = _copyNoname(from);
1450                         break;
1451                 case T_Material:
1452                         retval = _copyMaterial(from);
1453                         break;
1454                 case T_Sort:
1455                         retval = _copySort(from);
1456                         break;
1457                 case T_Group:
1458                         retval = _copyGroup(from);
1459                         break;
1460                 case T_Agg:
1461                         retval = _copyAgg(from);
1462                         break;
1463                 case T_GroupClause:
1464                         retval = _copyGroupClause(from);
1465                         break;
1466                 case T_Unique:
1467                         retval = _copyUnique(from);
1468                         break;
1469                 case T_Hash:
1470                         retval = _copyHash(from);
1471                         break;
1472                 case T_SubPlan:
1473                         retval = _copySubPlan(from);
1474                         break;
1475
1476                         /*
1477                          * PRIMITIVE NODES
1478                          */
1479                 case T_Resdom:
1480                         retval = _copyResdom(from);
1481                         break;
1482                 case T_Fjoin:
1483                         retval = _copyFjoin(from);
1484                         break;
1485                 case T_Expr:
1486                         retval = _copyExpr(from);
1487                         break;
1488                 case T_Var:
1489                         retval = _copyVar(from);
1490                         break;
1491                 case T_Oper:
1492                         retval = _copyOper(from);
1493                         break;
1494                 case T_Const:
1495                         retval = _copyConst(from);
1496                         break;
1497                 case T_Param:
1498                         retval = _copyParam(from);
1499                         break;
1500                 case T_Func:
1501                         retval = _copyFunc(from);
1502                         break;
1503                 case T_Array:
1504                         retval = _copyArray(from);
1505                         break;
1506                 case T_ArrayRef:
1507                         retval = _copyArrayRef(from);
1508                         break;
1509                 case T_Aggref:
1510                         retval = _copyAggref(from);
1511                         break;
1512                 case T_SubLink:
1513                         retval = _copySubLink(from);
1514                         break;
1515                 case T_CaseExpr:
1516                         retval = _copyCaseExpr(from);
1517                         break;
1518                 case T_CaseWhen:
1519                         retval = _copyCaseWhen(from);
1520                         break;
1521
1522                         /*
1523                          * RELATION NODES
1524                          */
1525                 case T_RelOptInfo:
1526                         retval = _copyRelOptInfo(from);
1527                         break;
1528                 case T_Path:
1529                         retval = _copyPath(from);
1530                         break;
1531                 case T_IndexPath:
1532                         retval = _copyIndexPath(from);
1533                         break;
1534                 case T_NestPath:
1535                         retval = _copyNestPath(from);
1536                         break;
1537                 case T_MergePath:
1538                         retval = _copyMergePath(from);
1539                         break;
1540                 case T_HashPath:
1541                         retval = _copyHashPath(from);
1542                         break;
1543                 case T_PathKeyItem:
1544                         retval = _copyPathKeyItem(from);
1545                         break;
1546                 case T_RestrictInfo:
1547                         retval = _copyRestrictInfo(from);
1548                         break;
1549                 case T_JoinInfo:
1550                         retval = _copyJoinInfo(from);
1551                         break;
1552                 case T_Iter:
1553                         retval = _copyIter(from);
1554                         break;
1555                 case T_Stream:
1556                         retval = _copyStream(from);
1557                         break;
1558
1559                         /*
1560                          * PARSE NODES
1561                          */
1562                 case T_Query:
1563                         retval = _copyQuery(from);
1564                         break;
1565                 case T_TargetEntry:
1566                         retval = _copyTargetEntry(from);
1567                         break;
1568                 case T_RangeTblEntry:
1569                         retval = _copyRangeTblEntry(from);
1570                         break;
1571                 case T_RowMark:
1572                         retval = _copyRowMark(from);
1573                         break;
1574                 case T_SortClause:
1575                         retval = _copySortClause(from);
1576                         break;
1577                 case T_A_Const:
1578                         retval = _copyAConst(from);
1579                         break;
1580                 case T_TypeName:
1581                         retval = _copyTypeName(from);
1582                         break;
1583
1584                         /*
1585                          * VALUE NODES
1586                          */
1587                 case T_Integer:
1588                 case T_String:
1589                 case T_Float:
1590                         retval = _copyValue(from);
1591                         break;
1592                 case T_List:
1593                         {
1594                                 List       *list = from,
1595                                                    *l,
1596                                                    *nl;
1597
1598                                 /* rather ugly coding for speed... */
1599                                 /* Note the input list cannot be NIL if we got here. */
1600                                 nl = lcons(copyObject(lfirst(list)), NIL);
1601                                 retval = nl;
1602
1603                                 foreach(l, lnext(list))
1604                                 {
1605                                         lnext(nl) = lcons(copyObject(lfirst(l)), NIL);
1606                                         nl = lnext(nl);
1607                                 }
1608                         }
1609                         break;
1610                 default:
1611                         elog(ERROR, "copyObject: don't know how to copy %d", nodeTag(from));
1612                         retval = from;
1613                         break;
1614         }
1615         return retval;
1616 }