From 8c67429e58059dd90868a3a123e4904175939c13 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Thu, 3 Mar 2016 19:42:37 -0800 Subject: [PATCH] Use extensible node API, abstract read-/out- funcs This introduces macros to wrap differences between 9.5 and 9.6 read- and out- functions for our custom nodes, allowing better code reuse for those functions. Additionally, if running on PostgreSQL 9.6, this change will register extensible node types for all our custom nodes, permitting us to rely on the standard PostgreSQL nodeToString, stringToNode, and readNode functions. Long-term, this change lets us avoid copy-pasting a ton of readfuncs code as well as well as some other static methods we've been copying in the past. --- .gitattributes | 1 - src/backend/distributed/shared_library_init.c | 4 + .../distributed/utils/citus_nodefuncs.c | 103 + .../distributed/utils/citus_outfuncs.c | 195 +- src/backend/distributed/utils/citus_read.c | 33 +- .../distributed/utils/citus_readfuncs.c | 383 +++ .../distributed/utils/citus_readfuncs_95.c | 224 +- .../distributed/utils/citus_readfuncs_96.c | 2808 ----------------- src/include/distributed/citus_nodefuncs.h | 49 + src/include/distributed/citus_nodes.h | 76 +- .../distributed/master_metadata_utility.h | 4 +- .../distributed/multi_logical_planner.h | 2 +- .../distributed/multi_physical_planner.h | 6 +- 13 files changed, 769 insertions(+), 3119 deletions(-) create mode 100644 src/backend/distributed/utils/citus_readfuncs.c delete mode 100644 src/backend/distributed/utils/citus_readfuncs_96.c diff --git a/.gitattributes b/.gitattributes index e759429fa..9f2989b09 100644 --- a/.gitattributes +++ b/.gitattributes @@ -28,7 +28,6 @@ configure -whitespace src/backend/distributed/utils/citus_outfuncs.c -citus-style src/backend/distributed/utils/citus_read.c -citus-style src/backend/distributed/utils/citus_readfuncs_95.c -citus-style -src/backend/distributed/utils/citus_readfuncs_96.c -citus-style src/backend/distributed/utils/ruleutils_95.c -citus-style src/backend/distributed/utils/ruleutils_96.c -citus-style src/include/distributed/citus_nodes.h -citus-style diff --git a/src/backend/distributed/shared_library_init.c b/src/backend/distributed/shared_library_init.c index 549d20958..149cd3d13 100644 --- a/src/backend/distributed/shared_library_init.c +++ b/src/backend/distributed/shared_library_init.c @@ -18,6 +18,7 @@ #include "commands/explain.h" #include "executor/executor.h" +#include "distributed/citus_nodefuncs.h" #include "distributed/commit_protocol.h" #include "distributed/master_protocol.h" #include "distributed/multi_copy.h" @@ -129,6 +130,9 @@ _PG_init(void) */ RegisterCitusConfigVariables(); + /* make our additional node types known */ + RegisterNodes(); + /* intercept planner */ planner_hook = multi_planner; diff --git a/src/backend/distributed/utils/citus_nodefuncs.c b/src/backend/distributed/utils/citus_nodefuncs.c index 3b0f4cfe7..4846437ec 100644 --- a/src/backend/distributed/utils/citus_nodefuncs.c +++ b/src/backend/distributed/utils/citus_nodefuncs.c @@ -11,9 +11,31 @@ #include "postgres.h" #include "catalog/pg_type.h" +#include "distributed/citus_nodes.h" #include "distributed/citus_nodefuncs.h" #include "distributed/metadata_cache.h" +static const char *CitusNodeTagNamesD[] = { + "MultiNode", + "MultiTreeRoot", + "MultiProject", + "MultiCollect", + "MultiSelect", + "MultiTable", + "MultiJoin", + "MultiPartition", + "MultiCartesianProduct", + "MultiExtendedOp", + "Job", + "MapMergeJob", + "MultiPlan", + "Task", + "ShardInterval", + "ShardPlacement" +}; + +const char **CitusNodeTagNames = CitusNodeTagNamesD; + /* exports for SQL callable functions */ PG_FUNCTION_INFO_V1(citus_extradata_container); @@ -307,3 +329,84 @@ citus_extradata_container(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } + + +#if (PG_VERSION_NUM >= 90600) + +static void +CopyUnsupportedCitusNode(struct ExtensibleNode *newnode, + const struct ExtensibleNode *oldnode) +{ + ereport(ERROR, (errmsg("not implemented"))); +} + + +static bool +EqualUnsupportedCitusNode(const struct ExtensibleNode *a, + const struct ExtensibleNode *b) +{ + ereport(ERROR, (errmsg("not implemented"))); +} + + +/* *INDENT-OFF* */ +#define DEFINE_NODE_METHODS(type) \ + { \ + #type, \ + sizeof(type), \ + CopyUnsupportedCitusNode, \ + EqualUnsupportedCitusNode, \ + Out##type, \ + Read##type \ + } + +#define DEFINE_NODE_METHODS_NO_READ(type) \ + { \ + #type, \ + sizeof(type), \ + CopyUnsupportedCitusNode, \ + EqualUnsupportedCitusNode, \ + Out##type, \ + ReadUnsupportedCitusNode \ + } + + +/* *INDENT-ON* */ +const ExtensibleNodeMethods nodeMethods[] = +{ + DEFINE_NODE_METHODS(MultiPlan), + DEFINE_NODE_METHODS(Job), + DEFINE_NODE_METHODS(ShardInterval), + DEFINE_NODE_METHODS(MapMergeJob), + DEFINE_NODE_METHODS(ShardPlacement), + DEFINE_NODE_METHODS(Task), + + /* nodes with only output support */ + DEFINE_NODE_METHODS_NO_READ(MultiNode), + DEFINE_NODE_METHODS_NO_READ(MultiTreeRoot), + DEFINE_NODE_METHODS_NO_READ(MultiProject), + DEFINE_NODE_METHODS_NO_READ(MultiCollect), + DEFINE_NODE_METHODS_NO_READ(MultiSelect), + DEFINE_NODE_METHODS_NO_READ(MultiTable), + DEFINE_NODE_METHODS_NO_READ(MultiJoin), + DEFINE_NODE_METHODS_NO_READ(MultiPartition), + DEFINE_NODE_METHODS_NO_READ(MultiCartesianProduct), + DEFINE_NODE_METHODS_NO_READ(MultiExtendedOp) +}; +#endif + +void +RegisterNodes(void) +{ +#if (PG_VERSION_NUM >= 90600) + int off; + + StaticAssertExpr(lengthof(nodeMethods) == lengthof(CitusNodeTagNamesD), + "number of node methods and names do not match"); + + for (off = 0; off < lengthof(nodeMethods); off++) + { + RegisterExtensibleNodeMethods(&nodeMethods[off]); + } +#endif +} diff --git a/src/backend/distributed/utils/citus_outfuncs.c b/src/backend/distributed/utils/citus_outfuncs.c index 50b043e7c..3c4cd213b 100644 --- a/src/backend/distributed/utils/citus_outfuncs.c +++ b/src/backend/distributed/utils/citus_outfuncs.c @@ -38,10 +38,21 @@ * routine. */ +/* Store const reference to raw input node in local named 'node' */ +#define WRITE_LOCALS(nodeTypeName) \ + const nodeTypeName *node = (const nodeTypeName *) raw_node + /* Write the label for the node type */ +#if (PG_VERSION_NUM >= 90600) +#define WRITE_NODE_TYPE(nodelabel) \ + (void) 0 + +#else #define WRITE_NODE_TYPE(nodelabel) \ appendStringInfoString(str, nodelabel) +#endif + /* Write an integer field (anything written as ":fldname %d") */ #define WRITE_INT_FIELD(fldname) \ appendStringInfo(str, " :" CppAsString(fldname) " %d", node->fldname) @@ -83,7 +94,7 @@ /* Write a character-string (possibly NULL) field */ #define WRITE_STRING_FIELD(fldname) \ (appendStringInfo(str, " :" CppAsString(fldname) " "), \ - _outToken(str, node->fldname)) + outToken(str, node->fldname)) /* Write a parse location field (actually same as INT case) */ #define WRITE_LOCATION_FIELD(fldname) \ @@ -92,7 +103,7 @@ /* Write a Node field */ #define WRITE_NODE_FIELD(fldname) \ (appendStringInfo(str, " :" CppAsString(fldname) " "), \ - _outNode(str, node->fldname)) + outNode(str, node->fldname)) /* Write a bitmapset field */ #define WRITE_BITMAPSET_FIELD(fldname) \ @@ -102,18 +113,18 @@ #define booltostr(x) ((x) ? "true" : "false") -static void _outNode(StringInfo str, const void *obj); - +#if (PG_VERSION_NUM < 90600) +static void outNode(StringInfo str, const void *obj); /* - * _outToken + * outToken * Convert an ordinary string (eg, an identifier) into a form that * will be decoded back to a plain token by read.c's functions. * * If a null or empty string is given, it is encoded as "<>". */ static void -_outToken(StringInfo str, const char *s) +outToken(StringInfo str, const char *s) { if (s == NULL || *s == '\0') { @@ -166,7 +177,7 @@ _outList(StringInfo str, const List *node) */ if (IsA(node, List)) { - _outNode(str, lfirst(lc)); + outNode(str, lfirst(lc)); if (lnext(lc)) appendStringInfoChar(str, ' '); } @@ -187,7 +198,7 @@ _outList(StringInfo str, const List *node) * Print the value of a Datum given its type. */ static void -_outDatum(StringInfo str, Datum value, int typlen, bool typbyval) +outDatum(StringInfo str, Datum value, int typlen, bool typbyval) { Size length, i; @@ -218,38 +229,49 @@ _outDatum(StringInfo str, Datum value, int typlen, bool typbyval) } } +#endif /***************************************************************************** * Output routines for Citus node types *****************************************************************************/ static void -_outMultiUnaryNode(StringInfo str, const MultiUnaryNode *node) +OutMultiUnaryNodeFields(StringInfo str, const MultiUnaryNode *node) { WRITE_NODE_FIELD(childNode); } static void -_outMultiBinaryNode(StringInfo str, const MultiBinaryNode *node) +OutMultiBinaryNodeFields(StringInfo str, const MultiBinaryNode *node) { WRITE_NODE_FIELD(leftChildNode); WRITE_NODE_FIELD(rightChildNode); } - -static void -_outMultiTreeRoot(StringInfo str, const MultiTreeRoot *node) +void +OutMultiNode(OUTFUNC_ARGS) { - WRITE_NODE_TYPE("MULTITREEROOT"); - - _outMultiUnaryNode(str, (const MultiUnaryNode *) node); + WRITE_NODE_TYPE("MULTINODE"); } -static void -_outMultiPlan(StringInfo str, const MultiPlan *node) +void +OutMultiTreeRoot(OUTFUNC_ARGS) { + WRITE_LOCALS(MultiTreeRoot); + + WRITE_NODE_TYPE("MULTITREEROOT"); + + OutMultiUnaryNodeFields(str, (const MultiUnaryNode *) node); +} + + +void +OutMultiPlan(OUTFUNC_ARGS) +{ + WRITE_LOCALS(MultiPlan); + WRITE_NODE_TYPE("MULTIPLAN"); WRITE_NODE_FIELD(workerJob); @@ -258,87 +280,95 @@ _outMultiPlan(StringInfo str, const MultiPlan *node) } -static void -_outMultiProject(StringInfo str, const MultiProject *node) +void +OutMultiProject(OUTFUNC_ARGS) { + WRITE_LOCALS(MultiProject); WRITE_NODE_TYPE("MULTIPROJECT"); WRITE_NODE_FIELD(columnList); - _outMultiUnaryNode(str, (const MultiUnaryNode *) node); + OutMultiUnaryNodeFields(str, (const MultiUnaryNode *) node); } -static void -_outMultiCollect(StringInfo str, const MultiCollect *node) +void +OutMultiCollect(OUTFUNC_ARGS) { + WRITE_LOCALS(MultiCollect); WRITE_NODE_TYPE("MULTICOLLECT"); - _outMultiUnaryNode(str, (const MultiUnaryNode *) node); + OutMultiUnaryNodeFields(str, (const MultiUnaryNode *) node); } -static void -_outMultiSelect(StringInfo str, const MultiSelect *node) +void +OutMultiSelect(OUTFUNC_ARGS) { + WRITE_LOCALS(MultiSelect); WRITE_NODE_TYPE("MULTISELECT"); WRITE_NODE_FIELD(selectClauseList); - _outMultiUnaryNode(str, (const MultiUnaryNode *) node); + OutMultiUnaryNodeFields(str, (const MultiUnaryNode *) node); } -static void -_outMultiTable(StringInfo str, const MultiTable *node) +void +OutMultiTable(OUTFUNC_ARGS) { + WRITE_LOCALS(MultiTable); WRITE_NODE_TYPE("MULTITABLE"); WRITE_OID_FIELD(relationId); WRITE_INT_FIELD(rangeTableId); - _outMultiUnaryNode(str, (const MultiUnaryNode *) node); + OutMultiUnaryNodeFields(str, (const MultiUnaryNode *) node); } -static void -_outMultiJoin(StringInfo str, const MultiJoin *node) +void +OutMultiJoin(OUTFUNC_ARGS) { + WRITE_LOCALS(MultiJoin); WRITE_NODE_TYPE("MULTIJOIN"); WRITE_NODE_FIELD(joinClauseList); WRITE_ENUM_FIELD(joinRuleType, JoinRuleType); WRITE_ENUM_FIELD(joinType, JoinType); - _outMultiBinaryNode(str, (const MultiBinaryNode *) node); + OutMultiBinaryNodeFields(str, (const MultiBinaryNode *) node); } -static void -_outMultiPartition(StringInfo str, const MultiPartition *node) +void +OutMultiPartition(OUTFUNC_ARGS) { + WRITE_LOCALS(MultiPartition); WRITE_NODE_TYPE("MULTIPARTITION"); WRITE_NODE_FIELD(partitionColumn); - _outMultiUnaryNode(str, (const MultiUnaryNode *) node); + OutMultiUnaryNodeFields(str, (const MultiUnaryNode *) node); } -static void -_outMultiCartesianProduct(StringInfo str, const MultiCartesianProduct *node) +void +OutMultiCartesianProduct(OUTFUNC_ARGS) { + WRITE_LOCALS(MultiCartesianProduct); WRITE_NODE_TYPE("MULTICARTESIANPRODUCT"); - _outMultiBinaryNode(str, (const MultiBinaryNode *) node); + OutMultiBinaryNodeFields(str, (const MultiBinaryNode *) node); } -static void -_outMultiExtendedOp(StringInfo str, const MultiExtendedOp *node) +void +OutMultiExtendedOp(OUTFUNC_ARGS) { + WRITE_LOCALS(MultiExtendedOp); WRITE_NODE_TYPE("MULTIEXTENDEDOP"); WRITE_NODE_FIELD(targetList); @@ -348,11 +378,11 @@ _outMultiExtendedOp(StringInfo str, const MultiExtendedOp *node) WRITE_NODE_FIELD(limitOffset); WRITE_NODE_FIELD(havingQual); - _outMultiUnaryNode(str, (const MultiUnaryNode *) node); + OutMultiUnaryNodeFields(str, (const MultiUnaryNode *) node); } static void -_outJobInfo(StringInfo str, const Job *node) +OutJobFields(StringInfo str, const Job *node) { WRITE_UINT64_FIELD(jobId); WRITE_NODE_FIELD(jobQuery); @@ -362,18 +392,20 @@ _outJobInfo(StringInfo str, const Job *node) } -static void -_outJob(StringInfo str, const Job *node) +void +OutJob(OUTFUNC_ARGS) { + WRITE_LOCALS(Job); WRITE_NODE_TYPE("JOB"); - _outJobInfo(str, node); + OutJobFields(str, node); } -static void -_outShardInterval(StringInfo str, const ShardInterval *node) +void +OutShardInterval(OUTFUNC_ARGS) { + WRITE_LOCALS(ShardInterval); WRITE_NODE_TYPE("SHARDINTERVAL"); WRITE_OID_FIELD(relationId); @@ -388,27 +420,28 @@ _outShardInterval(StringInfo str, const ShardInterval *node) if (!node->minValueExists) appendStringInfoString(str, "<>"); else - _outDatum(str, node->minValue, node->valueTypeLen, node->valueByVal); + outDatum(str, node->minValue, node->valueTypeLen, node->valueByVal); appendStringInfoString(str, " :maxValue "); if (!node->maxValueExists) appendStringInfoString(str, "<>"); else - _outDatum(str, node->maxValue, node->valueTypeLen, node->valueByVal); + outDatum(str, node->maxValue, node->valueTypeLen, node->valueByVal); WRITE_UINT64_FIELD(shardId); } -static void -_outMapMergeJob(StringInfo str, const MapMergeJob *node) +void +OutMapMergeJob(OUTFUNC_ARGS) { + WRITE_LOCALS(MapMergeJob); int arrayLength = node->sortedShardIntervalArrayLength; int i; WRITE_NODE_TYPE("MAPMERGEJOB"); - _outJobInfo(str, (Job *) node); + OutJobFields(str, (Job *) node); WRITE_NODE_FIELD(reduceQuery); WRITE_ENUM_FIELD(partitionType, PartitionType); WRITE_NODE_FIELD(partitionColumn); @@ -417,9 +450,7 @@ _outMapMergeJob(StringInfo str, const MapMergeJob *node) for (i = 0; i < arrayLength; ++i) { - ShardInterval *writeElement = node->sortedShardIntervalArray[i]; - - _outShardInterval(str, writeElement); + outNode(str, node->sortedShardIntervalArray[i]); } WRITE_NODE_FIELD(mapTaskList); @@ -427,9 +458,10 @@ _outMapMergeJob(StringInfo str, const MapMergeJob *node) } -static void -_outShardPlacement(StringInfo str, const ShardPlacement *node) +void +OutShardPlacement(OUTFUNC_ARGS) { + WRITE_LOCALS(ShardPlacement); WRITE_NODE_TYPE("SHARDPLACEMENT"); WRITE_UINT64_FIELD(placementId); @@ -441,9 +473,10 @@ _outShardPlacement(StringInfo str, const ShardPlacement *node) } -static void -_outTask(StringInfo str, const Task *node) +void +OutTask(OUTFUNC_ARGS) { + WRITE_LOCALS(Task); WRITE_NODE_TYPE("TASK"); WRITE_ENUM_FIELD(taskType, TaskType); @@ -462,13 +495,14 @@ _outTask(StringInfo str, const Task *node) WRITE_BOOL_FIELD(requiresMasterEvaluation); } +#if (PG_VERSION_NUM < 90600) /* - * _outNode - + * outNode - * converts a Node into ascii string and append it to 'str' */ static void -_outNode(StringInfo str, const void *obj) +outNode(StringInfo str, const void *obj) { if (obj == NULL) { @@ -487,91 +521,91 @@ _outNode(StringInfo str, const void *obj) case T_MultiTreeRoot: appendStringInfoChar(str, '{'); - _outMultiTreeRoot(str, obj); + OutMultiTreeRoot(str, obj); appendStringInfoChar(str, '}'); break; case T_MultiProject: appendStringInfoChar(str, '{'); - _outMultiProject(str, obj); + OutMultiProject(str, obj); appendStringInfoChar(str, '}'); break; case T_MultiCollect: appendStringInfoChar(str, '{'); - _outMultiCollect(str, obj); + OutMultiCollect(str, obj); appendStringInfoChar(str, '}'); break; case T_MultiSelect: appendStringInfoChar(str, '{'); - _outMultiSelect(str, obj); + OutMultiSelect(str, obj); appendStringInfoChar(str, '}'); break; case T_MultiTable: appendStringInfoChar(str, '{'); - _outMultiTable(str, obj); + OutMultiTable(str, obj); appendStringInfoChar(str, '}'); break; case T_MultiJoin: appendStringInfoChar(str, '{'); - _outMultiJoin(str, obj); + OutMultiJoin(str, obj); appendStringInfoChar(str, '}'); break; case T_MultiPartition: appendStringInfoChar(str, '{'); - _outMultiPartition(str, obj); + OutMultiPartition(str, obj); appendStringInfoChar(str, '}'); break; case T_MultiCartesianProduct: appendStringInfoChar(str, '{'); - _outMultiCartesianProduct(str, obj); + OutMultiCartesianProduct(str, obj); appendStringInfoChar(str, '}'); break; case T_MultiExtendedOp: appendStringInfoChar(str, '{'); - _outMultiExtendedOp(str, obj); + OutMultiExtendedOp(str, obj); appendStringInfoChar(str, '}'); break; case T_Job: appendStringInfoChar(str, '{'); - _outJob(str, obj); + OutJob(str, obj); appendStringInfoChar(str, '}'); break; case T_MapMergeJob: appendStringInfoChar(str, '{'); - _outMapMergeJob(str, obj); + OutMapMergeJob(str, obj); appendStringInfoChar(str, '}'); break; case T_MultiPlan: appendStringInfoChar(str, '{'); - _outMultiPlan(str, obj); + OutMultiPlan(str, obj); appendStringInfoChar(str, '}'); break; case T_Task: appendStringInfoChar(str, '{'); - _outTask(str, obj); + OutTask(str, obj); appendStringInfoChar(str, '}'); break; case T_ShardInterval: appendStringInfoChar(str, '{'); - _outShardInterval(str, obj); + OutShardInterval(str, obj); appendStringInfoChar(str, '}'); break; case T_ShardPlacement: appendStringInfoChar(str, '{'); - _outShardPlacement(str, obj); + OutShardPlacement(str, obj); appendStringInfoChar(str, '}'); break; @@ -581,6 +615,7 @@ _outNode(StringInfo str, const void *obj) } } +#endif /* * CitusNodeToString - @@ -589,9 +624,13 @@ _outNode(StringInfo str, const void *obj) char * CitusNodeToString(const void *obj) { +#if (PG_VERSION_NUM >= 90600) + return nodeToString(obj); +#else StringInfoData str; initStringInfo(&str); - _outNode(&str, obj); + outNode(&str, obj); return str.data; +#endif } diff --git a/src/backend/distributed/utils/citus_read.c b/src/backend/distributed/utils/citus_read.c index 5c9ba0ecd..03d7e50d1 100644 --- a/src/backend/distributed/utils/citus_read.c +++ b/src/backend/distributed/utils/citus_read.c @@ -29,6 +29,35 @@ #include "nodes/value.h" +/* + * For 9.6 onwards, we use 9.6's extensible node system, thus there's no need + * to copy various routines anymore. In that case, replace these functions + * with plain wrappers. + */ +#if (PG_VERSION_NUM >= 90600) + +void * +CitusStringToNode(char *str) +{ + return stringToNode(str); +} + + +char * +citus_pg_strtok(int *length) +{ + return pg_strtok(length); +} + + +void * +CitusNodeRead(char *token, int tok_len) +{ + return nodeRead(token, tok_len); +} + +#else + /* Static state for citus_pg_strtok */ static char *citus_pg_strtok_ptr = NULL; @@ -63,7 +92,7 @@ CitusStringToNode(char *str) /* * citus_pg_strtok is a copy of postgres' pg_strtok routine, referencing * citus_pg_strtok_ptr instead of pg_strtok_ptr as state. -*/ + */ char * citus_pg_strtok(int *length) { @@ -346,3 +375,5 @@ CitusNodeRead(char *token, int tok_len) return (void *) result; } + +#endif /* (PG_VERSION_NUM < 90600) */ diff --git a/src/backend/distributed/utils/citus_readfuncs.c b/src/backend/distributed/utils/citus_readfuncs.c new file mode 100644 index 000000000..1b85b0b93 --- /dev/null +++ b/src/backend/distributed/utils/citus_readfuncs.c @@ -0,0 +1,383 @@ +/*------------------------------------------------------------------------- + * + * citus_readfuncs.c + * Citus specific node functions + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * Portions Copyright (c) 2012-2015, Citus Data, Inc. + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include + +#include "distributed/citus_nodefuncs.h" +#include "nodes/parsenodes.h" +#include "nodes/readfuncs.h" + + +/* + * Macros to simplify reading of different kinds of fields. Use these + * wherever possible to reduce the chance for silly typos. Note that these + * hard-wire conventions about the names of the local variables in a Read + * routine. + */ + +/* Macros for declaring appropriate local variables */ +/* A few guys need only local_node */ +#if (PG_VERSION_NUM >= 90600) +static inline Node * +CitusSetTag(Node *node, int tag) +{ + CitusNode *citus_node = (CitusNode *) node; + citus_node->citus_tag = tag; + return node; +} + + +/* *INDENT-OFF* */ +#define READ_LOCALS_NO_FIELDS(nodeTypeName) \ + nodeTypeName *local_node = (nodeTypeName *) CitusSetTag((Node *) node, T_##nodeTypeName) +#else +#define READ_LOCALS_NO_FIELDS(nodeTypeName) \ + nodeTypeName *local_node = CitusMakeNode(nodeTypeName) +#endif + +/* And a few guys need only the citus_pg_strtok support fields */ +#define READ_TEMP_LOCALS() \ + char *token; \ + int length + +/* ... but most need both */ +#define READ_LOCALS(nodeTypeName) \ + READ_LOCALS_NO_FIELDS(nodeTypeName); \ + READ_TEMP_LOCALS() + +/* Read an integer field (anything written as ":fldname %d") */ +#define READ_INT_FIELD(fldname) \ + token = citus_pg_strtok(&length); /* skip :fldname */ \ + token = citus_pg_strtok(&length); /* get field value */ \ + local_node->fldname = atoi(token) + +/* Read an unsigned integer field (anything written as ":fldname %u") */ +#define READ_UINT_FIELD(fldname) \ + token = citus_pg_strtok(&length); /* skip :fldname */ \ + token = citus_pg_strtok(&length); /* get field value */ \ + local_node->fldname = atoui(token) + +/* XXX: CITUS Read an uint64 field (anything written as ":fldname %u") */ +#define READ_UINT64_FIELD(fldname) \ + token = citus_pg_strtok(&length); /* skip :fldname */ \ + token = citus_pg_strtok(&length); /* get field value */ \ + local_node->fldname = atoull(token) + +/* Read an OID field (don't hard-wire assumption that OID is same as uint) */ +#define READ_OID_FIELD(fldname) \ + token = citus_pg_strtok(&length); /* skip :fldname */ \ + token = citus_pg_strtok(&length); /* get field value */ \ + local_node->fldname = atooid(token) + +/* Read a char field (ie, one ascii character) */ +#define READ_CHAR_FIELD(fldname) \ + token = citus_pg_strtok(&length); /* skip :fldname */ \ + token = citus_pg_strtok(&length); /* get field value */ \ + local_node->fldname = token[0] + +/* Read an enumerated-type field that was written as an integer code */ +#define READ_ENUM_FIELD(fldname, enumtype) \ + token = citus_pg_strtok(&length); /* skip :fldname */ \ + token = citus_pg_strtok(&length); /* get field value */ \ + local_node->fldname = (enumtype) atoi(token) + +/* Read a float field */ +#define READ_FLOAT_FIELD(fldname) \ + token = citus_pg_strtok(&length); /* skip :fldname */ \ + token = citus_pg_strtok(&length); /* get field value */ \ + local_node->fldname = atof(token) + +/* Read a boolean field */ +#define READ_BOOL_FIELD(fldname) \ + token = citus_pg_strtok(&length); /* skip :fldname */ \ + token = citus_pg_strtok(&length); /* get field value */ \ + local_node->fldname = strtobool(token) + +/* Read a character-string field */ +#define READ_STRING_FIELD(fldname) \ + token = citus_pg_strtok(&length); /* skip :fldname */ \ + token = citus_pg_strtok(&length); /* get field value */ \ + local_node->fldname = nullable_string(token, length) + +/* Read a parse location field (and throw away the value, per notes above) */ +#define READ_LOCATION_FIELD(fldname) \ + token = citus_pg_strtok(&length); /* skip :fldname */ \ + token = citus_pg_strtok(&length); /* get field value */ \ + (void) token; /* in case not used elsewhere */ \ + local_node->fldname = -1 /* set field to "unknown" */ + +/* Read a Node field XXX: Citus: replaced call to nodeRead with CitusNodeRead */ +#define READ_NODE_FIELD(fldname) \ + token = citus_pg_strtok(&length); /* skip :fldname */ \ + (void) token; /* in case not used elsewhere */ \ + local_node->fldname = CitusNodeRead(NULL, 0) + +/* Routine exit */ +#if (PG_VERSION_NUM >= 90600) +#define READ_DONE() \ + return; +#else +#define READ_DONE() \ + return (Node *) local_node +#endif + + +/* + * NOTE: use atoi() to read values written with %d, or atoui() to read + * values written with %u in outfuncs.c. An exception is OID values, + * for which use atooid(). (As of 7.1, outfuncs.c writes OIDs as %u, + * but this will probably change in the future.) + */ +#define atoui(x) ((unsigned int) strtoul((x), NULL, 10)) + +#define atooid(x) ((Oid) strtoul((x), NULL, 10)) + +/* XXX: Citus */ +#define atoull(x) ((uint64) strtoull((x), NULL, 10)) + +#define strtobool(x) ((*(x) == 't') ? true : false) + +#define nullable_string(token,length) \ + ((length) == 0 ? NULL : debackslash(token, length)) + + +static void +readJobInfo(Job *local_node) +{ + READ_TEMP_LOCALS(); + + READ_UINT64_FIELD(jobId); + READ_NODE_FIELD(jobQuery); + READ_NODE_FIELD(taskList); + READ_NODE_FIELD(dependedJobList); + READ_BOOL_FIELD(subqueryPushdown); +} + + +READFUNC_RET +ReadJob(READFUNC_ARGS) +{ + READ_LOCALS_NO_FIELDS(Job); + + readJobInfo(local_node); + + READ_DONE(); +} + + +READFUNC_RET +ReadMultiPlan(READFUNC_ARGS) +{ + READ_LOCALS(MultiPlan); + + READ_NODE_FIELD(workerJob); + READ_NODE_FIELD(masterQuery); + READ_STRING_FIELD(masterTableName); + + READ_DONE(); +} + + +READFUNC_RET +ReadShardInterval(READFUNC_ARGS) +{ + READ_LOCALS(ShardInterval); + + READ_OID_FIELD(relationId); + READ_CHAR_FIELD(storageType); + READ_OID_FIELD(valueTypeId); + READ_INT_FIELD(valueTypeLen); + READ_BOOL_FIELD(valueByVal); + READ_BOOL_FIELD(minValueExists); + READ_BOOL_FIELD(maxValueExists); + + token = citus_pg_strtok(&length); /* skip :minValue */ + if (!local_node->minValueExists) + token = citus_pg_strtok(&length); /* skip "<>" */ + else + local_node->minValue = readDatum(local_node->valueByVal); + + token = citus_pg_strtok(&length); /* skip :maxValue */ + if (!local_node->minValueExists) + token = citus_pg_strtok(&length); /* skip "<>" */ + else + local_node->maxValue = readDatum(local_node->valueByVal); + + READ_UINT64_FIELD(shardId); + + READ_DONE(); +} + + +READFUNC_RET +ReadMapMergeJob(READFUNC_ARGS) +{ + int arrayLength; + int i; + + READ_LOCALS(MapMergeJob); + + readJobInfo(&local_node->job); + + READ_NODE_FIELD(reduceQuery); + READ_ENUM_FIELD(partitionType, PartitionType); + READ_NODE_FIELD(partitionColumn); + READ_UINT_FIELD(partitionCount); + READ_INT_FIELD(sortedShardIntervalArrayLength); + + arrayLength = local_node->sortedShardIntervalArrayLength; + + /* now build & read sortedShardIntervalArray */ + local_node->sortedShardIntervalArray = + (ShardInterval**) palloc(arrayLength * sizeof(ShardInterval *)); + + for (i = 0; i < arrayLength; ++i) + { + /* can't use READ_NODE_FIELD, no field names */ + local_node->sortedShardIntervalArray[i] = CitusNodeRead(NULL, 0); + } + + READ_NODE_FIELD(mapTaskList); + READ_NODE_FIELD(mergeTaskList); + + READ_DONE(); +} + + +READFUNC_RET +ReadShardPlacement(READFUNC_ARGS) +{ + READ_LOCALS(ShardPlacement); + + READ_OID_FIELD(placementId); + READ_UINT64_FIELD(shardId); + READ_UINT64_FIELD(shardLength); + READ_ENUM_FIELD(shardState, RelayFileState); + READ_STRING_FIELD(nodeName); + READ_UINT_FIELD(nodePort); + + READ_DONE(); +} + + +READFUNC_RET +ReadTask(READFUNC_ARGS) +{ + READ_LOCALS(Task); + + READ_ENUM_FIELD(taskType, TaskType); + READ_UINT64_FIELD(jobId); + READ_UINT_FIELD(taskId); + READ_STRING_FIELD(queryString); + READ_UINT64_FIELD(anchorShardId); + READ_NODE_FIELD(taskPlacementList); + READ_NODE_FIELD(dependedTaskList); + READ_UINT_FIELD(partitionId); + READ_UINT_FIELD(upstreamTaskId); + READ_NODE_FIELD(shardInterval); + READ_BOOL_FIELD(assignmentConstrained); + READ_NODE_FIELD(taskExecution); + READ_BOOL_FIELD(upsertQuery); + READ_BOOL_FIELD(requiresMasterEvaluation); + + READ_DONE(); +} + +READFUNC_RET +ReadUnsupportedCitusNode(READFUNC_ARGS) +{ + ereport(ERROR, (errmsg("not implemented"))); +} + + +#if (PG_VERSION_NUM < 90600) + +/* + * readDatum + * + * Given a string representation of a constant, recreate the appropriate + * Datum. The string representation embeds length info, but not byValue, + * so we must be told that. + */ +Datum +readDatum(bool typbyval) +{ + Size length, + i; + int tokenLength; + char *token; + Datum res; + char *s; + + /* + * read the actual length of the value + */ + token = citus_pg_strtok(&tokenLength); + length = atoui(token); + + token = citus_pg_strtok(&tokenLength); /* read the '[' */ + if (token == NULL || token[0] != '[') + elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu", + token ? (const char *) token : "[NULL]", length); + + if (typbyval) + { + if (length > (Size) sizeof(Datum)) + elog(ERROR, "byval datum but length = %zu", length); + res = (Datum) 0; + s = (char *) (&res); + for (i = 0; i < (Size) sizeof(Datum); i++) + { + token = citus_pg_strtok(&tokenLength); + s[i] = (char) atoi(token); + } + } + else if (length <= 0) + res = (Datum) NULL; + else + { + s = (char *) palloc(length); + for (i = 0; i < length; i++) + { + token = citus_pg_strtok(&tokenLength); + s[i] = (char) atoi(token); + } + res = PointerGetDatum(s); + } + + token = citus_pg_strtok(&tokenLength); /* read the ']' */ + if (token == NULL || token[0] != ']') + elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu", + token ? (const char *) token : "[NULL]", length); + + return res; +} +#endif + + +#if (PG_VERSION_NUM >= 90600) + +/* *INDENT-ON* */ + +/* + * For 9.6+ we can just use the, now extensible, parseNodeString(). Before + * that citus_readfuncs_$ver.c has a version specific implementation. + */ +Node * +CitusParseNodeString(void) +{ + return parseNodeString(); +} + + +#endif diff --git a/src/backend/distributed/utils/citus_readfuncs_95.c b/src/backend/distributed/utils/citus_readfuncs_95.c index e0609f602..811074078 100644 --- a/src/backend/distributed/utils/citus_readfuncs_95.c +++ b/src/backend/distributed/utils/citus_readfuncs_95.c @@ -144,8 +144,6 @@ ((length) == 0 ? NULL : debackslash(token, length)) -static Datum readDatum(bool typbyval); - /* * _readBitmapset */ @@ -1368,216 +1366,6 @@ _readTableSampleClause(void) } -/* XXX: BEGIN Citus Nodes */ - -static void -_readJobInfo(Job *local_node) -{ - READ_TEMP_LOCALS(); - - READ_UINT64_FIELD(jobId); - READ_NODE_FIELD(jobQuery); - READ_NODE_FIELD(taskList); - READ_NODE_FIELD(dependedJobList); - READ_BOOL_FIELD(subqueryPushdown); -} - - -static Job * -_readJob(void) -{ - READ_LOCALS_NO_FIELDS(Job); - - _readJobInfo(local_node); - - READ_DONE(); -} - - -static MultiPlan * -_readMultiPlan(void) -{ - READ_LOCALS(MultiPlan); - - READ_NODE_FIELD(workerJob); - READ_NODE_FIELD(masterQuery); - READ_STRING_FIELD(masterTableName); - - READ_DONE(); -} - - -static ShardInterval * -_readShardInterval(void) -{ - READ_LOCALS(ShardInterval); - - - READ_OID_FIELD(relationId); - READ_CHAR_FIELD(storageType); - READ_OID_FIELD(valueTypeId); - READ_INT_FIELD(valueTypeLen); - READ_BOOL_FIELD(valueByVal); - READ_BOOL_FIELD(minValueExists); - READ_BOOL_FIELD(maxValueExists); - - token = citus_pg_strtok(&length); /* skip :minValue */ - if (!local_node->minValueExists) - token = citus_pg_strtok(&length); /* skip "<>" */ - else - local_node->minValue = readDatum(local_node->valueByVal); - - token = citus_pg_strtok(&length); /* skip :maxValue */ - if (!local_node->minValueExists) - token = citus_pg_strtok(&length); /* skip "<>" */ - else - local_node->maxValue = readDatum(local_node->valueByVal); - - READ_UINT64_FIELD(shardId); - - READ_DONE(); -} - - -static MapMergeJob * -_readMapMergeJob(void) -{ - int arrayLength; - int i; - - READ_LOCALS(MapMergeJob); - - _readJobInfo(&local_node->job); - - READ_NODE_FIELD(reduceQuery); - READ_ENUM_FIELD(partitionType, PartitionType); - READ_NODE_FIELD(partitionColumn); - READ_UINT_FIELD(partitionCount); - READ_INT_FIELD(sortedShardIntervalArrayLength); - - arrayLength = local_node->sortedShardIntervalArrayLength; - - /* now build & read sortedShardIntervalArray */ - local_node->sortedShardIntervalArray = - (ShardInterval**) palloc(arrayLength * sizeof(ShardInterval *)); - - for (i = 0; i < arrayLength; ++i) - { - local_node->sortedShardIntervalArray[i] = _readShardInterval(); - } - - READ_NODE_FIELD(mapTaskList); - READ_NODE_FIELD(mergeTaskList); - - READ_DONE(); -} - - -static ShardPlacement * -_readShardPlacement(void) -{ - READ_LOCALS(ShardPlacement); - - READ_UINT64_FIELD(placementId); - READ_UINT64_FIELD(shardId); - READ_UINT64_FIELD(shardLength); - READ_ENUM_FIELD(shardState, RelayFileState); - READ_STRING_FIELD(nodeName); - READ_UINT_FIELD(nodePort); - - READ_DONE(); -} - - -static Task * -_readTask(void) -{ - READ_LOCALS(Task); - - READ_ENUM_FIELD(taskType, TaskType); - READ_UINT64_FIELD(jobId); - READ_UINT_FIELD(taskId); - READ_STRING_FIELD(queryString); - READ_UINT64_FIELD(anchorShardId); - READ_NODE_FIELD(taskPlacementList); - READ_NODE_FIELD(dependedTaskList); - READ_UINT_FIELD(partitionId); - READ_UINT_FIELD(upstreamTaskId); - READ_NODE_FIELD(shardInterval); - READ_BOOL_FIELD(assignmentConstrained); - READ_NODE_FIELD(taskExecution); - READ_BOOL_FIELD(upsertQuery); - READ_BOOL_FIELD(requiresMasterEvaluation); - - READ_DONE(); -} - - -/* XXX: END Citus Nodes */ - - -/* - * readDatum - * - * Given a string representation of a constant, recreate the appropriate - * Datum. The string representation embeds length info, but not byValue, - * so we must be told that. - */ -static Datum -readDatum(bool typbyval) -{ - Size length, - i; - int tokenLength; - char *token; - Datum res; - char *s; - - /* - * read the actual length of the value - */ - token = citus_pg_strtok(&tokenLength); - length = atoui(token); - - token = citus_pg_strtok(&tokenLength); /* read the '[' */ - if (token == NULL || token[0] != '[') - elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu", - token ? (const char *) token : "[NULL]", length); - - if (typbyval) - { - if (length > (Size) sizeof(Datum)) - elog(ERROR, "byval datum but length = %zu", length); - res = (Datum) 0; - s = (char *) (&res); - for (i = 0; i < (Size) sizeof(Datum); i++) - { - token = citus_pg_strtok(&tokenLength); - s[i] = (char) atoi(token); - } - } - else if (length <= 0) - res = (Datum) NULL; - else - { - s = (char *) palloc(length); - for (i = 0; i < length; i++) - { - token = citus_pg_strtok(&tokenLength); - s[i] = (char) atoi(token); - } - res = PointerGetDatum(s); - } - - token = citus_pg_strtok(&tokenLength); /* read the ']' */ - if (token == NULL || token[0] != ']') - elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu", - token ? (const char *) token : "[NULL]", length); - - return res; -} - - /* * parseNodeString * @@ -1718,17 +1506,17 @@ CitusParseNodeString(void) return_value = _readDeclareCursorStmt(); /* XXX: BEGIN Citus Nodes */ else if (MATCH("MULTIPLAN", 9)) - return_value = _readMultiPlan(); + return_value = ReadMultiPlan(); else if (MATCH("JOB", 3)) - return_value = _readJob(); + return_value = ReadJob(); else if (MATCH("SHARDINTERVAL", 13)) - return_value = _readShardInterval(); + return_value = ReadShardInterval(); else if (MATCH("MAPMERGEJOB", 11)) - return_value = _readMapMergeJob(); + return_value = ReadMapMergeJob(); else if (MATCH("SHARDPLACEMENT", 14)) - return_value = _readShardPlacement(); + return_value = ReadShardPlacement(); else if (MATCH("TASK", 4)) - return_value = _readTask(); + return_value = ReadTask(); /* XXX: END Citus Nodes */ else { diff --git a/src/backend/distributed/utils/citus_readfuncs_96.c b/src/backend/distributed/utils/citus_readfuncs_96.c deleted file mode 100644 index 4c9946594..000000000 --- a/src/backend/distributed/utils/citus_readfuncs_96.c +++ /dev/null @@ -1,2808 +0,0 @@ -/*------------------------------------------------------------------------- - * - * citus_readfuncs.c - * Citus adapted reader functions for Citus & Postgres tree nodes - * - * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * Portions Copyright (c) 2012-2016, Citus Data, Inc. - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" - -#if (PG_VERSION_NUM >= 90600 && PG_VERSION_NUM < 90700) - -#include - -#include "fmgr.h" -#include "nodes/extensible.h" -#include "distributed/citus_nodefuncs.h" -#include "distributed/master_metadata_utility.h" -#include "distributed/multi_logical_planner.h" -#include "distributed/multi_physical_planner.h" -#include "nodes/parsenodes.h" -#include "nodes/plannodes.h" -#include "nodes/readfuncs.h" - - -/* - * Macros to simplify reading of different kinds of fields. Use these - * wherever possible to reduce the chance for silly typos. Note that these - * hard-wire conventions about the names of the local variables in a Read - * routine. - */ - -/* Macros for declaring appropriate local variables */ - -/* A few guys need only local_node */ -#define READ_LOCALS_NO_FIELDS(nodeTypeName) \ - nodeTypeName *local_node = CitusMakeNode(nodeTypeName) - -/* And a few guys need only the citus_pg_strtok support fields */ -#define READ_TEMP_LOCALS() \ - char *token; \ - int length - -/* ... but most need both */ -#define READ_LOCALS(nodeTypeName) \ - READ_LOCALS_NO_FIELDS(nodeTypeName); \ - READ_TEMP_LOCALS() - -/* Read an integer field (anything written as ":fldname %d") */ -#define READ_INT_FIELD(fldname) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - token = citus_pg_strtok(&length); /* get field value */ \ - local_node->fldname = atoi(token) - -/* Read an unsigned integer field (anything written as ":fldname %u") */ -#define READ_UINT_FIELD(fldname) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - token = citus_pg_strtok(&length); /* get field value */ \ - local_node->fldname = atoui(token) - -/* XXX: CITUS Read an uint64 field (anything written as ":fldname %u") */ -#define READ_UINT64_FIELD(fldname) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - token = citus_pg_strtok(&length); /* get field value */ \ - local_node->fldname = atoull(token) - -/* Read an long integer field (anything written as ":fldname %ld") */ -#define READ_LONG_FIELD(fldname) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - token = citus_pg_strtok(&length); /* get field value */ \ - local_node->fldname = atol(token) - -/* Read an OID field (don't hard-wire assumption that OID is same as uint) */ -#define READ_OID_FIELD(fldname) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - token = citus_pg_strtok(&length); /* get field value */ \ - local_node->fldname = atooid(token) - -/* Read a char field (ie, one ascii character) */ -#define READ_CHAR_FIELD(fldname) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - token = citus_pg_strtok(&length); /* get field value */ \ - local_node->fldname = token[0] - -/* Read an enumerated-type field that was written as an integer code */ -#define READ_ENUM_FIELD(fldname, enumtype) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - token = citus_pg_strtok(&length); /* get field value */ \ - local_node->fldname = (enumtype) atoi(token) - -/* Read a float field */ -#define READ_FLOAT_FIELD(fldname) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - token = citus_pg_strtok(&length); /* get field value */ \ - local_node->fldname = atof(token) - -/* Read a boolean field */ -#define READ_BOOL_FIELD(fldname) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - token = citus_pg_strtok(&length); /* get field value */ \ - local_node->fldname = strtobool(token) - -/* Read a character-string field */ -#define READ_STRING_FIELD(fldname) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - token = citus_pg_strtok(&length); /* get field value */ \ - local_node->fldname = nullable_string(token, length) - -/* Read a parse location field (and throw away the value, per notes above) */ -#define READ_LOCATION_FIELD(fldname) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - token = citus_pg_strtok(&length); /* get field value */ \ - (void) token; /* in case not used elsewhere */ \ - local_node->fldname = -1 /* set field to "unknown" */ - -/* Read a Node field XXX: Citus: replaced call to nodeRead with CitusNodeRead */ -/* Read a Node field */ -#define READ_NODE_FIELD(fldname) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - (void) token; /* in case not used elsewhere */ \ - local_node->fldname = CitusNodeRead(NULL, 0) - -/* Read a bitmapset field */ -#define READ_BITMAPSET_FIELD(fldname) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - (void) token; /* in case not used elsewhere */ \ - local_node->fldname = _readBitmapset() - -/* Read an attribute number array */ -#define READ_ATTRNUMBER_ARRAY(fldname, len) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - local_node->fldname = _readAttrNumberCols(len); - -/* Read an oid array */ -#define READ_OID_ARRAY(fldname, len) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - local_node->fldname = _readOidCols(len); - -/* Read an int array */ -#define READ_INT_ARRAY(fldname, len) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - local_node->fldname = _readIntCols(len); - -/* Read a bool array */ -#define READ_BOOL_ARRAY(fldname, len) \ - token = citus_pg_strtok(&length); /* skip :fldname */ \ - local_node->fldname = _readBoolCols(len); - -/* Routine exit */ -#define READ_DONE() \ - return local_node - - -/* - * NOTE: use atoi() to read values written with %d, or atoui() to read - * values written with %u in outfuncs.c. An exception is OID values, - * for which use atooid(). (As of 7.1, outfuncs.c writes OIDs as %u, - * but this will probably change in the future.) - */ -#define atoui(x) ((unsigned int) strtoul((x), NULL, 10)) - -#define atooid(x) ((Oid) strtoul((x), NULL, 10)) - -/* XXX: Citus */ -#define atoull(x) ((uint64) strtoull((x), NULL, 10)) - -#define strtobool(x) ((*(x) == 't') ? true : false) - -#define nullable_string(token,length) \ - ((length) == 0 ? NULL : debackslash(token, length)) - - -static Datum CitusReadDatum(bool typbyval); -static AttrNumber * _readAttrNumberCols(int numCols); -static Oid * _readOidCols(int numCols); -static int * _readIntCols(int numCols); -static bool * _readBoolCols(int numCols); - - -/* - * _readBitmapset - */ -static Bitmapset * -_readBitmapset(void) -{ - Bitmapset *result = NULL; - - READ_TEMP_LOCALS(); - - token = citus_pg_strtok(&length); - if (token == NULL) - elog(ERROR, "incomplete Bitmapset structure"); - if (length != 1 || token[0] != '(') - elog(ERROR, "unrecognized token: \"%.*s\"", length, token); - - token = citus_pg_strtok(&length); - if (token == NULL) - elog(ERROR, "incomplete Bitmapset structure"); - if (length != 1 || token[0] != 'b') - elog(ERROR, "unrecognized token: \"%.*s\"", length, token); - - for (;;) - { - int val; - char *endptr; - - token = citus_pg_strtok(&length); - if (token == NULL) - elog(ERROR, "unterminated Bitmapset structure"); - if (length == 1 && token[0] == ')') - break; - val = (int) strtol(token, &endptr, 10); - if (endptr != token + length) - elog(ERROR, "unrecognized integer: \"%.*s\"", length, token); - result = bms_add_member(result, val); - } - - return result; -} - -/* - * _readQuery - */ -static Query * -_readQuery(void) -{ - READ_LOCALS(Query); - - READ_ENUM_FIELD(commandType, CmdType); - READ_ENUM_FIELD(querySource, QuerySource); - local_node->queryId = 0; /* not saved in output format */ - READ_BOOL_FIELD(canSetTag); - READ_NODE_FIELD(utilityStmt); - READ_INT_FIELD(resultRelation); - READ_BOOL_FIELD(hasAggs); - READ_BOOL_FIELD(hasWindowFuncs); - READ_BOOL_FIELD(hasSubLinks); - READ_BOOL_FIELD(hasDistinctOn); - READ_BOOL_FIELD(hasRecursive); - READ_BOOL_FIELD(hasModifyingCTE); - READ_BOOL_FIELD(hasForUpdate); - READ_BOOL_FIELD(hasRowSecurity); - READ_NODE_FIELD(cteList); - READ_NODE_FIELD(rtable); - READ_NODE_FIELD(jointree); - READ_NODE_FIELD(targetList); - READ_NODE_FIELD(onConflict); - READ_NODE_FIELD(returningList); - READ_NODE_FIELD(groupClause); - READ_NODE_FIELD(groupingSets); - READ_NODE_FIELD(havingQual); - READ_NODE_FIELD(windowClause); - READ_NODE_FIELD(distinctClause); - READ_NODE_FIELD(sortClause); - READ_NODE_FIELD(limitOffset); - READ_NODE_FIELD(limitCount); - READ_NODE_FIELD(rowMarks); - READ_NODE_FIELD(setOperations); - READ_NODE_FIELD(constraintDeps); - - READ_DONE(); -} - -/* - * _readNotifyStmt - */ -static NotifyStmt * -_readNotifyStmt(void) -{ - READ_LOCALS(NotifyStmt); - - READ_STRING_FIELD(conditionname); - READ_STRING_FIELD(payload); - - READ_DONE(); -} - -/* - * _readDeclareCursorStmt - */ -static DeclareCursorStmt * -_readDeclareCursorStmt(void) -{ - READ_LOCALS(DeclareCursorStmt); - - READ_STRING_FIELD(portalname); - READ_INT_FIELD(options); - READ_NODE_FIELD(query); - - READ_DONE(); -} - -/* - * _readWithCheckOption - */ -static WithCheckOption * -_readWithCheckOption(void) -{ - READ_LOCALS(WithCheckOption); - - READ_ENUM_FIELD(kind, WCOKind); - READ_STRING_FIELD(relname); - READ_STRING_FIELD(polname); - READ_NODE_FIELD(qual); - READ_BOOL_FIELD(cascaded); - - READ_DONE(); -} - -/* - * _readSortGroupClause - */ -static SortGroupClause * -_readSortGroupClause(void) -{ - READ_LOCALS(SortGroupClause); - - READ_UINT_FIELD(tleSortGroupRef); - READ_OID_FIELD(eqop); - READ_OID_FIELD(sortop); - READ_BOOL_FIELD(nulls_first); - READ_BOOL_FIELD(hashable); - - READ_DONE(); -} - -/* - * _readGroupingSet - */ -static GroupingSet * -_readGroupingSet(void) -{ - READ_LOCALS(GroupingSet); - - READ_ENUM_FIELD(kind, GroupingSetKind); - READ_NODE_FIELD(content); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readWindowClause - */ -static WindowClause * -_readWindowClause(void) -{ - READ_LOCALS(WindowClause); - - READ_STRING_FIELD(name); - READ_STRING_FIELD(refname); - READ_NODE_FIELD(partitionClause); - READ_NODE_FIELD(orderClause); - READ_INT_FIELD(frameOptions); - READ_NODE_FIELD(startOffset); - READ_NODE_FIELD(endOffset); - READ_UINT_FIELD(winref); - READ_BOOL_FIELD(copiedOrder); - - READ_DONE(); -} - -/* - * _readRowMarkClause - */ -static RowMarkClause * -_readRowMarkClause(void) -{ - READ_LOCALS(RowMarkClause); - - READ_UINT_FIELD(rti); - READ_ENUM_FIELD(strength, LockClauseStrength); - READ_ENUM_FIELD(waitPolicy, LockWaitPolicy); - READ_BOOL_FIELD(pushedDown); - - READ_DONE(); -} - -/* - * _readCommonTableExpr - */ -static CommonTableExpr * -_readCommonTableExpr(void) -{ - READ_LOCALS(CommonTableExpr); - - READ_STRING_FIELD(ctename); - READ_NODE_FIELD(aliascolnames); - READ_NODE_FIELD(ctequery); - READ_LOCATION_FIELD(location); - READ_BOOL_FIELD(cterecursive); - READ_INT_FIELD(cterefcount); - READ_NODE_FIELD(ctecolnames); - READ_NODE_FIELD(ctecoltypes); - READ_NODE_FIELD(ctecoltypmods); - READ_NODE_FIELD(ctecolcollations); - - READ_DONE(); -} - -/* - * _readSetOperationStmt - */ -static SetOperationStmt * -_readSetOperationStmt(void) -{ - READ_LOCALS(SetOperationStmt); - - READ_ENUM_FIELD(op, SetOperation); - READ_BOOL_FIELD(all); - READ_NODE_FIELD(larg); - READ_NODE_FIELD(rarg); - READ_NODE_FIELD(colTypes); - READ_NODE_FIELD(colTypmods); - READ_NODE_FIELD(colCollations); - READ_NODE_FIELD(groupClauses); - - READ_DONE(); -} - - -/* - * Stuff from primnodes.h. - */ - -static Alias * -_readAlias(void) -{ - READ_LOCALS(Alias); - - READ_STRING_FIELD(aliasname); - READ_NODE_FIELD(colnames); - - READ_DONE(); -} - -static RangeVar * -_readRangeVar(void) -{ - READ_LOCALS(RangeVar); - - local_node->catalogname = NULL; /* not currently saved in output - * format */ - - READ_STRING_FIELD(schemaname); - READ_STRING_FIELD(relname); - READ_ENUM_FIELD(inhOpt, InhOption); - READ_CHAR_FIELD(relpersistence); - READ_NODE_FIELD(alias); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -static IntoClause * -_readIntoClause(void) -{ - READ_LOCALS(IntoClause); - - READ_NODE_FIELD(rel); - READ_NODE_FIELD(colNames); - READ_NODE_FIELD(options); - READ_ENUM_FIELD(onCommit, OnCommitAction); - READ_STRING_FIELD(tableSpaceName); - READ_NODE_FIELD(viewQuery); - READ_BOOL_FIELD(skipData); - - READ_DONE(); -} - -/* - * _readVar - */ -static Var * -_readVar(void) -{ - READ_LOCALS(Var); - - READ_UINT_FIELD(varno); - READ_INT_FIELD(varattno); - READ_OID_FIELD(vartype); - READ_INT_FIELD(vartypmod); - READ_OID_FIELD(varcollid); - READ_UINT_FIELD(varlevelsup); - READ_UINT_FIELD(varnoold); - READ_INT_FIELD(varoattno); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readConst - */ -static Const * -_readConst(void) -{ - READ_LOCALS(Const); - - READ_OID_FIELD(consttype); - READ_INT_FIELD(consttypmod); - READ_OID_FIELD(constcollid); - READ_INT_FIELD(constlen); - READ_BOOL_FIELD(constbyval); - READ_BOOL_FIELD(constisnull); - READ_LOCATION_FIELD(location); - - token = citus_pg_strtok(&length); /* skip :constvalue */ - if (local_node->constisnull) - token = citus_pg_strtok(&length); /* skip "<>" */ - else - local_node->constvalue = CitusReadDatum(local_node->constbyval); - - READ_DONE(); -} - -/* - * _readParam - */ -static Param * -_readParam(void) -{ - READ_LOCALS(Param); - - READ_ENUM_FIELD(paramkind, ParamKind); - READ_INT_FIELD(paramid); - READ_OID_FIELD(paramtype); - READ_INT_FIELD(paramtypmod); - READ_OID_FIELD(paramcollid); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readAggref - */ -static Aggref * -_readAggref(void) -{ - READ_LOCALS(Aggref); - - READ_OID_FIELD(aggfnoid); - READ_OID_FIELD(aggtype); - READ_OID_FIELD(aggcollid); - READ_OID_FIELD(inputcollid); - READ_OID_FIELD(aggtranstype); - READ_NODE_FIELD(aggargtypes); - READ_NODE_FIELD(aggdirectargs); - READ_NODE_FIELD(args); - READ_NODE_FIELD(aggorder); - READ_NODE_FIELD(aggdistinct); - READ_NODE_FIELD(aggfilter); - READ_BOOL_FIELD(aggstar); - READ_BOOL_FIELD(aggvariadic); - READ_CHAR_FIELD(aggkind); - READ_UINT_FIELD(agglevelsup); - READ_ENUM_FIELD(aggsplit, AggSplit); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readGroupingFunc - */ -static GroupingFunc * -_readGroupingFunc(void) -{ - READ_LOCALS(GroupingFunc); - - READ_NODE_FIELD(args); - READ_NODE_FIELD(refs); - READ_NODE_FIELD(cols); - READ_UINT_FIELD(agglevelsup); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readWindowFunc - */ -static WindowFunc * -_readWindowFunc(void) -{ - READ_LOCALS(WindowFunc); - - READ_OID_FIELD(winfnoid); - READ_OID_FIELD(wintype); - READ_OID_FIELD(wincollid); - READ_OID_FIELD(inputcollid); - READ_NODE_FIELD(args); - READ_NODE_FIELD(aggfilter); - READ_UINT_FIELD(winref); - READ_BOOL_FIELD(winstar); - READ_BOOL_FIELD(winagg); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readArrayRef - */ -static ArrayRef * -_readArrayRef(void) -{ - READ_LOCALS(ArrayRef); - - READ_OID_FIELD(refarraytype); - READ_OID_FIELD(refelemtype); - READ_INT_FIELD(reftypmod); - READ_OID_FIELD(refcollid); - READ_NODE_FIELD(refupperindexpr); - READ_NODE_FIELD(reflowerindexpr); - READ_NODE_FIELD(refexpr); - READ_NODE_FIELD(refassgnexpr); - - READ_DONE(); -} - -/* - * _readFuncExpr - */ -static FuncExpr * -_readFuncExpr(void) -{ - READ_LOCALS(FuncExpr); - - READ_OID_FIELD(funcid); - READ_OID_FIELD(funcresulttype); - READ_BOOL_FIELD(funcretset); - READ_BOOL_FIELD(funcvariadic); - READ_ENUM_FIELD(funcformat, CoercionForm); - READ_OID_FIELD(funccollid); - READ_OID_FIELD(inputcollid); - READ_NODE_FIELD(args); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readNamedArgExpr - */ -static NamedArgExpr * -_readNamedArgExpr(void) -{ - READ_LOCALS(NamedArgExpr); - - READ_NODE_FIELD(arg); - READ_STRING_FIELD(name); - READ_INT_FIELD(argnumber); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readOpExpr - */ -static OpExpr * -_readOpExpr(void) -{ - READ_LOCALS(OpExpr); - - READ_OID_FIELD(opno); - READ_OID_FIELD(opfuncid); - READ_OID_FIELD(opresulttype); - READ_BOOL_FIELD(opretset); - READ_OID_FIELD(opcollid); - READ_OID_FIELD(inputcollid); - READ_NODE_FIELD(args); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readDistinctExpr - */ -static DistinctExpr * -_readDistinctExpr(void) -{ - READ_LOCALS(DistinctExpr); - - READ_OID_FIELD(opno); - READ_OID_FIELD(opfuncid); - READ_OID_FIELD(opresulttype); - READ_BOOL_FIELD(opretset); - READ_OID_FIELD(opcollid); - READ_OID_FIELD(inputcollid); - READ_NODE_FIELD(args); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readNullIfExpr - */ -static NullIfExpr * -_readNullIfExpr(void) -{ - READ_LOCALS(NullIfExpr); - - READ_OID_FIELD(opno); - READ_OID_FIELD(opfuncid); - READ_OID_FIELD(opresulttype); - READ_BOOL_FIELD(opretset); - READ_OID_FIELD(opcollid); - READ_OID_FIELD(inputcollid); - READ_NODE_FIELD(args); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readScalarArrayOpExpr - */ -static ScalarArrayOpExpr * -_readScalarArrayOpExpr(void) -{ - READ_LOCALS(ScalarArrayOpExpr); - - READ_OID_FIELD(opno); - READ_OID_FIELD(opfuncid); - READ_BOOL_FIELD(useOr); - READ_OID_FIELD(inputcollid); - READ_NODE_FIELD(args); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readBoolExpr - */ -static BoolExpr * -_readBoolExpr(void) -{ - READ_LOCALS(BoolExpr); - - /* do-it-yourself enum representation */ - token = citus_pg_strtok(&length); /* skip :boolop */ - token = citus_pg_strtok(&length); /* get field value */ - if (strncmp(token, "and", 3) == 0) - local_node->boolop = AND_EXPR; - else if (strncmp(token, "or", 2) == 0) - local_node->boolop = OR_EXPR; - else if (strncmp(token, "not", 3) == 0) - local_node->boolop = NOT_EXPR; - else - elog(ERROR, "unrecognized boolop \"%.*s\"", length, token); - - READ_NODE_FIELD(args); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readSubLink - */ -static SubLink * -_readSubLink(void) -{ - READ_LOCALS(SubLink); - - READ_ENUM_FIELD(subLinkType, SubLinkType); - READ_INT_FIELD(subLinkId); - READ_NODE_FIELD(testexpr); - READ_NODE_FIELD(operName); - READ_NODE_FIELD(subselect); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readSubPlan is not needed since it doesn't appear in stored rules. - */ - -/* - * _readFieldSelect - */ -static FieldSelect * -_readFieldSelect(void) -{ - READ_LOCALS(FieldSelect); - - READ_NODE_FIELD(arg); - READ_INT_FIELD(fieldnum); - READ_OID_FIELD(resulttype); - READ_INT_FIELD(resulttypmod); - READ_OID_FIELD(resultcollid); - - READ_DONE(); -} - -/* - * _readFieldStore - */ -static FieldStore * -_readFieldStore(void) -{ - READ_LOCALS(FieldStore); - - READ_NODE_FIELD(arg); - READ_NODE_FIELD(newvals); - READ_NODE_FIELD(fieldnums); - READ_OID_FIELD(resulttype); - - READ_DONE(); -} - -/* - * _readRelabelType - */ -static RelabelType * -_readRelabelType(void) -{ - READ_LOCALS(RelabelType); - - READ_NODE_FIELD(arg); - READ_OID_FIELD(resulttype); - READ_INT_FIELD(resulttypmod); - READ_OID_FIELD(resultcollid); - READ_ENUM_FIELD(relabelformat, CoercionForm); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readCoerceViaIO - */ -static CoerceViaIO * -_readCoerceViaIO(void) -{ - READ_LOCALS(CoerceViaIO); - - READ_NODE_FIELD(arg); - READ_OID_FIELD(resulttype); - READ_OID_FIELD(resultcollid); - READ_ENUM_FIELD(coerceformat, CoercionForm); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readArrayCoerceExpr - */ -static ArrayCoerceExpr * -_readArrayCoerceExpr(void) -{ - READ_LOCALS(ArrayCoerceExpr); - - READ_NODE_FIELD(arg); - READ_OID_FIELD(elemfuncid); - READ_OID_FIELD(resulttype); - READ_INT_FIELD(resulttypmod); - READ_OID_FIELD(resultcollid); - READ_BOOL_FIELD(isExplicit); - READ_ENUM_FIELD(coerceformat, CoercionForm); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readConvertRowtypeExpr - */ -static ConvertRowtypeExpr * -_readConvertRowtypeExpr(void) -{ - READ_LOCALS(ConvertRowtypeExpr); - - READ_NODE_FIELD(arg); - READ_OID_FIELD(resulttype); - READ_ENUM_FIELD(convertformat, CoercionForm); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readCollateExpr - */ -static CollateExpr * -_readCollateExpr(void) -{ - READ_LOCALS(CollateExpr); - - READ_NODE_FIELD(arg); - READ_OID_FIELD(collOid); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readCaseExpr - */ -static CaseExpr * -_readCaseExpr(void) -{ - READ_LOCALS(CaseExpr); - - READ_OID_FIELD(casetype); - READ_OID_FIELD(casecollid); - READ_NODE_FIELD(arg); - READ_NODE_FIELD(args); - READ_NODE_FIELD(defresult); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readCaseWhen - */ -static CaseWhen * -_readCaseWhen(void) -{ - READ_LOCALS(CaseWhen); - - READ_NODE_FIELD(expr); - READ_NODE_FIELD(result); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readCaseTestExpr - */ -static CaseTestExpr * -_readCaseTestExpr(void) -{ - READ_LOCALS(CaseTestExpr); - - READ_OID_FIELD(typeId); - READ_INT_FIELD(typeMod); - READ_OID_FIELD(collation); - - READ_DONE(); -} - -/* - * _readArrayExpr - */ -static ArrayExpr * -_readArrayExpr(void) -{ - READ_LOCALS(ArrayExpr); - - READ_OID_FIELD(array_typeid); - READ_OID_FIELD(array_collid); - READ_OID_FIELD(element_typeid); - READ_NODE_FIELD(elements); - READ_BOOL_FIELD(multidims); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readRowExpr - */ -static RowExpr * -_readRowExpr(void) -{ - READ_LOCALS(RowExpr); - - READ_NODE_FIELD(args); - READ_OID_FIELD(row_typeid); - READ_ENUM_FIELD(row_format, CoercionForm); - READ_NODE_FIELD(colnames); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readRowCompareExpr - */ -static RowCompareExpr * -_readRowCompareExpr(void) -{ - READ_LOCALS(RowCompareExpr); - - READ_ENUM_FIELD(rctype, RowCompareType); - READ_NODE_FIELD(opnos); - READ_NODE_FIELD(opfamilies); - READ_NODE_FIELD(inputcollids); - READ_NODE_FIELD(largs); - READ_NODE_FIELD(rargs); - - READ_DONE(); -} - -/* - * _readCoalesceExpr - */ -static CoalesceExpr * -_readCoalesceExpr(void) -{ - READ_LOCALS(CoalesceExpr); - - READ_OID_FIELD(coalescetype); - READ_OID_FIELD(coalescecollid); - READ_NODE_FIELD(args); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readMinMaxExpr - */ -static MinMaxExpr * -_readMinMaxExpr(void) -{ - READ_LOCALS(MinMaxExpr); - - READ_OID_FIELD(minmaxtype); - READ_OID_FIELD(minmaxcollid); - READ_OID_FIELD(inputcollid); - READ_ENUM_FIELD(op, MinMaxOp); - READ_NODE_FIELD(args); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readXmlExpr - */ -static XmlExpr * -_readXmlExpr(void) -{ - READ_LOCALS(XmlExpr); - - READ_ENUM_FIELD(op, XmlExprOp); - READ_STRING_FIELD(name); - READ_NODE_FIELD(named_args); - READ_NODE_FIELD(arg_names); - READ_NODE_FIELD(args); - READ_ENUM_FIELD(xmloption, XmlOptionType); - READ_OID_FIELD(type); - READ_INT_FIELD(typmod); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readNullTest - */ -static NullTest * -_readNullTest(void) -{ - READ_LOCALS(NullTest); - - READ_NODE_FIELD(arg); - READ_ENUM_FIELD(nulltesttype, NullTestType); - READ_BOOL_FIELD(argisrow); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readBooleanTest - */ -static BooleanTest * -_readBooleanTest(void) -{ - READ_LOCALS(BooleanTest); - - READ_NODE_FIELD(arg); - READ_ENUM_FIELD(booltesttype, BoolTestType); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readCoerceToDomain - */ -static CoerceToDomain * -_readCoerceToDomain(void) -{ - READ_LOCALS(CoerceToDomain); - - READ_NODE_FIELD(arg); - READ_OID_FIELD(resulttype); - READ_INT_FIELD(resulttypmod); - READ_OID_FIELD(resultcollid); - READ_ENUM_FIELD(coercionformat, CoercionForm); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readCoerceToDomainValue - */ -static CoerceToDomainValue * -_readCoerceToDomainValue(void) -{ - READ_LOCALS(CoerceToDomainValue); - - READ_OID_FIELD(typeId); - READ_INT_FIELD(typeMod); - READ_OID_FIELD(collation); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readSetToDefault - */ -static SetToDefault * -_readSetToDefault(void) -{ - READ_LOCALS(SetToDefault); - - READ_OID_FIELD(typeId); - READ_INT_FIELD(typeMod); - READ_OID_FIELD(collation); - READ_LOCATION_FIELD(location); - - READ_DONE(); -} - -/* - * _readCurrentOfExpr - */ -static CurrentOfExpr * -_readCurrentOfExpr(void) -{ - READ_LOCALS(CurrentOfExpr); - - READ_UINT_FIELD(cvarno); - READ_STRING_FIELD(cursor_name); - READ_INT_FIELD(cursor_param); - - READ_DONE(); -} - -/* - * _readInferenceElem - */ -static InferenceElem * -_readInferenceElem(void) -{ - READ_LOCALS(InferenceElem); - - READ_NODE_FIELD(expr); - READ_OID_FIELD(infercollid); - READ_OID_FIELD(inferopclass); - - READ_DONE(); -} - -/* - * _readTargetEntry - */ -static TargetEntry * -_readTargetEntry(void) -{ - READ_LOCALS(TargetEntry); - - READ_NODE_FIELD(expr); - READ_INT_FIELD(resno); - READ_STRING_FIELD(resname); - READ_UINT_FIELD(ressortgroupref); - READ_OID_FIELD(resorigtbl); - READ_INT_FIELD(resorigcol); - READ_BOOL_FIELD(resjunk); - - READ_DONE(); -} - -/* - * _readRangeTblRef - */ -static RangeTblRef * -_readRangeTblRef(void) -{ - READ_LOCALS(RangeTblRef); - - READ_INT_FIELD(rtindex); - - READ_DONE(); -} - -/* - * _readJoinExpr - */ -static JoinExpr * -_readJoinExpr(void) -{ - READ_LOCALS(JoinExpr); - - READ_ENUM_FIELD(jointype, JoinType); - READ_BOOL_FIELD(isNatural); - READ_NODE_FIELD(larg); - READ_NODE_FIELD(rarg); - READ_NODE_FIELD(usingClause); - READ_NODE_FIELD(quals); - READ_NODE_FIELD(alias); - READ_INT_FIELD(rtindex); - - READ_DONE(); -} - -/* - * _readFromExpr - */ -static FromExpr * -_readFromExpr(void) -{ - READ_LOCALS(FromExpr); - - READ_NODE_FIELD(fromlist); - READ_NODE_FIELD(quals); - - READ_DONE(); -} - -/* - * _readOnConflictExpr - */ -static OnConflictExpr * -_readOnConflictExpr(void) -{ - READ_LOCALS(OnConflictExpr); - - READ_ENUM_FIELD(action, OnConflictAction); - READ_NODE_FIELD(arbiterElems); - READ_NODE_FIELD(arbiterWhere); - READ_OID_FIELD(constraint); - READ_NODE_FIELD(onConflictSet); - READ_NODE_FIELD(onConflictWhere); - READ_INT_FIELD(exclRelIndex); - READ_NODE_FIELD(exclRelTlist); - - READ_DONE(); -} - -/* - * Stuff from parsenodes.h. - */ - -/* - * _readRangeTblEntry - */ -static RangeTblEntry * -_readRangeTblEntry(void) -{ - READ_LOCALS(RangeTblEntry); - - /* put alias + eref first to make dump more legible */ - READ_NODE_FIELD(alias); - READ_NODE_FIELD(eref); - READ_ENUM_FIELD(rtekind, RTEKind); - - switch (local_node->rtekind) - { - case RTE_RELATION: - READ_OID_FIELD(relid); - READ_CHAR_FIELD(relkind); - READ_NODE_FIELD(tablesample); - break; - case RTE_SUBQUERY: - READ_NODE_FIELD(subquery); - READ_BOOL_FIELD(security_barrier); - break; - case RTE_JOIN: - READ_ENUM_FIELD(jointype, JoinType); - READ_NODE_FIELD(joinaliasvars); - break; - case RTE_FUNCTION: - READ_NODE_FIELD(functions); - READ_BOOL_FIELD(funcordinality); - break; - case RTE_VALUES: - READ_NODE_FIELD(values_lists); - READ_NODE_FIELD(values_collations); - break; - case RTE_CTE: - READ_STRING_FIELD(ctename); - READ_UINT_FIELD(ctelevelsup); - READ_BOOL_FIELD(self_reference); - READ_NODE_FIELD(ctecoltypes); - READ_NODE_FIELD(ctecoltypmods); - READ_NODE_FIELD(ctecolcollations); - break; - default: - elog(ERROR, "unrecognized RTE kind: %d", - (int) local_node->rtekind); - break; - } - - READ_BOOL_FIELD(lateral); - READ_BOOL_FIELD(inh); - READ_BOOL_FIELD(inFromCl); - READ_UINT_FIELD(requiredPerms); - READ_OID_FIELD(checkAsUser); - READ_BITMAPSET_FIELD(selectedCols); - READ_BITMAPSET_FIELD(insertedCols); - READ_BITMAPSET_FIELD(updatedCols); - READ_NODE_FIELD(securityQuals); - - READ_DONE(); -} - -/* - * _readRangeTblFunction - */ -static RangeTblFunction * -_readRangeTblFunction(void) -{ - READ_LOCALS(RangeTblFunction); - - READ_NODE_FIELD(funcexpr); - READ_INT_FIELD(funccolcount); - READ_NODE_FIELD(funccolnames); - READ_NODE_FIELD(funccoltypes); - READ_NODE_FIELD(funccoltypmods); - READ_NODE_FIELD(funccolcollations); - READ_BITMAPSET_FIELD(funcparams); - - READ_DONE(); -} - -/* - * _readTableSampleClause - */ -static TableSampleClause * -_readTableSampleClause(void) -{ - READ_LOCALS(TableSampleClause); - - READ_OID_FIELD(tsmhandler); - READ_NODE_FIELD(args); - READ_NODE_FIELD(repeatable); - - READ_DONE(); -} - -/* - * _readDefElem - */ -static DefElem * -_readDefElem(void) -{ - READ_LOCALS(DefElem); - - READ_STRING_FIELD(defnamespace); - READ_STRING_FIELD(defname); - READ_NODE_FIELD(arg); - READ_ENUM_FIELD(defaction, DefElemAction); - - READ_DONE(); -} - -/* - * _readPlannedStmt - */ -static PlannedStmt * -_readPlannedStmt(void) -{ - READ_LOCALS(PlannedStmt); - - READ_ENUM_FIELD(commandType, CmdType); - READ_UINT_FIELD(queryId); - READ_BOOL_FIELD(hasReturning); - READ_BOOL_FIELD(hasModifyingCTE); - READ_BOOL_FIELD(canSetTag); - READ_BOOL_FIELD(transientPlan); - READ_BOOL_FIELD(dependsOnRole); - READ_BOOL_FIELD(parallelModeNeeded); - READ_NODE_FIELD(planTree); - READ_NODE_FIELD(rtable); - READ_NODE_FIELD(resultRelations); - READ_NODE_FIELD(utilityStmt); - READ_NODE_FIELD(subplans); - READ_BITMAPSET_FIELD(rewindPlanIDs); - READ_NODE_FIELD(rowMarks); - READ_NODE_FIELD(relationOids); - READ_NODE_FIELD(invalItems); - READ_INT_FIELD(nParamExec); - - READ_DONE(); -} - -/* - * ReadCommonPlan - * Assign the basic stuff of all nodes that inherit from Plan - */ -static void -ReadCommonPlan(Plan *local_node) -{ - READ_TEMP_LOCALS(); - - READ_FLOAT_FIELD(startup_cost); - READ_FLOAT_FIELD(total_cost); - READ_FLOAT_FIELD(plan_rows); - READ_INT_FIELD(plan_width); - READ_BOOL_FIELD(parallel_aware); - READ_INT_FIELD(plan_node_id); - READ_NODE_FIELD(targetlist); - READ_NODE_FIELD(qual); - READ_NODE_FIELD(lefttree); - READ_NODE_FIELD(righttree); - READ_NODE_FIELD(initPlan); - READ_BITMAPSET_FIELD(extParam); - READ_BITMAPSET_FIELD(allParam); -} - -/* - * _readPlan - */ -static Plan * -_readPlan(void) -{ - READ_LOCALS_NO_FIELDS(Plan); - - ReadCommonPlan(local_node); - - READ_DONE(); -} - -/* - * _readResult - */ -static Result * -_readResult(void) -{ - READ_LOCALS(Result); - - ReadCommonPlan(&local_node->plan); - - READ_NODE_FIELD(resconstantqual); - - READ_DONE(); -} - -/* - * _readModifyTable - */ -static ModifyTable * -_readModifyTable(void) -{ - READ_LOCALS(ModifyTable); - - ReadCommonPlan(&local_node->plan); - - READ_ENUM_FIELD(operation, CmdType); - READ_BOOL_FIELD(canSetTag); - READ_UINT_FIELD(nominalRelation); - READ_NODE_FIELD(resultRelations); - READ_INT_FIELD(resultRelIndex); - READ_NODE_FIELD(plans); - READ_NODE_FIELD(withCheckOptionLists); - READ_NODE_FIELD(returningLists); - READ_NODE_FIELD(fdwPrivLists); - READ_BITMAPSET_FIELD(fdwDirectModifyPlans); - READ_NODE_FIELD(rowMarks); - READ_INT_FIELD(epqParam); - READ_ENUM_FIELD(onConflictAction, OnConflictAction); - READ_NODE_FIELD(arbiterIndexes); - READ_NODE_FIELD(onConflictSet); - READ_NODE_FIELD(onConflictWhere); - READ_UINT_FIELD(exclRelRTI); - READ_NODE_FIELD(exclRelTlist); - - READ_DONE(); -} - -/* - * _readAppend - */ -static Append * -_readAppend(void) -{ - READ_LOCALS(Append); - - ReadCommonPlan(&local_node->plan); - - READ_NODE_FIELD(appendplans); - - READ_DONE(); -} - -/* - * _readMergeAppend - */ -static MergeAppend * -_readMergeAppend(void) -{ - READ_LOCALS(MergeAppend); - - ReadCommonPlan(&local_node->plan); - - READ_NODE_FIELD(mergeplans); - READ_INT_FIELD(numCols); - READ_ATTRNUMBER_ARRAY(sortColIdx, local_node->numCols); - READ_OID_ARRAY(sortOperators, local_node->numCols); - READ_OID_ARRAY(collations, local_node->numCols); - READ_BOOL_ARRAY(nullsFirst, local_node->numCols); - - READ_DONE(); -} - -/* - * _readRecursiveUnion - */ -static RecursiveUnion * -_readRecursiveUnion(void) -{ - READ_LOCALS(RecursiveUnion); - - ReadCommonPlan(&local_node->plan); - - READ_INT_FIELD(wtParam); - READ_INT_FIELD(numCols); - READ_ATTRNUMBER_ARRAY(dupColIdx, local_node->numCols); - READ_OID_ARRAY(dupOperators, local_node->numCols); - READ_LONG_FIELD(numGroups); - - READ_DONE(); -} - -/* - * _readBitmapAnd - */ -static BitmapAnd * -_readBitmapAnd(void) -{ - READ_LOCALS(BitmapAnd); - - ReadCommonPlan(&local_node->plan); - - READ_NODE_FIELD(bitmapplans); - - READ_DONE(); -} - -/* - * _readBitmapOr - */ -static BitmapOr * -_readBitmapOr(void) -{ - READ_LOCALS(BitmapOr); - - ReadCommonPlan(&local_node->plan); - - READ_NODE_FIELD(bitmapplans); - - READ_DONE(); -} - -/* - * ReadCommonScan - * Assign the basic stuff of all nodes that inherit from Scan - */ -static void -ReadCommonScan(Scan *local_node) -{ - READ_TEMP_LOCALS(); - - ReadCommonPlan(&local_node->plan); - - READ_UINT_FIELD(scanrelid); -} - -/* - * _readScan - */ -static Scan * -_readScan(void) -{ - READ_LOCALS_NO_FIELDS(Scan); - - ReadCommonScan(local_node); - - READ_DONE(); -} - -/* - * _readSeqScan - */ -static SeqScan * -_readSeqScan(void) -{ - READ_LOCALS_NO_FIELDS(SeqScan); - - ReadCommonScan(local_node); - - READ_DONE(); -} - -/* - * _readSampleScan - */ -static SampleScan * -_readSampleScan(void) -{ - READ_LOCALS(SampleScan); - - ReadCommonScan(&local_node->scan); - - READ_NODE_FIELD(tablesample); - - READ_DONE(); -} - -/* - * _readIndexScan - */ -static IndexScan * -_readIndexScan(void) -{ - READ_LOCALS(IndexScan); - - ReadCommonScan(&local_node->scan); - - READ_OID_FIELD(indexid); - READ_NODE_FIELD(indexqual); - READ_NODE_FIELD(indexqualorig); - READ_NODE_FIELD(indexorderby); - READ_NODE_FIELD(indexorderbyorig); - READ_NODE_FIELD(indexorderbyops); - READ_ENUM_FIELD(indexorderdir, ScanDirection); - - READ_DONE(); -} - -/* - * _readIndexOnlyScan - */ -static IndexOnlyScan * -_readIndexOnlyScan(void) -{ - READ_LOCALS(IndexOnlyScan); - - ReadCommonScan(&local_node->scan); - - READ_OID_FIELD(indexid); - READ_NODE_FIELD(indexqual); - READ_NODE_FIELD(indexorderby); - READ_NODE_FIELD(indextlist); - READ_ENUM_FIELD(indexorderdir, ScanDirection); - - READ_DONE(); -} - -/* - * _readBitmapIndexScan - */ -static BitmapIndexScan * -_readBitmapIndexScan(void) -{ - READ_LOCALS(BitmapIndexScan); - - ReadCommonScan(&local_node->scan); - - READ_OID_FIELD(indexid); - READ_NODE_FIELD(indexqual); - READ_NODE_FIELD(indexqualorig); - - READ_DONE(); -} - -/* - * _readBitmapHeapScan - */ -static BitmapHeapScan * -_readBitmapHeapScan(void) -{ - READ_LOCALS(BitmapHeapScan); - - ReadCommonScan(&local_node->scan); - - READ_NODE_FIELD(bitmapqualorig); - - READ_DONE(); -} - -/* - * _readTidScan - */ -static TidScan * -_readTidScan(void) -{ - READ_LOCALS(TidScan); - - ReadCommonScan(&local_node->scan); - - READ_NODE_FIELD(tidquals); - - READ_DONE(); -} - -/* - * _readSubqueryScan - */ -static SubqueryScan * -_readSubqueryScan(void) -{ - READ_LOCALS(SubqueryScan); - - ReadCommonScan(&local_node->scan); - - READ_NODE_FIELD(subplan); - - READ_DONE(); -} - -/* - * _readFunctionScan - */ -static FunctionScan * -_readFunctionScan(void) -{ - READ_LOCALS(FunctionScan); - - ReadCommonScan(&local_node->scan); - - READ_NODE_FIELD(functions); - READ_BOOL_FIELD(funcordinality); - - READ_DONE(); -} - -/* - * _readValuesScan - */ -static ValuesScan * -_readValuesScan(void) -{ - READ_LOCALS(ValuesScan); - - ReadCommonScan(&local_node->scan); - - READ_NODE_FIELD(values_lists); - - READ_DONE(); -} - -/* - * _readCteScan - */ -static CteScan * -_readCteScan(void) -{ - READ_LOCALS(CteScan); - - ReadCommonScan(&local_node->scan); - - READ_INT_FIELD(ctePlanId); - READ_INT_FIELD(cteParam); - - READ_DONE(); -} - -/* - * _readWorkTableScan - */ -static WorkTableScan * -_readWorkTableScan(void) -{ - READ_LOCALS(WorkTableScan); - - ReadCommonScan(&local_node->scan); - - READ_INT_FIELD(wtParam); - - READ_DONE(); -} - -/* - * _readForeignScan - */ -static ForeignScan * -_readForeignScan(void) -{ - READ_LOCALS(ForeignScan); - - ReadCommonScan(&local_node->scan); - - READ_ENUM_FIELD(operation, CmdType); - READ_OID_FIELD(fs_server); - READ_NODE_FIELD(fdw_exprs); - READ_NODE_FIELD(fdw_private); - READ_NODE_FIELD(fdw_scan_tlist); - READ_NODE_FIELD(fdw_recheck_quals); - READ_BITMAPSET_FIELD(fs_relids); - READ_BOOL_FIELD(fsSystemCol); - - READ_DONE(); -} - -/* - * _readCustomScan - */ -static CustomScan * -_readCustomScan(void) -{ - READ_LOCALS(CustomScan); - char *custom_name; - const CustomScanMethods *methods; - - ReadCommonScan(&local_node->scan); - - READ_UINT_FIELD(flags); - READ_NODE_FIELD(custom_plans); - READ_NODE_FIELD(custom_exprs); - READ_NODE_FIELD(custom_private); - READ_NODE_FIELD(custom_scan_tlist); - READ_BITMAPSET_FIELD(custom_relids); - - /* Lookup CustomScanMethods by CustomName */ - token = citus_pg_strtok(&length); /* skip methods: */ - token = citus_pg_strtok(&length); /* CustomName */ - custom_name = nullable_string(token, length); - methods = GetCustomScanMethods(custom_name, false); - local_node->methods = methods; - - READ_DONE(); -} - -/* - * ReadCommonJoin - * Assign the basic stuff of all nodes that inherit from Join - */ -static void -ReadCommonJoin(Join *local_node) -{ - READ_TEMP_LOCALS(); - - ReadCommonPlan(&local_node->plan); - - READ_ENUM_FIELD(jointype, JoinType); - READ_NODE_FIELD(joinqual); -} - -/* - * _readJoin - */ -static Join * -_readJoin(void) -{ - READ_LOCALS_NO_FIELDS(Join); - - ReadCommonJoin(local_node); - - READ_DONE(); -} - -/* - * _readNestLoop - */ -static NestLoop * -_readNestLoop(void) -{ - READ_LOCALS(NestLoop); - - ReadCommonJoin(&local_node->join); - - READ_NODE_FIELD(nestParams); - - READ_DONE(); -} - -/* - * _readMergeJoin - */ -static MergeJoin * -_readMergeJoin(void) -{ - int numCols; - - READ_LOCALS(MergeJoin); - - ReadCommonJoin(&local_node->join); - - READ_NODE_FIELD(mergeclauses); - - numCols = list_length(local_node->mergeclauses); - - READ_OID_ARRAY(mergeFamilies, numCols); - READ_OID_ARRAY(mergeCollations, numCols); - READ_INT_ARRAY(mergeStrategies, numCols); - READ_BOOL_ARRAY(mergeNullsFirst, numCols); - - READ_DONE(); -} - -/* - * _readHashJoin - */ -static HashJoin * -_readHashJoin(void) -{ - READ_LOCALS(HashJoin); - - ReadCommonJoin(&local_node->join); - - READ_NODE_FIELD(hashclauses); - - READ_DONE(); -} - -/* - * _readMaterial - */ -static Material * -_readMaterial(void) -{ - READ_LOCALS_NO_FIELDS(Material); - - ReadCommonPlan(&local_node->plan); - - READ_DONE(); -} - -/* - * _readSort - */ -static Sort * -_readSort(void) -{ - READ_LOCALS(Sort); - - ReadCommonPlan(&local_node->plan); - - READ_INT_FIELD(numCols); - READ_ATTRNUMBER_ARRAY(sortColIdx, local_node->numCols); - READ_OID_ARRAY(sortOperators, local_node->numCols); - READ_OID_ARRAY(collations, local_node->numCols); - READ_BOOL_ARRAY(nullsFirst, local_node->numCols); - - READ_DONE(); -} - -/* - * _readGroup - */ -static Group * -_readGroup(void) -{ - READ_LOCALS(Group); - - ReadCommonPlan(&local_node->plan); - - READ_INT_FIELD(numCols); - READ_ATTRNUMBER_ARRAY(grpColIdx, local_node->numCols); - READ_OID_ARRAY(grpOperators, local_node->numCols); - - READ_DONE(); -} - -/* - * _readAgg - */ -static Agg * -_readAgg(void) -{ - READ_LOCALS(Agg); - - ReadCommonPlan(&local_node->plan); - - READ_ENUM_FIELD(aggstrategy, AggStrategy); - READ_ENUM_FIELD(aggsplit, AggSplit); - READ_INT_FIELD(numCols); - READ_ATTRNUMBER_ARRAY(grpColIdx, local_node->numCols); - READ_OID_ARRAY(grpOperators, local_node->numCols); - READ_LONG_FIELD(numGroups); - READ_BITMAPSET_FIELD(aggParams); - READ_NODE_FIELD(groupingSets); - READ_NODE_FIELD(chain); - - READ_DONE(); -} - -/* - * _readWindowAgg - */ -static WindowAgg * -_readWindowAgg(void) -{ - READ_LOCALS(WindowAgg); - - ReadCommonPlan(&local_node->plan); - - READ_UINT_FIELD(winref); - READ_INT_FIELD(partNumCols); - READ_ATTRNUMBER_ARRAY(partColIdx, local_node->partNumCols); - READ_OID_ARRAY(partOperators, local_node->partNumCols); - READ_INT_FIELD(ordNumCols); - READ_ATTRNUMBER_ARRAY(ordColIdx, local_node->ordNumCols); - READ_OID_ARRAY(ordOperators, local_node->ordNumCols); - READ_INT_FIELD(frameOptions); - READ_NODE_FIELD(startOffset); - READ_NODE_FIELD(endOffset); - - READ_DONE(); -} - -/* - * _readUnique - */ -static Unique * -_readUnique(void) -{ - READ_LOCALS(Unique); - - ReadCommonPlan(&local_node->plan); - - READ_INT_FIELD(numCols); - READ_ATTRNUMBER_ARRAY(uniqColIdx, local_node->numCols); - READ_OID_ARRAY(uniqOperators, local_node->numCols); - - READ_DONE(); -} - -/* - * _readGather - */ -static Gather * -_readGather(void) -{ - READ_LOCALS(Gather); - - ReadCommonPlan(&local_node->plan); - - READ_INT_FIELD(num_workers); - READ_BOOL_FIELD(single_copy); - READ_BOOL_FIELD(invisible); - - READ_DONE(); -} - -/* - * _readHash - */ -static Hash * -_readHash(void) -{ - READ_LOCALS(Hash); - - ReadCommonPlan(&local_node->plan); - - READ_OID_FIELD(skewTable); - READ_INT_FIELD(skewColumn); - READ_BOOL_FIELD(skewInherit); - READ_OID_FIELD(skewColType); - READ_INT_FIELD(skewColTypmod); - - READ_DONE(); -} - -/* - * _readSetOp - */ -static SetOp * -_readSetOp(void) -{ - READ_LOCALS(SetOp); - - ReadCommonPlan(&local_node->plan); - - READ_ENUM_FIELD(cmd, SetOpCmd); - READ_ENUM_FIELD(strategy, SetOpStrategy); - READ_INT_FIELD(numCols); - READ_ATTRNUMBER_ARRAY(dupColIdx, local_node->numCols); - READ_OID_ARRAY(dupOperators, local_node->numCols); - READ_INT_FIELD(flagColIdx); - READ_INT_FIELD(firstFlag); - READ_LONG_FIELD(numGroups); - - READ_DONE(); -} - -/* - * _readLockRows - */ -static LockRows * -_readLockRows(void) -{ - READ_LOCALS(LockRows); - - ReadCommonPlan(&local_node->plan); - - READ_NODE_FIELD(rowMarks); - READ_INT_FIELD(epqParam); - - READ_DONE(); -} - -/* - * _readLimit - */ -static Limit * -_readLimit(void) -{ - READ_LOCALS(Limit); - - ReadCommonPlan(&local_node->plan); - - READ_NODE_FIELD(limitOffset); - READ_NODE_FIELD(limitCount); - - READ_DONE(); -} - -/* - * _readNestLoopParam - */ -static NestLoopParam * -_readNestLoopParam(void) -{ - READ_LOCALS(NestLoopParam); - - READ_INT_FIELD(paramno); - READ_NODE_FIELD(paramval); - - READ_DONE(); -} - -/* - * _readPlanRowMark - */ -static PlanRowMark * -_readPlanRowMark(void) -{ - READ_LOCALS(PlanRowMark); - - READ_UINT_FIELD(rti); - READ_UINT_FIELD(prti); - READ_UINT_FIELD(rowmarkId); - READ_ENUM_FIELD(markType, RowMarkType); - READ_INT_FIELD(allMarkTypes); - READ_ENUM_FIELD(strength, LockClauseStrength); - READ_ENUM_FIELD(waitPolicy, LockWaitPolicy); - READ_BOOL_FIELD(isParent); - - READ_DONE(); -} - -/* - * _readPlanInvalItem - */ -static PlanInvalItem * -_readPlanInvalItem(void) -{ - READ_LOCALS(PlanInvalItem); - - READ_INT_FIELD(cacheId); - READ_UINT_FIELD(hashValue); - - READ_DONE(); -} - -/* - * _readSubPlan - */ -static SubPlan * -_readSubPlan(void) -{ - READ_LOCALS(SubPlan); - - READ_ENUM_FIELD(subLinkType, SubLinkType); - READ_NODE_FIELD(testexpr); - READ_NODE_FIELD(paramIds); - READ_INT_FIELD(plan_id); - READ_STRING_FIELD(plan_name); - READ_OID_FIELD(firstColType); - READ_INT_FIELD(firstColTypmod); - READ_OID_FIELD(firstColCollation); - READ_BOOL_FIELD(useHashTable); - READ_BOOL_FIELD(unknownEqFalse); - READ_NODE_FIELD(setParam); - READ_NODE_FIELD(parParam); - READ_NODE_FIELD(args); - READ_FLOAT_FIELD(startup_cost); - READ_FLOAT_FIELD(per_call_cost); - - READ_DONE(); -} - -/* - * _readAlternativeSubPlan - */ -static AlternativeSubPlan * -_readAlternativeSubPlan(void) -{ - READ_LOCALS(AlternativeSubPlan); - - READ_NODE_FIELD(subplans); - - READ_DONE(); -} - -/* - * _readExtensibleNode - */ -static ExtensibleNode * -_readExtensibleNode(void) -{ - const ExtensibleNodeMethods *methods; - ExtensibleNode *local_node; - const char *extnodename; - - READ_TEMP_LOCALS(); - - token = citus_pg_strtok(&length); /* skip :extnodename */ - token = citus_pg_strtok(&length); /* get extnodename */ - - extnodename = nullable_string(token, length); - if (!extnodename) - elog(ERROR, "extnodename has to be supplied"); - methods = GetExtensibleNodeMethods(extnodename, false); - - local_node = (ExtensibleNode *) newNode(methods->node_size, - T_ExtensibleNode); - local_node->extnodename = extnodename; - - /* deserialize the private fields */ - methods->nodeRead(local_node); - - READ_DONE(); -} - -/* XXX: BEGIN Citus Nodes */ - -static void -_readJobInfo(Job *local_node) -{ - READ_TEMP_LOCALS(); - - READ_UINT64_FIELD(jobId); - READ_NODE_FIELD(jobQuery); - READ_NODE_FIELD(taskList); - READ_NODE_FIELD(dependedJobList); - READ_BOOL_FIELD(subqueryPushdown); -} - - -static Job * -_readJob(void) -{ - READ_LOCALS_NO_FIELDS(Job); - - _readJobInfo(local_node); - - READ_DONE(); -} - - -static MultiPlan * -_readMultiPlan(void) -{ - READ_LOCALS(MultiPlan); - - READ_NODE_FIELD(workerJob); - READ_NODE_FIELD(masterQuery); - READ_STRING_FIELD(masterTableName); - - READ_DONE(); -} - - -static ShardInterval * -_readShardInterval(void) -{ - READ_LOCALS(ShardInterval); - - - READ_OID_FIELD(relationId); - READ_CHAR_FIELD(storageType); - READ_OID_FIELD(valueTypeId); - READ_INT_FIELD(valueTypeLen); - READ_BOOL_FIELD(valueByVal); - READ_BOOL_FIELD(minValueExists); - READ_BOOL_FIELD(maxValueExists); - - token = citus_pg_strtok(&length); /* skip :minValue */ - if (!local_node->minValueExists) - token = citus_pg_strtok(&length); /* skip "<>" */ - else - local_node->minValue = CitusReadDatum(local_node->valueByVal); - - token = citus_pg_strtok(&length); /* skip :maxValue */ - if (!local_node->minValueExists) - token = citus_pg_strtok(&length); /* skip "<>" */ - else - local_node->maxValue = CitusReadDatum(local_node->valueByVal); - - READ_UINT64_FIELD(shardId); - - READ_DONE(); -} - - -static MapMergeJob * -_readMapMergeJob(void) -{ - int arrayLength; - int i; - - READ_LOCALS(MapMergeJob); - - _readJobInfo(&local_node->job); - - READ_NODE_FIELD(reduceQuery); - READ_ENUM_FIELD(partitionType, PartitionType); - READ_NODE_FIELD(partitionColumn); - READ_UINT_FIELD(partitionCount); - READ_INT_FIELD(sortedShardIntervalArrayLength); - - arrayLength = local_node->sortedShardIntervalArrayLength; - - /* now build & read sortedShardIntervalArray */ - local_node->sortedShardIntervalArray = - (ShardInterval**) palloc(arrayLength * sizeof(ShardInterval *)); - - for (i = 0; i < arrayLength; ++i) - { - local_node->sortedShardIntervalArray[i] = _readShardInterval(); - } - - READ_NODE_FIELD(mapTaskList); - READ_NODE_FIELD(mergeTaskList); - - READ_DONE(); -} - - -static ShardPlacement * -_readShardPlacement(void) -{ - READ_LOCALS(ShardPlacement); - - READ_OID_FIELD(placementId); - READ_UINT64_FIELD(shardId); - READ_UINT64_FIELD(shardLength); - READ_ENUM_FIELD(shardState, RelayFileState); - READ_STRING_FIELD(nodeName); - READ_UINT_FIELD(nodePort); - - READ_DONE(); -} - - -static Task * -_readTask(void) -{ - READ_LOCALS(Task); - - READ_ENUM_FIELD(taskType, TaskType); - READ_UINT64_FIELD(jobId); - READ_UINT_FIELD(taskId); - READ_STRING_FIELD(queryString); - READ_UINT64_FIELD(anchorShardId); - READ_NODE_FIELD(taskPlacementList); - READ_NODE_FIELD(dependedTaskList); - READ_UINT_FIELD(partitionId); - READ_UINT_FIELD(upstreamTaskId); - READ_NODE_FIELD(shardInterval); - READ_BOOL_FIELD(assignmentConstrained); - READ_NODE_FIELD(taskExecution); - READ_BOOL_FIELD(upsertQuery); - READ_BOOL_FIELD(requiresMasterEvaluation); - - READ_DONE(); -} - - -/* XXX: END Citus Nodes */ - - -/* - * parseNodeString - * - * Given a character string representing a node tree, parseNodeString creates - * the internal node structure. - * - * The string to be read must already have been loaded into citus_pg_strtok(). - */ -Node * -CitusParseNodeString(void) -{ - void *return_value; - - READ_TEMP_LOCALS(); - - token = citus_pg_strtok(&length); - -#define MATCH(tokname, namelen) \ - (length == namelen && memcmp(token, tokname, namelen) == 0) - - if (MATCH("QUERY", 5)) - return_value = _readQuery(); - else if (MATCH("WITHCHECKOPTION", 15)) - return_value = _readWithCheckOption(); - else if (MATCH("SORTGROUPCLAUSE", 15)) - return_value = _readSortGroupClause(); - else if (MATCH("GROUPINGSET", 11)) - return_value = _readGroupingSet(); - else if (MATCH("WINDOWCLAUSE", 12)) - return_value = _readWindowClause(); - else if (MATCH("ROWMARKCLAUSE", 13)) - return_value = _readRowMarkClause(); - else if (MATCH("COMMONTABLEEXPR", 15)) - return_value = _readCommonTableExpr(); - else if (MATCH("SETOPERATIONSTMT", 16)) - return_value = _readSetOperationStmt(); - else if (MATCH("ALIAS", 5)) - return_value = _readAlias(); - else if (MATCH("RANGEVAR", 8)) - return_value = _readRangeVar(); - else if (MATCH("INTOCLAUSE", 10)) - return_value = _readIntoClause(); - else if (MATCH("VAR", 3)) - return_value = _readVar(); - else if (MATCH("CONST", 5)) - return_value = _readConst(); - else if (MATCH("PARAM", 5)) - return_value = _readParam(); - else if (MATCH("AGGREF", 6)) - return_value = _readAggref(); - else if (MATCH("GROUPINGFUNC", 12)) - return_value = _readGroupingFunc(); - else if (MATCH("WINDOWFUNC", 10)) - return_value = _readWindowFunc(); - else if (MATCH("ARRAYREF", 8)) - return_value = _readArrayRef(); - else if (MATCH("FUNCEXPR", 8)) - return_value = _readFuncExpr(); - else if (MATCH("NAMEDARGEXPR", 12)) - return_value = _readNamedArgExpr(); - else if (MATCH("OPEXPR", 6)) - return_value = _readOpExpr(); - else if (MATCH("DISTINCTEXPR", 12)) - return_value = _readDistinctExpr(); - else if (MATCH("NULLIFEXPR", 10)) - return_value = _readNullIfExpr(); - else if (MATCH("SCALARARRAYOPEXPR", 17)) - return_value = _readScalarArrayOpExpr(); - else if (MATCH("BOOLEXPR", 8)) - return_value = _readBoolExpr(); - else if (MATCH("SUBLINK", 7)) - return_value = _readSubLink(); - else if (MATCH("FIELDSELECT", 11)) - return_value = _readFieldSelect(); - else if (MATCH("FIELDSTORE", 10)) - return_value = _readFieldStore(); - else if (MATCH("RELABELTYPE", 11)) - return_value = _readRelabelType(); - else if (MATCH("COERCEVIAIO", 11)) - return_value = _readCoerceViaIO(); - else if (MATCH("ARRAYCOERCEEXPR", 15)) - return_value = _readArrayCoerceExpr(); - else if (MATCH("CONVERTROWTYPEEXPR", 18)) - return_value = _readConvertRowtypeExpr(); - else if (MATCH("COLLATE", 7)) - return_value = _readCollateExpr(); - else if (MATCH("CASE", 4)) - return_value = _readCaseExpr(); - else if (MATCH("WHEN", 4)) - return_value = _readCaseWhen(); - else if (MATCH("CASETESTEXPR", 12)) - return_value = _readCaseTestExpr(); - else if (MATCH("ARRAY", 5)) - return_value = _readArrayExpr(); - else if (MATCH("ROW", 3)) - return_value = _readRowExpr(); - else if (MATCH("ROWCOMPARE", 10)) - return_value = _readRowCompareExpr(); - else if (MATCH("COALESCE", 8)) - return_value = _readCoalesceExpr(); - else if (MATCH("MINMAX", 6)) - return_value = _readMinMaxExpr(); - else if (MATCH("XMLEXPR", 7)) - return_value = _readXmlExpr(); - else if (MATCH("NULLTEST", 8)) - return_value = _readNullTest(); - else if (MATCH("BOOLEANTEST", 11)) - return_value = _readBooleanTest(); - else if (MATCH("COERCETODOMAIN", 14)) - return_value = _readCoerceToDomain(); - else if (MATCH("COERCETODOMAINVALUE", 19)) - return_value = _readCoerceToDomainValue(); - else if (MATCH("SETTODEFAULT", 12)) - return_value = _readSetToDefault(); - else if (MATCH("CURRENTOFEXPR", 13)) - return_value = _readCurrentOfExpr(); - else if (MATCH("INFERENCEELEM", 13)) - return_value = _readInferenceElem(); - else if (MATCH("TARGETENTRY", 11)) - return_value = _readTargetEntry(); - else if (MATCH("RANGETBLREF", 11)) - return_value = _readRangeTblRef(); - else if (MATCH("JOINEXPR", 8)) - return_value = _readJoinExpr(); - else if (MATCH("FROMEXPR", 8)) - return_value = _readFromExpr(); - else if (MATCH("ONCONFLICTEXPR", 14)) - return_value = _readOnConflictExpr(); - else if (MATCH("RTE", 3)) - return_value = _readRangeTblEntry(); - else if (MATCH("RANGETBLFUNCTION", 16)) - return_value = _readRangeTblFunction(); - else if (MATCH("TABLESAMPLECLAUSE", 17)) - return_value = _readTableSampleClause(); - else if (MATCH("NOTIFY", 6)) - return_value = _readNotifyStmt(); - else if (MATCH("DEFELEM", 7)) - return_value = _readDefElem(); - else if (MATCH("DECLARECURSOR", 13)) - return_value = _readDeclareCursorStmt(); - else if (MATCH("PLANNEDSTMT", 11)) - return_value = _readPlannedStmt(); - else if (MATCH("PLAN", 4)) - return_value = _readPlan(); - else if (MATCH("RESULT", 6)) - return_value = _readResult(); - else if (MATCH("MODIFYTABLE", 11)) - return_value = _readModifyTable(); - else if (MATCH("APPEND", 6)) - return_value = _readAppend(); - else if (MATCH("MERGEAPPEND", 11)) - return_value = _readMergeAppend(); - else if (MATCH("RECURSIVEUNION", 14)) - return_value = _readRecursiveUnion(); - else if (MATCH("BITMAPAND", 9)) - return_value = _readBitmapAnd(); - else if (MATCH("BITMAPOR", 8)) - return_value = _readBitmapOr(); - else if (MATCH("SCAN", 4)) - return_value = _readScan(); - else if (MATCH("SEQSCAN", 7)) - return_value = _readSeqScan(); - else if (MATCH("SAMPLESCAN", 10)) - return_value = _readSampleScan(); - else if (MATCH("INDEXSCAN", 9)) - return_value = _readIndexScan(); - else if (MATCH("INDEXONLYSCAN", 13)) - return_value = _readIndexOnlyScan(); - else if (MATCH("BITMAPINDEXSCAN", 15)) - return_value = _readBitmapIndexScan(); - else if (MATCH("BITMAPHEAPSCAN", 14)) - return_value = _readBitmapHeapScan(); - else if (MATCH("TIDSCAN", 7)) - return_value = _readTidScan(); - else if (MATCH("SUBQUERYSCAN", 12)) - return_value = _readSubqueryScan(); - else if (MATCH("FUNCTIONSCAN", 12)) - return_value = _readFunctionScan(); - else if (MATCH("VALUESSCAN", 10)) - return_value = _readValuesScan(); - else if (MATCH("CTESCAN", 7)) - return_value = _readCteScan(); - else if (MATCH("WORKTABLESCAN", 13)) - return_value = _readWorkTableScan(); - else if (MATCH("FOREIGNSCAN", 11)) - return_value = _readForeignScan(); - else if (MATCH("CUSTOMSCAN", 10)) - return_value = _readCustomScan(); - else if (MATCH("JOIN", 4)) - return_value = _readJoin(); - else if (MATCH("NESTLOOP", 8)) - return_value = _readNestLoop(); - else if (MATCH("MERGEJOIN", 9)) - return_value = _readMergeJoin(); - else if (MATCH("HASHJOIN", 8)) - return_value = _readHashJoin(); - else if (MATCH("MATERIAL", 8)) - return_value = _readMaterial(); - else if (MATCH("SORT", 4)) - return_value = _readSort(); - else if (MATCH("GROUP", 5)) - return_value = _readGroup(); - else if (MATCH("AGG", 3)) - return_value = _readAgg(); - else if (MATCH("WINDOWAGG", 9)) - return_value = _readWindowAgg(); - else if (MATCH("UNIQUE", 6)) - return_value = _readUnique(); - else if (MATCH("GATHER", 6)) - return_value = _readGather(); - else if (MATCH("HASH", 4)) - return_value = _readHash(); - else if (MATCH("SETOP", 5)) - return_value = _readSetOp(); - else if (MATCH("LOCKROWS", 8)) - return_value = _readLockRows(); - else if (MATCH("LIMIT", 5)) - return_value = _readLimit(); - else if (MATCH("NESTLOOPPARAM", 13)) - return_value = _readNestLoopParam(); - else if (MATCH("PLANROWMARK", 11)) - return_value = _readPlanRowMark(); - else if (MATCH("PLANINVALITEM", 13)) - return_value = _readPlanInvalItem(); - else if (MATCH("SUBPLAN", 7)) - return_value = _readSubPlan(); - else if (MATCH("ALTERNATIVESUBPLAN", 18)) - return_value = _readAlternativeSubPlan(); - else if (MATCH("EXTENSIBLENODE", 14)) - return_value = _readExtensibleNode(); - /* XXX: BEGIN Citus Nodes */ - else if (MATCH("MULTIPLAN", 9)) - return_value = _readMultiPlan(); - else if (MATCH("JOB", 3)) - return_value = _readJob(); - else if (MATCH("SHARDINTERVAL", 13)) - return_value = _readShardInterval(); - else if (MATCH("MAPMERGEJOB", 11)) - return_value = _readMapMergeJob(); - else if (MATCH("SHARDPLACEMENT", 14)) - return_value = _readShardPlacement(); - else if (MATCH("TASK", 4)) - return_value = _readTask(); - /* XXX: END Citus Nodes */ - else - { - elog(ERROR, "badly formatted node string \"%.32s\"...", token); - return_value = NULL; /* keep compiler quiet */ - } - - return (Node *) return_value; -} - - -/* - * readDatum - * - * Given a string representation of a constant, recreate the appropriate - * Datum. The string representation embeds length info, but not byValue, - * so we must be told that. - */ -static Datum -CitusReadDatum(bool typbyval) -{ - Size length, - i; - int tokenLength; - char *token; - Datum res; - char *s; - - /* - * read the actual length of the value - */ - token = citus_pg_strtok(&tokenLength); - length = atoui(token); - - token = citus_pg_strtok(&tokenLength); /* read the '[' */ - if (token == NULL || token[0] != '[') - elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu", - token ? (const char *) token : "[NULL]", length); - - if (typbyval) - { - if (length > (Size) sizeof(Datum)) - elog(ERROR, "byval datum but length = %zu", length); - res = (Datum) 0; - s = (char *) (&res); - for (i = 0; i < (Size) sizeof(Datum); i++) - { - token = citus_pg_strtok(&tokenLength); - s[i] = (char) atoi(token); - } - } - else if (length <= 0) - res = (Datum) NULL; - else - { - s = (char *) palloc(length); - for (i = 0; i < length; i++) - { - token = citus_pg_strtok(&tokenLength); - s[i] = (char) atoi(token); - } - res = PointerGetDatum(s); - } - - token = citus_pg_strtok(&tokenLength); /* read the ']' */ - if (token == NULL || token[0] != ']') - elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu", - token ? (const char *) token : "[NULL]", length); - - return res; -} - -/* - * readAttrNumberCols - */ -static AttrNumber * -_readAttrNumberCols(int numCols) -{ - int tokenLength, - i; - char *token; - AttrNumber *attr_vals; - - if (numCols <= 0) - return NULL; - - attr_vals = (AttrNumber *) palloc(numCols * sizeof(AttrNumber)); - for (i = 0; i < numCols; i++) - { - token = citus_pg_strtok(&tokenLength); - attr_vals[i] = atoi(token); - } - - return attr_vals; -} - -/* - * readOidCols - */ -static Oid * -_readOidCols(int numCols) -{ - int tokenLength, - i; - char *token; - Oid *oid_vals; - - if (numCols <= 0) - return NULL; - - oid_vals = (Oid *) palloc(numCols * sizeof(Oid)); - for (i = 0; i < numCols; i++) - { - token = citus_pg_strtok(&tokenLength); - oid_vals[i] = atooid(token); - } - - return oid_vals; -} - -/* - * readIntCols - */ -static int * -_readIntCols(int numCols) -{ - int tokenLength, - i; - char *token; - int *int_vals; - - if (numCols <= 0) - return NULL; - - int_vals = (int *) palloc(numCols * sizeof(int)); - for (i = 0; i < numCols; i++) - { - token = citus_pg_strtok(&tokenLength); - int_vals[i] = atoi(token); - } - - return int_vals; -} - -/* - * readBoolCols - */ -static bool * -_readBoolCols(int numCols) -{ - int tokenLength, - i; - char *token; - bool *bool_vals; - - if (numCols <= 0) - return NULL; - - bool_vals = (bool *) palloc(numCols * sizeof(bool)); - for (i = 0; i < numCols; i++) - { - token = citus_pg_strtok(&tokenLength); - bool_vals[i] = strtobool(token); - } - - return bool_vals; -} - -#endif diff --git a/src/include/distributed/citus_nodefuncs.h b/src/include/distributed/citus_nodefuncs.h index 533715e21..7dc8a3653 100644 --- a/src/include/distributed/citus_nodefuncs.h +++ b/src/include/distributed/citus_nodefuncs.h @@ -37,6 +37,55 @@ extern void * CitusNodeRead(char *token, int tok_len); /* citus_readfuncs.c */ extern Node * CitusParseNodeString(void); +extern Datum readDatum(bool typbyval); +extern void RegisterNodes(void); + +/* + * Define read functions for citus nodes in a way they're usable across + * several major versions. That requires some macro-uglyness as 9.6+ is quite + * different from before. + */ + +#if (PG_VERSION_NUM >= 90600) +#define READFUNC_ARGS struct ExtensibleNode *node +#define READFUNC_RET void +#else +#define READFUNC_ARGS void +#define READFUNC_RET Node * +#endif + +#if (PG_VERSION_NUM >= 90600) +#define OUTFUNC_ARGS StringInfo str, const struct ExtensibleNode *raw_node +#else +#define OUTFUNC_ARGS StringInfo str, const Node *raw_node +#endif + +extern READFUNC_RET ReadJob(READFUNC_ARGS); +extern READFUNC_RET ReadMultiPlan(READFUNC_ARGS); +extern READFUNC_RET ReadShardInterval(READFUNC_ARGS); +extern READFUNC_RET ReadMapMergeJob(READFUNC_ARGS); +extern READFUNC_RET ReadShardPlacement(READFUNC_ARGS); +extern READFUNC_RET ReadTask(READFUNC_ARGS); + +extern READFUNC_RET ReadUnsupportedCitusNode(READFUNC_ARGS); + +extern void OutJob(OUTFUNC_ARGS); +extern void OutMultiPlan(OUTFUNC_ARGS); +extern void OutShardInterval(OUTFUNC_ARGS); +extern void OutMapMergeJob(OUTFUNC_ARGS); +extern void OutShardPlacement(OUTFUNC_ARGS); +extern void OutTask(OUTFUNC_ARGS); + +extern void OutMultiNode(OUTFUNC_ARGS); +extern void OutMultiTreeRoot(OUTFUNC_ARGS); +extern void OutMultiProject(OUTFUNC_ARGS); +extern void OutMultiCollect(OUTFUNC_ARGS); +extern void OutMultiSelect(OUTFUNC_ARGS); +extern void OutMultiTable(OUTFUNC_ARGS); +extern void OutMultiJoin(OUTFUNC_ARGS); +extern void OutMultiPartition(OUTFUNC_ARGS); +extern void OutMultiCartesianProduct(OUTFUNC_ARGS); +extern void OutMultiExtendedOp(OUTFUNC_ARGS); #endif /* CITUS_NODEFUNCS_H */ diff --git a/src/include/distributed/citus_nodes.h b/src/include/distributed/citus_nodes.h index af64b2859..f81b19173 100644 --- a/src/include/distributed/citus_nodes.h +++ b/src/include/distributed/citus_nodes.h @@ -3,6 +3,26 @@ * citus_nodes.h * Additional node types, and related infrastructure, for Citus. * + * To add a new node type to Citus, perform the following: + * + * * Add a new CitusNodeTag value to use as a tag for the node. Add + * the node's name at a corresponding offset within the array named + * CitusNodeTagNamesD at the top of citus_nodefuncs.c + * + * * Describe the node in a struct, which must have a CitusNode as + * its first element + * + * * Implement an 'outfunc' for the node in citus_outfuncs.c, using + * the macros defined within that file. This function will handle + * converting the node to a string + * + * * Implement a 'readfunc' for the node in citus_readfuncs.c, using + * the macros defined within that file. This function will handle + * converting strings into instances of the node + * + * * Use DEFINE_NODE_METHODS within the nodeMethods array (near the + * bottom of citus_nodefuncs.c) to register the node in PostgreSQL + * * Copyright (c) 2012-2016, Citus Data, Inc. * *------------------------------------------------------------------------- @@ -17,9 +37,10 @@ * * These have to be distinct from the ideas used in postgres' nodes.h */ +#define CITUS_NODE_TAG_START 1200 typedef enum CitusNodeTag { - T_MultiNode = 1200, /* FIXME: perhaps use something less predicable? */ + T_MultiNode = CITUS_NODE_TAG_START, /* FIXME: perhaps use something less predicable? */ T_MultiTreeRoot, T_MultiProject, T_MultiCollect, @@ -38,6 +59,46 @@ typedef enum CitusNodeTag } CitusNodeTag; +const char** CitusNodeTagNames; + +#if (PG_VERSION_NUM >= 90600) + +#include "nodes/extensible.h" + +typedef struct CitusNode +{ + ExtensibleNode extensible; + CitusNodeTag citus_tag; /* for quick type determination */ +} CitusNode; + +#define CitusNodeTag(nodeptr) CitusNodeTagI((Node*) nodeptr) + +static inline int +CitusNodeTagI(Node *node) +{ + if (!IsA(node, ExtensibleNode)) + { + return nodeTag(node); + } + + return ((CitusNode*)(node))->citus_tag; +} + +/* Citus variant of newNode(), don't use directly. */ +#define CitusNewNode(size, tag) \ +({ CitusNode *_result; \ + AssertMacro((size) >= sizeof(CitusNode)); /* need the tag, at least */ \ + _result = (CitusNode *) palloc0fast(size); \ + _result->extensible.type = T_ExtensibleNode; \ + _result->extensible.extnodename = CitusNodeTagNames[tag - CITUS_NODE_TAG_START]; \ + _result->citus_tag =(int) (tag); \ + _result; \ +}) + + +#else + +typedef CitusNodeTag CitusNode; /* * nodeTag equivalent that returns the node tag for both citus and postgres * node tag types. Needs to return int as there's no type that covers both @@ -46,12 +107,6 @@ typedef enum CitusNodeTag #define CitusNodeTag(nodeptr) (*((const int*)(nodeptr))) -/* - * IsA equivalent that compares node tags as integers, not as enum values. - */ -#define CitusIsA(nodeptr,_type_) (CitusNodeTag(nodeptr) == T_##_type_) - - /* Citus variant of newNode(), don't use directly. */ #define CitusNewNode(size, tag) \ ({ Node *_result; \ @@ -61,6 +116,13 @@ typedef enum CitusNodeTag _result; \ }) +#endif + +/* + * IsA equivalent that compares node tags, including Citus-specific nodes. + */ +#define CitusIsA(nodeptr,_type_) (CitusNodeTag(nodeptr) == T_##_type_) + /* * CitusMakeNode is Citus variant of makeNode(). Use it to create nodes of diff --git a/src/include/distributed/master_metadata_utility.h b/src/include/distributed/master_metadata_utility.h index 2b5d3c6b9..a267d7ff3 100644 --- a/src/include/distributed/master_metadata_utility.h +++ b/src/include/distributed/master_metadata_utility.h @@ -29,7 +29,7 @@ /* In-memory representation of a typed tuple in pg_dist_shard. */ typedef struct ShardInterval { - CitusNodeTag type; + CitusNode type; Oid relationId; char storageType; Oid valueTypeId; /* min/max value datum's typeId */ @@ -46,7 +46,7 @@ typedef struct ShardInterval /* In-memory representation of a tuple in pg_dist_shard_placement. */ typedef struct ShardPlacement { - CitusNodeTag type; + CitusNode type; uint64 placementId; /* sequence that implies this placement creation order */ uint64 shardId; uint64 shardLength; diff --git a/src/include/distributed/multi_logical_planner.h b/src/include/distributed/multi_logical_planner.h index f2acd3819..909a88339 100644 --- a/src/include/distributed/multi_logical_planner.h +++ b/src/include/distributed/multi_logical_planner.h @@ -35,7 +35,7 @@ */ typedef struct MultiNode { - CitusNodeTag type; + CitusNode type; struct MultiNode *parentNode; diff --git a/src/include/distributed/multi_physical_planner.h b/src/include/distributed/multi_physical_planner.h index ba21d6f1d..351ab9171 100644 --- a/src/include/distributed/multi_physical_planner.h +++ b/src/include/distributed/multi_physical_planner.h @@ -114,7 +114,7 @@ typedef enum */ typedef struct Job { - CitusNodeTag type; + CitusNode type; uint64 jobId; Query *jobQuery; List *taskList; @@ -152,7 +152,7 @@ typedef struct TaskExecution TaskExecution; typedef struct Task { - CitusNodeTag type; + CitusNode type; TaskType taskType; uint64 jobId; uint32 taskId; @@ -201,7 +201,7 @@ typedef struct JoinSequenceNode */ typedef struct MultiPlan { - CitusNodeTag type; + CitusNode type; Job *workerJob; Query *masterQuery; char *masterTableName;