diff options
| author | Pavan Deolasee | 2015-06-10 06:17:02 +0000 |
|---|---|---|
| committer | Pavan Deolasee | 2015-06-10 06:17:02 +0000 |
| commit | 160c111874923bd0c2dfa88eb094b29cca20d740 (patch) | |
| tree | da3412575f0dec534979878d01e8180c6d371105 | |
| parent | e98af6507f1a4c37b82f6e8f77bddee6ce395685 (diff) | |
Encode list of rel OIDs in a portable format for datanodes to translate them to
local OIDs correctly
We now have a new routine to send down list of portable relation OIDs. Right
now only one member of ModifyTable node uses it, but we should see if this is
necessary at other places too.
| -rw-r--r-- | src/backend/nodes/outfuncs.c | 46 | ||||
| -rw-r--r-- | src/backend/nodes/readfuncs.c | 49 |
2 files changed, 83 insertions, 12 deletions
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 02382151bf..8e42fb912c 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -126,8 +126,10 @@ set_portable_output(bool value) /* Write a Node field */ #define WRITE_NODE_FIELD(fldname) \ - (appendStringInfo(str, " :" CppAsString(fldname) " "), \ - _outNode(str, node->fldname)) + do { \ + appendStringInfo(str, " :" CppAsString(fldname) " "); \ + _outNode(str, node->fldname); \ + } while (0) /* Write a bitmapset field */ #define WRITE_BITMAPSET_FIELD(fldname) \ @@ -143,12 +145,36 @@ set_portable_output(bool value) * the OID on target node. The identifier depends on object type. */ +#define WRITE_RELID_INTERNAL(relid) \ + (_outToken(str, OidIsValid((relid)) ? NSP_NAME(get_rel_namespace((relid))) : NULL), \ + appendStringInfoChar(str, ' '), \ + _outToken(str, OidIsValid((relid)) ? get_rel_name((relid)) : NULL)) + /* write an OID which is a relation OID */ #define WRITE_RELID_FIELD(fldname) \ (appendStringInfo(str, " :" CppAsString(fldname) " "), \ - _outToken(str, OidIsValid(node->fldname) ? NSP_NAME(get_rel_namespace(node->fldname)) : NULL), \ - appendStringInfoChar(str, ' '), \ - _outToken(str, OidIsValid(node->fldname) ? get_rel_name(node->fldname) : NULL)) + WRITE_RELID_INTERNAL(node->fldname)) + +#define WRITE_RELID_LIST_FIELD(fldname) \ + do { \ + ListCell *lc; \ + char *sep = ""; \ + appendStringInfo(str, " :" CppAsString(fldname) " "); \ + if (node->fldname == NIL || list_length(node->fldname) == 0) \ + appendStringInfoString(str, "<>"); \ + else \ + { \ + appendStringInfoChar(str, '('); \ + foreach (lc, node->fldname) \ + { \ + Oid relid = lfirst_oid(lc); \ + appendStringInfoString(str, sep); \ + WRITE_RELID_INTERNAL(relid); \ + sep = ","; \ + } \ + appendStringInfoChar(str, ')'); \ + } \ + } while (0) /* write an OID which is a data type OID */ #define WRITE_TYPID_FIELD(fldname) \ @@ -225,6 +251,7 @@ set_portable_output(bool value) appendStringInfo(str, "<> <> -1"); \ } while (0) + #endif #define booltostr(x) ((x) ? "true" : "false") @@ -518,7 +545,16 @@ _outModifyTable(StringInfo str, const ModifyTable *node) #endif #endif WRITE_ENUM_FIELD(onConflictAction, OnConflictAction); +#ifdef XCP + if (portable_output) + WRITE_RELID_LIST_FIELD(arbiterIndexes); + else + { +#endif WRITE_NODE_FIELD(arbiterIndexes); +#ifdef XCP + } +#endif WRITE_NODE_FIELD(onConflictSet); WRITE_NODE_FIELD(onConflictWhere); WRITE_INT_FIELD(exclRelRTI); diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 84fce71dba..7d6f0001cb 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -162,9 +162,11 @@ set_portable_input(bool value) /* Read a Node field */ #define READ_NODE_FIELD(fldname) \ - token = pg_strtok(&length); /* skip :fldname */ \ - (void) token; /* in case not used elsewhere */ \ - local_node->fldname = nodeRead(NULL, 0) + do { \ + token = pg_strtok(&length); /* skip :fldname */ \ + (void) token; /* in case not used elsewhere */ \ + local_node->fldname = nodeRead(NULL, 0); \ + } while (0) /* Read a bitmapset field */ #define READ_BITMAPSET_FIELD(fldname) \ @@ -232,20 +234,48 @@ set_portable_input(bool value) #define NSP_OID(nspname) LookupNamespaceNoError(nspname) /* Read relation identifier and lookup the OID */ -#define READ_RELID_FIELD(fldname) \ +#define READ_RELID_INTERNAL(relid) \ do { \ char *nspname; /* namespace name */ \ char *relname; /* relation name */ \ - token = pg_strtok(&length); /* skip :fldname */ \ token = pg_strtok(&length); /* get nspname */ \ nspname = nullable_string(token, length); \ token = pg_strtok(&length); /* get relname */ \ relname = nullable_string(token, length); \ if (relname) \ - local_node->fldname = get_relname_relid(relname, \ + relid = get_relname_relid(relname, \ NSP_OID(nspname)); \ else \ - local_node->fldname = InvalidOid; \ + relid = InvalidOid; \ + } while (0) + +#define READ_RELID_FIELD(fldname) \ + do { \ + Oid relid; \ + token = pg_strtok(&length); /* skip :fldname */ \ + READ_RELID_INTERNAL(relid); \ + local_node->fldname = relid; \ + } while (0) + +#define READ_RELID_LIST_FIELD(fldname) \ + do { \ + token = pg_strtok(&length); /* skip :fldname */ \ + token = pg_strtok(&length); /* skip '(' */ \ + if (length > 0 ) \ + { \ + Assert(token[0] == '('); \ + for (;;) \ + { \ + Oid relid; \ + READ_RELID_INTERNAL(relid); \ + local_node->fldname = lappend_oid(local_node->fldname, relid); \ + token = pg_strtok(&length); \ + if (token[0] == ')') \ + break; \ + } \ + } \ + else \ + local_node->fldname = NIL; \ } while (0) /* Read data type identifier and lookup the OID */ @@ -2138,6 +2168,11 @@ _readModifyTable(void) #endif READ_ENUM_FIELD(onConflictAction, OnConflictAction); +#ifdef XCP + if (portable_input) + READ_RELID_LIST_FIELD(arbiterIndexes); + else +#endif READ_NODE_FIELD(arbiterIndexes); READ_NODE_FIELD(onConflictSet); READ_NODE_FIELD(onConflictWhere); |
