77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.93 1999/10/07 04:23:03 tgl Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.94 1999/11/01 05:15:13 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
1414
1515#include "postgres.h"
1616
17- #include "catalog/pg_type.h"
1817#include "optimizer/planmain.h"
1918#include "optimizer/subselect.h"
20- #include "utils/syscache.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+
2128
2229/*
2330 * 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).
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!
2640 */
2741List *
2842listCopy (List * list )
2943{
30- List * newlist = NIL ;
31- List * l ,
32- * nl = NIL ;
44+ List * newlist ,
45+ * l ,
46+ * nl ;
47+
48+ /* rather ugly coding for speed... */
49+ if (list == NIL )
50+ return NIL ;
3351
34- foreach (l , list )
52+ newlist = nl = lcons (lfirst (list ), NIL );
53+
54+ foreach (l , lnext (list ))
3555 {
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- }
56+ lnext (nl ) = lcons (lfirst (l ), NIL );
57+ nl = lnext (nl );
4358 }
4459 return newlist ;
4560}
4661
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-
5462/* ****************************************************************
5563 * plannodes.h copy functions
5664 * ****************************************************************
@@ -684,9 +692,6 @@ _copyOper(Oper *from)
684692static Const *
685693_copyConst (Const * from )
686694{
687- static Oid cached_type ;
688- static bool cached_typbyval ;
689-
690695 Const * newnode = makeNode (Const );
691696
692697 /* ----------------
@@ -696,92 +701,31 @@ _copyConst(Const *from)
696701 newnode -> consttype = from -> consttype ;
697702 newnode -> constlen = from -> constlen ;
698703
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 )
704+ if (from -> constbyval || from -> constisnull )
707705 {
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-
721706 /* ----------------
722- * get the type length and by-value from the type tuple and
723- * save the information in our one element cache.
707+ * passed by value so just copy the datum.
708+ * Also, don't try to copy struct when value is null!
724709 * ----------------
725710 */
726- Assert (PointerIsValid (typeTuple ));
727-
728- typeStruct = (Form_pg_type ) GETSTRUCT (typeTuple );
729- cached_typbyval = (typeStruct )-> typbyval ? true : false;
730- cached_type = from -> consttype ;
711+ newnode -> constvalue = from -> constvalue ;
731712 }
732-
733- from -> constbyval = cached_typbyval ;
734-
735- if (!from -> constisnull )
713+ else
736714 {
737715 /* ----------------
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...
716+ * not passed by value. datum contains a pointer.
741717 * ----------------
742718 */
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- }
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 );
782727 }
783- else
784- newnode -> constvalue = from -> constvalue ;
728+
785729 newnode -> constisnull = from -> constisnull ;
786730 newnode -> constbyval = from -> constbyval ;
787731 newnode -> constisset = from -> constisset ;
@@ -1646,21 +1590,19 @@ copyObject(void *from)
16461590 case T_List :
16471591 {
16481592 List * list = from ,
1649- * l ;
1650- List * newlist = NIL ,
1651- * nl = NIL ;
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 ;
16521600
1653- foreach (l , list )
1601+ foreach (l , lnext ( list ) )
16541602 {
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- }
1603+ lnext (nl ) = lcons (copyObject (lfirst (l )), NIL );
1604+ nl = lnext (nl );
16621605 }
1663- retval = newlist ;
16641606 }
16651607 break ;
16661608 default :
0 commit comments