mirror of https://github.com/citusdata/citus.git
363 lines
8.5 KiB
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);
|
|
}
|