diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 07e75c0f838c8f5d41b44f9d35c7656d80140b6b..5b7437b5644005171ed55ed5ab2ba37ff6ecba36 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -7,50 +7,58 @@ * * * 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 * **************************************************************** @@ -684,9 +692,6 @@ _copyOper(Oper *from) static Const * _copyConst(Const *from) { - static Oid cached_type; - static bool cached_typbyval; - Const *newnode = makeNode(Const); /* ---------------- @@ -696,92 +701,31 @@ _copyConst(Const *from) 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; @@ -1646,21 +1590,19 @@ copyObject(void *from) 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: