Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit c6f5f85

Browse files
committed
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.
1 parent ee2ad1c commit c6f5f85

File tree

1 file changed

+56
-114
lines changed

1 file changed

+56
-114
lines changed

src/backend/nodes/copyfuncs.c

+56-114
Original file line numberDiff line numberDiff line change
@@ -7,50 +7,58 @@
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
*/
2741
List *
2842
listCopy(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)
684692
static 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

Comments
 (0)