PostgreSQL Source Code
git master
copyfuncs.c
Go to the documentation of this file.
1
/*-------------------------------------------------------------------------
2
*
3
* copyfuncs.c
4
* Copy functions for Postgres tree nodes.
5
*
6
*
7
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
8
* Portions Copyright (c) 1994, Regents of the University of California
9
*
10
* IDENTIFICATION
11
* src/backend/nodes/copyfuncs.c
12
*
13
*-------------------------------------------------------------------------
14
*/
15
16
#include "
postgres.h
"
17
18
#include "
miscadmin.h
"
19
#include "
utils/datum.h
"
20
21
22
/*
23
* Macros to simplify copying of different kinds of fields. Use these
24
* wherever possible to reduce the chance for silly typos. Note that these
25
* hard-wire the convention that the local variables in a Copy routine are
26
* named 'newnode' and 'from'.
27
*/
28
29
/* Copy a simple scalar field (int, float, bool, enum, etc) */
30
#define COPY_SCALAR_FIELD(fldname) \
31
(newnode->fldname = from->fldname)
32
33
/* Copy a field that is a pointer to some kind of Node or Node tree */
34
#define COPY_NODE_FIELD(fldname) \
35
(newnode->fldname = copyObjectImpl(from->fldname))
36
37
/* Copy a field that is a pointer to a Bitmapset */
38
#define COPY_BITMAPSET_FIELD(fldname) \
39
(newnode->fldname = bms_copy(from->fldname))
40
41
/* Copy a field that is a pointer to a C string, or perhaps NULL */
42
#define COPY_STRING_FIELD(fldname) \
43
(newnode->fldname = from->fldname ? pstrdup(from->fldname) : (char *) NULL)
44
45
/* Copy a field that is an inline array */
46
#define COPY_ARRAY_FIELD(fldname) \
47
memcpy(newnode->fldname, from->fldname, sizeof(newnode->fldname))
48
49
/* Copy a field that is a pointer to a simple palloc'd object of size sz */
50
#define COPY_POINTER_FIELD(fldname, sz) \
51
do { \
52
Size _size = (sz); \
53
if (_size > 0) \
54
{ \
55
newnode->fldname = palloc(_size); \
56
memcpy(newnode->fldname, from->fldname, _size); \
57
} \
58
} while (0)
59
60
/* Copy a parse location field (for Copy, this is same as scalar case) */
61
#define COPY_LOCATION_FIELD(fldname) \
62
(newnode->fldname = from->fldname)
63
64
65
#include "copyfuncs.funcs.c"
66
67
68
/*
69
* Support functions for nodes with custom_copy_equal attribute
70
*/
71
72
static
Const
*
73
_copyConst
(
const
Const
*from)
74
{
75
Const
*newnode =
makeNode
(
Const
);
76
77
COPY_SCALAR_FIELD
(consttype);
78
COPY_SCALAR_FIELD
(consttypmod);
79
COPY_SCALAR_FIELD
(constcollid);
80
COPY_SCALAR_FIELD
(constlen);
81
82
if
(from->constbyval || from->constisnull)
83
{
84
/*
85
* passed by value so just copy the datum. Also, don't try to copy
86
* struct when value is null!
87
*/
88
newnode->constvalue = from->constvalue;
89
}
90
else
91
{
92
/*
93
* passed by reference. We need a palloc'd copy.
94
*/
95
newnode->constvalue =
datumCopy
(from->constvalue,
96
from->constbyval,
97
from->constlen);
98
}
99
100
COPY_SCALAR_FIELD
(constisnull);
101
COPY_SCALAR_FIELD
(constbyval);
102
COPY_LOCATION_FIELD
(location);
103
104
return
newnode;
105
}
106
107
static
A_Const
*
108
_copyA_Const
(
const
A_Const
*from)
109
{
110
A_Const
*newnode =
makeNode
(
A_Const
);
111
112
COPY_SCALAR_FIELD
(isnull);
113
if
(!from->
isnull
)
114
{
115
/* This part must duplicate other _copy*() functions. */
116
COPY_SCALAR_FIELD
(
val
.node.type);
117
switch
(
nodeTag
(&from->
val
))
118
{
119
case
T_Integer:
120
COPY_SCALAR_FIELD
(
val
.ival.ival);
121
break
;
122
case
T_Float:
123
COPY_STRING_FIELD
(
val
.fval.fval);
124
break
;
125
case
T_Boolean:
126
COPY_SCALAR_FIELD
(
val
.boolval.boolval);
127
break
;
128
case
T_String:
129
COPY_STRING_FIELD
(
val
.sval.sval);
130
break
;
131
case
T_BitString:
132
COPY_STRING_FIELD
(
val
.bsval.bsval);
133
break
;
134
default
:
135
elog
(
ERROR
,
"unrecognized node type: %d"
,
136
(
int
)
nodeTag
(&from->
val
));
137
break
;
138
}
139
}
140
141
COPY_LOCATION_FIELD
(location);
142
143
return
newnode;
144
}
145
146
static
ExtensibleNode
*
147
_copyExtensibleNode
(
const
ExtensibleNode
*from)
148
{
149
ExtensibleNode
*newnode;
150
const
ExtensibleNodeMethods
*methods;
151
152
methods =
GetExtensibleNodeMethods
(from->
extnodename
,
false
);
153
newnode = (
ExtensibleNode
*)
newNode
(methods->
node_size
,
154
T_ExtensibleNode);
155
COPY_STRING_FIELD
(extnodename);
156
157
/* copy the private fields */
158
methods->
nodeCopy
(newnode, from);
159
160
return
newnode;
161
}
162
163
static
Bitmapset
*
164
_copyBitmapset
(
const
Bitmapset
*from)
165
{
166
return
bms_copy
(from);
167
}
168
169
170
/*
171
* copyObjectImpl -- implementation of copyObject(); see nodes/nodes.h
172
*
173
* Create a copy of a Node tree or list. This is a "deep" copy: all
174
* substructure is copied too, recursively.
175
*/
176
void
*
177
copyObjectImpl
(
const
void
*from)
178
{
179
void
*retval;
180
181
if
(from == NULL)
182
return
NULL;
183
184
/* Guard against stack overflow due to overly complex expressions */
185
check_stack_depth
();
186
187
switch
(
nodeTag
(from))
188
{
189
#include "copyfuncs.switch.c"
190
191
case
T_List:
192
retval =
list_copy_deep
(from);
193
break
;
194
195
/*
196
* Lists of integers, OIDs and XIDs don't need to be deep-copied,
197
* so we perform a shallow copy via list_copy()
198
*/
199
case
T_IntList:
200
case
T_OidList:
201
case
T_XidList:
202
retval =
list_copy
(from);
203
break
;
204
205
default
:
206
elog
(
ERROR
,
"unrecognized node type: %d"
, (
int
)
nodeTag
(from));
207
retval = 0;
/* keep compiler quiet */
208
break
;
209
}
210
211
return
retval;
212
}
bms_copy
Bitmapset * bms_copy(const Bitmapset *a)
Definition:
bitmapset.c:122
_copyConst
static Const * _copyConst(const Const *from)
Definition:
copyfuncs.c:73
COPY_LOCATION_FIELD
#define COPY_LOCATION_FIELD(fldname)
Definition:
copyfuncs.c:61
COPY_STRING_FIELD
#define COPY_STRING_FIELD(fldname)
Definition:
copyfuncs.c:42
copyObjectImpl
void * copyObjectImpl(const void *from)
Definition:
copyfuncs.c:177
_copyA_Const
static A_Const * _copyA_Const(const A_Const *from)
Definition:
copyfuncs.c:108
_copyExtensibleNode
static ExtensibleNode * _copyExtensibleNode(const ExtensibleNode *from)
Definition:
copyfuncs.c:147
_copyBitmapset
static Bitmapset * _copyBitmapset(const Bitmapset *from)
Definition:
copyfuncs.c:164
COPY_SCALAR_FIELD
#define COPY_SCALAR_FIELD(fldname)
Definition:
copyfuncs.c:30
datumCopy
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition:
datum.c:132
datum.h
ERROR
#define ERROR
Definition:
elog.h:39
elog
#define elog(elevel,...)
Definition:
elog.h:225
GetExtensibleNodeMethods
const ExtensibleNodeMethods * GetExtensibleNodeMethods(const char *extnodename, bool missing_ok)
Definition:
extensible.c:125
val
long val
Definition:
informix.c:689
list_copy_deep
List * list_copy_deep(const List *oldlist)
Definition:
list.c:1639
list_copy
List * list_copy(const List *oldlist)
Definition:
list.c:1573
miscadmin.h
newNode
static Node * newNode(size_t size, NodeTag tag)
Definition:
nodes.h:144
nodeTag
#define nodeTag(nodeptr)
Definition:
nodes.h:133
makeNode
#define makeNode(_type_)
Definition:
nodes.h:155
check_stack_depth
void check_stack_depth(void)
Definition:
postgres.c:3540
postgres.h
A_Const
Definition:
parsenodes.h:360
A_Const::isnull
bool isnull
Definition:
parsenodes.h:365
A_Const::val
union ValUnion val
Definition:
parsenodes.h:364
Bitmapset
Definition:
bitmapset.h:50
Const
Definition:
primnodes.h:307
ExtensibleNodeMethods
Definition:
extensible.h:63
ExtensibleNodeMethods::node_size
Size node_size
Definition:
extensible.h:65
ExtensibleNodeMethods::nodeCopy
void(* nodeCopy)(struct ExtensibleNode *newnode, const struct ExtensibleNode *oldnode)
Definition:
extensible.h:66
ExtensibleNode
Definition:
extensible.h:33
ExtensibleNode::extnodename
const char * extnodename
Definition:
extensible.h:37
src
backend
nodes
copyfuncs.c
Generated on Tue Sep 17 2024 06:13:20 for PostgreSQL Source Code by
1.9.1