OSDN Git Service

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