*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.93 1999/10/07 04:23:03 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.94 1999/11/01 05:15:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-#include "catalog/pg_type.h"
#include "optimizer/planmain.h"
#include "optimizer/subselect.h"
-#include "utils/syscache.h"
+
+
+/*
+ * Node_Copy
+ * a macro to simplify calling of copyObject on the specified field
+ */
+#define Node_Copy(from, newnode, field) \
+ ((newnode)->field = copyObject((from)->field))
+
/*
* listCopy
- * this copy function only copies the "lcons-cells" of the list but not
- * its contents. (good for list of pointers as well as list of integers).
+ * This copy function only copies the "cons-cells" of the list, not the
+ * pointed-to objects. (Use copyObject if you want a "deep" copy.)
+ *
+ * We also use this function for copying lists of integers, which is
+ * grotty but unlikely to break --- it could fail if sizeof(pointer)
+ * is less than sizeof(int), but I don't know any such machines...
+ *
+ * Note that copyObject will surely coredump if applied to a list
+ * of integers!
*/
List *
listCopy(List *list)
{
- List *newlist = NIL;
- List *l,
- *nl = NIL;
+ List *newlist,
+ *l,
+ *nl;
+
+ /* rather ugly coding for speed... */
+ if (list == NIL)
+ return NIL;
- foreach(l, list)
+ newlist = nl = lcons(lfirst(list), NIL);
+
+ foreach(l, lnext(list))
{
- if (newlist == NIL)
- newlist = nl = lcons(lfirst(l), NIL);
- else
- {
- lnext(nl) = lcons(lfirst(l), NIL);
- nl = lnext(nl);
- }
+ lnext(nl) = lcons(lfirst(l), NIL);
+ nl = lnext(nl);
}
return newlist;
}
-/*
- * Node_Copy
- * a macro to simplify calling of copyObject on the specified field
- */
-#define Node_Copy(from, newnode, field) \
- newnode->field = copyObject(from->field)
-
/* ****************************************************************
* plannodes.h copy functions
* ****************************************************************
static Const *
_copyConst(Const *from)
{
- static Oid cached_type;
- static bool cached_typbyval;
-
Const *newnode = makeNode(Const);
/* ----------------
newnode->consttype = from->consttype;
newnode->constlen = from->constlen;
- /* ----------------
- * XXX super cheesy hack until parser/planner
- * puts in the right values here.
- *
- * But I like cheese.
- * ----------------
- */
- if (!from->constisnull && cached_type != from->consttype)
+ if (from->constbyval || from->constisnull)
{
- HeapTuple typeTuple;
- Form_pg_type typeStruct;
-
- /* ----------------
- * get the type tuple corresponding to the paramList->type,
- * If this fails, returnValue has been pre-initialized
- * to "null" so we just return it.
- * ----------------
- */
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(from->consttype),
- 0, 0, 0);
-
/* ----------------
- * get the type length and by-value from the type tuple and
- * save the information in our one element cache.
+ * passed by value so just copy the datum.
+ * Also, don't try to copy struct when value is null!
* ----------------
*/
- Assert(PointerIsValid(typeTuple));
-
- typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
- cached_typbyval = (typeStruct)->typbyval ? true : false;
- cached_type = from->consttype;
+ newnode->constvalue = from->constvalue;
}
-
- from->constbyval = cached_typbyval;
-
- if (!from->constisnull)
+ else
{
/* ----------------
- * copying the Datum in a const node is a bit trickier
- * because it might be a pointer and it might also be of
- * variable length...
+ * not passed by value. datum contains a pointer.
* ----------------
*/
- if (from->constbyval == true)
- {
- /* ----------------
- * passed by value so just copy the datum.
- * ----------------
- */
- newnode->constvalue = from->constvalue;
- }
- else
- {
- /* ----------------
- * not passed by value. datum contains a pointer.
- * ----------------
- */
- if (from->constlen != -1)
- {
- /* ----------------
- * fixed length structure
- * ----------------
- */
- newnode->constvalue = PointerGetDatum(palloc(from->constlen));
- memmove((char *) newnode->constvalue,
- (char *) from->constvalue, from->constlen);
- }
- else
- {
- /* ----------------
- * variable length structure. here the length is stored
- * in the first int pointed to by the constval.
- * ----------------
- */
- int length;
-
- length = VARSIZE(from->constvalue);
- newnode->constvalue = PointerGetDatum(palloc(length));
- memmove((char *) newnode->constvalue,
- (char *) from->constvalue, length);
- }
- }
+ int length = from->constlen;
+
+ if (length == -1) /* variable-length type? */
+ length = VARSIZE(from->constvalue);
+ newnode->constvalue = PointerGetDatum(palloc(length));
+ memcpy(DatumGetPointer(newnode->constvalue),
+ DatumGetPointer(from->constvalue),
+ length);
}
- else
- newnode->constvalue = from->constvalue;
+
newnode->constisnull = from->constisnull;
newnode->constbyval = from->constbyval;
newnode->constisset = from->constisset;
case T_List:
{
List *list = from,
- *l;
- List *newlist = NIL,
- *nl = NIL;
+ *l,
+ *nl;
+
+ /* rather ugly coding for speed... */
+ /* Note the input list cannot be NIL if we got here. */
+ nl = lcons(copyObject(lfirst(list)), NIL);
+ retval = nl;
- foreach(l, list)
+ foreach(l, lnext(list))
{
- if (newlist == NIL)
- newlist = nl = lcons(copyObject(lfirst(l)), NIL);
- else
- {
- lnext(nl) = lcons(copyObject(lfirst(l)), NIL);
- nl = lnext(nl);
- }
+ lnext(nl) = lcons(copyObject(lfirst(l)), NIL);
+ nl = lnext(nl);
}
- retval = newlist;
}
break;
default: