summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Vondra2017-09-19 21:06:46 +0000
committerTomas Vondra2017-09-19 21:06:46 +0000
commit6e08be4760267a29972094954543962034887596 (patch)
tree446a1da99c193b33ddf7d1838d782ab9b993f0d6
parentb05a0a0b5609c547965efbb5d499fb7cc36a4315 (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.c39
-rw-r--r--src/backend/nodes/readfuncs.c48
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);