#include "postgres.h"
#include "miscadmin.h"
#include "utils/datum.h"
#define COPY_SCALAR_FIELD(fldname) \
(newnode->fldname = from->fldname)
#define COPY_NODE_FIELD(fldname) \
(newnode->fldname = copyObjectImpl(from->fldname))
#define COPY_BITMAPSET_FIELD(fldname) \
(newnode->fldname = bms_copy(from->fldname))
#define COPY_STRING_FIELD(fldname) \
(newnode->fldname = from->fldname ? pstrdup(from->fldname) : (char *) NULL)
#define COPY_ARRAY_FIELD(fldname) \
memcpy(newnode->fldname, from->fldname, sizeof(newnode->fldname))
#define COPY_POINTER_FIELD(fldname, sz) \
do { \
Size _size = (sz); \
if (_size > 0) \
{ \
newnode->fldname = palloc(_size); \
memcpy(newnode->fldname, from->fldname, _size); \
} \
} while (0)
#define COPY_LOCATION_FIELD(fldname) \
(newnode->fldname = from->fldname)
#include "copyfuncs.funcs.c"
static Const *
_copyConst(const Const *from)
{
Const *newnode = makeNode(Const);
COPY_SCALAR_FIELD(consttype);
COPY_SCALAR_FIELD(consttypmod);
COPY_SCALAR_FIELD(constcollid);
COPY_SCALAR_FIELD(constlen);
if (from->constbyval || from->constisnull)
{
newnode->constvalue = from->constvalue;
}
else
{
newnode->constvalue = datumCopy(from->constvalue,
from->constbyval,
from->constlen);
}
COPY_SCALAR_FIELD(constisnull);
COPY_SCALAR_FIELD(constbyval);
COPY_LOCATION_FIELD(location);
return newnode;
}
static A_Const *
_copyA_Const(const A_Const *from)
{
A_Const *newnode = makeNode(A_Const);
COPY_SCALAR_FIELD(isnull);
if (!from->isnull)
{
COPY_SCALAR_FIELD(val.node.type);
switch (nodeTag(&from->val))
{
case T_Integer:
COPY_SCALAR_FIELD(val.ival.ival);
break;
case T_Float:
COPY_STRING_FIELD(val.fval.fval);
break;
case T_Boolean:
COPY_SCALAR_FIELD(val.boolval.boolval);
break;
case T_String:
COPY_STRING_FIELD(val.sval.sval);
break;
case T_BitString:
COPY_STRING_FIELD(val.bsval.bsval);
break;
default:
elog(ERROR, "unrecognized node type: %d",
(int) nodeTag(&from->val));
break;
}
}
COPY_LOCATION_FIELD(location);
return newnode;
}
static ExtensibleNode *
_copyExtensibleNode(const ExtensibleNode *from)
{
ExtensibleNode *newnode;
const ExtensibleNodeMethods *methods;
methods = GetExtensibleNodeMethods(from->extnodename, false);
newnode = (ExtensibleNode *) newNode(methods->node_size,
T_ExtensibleNode);
COPY_STRING_FIELD(extnodename);
methods->nodeCopy(newnode, from);
return newnode;
}
static Bitmapset *
_copyBitmapset(const Bitmapset *from)
{
return bms_copy(from);
}
void *
copyObjectImpl(const void *from)
{
void *retval;
if (from == NULL)
return NULL;
check_stack_depth();
switch (nodeTag(from))
{
#include "copyfuncs.switch.c"
case T_List:
retval = list_copy_deep(from);
break;
case T_IntList:
case T_OidList:
case T_XidList:
retval = list_copy(from);
break;
default:
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(from));
retval = 0;
break;
}
return retval;
}