citus/src/backend/distributed/utils/citus_copyfuncs.c

363 lines
8.5 KiB
C

/*-------------------------------------------------------------------------
*
* citus_copyfuncs.c
* Citus specific node copy functions
*
* Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) Citus Data, Inc.
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "utils/datum.h"
#include "distributed/citus_nodefuncs.h"
#include "distributed/listutils.h"
#include "distributed/multi_server_executor.h"
/*
* Macros to simplify copying of different kinds of fields. Use these
* wherever possible to reduce the chance for silly typos. Note that these
* hard-wire the convention that the local variables in a Copy routine are
* named 'newnode' and 'from'.
*/
static inline Node *
CitusSetTag(Node *node, int tag)
{
CitusNode *citus_node = (CitusNode *) node;
citus_node->citus_tag = tag;
return node;
}
#define DECLARE_FROM_AND_NEW_NODE(nodeTypeName) \
nodeTypeName *newnode = \
(nodeTypeName *) CitusSetTag((Node *) target_node, T_ ## nodeTypeName); \
nodeTypeName *from = (nodeTypeName *) source_node
/* Copy a simple scalar field (int, float, bool, enum, etc) */
#define COPY_SCALAR_FIELD(fldname) \
(newnode->fldname = from->fldname)
/* Copy a field that is a pointer to some kind of Node or Node tree */
#define COPY_NODE_FIELD(fldname) \
(newnode->fldname = copyObject(from->fldname))
/* Copy a field that is a pointer to a C string, or perhaps NULL */
#define COPY_STRING_FIELD(fldname) \
(newnode->fldname = from->fldname ? pstrdup(from->fldname) : (char *) NULL)
/* Copy a node array. Target array is also allocated. */
#define COPY_NODE_ARRAY(fldname, type, count) \
do { \
int i = 0; \
newnode->fldname = (type **) palloc(count * sizeof(type *)); \
for (i = 0; i < count; ++i) \
{ \
newnode->fldname[i] = copyObject(from->fldname[i]); \
} \
} \
while (0)
/* Copy a scalar array. Target array is also allocated. */
#define COPY_SCALAR_ARRAY(fldname, type, count) \
do { \
int i = 0; \
newnode->fldname = (type *) palloc(count * sizeof(type)); \
for (i = 0; i < count; ++i) \
{ \
newnode->fldname[i] = from->fldname[i]; \
} \
} \
while (0)
#define COPY_STRING_LIST(fldname) \
do { \
char *curString = NULL; \
List *newList = NIL; \
foreach_declared_ptr(curString, from->fldname) { \
char *newString = curString ? pstrdup(curString) : (char *) NULL; \
newList = lappend(newList, newString); \
} \
newnode->fldname = newList; \
} \
while (0)
static void CopyTaskQuery(Task *newnode, Task *from);
static void
copyJobInfo(Job *newnode, Job *from)
{
COPY_SCALAR_FIELD(jobId);
COPY_NODE_FIELD(jobQuery);
COPY_NODE_FIELD(taskList);
COPY_NODE_FIELD(dependentJobList);
COPY_SCALAR_FIELD(subqueryPushdown);
COPY_SCALAR_FIELD(requiresCoordinatorEvaluation);
COPY_SCALAR_FIELD(deferredPruning);
COPY_NODE_FIELD(partitionKeyValue);
COPY_NODE_FIELD(localPlannedStatements);
COPY_SCALAR_FIELD(parametersInJobQueryResolved);
}
void
CopyNodeJob(COPYFUNC_ARGS)
{
DECLARE_FROM_AND_NEW_NODE(Job);
copyJobInfo(newnode, from);
}
void
CopyNodeDistributedPlan(COPYFUNC_ARGS)
{
DECLARE_FROM_AND_NEW_NODE(DistributedPlan);
COPY_SCALAR_FIELD(planId);
COPY_SCALAR_FIELD(modLevel);
COPY_SCALAR_FIELD(expectResults);
COPY_NODE_FIELD(workerJob);
COPY_NODE_FIELD(combineQuery);
COPY_SCALAR_FIELD(queryId);
COPY_NODE_FIELD(relationIdList);
COPY_SCALAR_FIELD(targetRelationId);
COPY_NODE_FIELD(modifyQueryViaCoordinatorOrRepartition);
COPY_NODE_FIELD(selectPlanForModifyViaCoordinatorOrRepartition);
COPY_SCALAR_FIELD(modifyWithSelectMethod);
COPY_STRING_FIELD(intermediateResultIdPrefix);
COPY_NODE_FIELD(subPlanList);
COPY_NODE_FIELD(usedSubPlanNodeList);
COPY_SCALAR_FIELD(fastPathRouterPlan);
COPY_SCALAR_FIELD(numberOfTimesExecuted);
COPY_NODE_FIELD(planningError);
}
void
CopyNodeDistributedSubPlan(COPYFUNC_ARGS)
{
DECLARE_FROM_AND_NEW_NODE(DistributedSubPlan);
COPY_SCALAR_FIELD(subPlanId);
COPY_NODE_FIELD(plan);
}
void
CopyNodeUsedDistributedSubPlan(COPYFUNC_ARGS)
{
DECLARE_FROM_AND_NEW_NODE(UsedDistributedSubPlan);
COPY_STRING_FIELD(subPlanId);
COPY_SCALAR_FIELD(accessType);
}
void
CopyNodeShardInterval(COPYFUNC_ARGS)
{
DECLARE_FROM_AND_NEW_NODE(ShardInterval);
COPY_SCALAR_FIELD(relationId);
COPY_SCALAR_FIELD(storageType);
COPY_SCALAR_FIELD(valueTypeId);
COPY_SCALAR_FIELD(valueTypeLen);
COPY_SCALAR_FIELD(valueByVal);
COPY_SCALAR_FIELD(minValueExists);
COPY_SCALAR_FIELD(maxValueExists);
if (from->minValueExists)
{
newnode->minValue = datumCopy(from->minValue,
from->valueByVal,
from->valueTypeLen);
}
if (from->maxValueExists)
{
newnode->maxValue = datumCopy(from->maxValue,
from->valueByVal,
from->valueTypeLen);
}
COPY_SCALAR_FIELD(shardId);
COPY_SCALAR_FIELD(shardIndex);
}
void
CopyNodeMapMergeJob(COPYFUNC_ARGS)
{
DECLARE_FROM_AND_NEW_NODE(MapMergeJob);
copyJobInfo(&newnode->job, &from->job);
COPY_SCALAR_FIELD(partitionType);
COPY_NODE_FIELD(partitionColumn);
COPY_SCALAR_FIELD(partitionCount);
COPY_SCALAR_FIELD(sortedShardIntervalArrayLength);
int arrayLength = from->sortedShardIntervalArrayLength;
/* now build & read sortedShardIntervalArray */
COPY_NODE_ARRAY(sortedShardIntervalArray, ShardInterval, arrayLength);
COPY_NODE_FIELD(mapTaskList);
COPY_NODE_FIELD(mergeTaskList);
}
void
CopyNodeShardPlacement(COPYFUNC_ARGS)
{
DECLARE_FROM_AND_NEW_NODE(ShardPlacement);
COPY_SCALAR_FIELD(placementId);
COPY_SCALAR_FIELD(shardId);
COPY_SCALAR_FIELD(shardLength);
COPY_SCALAR_FIELD(groupId);
COPY_STRING_FIELD(nodeName);
COPY_SCALAR_FIELD(nodePort);
COPY_SCALAR_FIELD(nodeId);
COPY_SCALAR_FIELD(partitionMethod);
COPY_SCALAR_FIELD(colocationGroupId);
COPY_SCALAR_FIELD(representativeValue);
}
void
CopyNodeGroupShardPlacement(COPYFUNC_ARGS)
{
DECLARE_FROM_AND_NEW_NODE(GroupShardPlacement);
COPY_SCALAR_FIELD(placementId);
COPY_SCALAR_FIELD(shardId);
COPY_SCALAR_FIELD(shardLength);
COPY_SCALAR_FIELD(groupId);
}
void
CopyNodeRelationShard(COPYFUNC_ARGS)
{
DECLARE_FROM_AND_NEW_NODE(RelationShard);
COPY_SCALAR_FIELD(relationId);
COPY_SCALAR_FIELD(shardId);
}
void
CopyNodeRelationRowLock(COPYFUNC_ARGS)
{
DECLARE_FROM_AND_NEW_NODE(RelationRowLock);
COPY_SCALAR_FIELD(relationId);
COPY_SCALAR_FIELD(rowLockStrength);
}
static void
CopyTaskQuery(Task *newnode, Task *from)
{
COPY_SCALAR_FIELD(taskQuery.queryType);
switch (from->taskQuery.queryType)
{
case TASK_QUERY_TEXT:
{
COPY_STRING_FIELD(taskQuery.data.queryStringLazy);
break;
}
case TASK_QUERY_OBJECT:
{
COPY_NODE_FIELD(taskQuery.data.jobQueryReferenceForLazyDeparsing);
break;
}
case TASK_QUERY_TEXT_LIST:
{
COPY_STRING_LIST(taskQuery.data.queryStringList);
break;
}
case TASK_QUERY_LOCAL_PLAN:
{
COPY_NODE_FIELD(taskQuery.data.localPlan);
break;
}
default:
{
break;
}
}
}
void
CopyNodeTask(COPYFUNC_ARGS)
{
DECLARE_FROM_AND_NEW_NODE(Task);
COPY_SCALAR_FIELD(taskType);
COPY_SCALAR_FIELD(jobId);
COPY_SCALAR_FIELD(taskId);
CopyTaskQuery(newnode, from);
COPY_SCALAR_FIELD(anchorDistributedTableId);
COPY_SCALAR_FIELD(anchorShardId);
COPY_NODE_FIELD(taskPlacementList);
COPY_NODE_FIELD(dependentTaskList);
COPY_SCALAR_FIELD(partitionId);
COPY_SCALAR_FIELD(upstreamTaskId);
COPY_NODE_FIELD(shardInterval);
COPY_SCALAR_FIELD(assignmentConstrained);
COPY_SCALAR_FIELD(replicationModel);
COPY_SCALAR_FIELD(modifyWithSubquery);
COPY_NODE_FIELD(relationShardList);
COPY_NODE_FIELD(relationRowLockList);
COPY_NODE_FIELD(rowValuesLists);
COPY_SCALAR_FIELD(partiallyLocalOrRemote);
COPY_SCALAR_FIELD(parametersInQueryStringResolved);
COPY_SCALAR_FIELD(tupleDest);
COPY_SCALAR_FIELD(queryCount);
COPY_SCALAR_FIELD(totalReceivedTupleData);
COPY_SCALAR_FIELD(fetchedExplainAnalyzePlacementIndex);
COPY_STRING_FIELD(fetchedExplainAnalyzePlan);
COPY_SCALAR_FIELD(fetchedExplainAnalyzeExecutionDuration);
COPY_SCALAR_FIELD(isLocalTableModification);
COPY_SCALAR_FIELD(cannotBeExecutedInTransaction);
}
void
CopyNodeLocalPlannedStatement(COPYFUNC_ARGS)
{
DECLARE_FROM_AND_NEW_NODE(LocalPlannedStatement);
COPY_SCALAR_FIELD(shardId);
COPY_SCALAR_FIELD(localGroupId);
COPY_NODE_FIELD(localPlan);
}
void
CopyNodeDeferredErrorMessage(COPYFUNC_ARGS)
{
DECLARE_FROM_AND_NEW_NODE(DeferredErrorMessage);
COPY_SCALAR_FIELD(code);
COPY_STRING_FIELD(message);
COPY_STRING_FIELD(detail);
COPY_STRING_FIELD(hint);
COPY_STRING_FIELD(filename);
COPY_SCALAR_FIELD(linenumber);
COPY_STRING_FIELD(functionname);
}