Commit c6f5f858 authored by Tom Lane's avatar Tom Lane

Eliminate some unbelievably cheesy code in _copyConst().

Apparently, back in the dim reaches of prehistory, the parser couldn't
be trusted to label Const nodes with the correct constbyval value ...
and someone preferred to patch around this in copyObject rather than
fix the problem at the source.  The problem is long gone, but the hack
lingered on.  Until now.
parent ee2ad1cf
...@@ -7,50 +7,58 @@ ...@@ -7,50 +7,58 @@
* *
* *
* IDENTIFICATION * 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 "postgres.h"
#include "catalog/pg_type.h"
#include "optimizer/planmain.h" #include "optimizer/planmain.h"
#include "optimizer/subselect.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 * listCopy
* this copy function only copies the "lcons-cells" of the list but not * This copy function only copies the "cons-cells" of the list, not the
* its contents. (good for list of pointers as well as list of integers). * 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 * List *
listCopy(List *list) listCopy(List *list)
{ {
List *newlist = NIL; List *newlist,
List *l, *l,
*nl = NIL; *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) lnext(nl) = lcons(lfirst(l), NIL);
newlist = nl = lcons(lfirst(l), NIL); nl = lnext(nl);
else
{
lnext(nl) = lcons(lfirst(l), NIL);
nl = lnext(nl);
}
} }
return newlist; 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 * plannodes.h copy functions
* **************************************************************** * ****************************************************************
...@@ -684,9 +692,6 @@ _copyOper(Oper *from) ...@@ -684,9 +692,6 @@ _copyOper(Oper *from)
static Const * static Const *
_copyConst(Const *from) _copyConst(Const *from)
{ {
static Oid cached_type;
static bool cached_typbyval;
Const *newnode = makeNode(Const); Const *newnode = makeNode(Const);
/* ---------------- /* ----------------
...@@ -696,92 +701,31 @@ _copyConst(Const *from) ...@@ -696,92 +701,31 @@ _copyConst(Const *from)
newnode->consttype = from->consttype; newnode->consttype = from->consttype;
newnode->constlen = from->constlen; newnode->constlen = from->constlen;
/* ---------------- if (from->constbyval || from->constisnull)
* XXX super cheesy hack until parser/planner
* puts in the right values here.
*
* But I like cheese.
* ----------------
*/
if (!from->constisnull && cached_type != from->consttype)
{ {
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 * passed by value so just copy the datum.
* save the information in our one element cache. * Also, don't try to copy struct when value is null!
* ---------------- * ----------------
*/ */
Assert(PointerIsValid(typeTuple)); newnode->constvalue = from->constvalue;
typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
cached_typbyval = (typeStruct)->typbyval ? true : false;
cached_type = from->consttype;
} }
else
from->constbyval = cached_typbyval;
if (!from->constisnull)
{ {
/* ---------------- /* ----------------
* copying the Datum in a const node is a bit trickier * not passed by value. datum contains a pointer.
* because it might be a pointer and it might also be of
* variable length...
* ---------------- * ----------------
*/ */
if (from->constbyval == true) int length = from->constlen;
{
/* ---------------- if (length == -1) /* variable-length type? */
* passed by value so just copy the datum. length = VARSIZE(from->constvalue);
* ---------------- newnode->constvalue = PointerGetDatum(palloc(length));
*/ memcpy(DatumGetPointer(newnode->constvalue),
newnode->constvalue = from->constvalue; DatumGetPointer(from->constvalue),
} length);
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);
}
}
} }
else
newnode->constvalue = from->constvalue;
newnode->constisnull = from->constisnull; newnode->constisnull = from->constisnull;
newnode->constbyval = from->constbyval; newnode->constbyval = from->constbyval;
newnode->constisset = from->constisset; newnode->constisset = from->constisset;
...@@ -1646,21 +1590,19 @@ copyObject(void *from) ...@@ -1646,21 +1590,19 @@ copyObject(void *from)
case T_List: case T_List:
{ {
List *list = from, List *list = from,
*l; *l,
List *newlist = NIL, *nl;
*nl = NIL;
/* 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) lnext(nl) = lcons(copyObject(lfirst(l)), NIL);
newlist = nl = lcons(copyObject(lfirst(l)), NIL); nl = lnext(nl);
else
{
lnext(nl) = lcons(copyObject(lfirst(l)), NIL);
nl = lnext(nl);
}
} }
retval = newlist;
} }
break; break;
default: default:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment