From: Tomas Vondra Date: Fri, 20 Jan 2017 23:34:46 +0000 (+0100) Subject: fix 'ERROR: unrecognized token' failures in _readWindowAgg() X-Git-Tag: XL_10_R1BETA1~429 X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=ee7712beaa11989881d8daaba0f5dfd4033b98b7;p=postgres-xl.git fix 'ERROR: unrecognized token' failures in _readWindowAgg() The _outWindowAgg() and _readWindowAgg() were inconsistent, resulting in failures in stringToNode(). In particular _outWindowAgg() was producing output with tokens :partOperations and :ordOperations, while _readWindowAgg() expected :partOperators and :ordOperators. Perhaps more importantly, _readWindowAgg() used READ_OID_ARRAY marco to parse :ordOperators, but the macro ignores portable_output flag. So parsing the string failed. Fixed mostly by reverting to the XL 9.5 code. --- diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 4769f17a8f..293da7f1c9 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -1112,7 +1112,7 @@ _outWindowAgg(StringInfo str, const WindowAgg *node) for (i = 0; i < node->partNumCols; i++) appendStringInfo(str, " %d", node->partColIdx[i]); - appendStringInfoString(str, " :partOperations"); + appendStringInfoString(str, " :partOperators"); for (i = 0; i < node->partNumCols; i++) #ifdef XCP if (portable_output) @@ -1148,7 +1148,7 @@ _outWindowAgg(StringInfo str, const WindowAgg *node) for (i = 0; i < node->ordNumCols; i++) appendStringInfo(str, " %d", node->ordColIdx[i]); - appendStringInfoString(str, " :ordOperations"); + appendStringInfoString(str, " :ordOperators"); for (i = 0; i < node->ordNumCols; i++) #ifdef XCP if (portable_output) diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 63327aac74..023d409f91 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -2940,17 +2940,123 @@ _readAgg(void) static WindowAgg * _readWindowAgg(void) { - READ_LOCALS(WindowAgg); + int i; - ReadCommonPlan(&local_node->plan); + READ_PLAN_FIELDS(WindowAgg); READ_UINT_FIELD(winref); READ_INT_FIELD(partNumCols); - READ_ATTRNUMBER_ARRAY(partColIdx, local_node->partNumCols); - READ_OID_ARRAY(partOperators, local_node->partNumCols); + + token = pg_strtok(&length); /* skip :partColIdx */ + local_node->partColIdx = (AttrNumber *) palloc(local_node->partNumCols * sizeof(AttrNumber)); + for (i = 0; i < local_node->partNumCols; i++) + { + token = pg_strtok(&length); + local_node->partColIdx[i] = atoi(token); + } + + token = pg_strtok(&length); /* skip :partOperators */ + local_node->partOperators = (Oid *) palloc(local_node->partNumCols * sizeof(Oid)); + for (i = 0; i < local_node->partNumCols; i++) + { + token = pg_strtok(&length); + if (portable_input) + { + char *nspname; /* namespace name */ + char *oprname; /* operator name */ + char *leftnspname; /* left type namespace */ + char *leftname; /* left type name */ + Oid oprleft; /* left type */ + char *rightnspname; /* right type namespace */ + char *rightname; /* right type name */ + Oid oprright; /* right type */ + /* token is already set to nspname */ + nspname = nullable_string(token, length); + token = pg_strtok(&length); /* get operator name */ + oprname = nullable_string(token, length); + token = pg_strtok(&length); /* left type namespace */ + leftnspname = nullable_string(token, length); + token = pg_strtok(&length); /* left type name */ + leftname = nullable_string(token, length); + token = pg_strtok(&length); /* right type namespace */ + rightnspname = nullable_string(token, length); + token = pg_strtok(&length); /* right type name */ + rightname = nullable_string(token, length); + if (leftname) + oprleft = get_typname_typid(leftname, + NSP_OID(leftnspname)); + else + oprleft = InvalidOid; + if (rightname) + oprright = get_typname_typid(rightname, + NSP_OID(rightnspname)); + else + oprright = InvalidOid; + local_node->partOperators[i] = get_operid(oprname, + oprleft, + oprright, + NSP_OID(nspname)); + } + else + local_node->partOperators[i] = atooid(token); + } + READ_INT_FIELD(ordNumCols); - READ_ATTRNUMBER_ARRAY(ordColIdx, local_node->ordNumCols); - READ_OID_ARRAY(ordOperators, local_node->ordNumCols); + + token = pg_strtok(&length); /* skip :ordColIdx */ + local_node->ordColIdx = (AttrNumber *) palloc(local_node->ordNumCols * sizeof(AttrNumber)); + for (i = 0; i < local_node->ordNumCols; i++) + { + token = pg_strtok(&length); + local_node->ordColIdx[i] = atoi(token); + } + + token = pg_strtok(&length); /* skip :ordOperators */ + local_node->ordOperators = (Oid *) palloc(local_node->ordNumCols * sizeof(Oid)); + for (i = 0; i < local_node->ordNumCols; i++) + { + token = pg_strtok(&length); + if (portable_input) + { + char *nspname; /* namespace name */ + char *oprname; /* operator name */ + char *leftnspname; /* left type namespace */ + char *leftname; /* left type name */ + Oid oprleft; /* left type */ + char *rightnspname; /* right type namespace */ + char *rightname; /* right type name */ + Oid oprright; /* right type */ + /* token is already set to nspname */ + nspname = nullable_string(token, length); + token = pg_strtok(&length); /* get operator name */ + oprname = nullable_string(token, length); + token = pg_strtok(&length); /* left type namespace */ + leftnspname = nullable_string(token, length); + token = pg_strtok(&length); /* left type name */ + leftname = nullable_string(token, length); + token = pg_strtok(&length); /* right type namespace */ + rightnspname = nullable_string(token, length); + token = pg_strtok(&length); /* right type name */ + rightname = nullable_string(token, length); + if (leftname) + oprleft = get_typname_typid(leftname, + NSP_OID(leftnspname)); + else + oprleft = InvalidOid; + if (rightname) + oprright = get_typname_typid(rightname, + NSP_OID(rightnspname)); + else + oprright = InvalidOid; + local_node->ordOperators[i] = get_operid(oprname, + oprleft, + oprright, + NSP_OID(nspname)); + } + else + local_node->ordOperators[i] = atooid(token); + } + READ_INT_FIELD(frameOptions); READ_NODE_FIELD(startOffset); READ_NODE_FIELD(endOffset);