OSDN Git Service

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