diff options
author | Tomas Vondra | 2017-09-19 21:06:46 +0000 |
---|---|---|
committer | Tomas Vondra | 2017-09-19 21:06:46 +0000 |
commit | 6e08be4760267a29972094954543962034887596 (patch) | |
tree | 446a1da99c193b33ddf7d1838d782ab9b993f0d6 | |
parent | b05a0a0b5609c547965efbb5d499fb7cc36a4315 (diff) |
Handle Aggref->aggargtypes in out/readfuncs.c
When communicating with other nodes, we send names of objects instead
of OIDs as those are assigned on each node independently. We failed to
do this for Aggref->aggargtypes, which worked fine for built-in data
types (those have the same OID on all nodes), but resulted in failures
for custom data types (like for example FIXEDDECIMAL).
ERROR: cache lookup failed for type 16731
This fixes it by implementing READ/WRITE_TYPID_LIST_FIELD, similarly
to what we had for RELID.
Note: Turns out the WRITE_RELID_LIST_FIELD was broken, but apparently
we never call it in XL as it's only used for arbiterIndexes field. So
fix that too, in case we enable the feature in the future.
-rw-r--r-- | src/backend/nodes/outfuncs.c | 39 | ||||
-rw-r--r-- | src/backend/nodes/readfuncs.c | 48 |
2 files changed, 77 insertions, 10 deletions
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index cf05a61342..99b70b717f 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -173,18 +173,42 @@ static void outChar(StringInfo str, char c); Oid relid = lfirst_oid(lc); \ appendStringInfoString(str, sep); \ WRITE_RELID_INTERNAL(relid); \ - sep = ","; \ + sep = " , "; \ } \ - appendStringInfoChar(str, ')'); \ + appendStringInfoString(str, " )"); \ } \ } while (0) +#define WRITE_TYPID_INTERNAL(typid) \ + (outToken(str, OidIsValid(typid) ? NSP_NAME(get_typ_namespace(typid)) : NULL), \ + appendStringInfoChar(str, ' '), \ + outToken(str, OidIsValid(typid) ? get_typ_name(typid) : NULL)) + /* write an OID which is a data type OID */ #define WRITE_TYPID_FIELD(fldname) \ (appendStringInfo(str, " :" CppAsString(fldname) " "), \ - outToken(str, OidIsValid(node->fldname) ? NSP_NAME(get_typ_namespace(node->fldname)) : NULL), \ - appendStringInfoChar(str, ' '), \ - outToken(str, OidIsValid(node->fldname) ? get_typ_name(node->fldname) : NULL)) + WRITE_TYPID_INTERNAL(node->fldname)) + +#define WRITE_TYPID_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 typid = lfirst_oid(lc); \ + appendStringInfoString(str, sep); \ + WRITE_TYPID_INTERNAL(typid); \ + sep = " , "; \ + } \ + appendStringInfoString(str, " )"); \ + } \ + } while (0) /* write an OID which is a function OID */ #define WRITE_FUNCID_FIELD(fldname) \ @@ -1868,6 +1892,11 @@ _outAggref(StringInfo str, const Aggref *node) else #endif WRITE_OID_FIELD(aggtranstype); +#ifdef XCP + if (portable_output) + WRITE_TYPID_LIST_FIELD(aggargtypes); + else +#endif WRITE_NODE_FIELD(aggargtypes); WRITE_NODE_FIELD(aggdirectargs); WRITE_NODE_FIELD(args); diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index dd47b2698c..a3bfe81afd 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -243,20 +243,53 @@ set_portable_input(bool value) } while (0) /* Read data type identifier and lookup the OID */ -#define READ_TYPID_FIELD(fldname) \ +#define READ_TYPID_INTERNAL(typid) \ do { \ char *nspname; /* namespace name */ \ char *typname; /* data type name */ \ - token = pg_strtok(&length); /* skip :fldname */ \ token = pg_strtok(&length); /* get nspname */ \ nspname = nullable_string(token, length); \ token = pg_strtok(&length); /* get typname */ \ typname = nullable_string(token, length); \ if (typname) \ - local_node->fldname = get_typname_typid(typname, \ - NSP_OID(nspname)); \ + { \ + typid = get_typname_typid(typname, \ + NSP_OID(nspname)); \ + if (!OidIsValid((typid))) \ + elog(WARNING, "could not find OID for type %s.%s", nspname,\ + typname); \ + } \ else \ - local_node->fldname = InvalidOid; \ + typid = InvalidOid; \ + } while (0) + +#define READ_TYPID_FIELD(fldname) \ + do { \ + Oid typid; \ + token = pg_strtok(&length); /* skip :fldname */ \ + READ_TYPID_INTERNAL(typid); \ + local_node->fldname = typid; \ + } while (0) + +#define READ_TYPID_LIST_FIELD(fldname) \ + do { \ + token = pg_strtok(&length); /* skip :fldname */ \ + token = pg_strtok(&length); /* skip '(' */ \ + if (length > 0 ) \ + { \ + Assert(token[0] == '('); \ + for (;;) \ + { \ + Oid typid; \ + READ_TYPID_INTERNAL(typid); \ + local_node->fldname = lappend_oid(local_node->fldname, typid); \ + token = pg_strtok(&length); \ + if (token[0] == ')') \ + break; \ + } \ + } \ + else \ + local_node->fldname = NIL; \ } while (0) /* Read function identifier and lookup the OID */ @@ -882,6 +915,11 @@ _readAggref(void) else #endif READ_OID_FIELD(aggtranstype); +#ifdef XCP + if (portable_input) + READ_TYPID_LIST_FIELD(aggargtypes); + else +#endif READ_NODE_FIELD(aggargtypes); READ_NODE_FIELD(aggdirectargs); READ_NODE_FIELD(args); |