From 59a46fac699b9d4002f82baa945222024d011046 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Wed, 5 Apr 2017 18:14:48 +0200 Subject: [PATCH] Revert "Use backend quoting functions instead of libpq" Revert the patch since it broke tests for gprestore and gptransfer in the main pipeline. While the test quoted in the original Jira passes there seems to be more to it than meets the Jira.. Revert for now. Reverts: commit 1bb0b76514842e7a3085cc6cf16b544a04470268 Author: Daniel Gustafsson Date: Wed Apr 5 13:07:10 2017 +0200 Use backend quoting functions instead of libpq libpq is front-end code and shouldn't be used in backend processes. The requirement here is to correctly quote the relation name in partitioning such that pg_dump/gp_dump can create working DDL for the partition hierarchy. For this purpose, quote_literal_internal() does the same thing as PQescapeString(). The following relation definitions were hitting the previous bug fixed by applying proper quoting: --- src/backend/utils/adt/ruleutils.c | 57 ++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 18e9ad7431..e02939d31f 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -6969,12 +6969,31 @@ partition_rule_def_worker(PartitionRule *rule, Node *start, if (bLeafTablename) /* MPP-6297: dump by tablename */ { StringInfoData sid1; + PQExpBuffer pqbuf = createPQExpBuffer(); initStringInfo(&sid1); - /* Always quote to make WITH (tablename=...) work correctly */ + /* always quote to make WITH (tablename=...) work correctly */ + /* MPP-12243: but don't use quote_identifier if already quoted! */ + char *relname = get_rel_name(rule->parchildrelid); - appendStringInfo(&sid1, "tablename=%s", quote_literal_internal(relname)); + int len = strlen(relname); + + if(strchr(relname, '\\') != NULL) + appendPQExpBufferChar(pqbuf, ESCAPE_STRING_SYNTAX); + + appendPQExpBufferChar(pqbuf, '\''); + + if(!enlargePQExpBuffer(pqbuf, 2 * len + 2)) + elog(ERROR, "failed to increase buffer size for escaping relname %s", relname); + + pqbuf->len += PQescapeString(pqbuf->data + pqbuf->len, relname, len); + + appendPQExpBufferChar(pqbuf, '\''); + + appendStringInfo(&sid1, "tablename=%s", pqbuf->data); + + destroyPQExpBuffer(pqbuf); /* MPP-7191, MPP-7193: fully-qualify storage type if not * specified (and not a template) @@ -7025,16 +7044,36 @@ partition_rule_def_worker(PartitionRule *rule, Node *start, if (bLeafTablename && part->paristemplate) { - /* - * Make a fake tablename for template entries to invoke special - * dump/restore magic in parse_partition.c:partition_range_every() - * for EVERY. Note that the tablename is ignored during SET - * SUBPARTITION TEMPLATE because the template rules do not have - * corresponding relations (MPP-6297) + /* hackery! */ + /* MPP-6297: Make a fake tablename for template entries to + * invoke special dump/restore magic for EVERY in + * analyze.c:partition_range_every(). Note that the + * tablename is ignored during SET SUBPARTITION TEMPLATE + * because the template rules do not have corresponding + * relations + * + * MPP-10480: use tablename */ + PQExpBuffer pqbuf = createPQExpBuffer(); char *relname = get_rel_name(part->parrelid); - appendStringInfo(&buf, "tablename=%s", quote_literal_internal(relname)); + int len = strlen(relname); + + if(strchr(relname, '\\') != NULL) + appendPQExpBufferChar(pqbuf, ESCAPE_STRING_SYNTAX); + + appendPQExpBufferChar(pqbuf, '\''); + + if(!enlargePQExpBuffer(pqbuf, 2 * len + 2)) + elog(ERROR, "failed to increase buffer size for escaping relname %s", relname); + + pqbuf->len += PQescapeString(pqbuf->data + pqbuf->len, relname, len); + + appendPQExpBufferChar(pqbuf, '\''); + + appendStringInfo(&buf, "tablename=%s", pqbuf->data); + + destroyPQExpBuffer(pqbuf); } opts = rule->parreloptions; -- GitLab