1/*-------------------------------------------------------------------------
4 * Copy functions for Postgres tree nodes.
7 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/nodes/copyfuncs.c
13 *-------------------------------------------------------------------------
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'.
29/* Copy a simple scalar field (int, float, bool, enum, etc) */
30 #define COPY_SCALAR_FIELD(fldname) \
31 (newnode->fldname = from->fldname)
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))
37/* Copy a field that is a pointer to a Bitmapset */
38 #define COPY_BITMAPSET_FIELD(fldname) \
39 (newnode->fldname = bms_copy(from->fldname))
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) : NULL)
45/* Copy a field that is an inline array */
46 #define COPY_ARRAY_FIELD(fldname) \
47 memcpy(newnode->fldname, from->fldname, sizeof(newnode->fldname))
49/* Copy a field that is a pointer to a simple palloc'd object of size sz */
50 #define COPY_POINTER_FIELD(fldname, sz) \
55 newnode->fldname = palloc(_size); \
56 memcpy(newnode->fldname, from->fldname, _size); \
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)
65#include "copyfuncs.funcs.c"
69 * Support functions for nodes with custom_copy_equal attribute
82 if (from->constbyval || from->constisnull)
85 * passed by value so just copy the datum. Also, don't try to copy
86 * struct when value is null!
88 newnode->constvalue = from->constvalue;
93 * passed by reference. We need a palloc'd copy.
95 newnode->constvalue =
datumCopy(from->constvalue,
115 /* This part must duplicate other _copy*() functions. */
135 elog(
ERROR,
"unrecognized node type: %d",
157 /* copy the private fields */
171 * copyObjectImpl -- implementation of copyObject(); see nodes/nodes.h
173 * Create a copy of a Node tree or list. This is a "deep" copy: all
174 * substructure is copied too, recursively.
184 /* Guard against stack overflow due to overly complex expressions */
189#include "copyfuncs.switch.c"
196 * Lists of integers, OIDs and XIDs don't need to be deep-copied,
197 * so we perform a shallow copy via list_copy()
207 retval = 0;
/* keep compiler quiet */
Bitmapset * bms_copy(const Bitmapset *a)
static Const * _copyConst(const Const *from)
static ExtensibleNode * _copyExtensibleNode(const ExtensibleNode *from)
#define COPY_LOCATION_FIELD(fldname)
void * copyObjectImpl(const void *from)
static A_Const * _copyA_Const(const A_Const *from)
#define COPY_STRING_FIELD(fldname)
static Bitmapset * _copyBitmapset(const Bitmapset *from)
#define COPY_SCALAR_FIELD(fldname)
Datum datumCopy(Datum value, bool typByVal, int typLen)
const ExtensibleNodeMethods * GetExtensibleNodeMethods(const char *extnodename, bool missing_ok)
List * list_copy_deep(const List *oldlist)
List * list_copy(const List *oldlist)
static Node * newNode(size_t size, NodeTag tag)
void check_stack_depth(void)
void(* nodeCopy)(struct ExtensibleNode *newnode, const struct ExtensibleNode *oldnode)