From: Yugo Nagata Date: Wed, 19 Aug 2015 07:13:00 +0000 (+0900) Subject: Fix inconsistency of sequence values in replication mode X-Git-Tag: V3_4_4~54 X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=43ff7d3de9db4c8a1143258f4ffff98682dab560;p=pgpool2.git Fix inconsistency of sequence values in replication mode Due to the following commit, table names were always quoted in queries to check needs for insert lock, whether this is view, wheter this has default value of timestamp etc. However, when schema name was provided, table name was quoted wrongly as like "public.tbl" instead of "public"."tbl". So, pool_regclass and to_regclass couldn't find right talbe oid and insert lock was never executed. This caused inconsistency between DB nodes. In previous codes, quotation marks "" are once remove from table name returnd by nodeToString, and re-quoted in issued query. Instead, fixed codes don't remove and use directy in pgpool_regclass or to_regclass. make_table_from_rangevar() are also fixed to return table name including quotation marks. However, when neither pgool_regclass or to_regclass is available, quotation marks and schema name are removed from table name, because pg_class.relname is used in this case. In addition, fix to use to_regclass in insert lock functions if available. --- diff --git a/src/include/protocol/protocol_defs.h b/src/include/protocol/protocol_defs.h index 8c413912f..2e1c6cbcf 100644 --- a/src/include/protocol/protocol_defs.h +++ b/src/include/protocol/protocol_defs.h @@ -12,6 +12,8 @@ #define ROWLOCKQUERY2 "SELECT 1 FROM pgpool_catalog.insert_lock WHERE reloid = pgpool_regclass('%s') FOR UPDATE" +#define ROWLOCKQUERY3 "SELECT 1 FROM pgpool_catalog.insert_lock WHERE reloid = to_regclass('%s') FOR UPDATE" + #define MAX_NAME_LEN 128 diff --git a/src/include/utils/pool_relcache.h b/src/include/utils/pool_relcache.h index dc6e2ad07..c7510f429 100644 --- a/src/include/utils/pool_relcache.h +++ b/src/include/utils/pool_relcache.h @@ -70,6 +70,7 @@ extern POOL_RELCACHE *pool_create_relcache(int cachesize, char *sql, bool issessionlocal); extern void pool_discard_relcache(POOL_RELCACHE *relcache); extern void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backend, char *table); +extern char *remove_quotes_and_schema_from_relname(char *table); extern void *int_register_func(POOL_SELECT_RESULT *res); extern void *int_unregister_func(void *data); extern void *string_register_func(POOL_SELECT_RESULT *res); diff --git a/src/protocol/pool_process_query.c b/src/protocol/pool_process_query.c index f4676c8e0..f3c246a69 100644 --- a/src/protocol/pool_process_query.c +++ b/src/protocol/pool_process_query.c @@ -2772,13 +2772,13 @@ int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node) * Query to know if the target table has SERIAL column or not. * This query is valid through PostgreSQL 7.3 or higher. */ -#define NEXTVALQUERY "SELECT count(*) FROM pg_catalog.pg_attrdef AS d, pg_catalog.pg_class AS c WHERE d.adrelid = c.oid AND d.adsrc ~ 'nextval' AND c.relname = '\"%s\"'" +#define NEXTVALQUERY "SELECT count(*) FROM pg_catalog.pg_attrdef AS d, pg_catalog.pg_class AS c WHERE d.adrelid = c.oid AND d.adsrc ~ 'nextval' AND c.relname = '%s'" -#define NEXTVALQUERY2 "SELECT count(*) FROM pg_catalog.pg_attrdef AS d, pg_catalog.pg_class AS c WHERE d.adrelid = c.oid AND d.adsrc ~ 'nextval' AND c.oid = pgpool_regclass('\"%s\"')" +#define NEXTVALQUERY2 "SELECT count(*) FROM pg_catalog.pg_attrdef AS d, pg_catalog.pg_class AS c WHERE d.adrelid = c.oid AND d.adsrc ~ 'nextval' AND c.oid = pgpool_regclass('%s')" -#define NEXTVALQUERY3 "SELECT count(*) FROM pg_catalog.pg_attrdef AS d, pg_catalog.pg_class AS c WHERE d.adrelid = c.oid AND d.adsrc ~ 'nextval' AND c.oid = to_regclass('\"%s\"')" +#define NEXTVALQUERY3 "SELECT count(*) FROM pg_catalog.pg_attrdef AS d, pg_catalog.pg_class AS c WHERE d.adrelid = c.oid AND d.adsrc ~ 'nextval' AND c.oid = to_regclass('%s')" - char *str; + char *table; int result; static POOL_RELCACHE *relcache; @@ -2811,14 +2811,17 @@ int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node) */ /* obtain table name */ - str = get_insert_command_table_name((InsertStmt *)node); - if (str == NULL) + table = get_insert_command_table_name((InsertStmt *)node); + if (table == NULL) { ereport(LOG, (errmsg("unable to get table name from insert statement while checking if table locking is required"))); return 0; } + if (!pool_has_to_regclass() && !pool_has_pgpool_regclass()) + table = remove_quotes_and_schema_from_relname(table); + /* * If relcache does not exist, create it. */ @@ -2855,11 +2858,13 @@ int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node) * Search relcache. */ #ifdef USE_TABLE_LOCK - result = pool_search_relcache(relcache, backend, str)==0?0:1; + result = pool_search_relcache(relcache, backend, table)==0?0:1; #elif USE_SEQUENCE_LOCK - result = pool_search_relcache(relcache, backend, str)==0?0:2; + result = pool_search_relcache(relcache, backend, table)==0?0:2; #else - result = pool_search_relcache(relcache, backend, str)==0?0:3; + ereport(LOG, + (errmsg("use %s",table))); + result = pool_search_relcache(relcache, backend, table)==0?0:3; #endif return result; } @@ -2878,13 +2883,12 @@ int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node) */ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *query, InsertStmt *node, int lock_kind) { - char *table, *p; + char *table; int len = 0; char qbuf[1024]; int i, deadlock_detected = 0; char *adsrc; char seq_rel_name[MAX_NAME_LEN+1]; - char rel_name[MAX_NAME_LEN+1]; regex_t preg; size_t nmatch = 2; regmatch_t pmatch[nmatch]; @@ -2905,15 +2909,6 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend return POOL_CONTINUE; } - /* trim quotes */ - p = table; - for (i=0; *p; p++) - { - if (*p != '"') - rel_name[i++] = *p; - } - rel_name[i] = '\0'; - /* table lock for insert target table? */ if (lock_kind == 1) { @@ -2956,6 +2951,9 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend } } + if (!pool_has_to_regclass() && !pool_has_pgpool_regclass()) + table = remove_quotes_and_schema_from_relname(table); + /* * Search relcache. */ @@ -3003,10 +3001,15 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend { if (pool_has_insert_lock()) { - if (pool_has_pgpool_regclass()) - snprintf(qbuf, sizeof(qbuf), ROWLOCKQUERY2, rel_name); + if (pool_has_to_regclass()) + snprintf(qbuf, sizeof(qbuf), ROWLOCKQUERY3, table); + else if (pool_has_pgpool_regclass()) + snprintf(qbuf, sizeof(qbuf), ROWLOCKQUERY2, table); else - snprintf(qbuf, sizeof(qbuf), ROWLOCKQUERY, rel_name); + { + table = remove_quotes_and_schema_from_relname(table); + snprintf(qbuf, sizeof(qbuf), ROWLOCKQUERY, table); + } } else { @@ -3048,7 +3051,7 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend result = NULL; /* insert a lock target row into insert_lock table */ - status = add_lock_target(frontend, backend, rel_name); + status = add_lock_target(frontend, backend, table); if (status == POOL_CONTINUE) { per_node_statement_log(backend, MASTER_NODE_ID, qbuf); @@ -3244,10 +3247,12 @@ static bool has_lock_target(POOL_CONNECTION *frontend, if (table) { - if (pool_has_pgpool_regclass()) - snprintf(qbuf, sizeof(qbuf), "SELECT 1 FROM pgpool_catalog.insert_lock WHERE reloid = pgpool_regclass('\"%s\"')%s", table, suffix); + if (pool_has_to_regclass()) + snprintf(qbuf, sizeof(qbuf), "SELECT 1 FROM pgpool_catalog.insert_lock WHERE reloid = to_regclass('%s')%s", table, suffix); + else if (pool_has_pgpool_regclass()) + snprintf(qbuf, sizeof(qbuf), "SELECT 1 FROM pgpool_catalog.insert_lock WHERE reloid = pgpool_regclass('%s')%s", table, suffix); else - snprintf(qbuf, sizeof(qbuf), "SELECT 1 FROM pgpool_catalog.insert_lock WHERE reloid = (SELECT oid FROM pg_catalog.pg_class WHERE relname = '\"%s\"' ORDER BY oid LIMIT 1)%s", table, suffix); + snprintf(qbuf, sizeof(qbuf), "SELECT 1 FROM pgpool_catalog.insert_lock WHERE reloid = (SELECT oid FROM pg_catalog.pg_class WHERE relname = '%s' ORDER BY oid LIMIT 1)%s", table, suffix); } else { @@ -3280,10 +3285,12 @@ static POOL_STATUS insert_oid_into_insert_lock(POOL_CONNECTION *frontend, if (table) { - if (pool_has_pgpool_regclass()) - snprintf(qbuf, sizeof(qbuf), "INSERT INTO pgpool_catalog.insert_lock VALUES (pgpool_regclass('\"%s\"'))", table); + if (pool_has_to_regclass()) + snprintf(qbuf, sizeof(qbuf), "INSERT INTO pgpool_catalog.insert_lock VALUES (to_regclass('%s'))", table); + else if (pool_has_pgpool_regclass()) + snprintf(qbuf, sizeof(qbuf), "INSERT INTO pgpool_catalog.insert_lock VALUES (pgpool_regclass('%s'))", table); else - snprintf(qbuf, sizeof(qbuf), "INSERT INTO pgpool_catalog.insert_lock SELECT oid FROM pg_catalog.pg_class WHERE relname = '\"%s\"' ORDER BY oid LIMIT 1", table); + snprintf(qbuf, sizeof(qbuf), "INSERT INTO pgpool_catalog.insert_lock SELECT oid FROM pg_catalog.pg_class WHERE relname = '%s' ORDER BY oid LIMIT 1", table); } else { @@ -3338,7 +3345,7 @@ bool is_partition_table(POOL_CONNECTION_POOL *backend, Node *node) static char *get_insert_command_table_name(InsertStmt *node) { POOL_SESSION_CONTEXT *session_context; - static char table[128]; + static char table[MAX_NAME_LEN+1]; char *p; session_context = pool_get_session_context(true); diff --git a/src/rewrite/pool_timestamp.c b/src/rewrite/pool_timestamp.c index 8b125736c..a169a2959 100644 --- a/src/rewrite/pool_timestamp.c +++ b/src/rewrite/pool_timestamp.c @@ -156,14 +156,17 @@ relcache_lookup(TSRewriteContext *ctx) " , false)" \ " FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a " \ " LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum)" \ - " WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = to_regclass('\"%s\"')" \ + " WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = to_regclass('%s')" \ " ORDER BY a.attnum" char *query; + char *table_name; + + table_name = ctx->relname; if (pool_has_to_regclass()) { - query = ATTRDEFQUERY3; + query = ATTRDEFQUERY3; } else if (pool_has_pgpool_regclass()) { @@ -172,6 +175,7 @@ relcache_lookup(TSRewriteContext *ctx) else { query = ATTRDEFQUERY; + table_name = remove_quotes_and_schema_from_relname(table_name); } if (!ts_relcache) @@ -186,7 +190,7 @@ relcache_lookup(TSRewriteContext *ctx) } } - return (TSRel *) pool_search_relcache(ts_relcache, ctx->backend, ctx->relname); + return (TSRel *) pool_search_relcache(ts_relcache, ctx->backend, table_name); } static Node * diff --git a/src/utils/pool_relcache.c b/src/utils/pool_relcache.c index f3c19129b..9872a53c3 100644 --- a/src/utils/pool_relcache.c +++ b/src/utils/pool_relcache.c @@ -93,7 +93,6 @@ void pool_discard_relcache(POOL_RELCACHE *relcache) */ void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backend, char *table) { - char *rel; char *dbname; int i; int maxrefcnt = INT_MAX; @@ -105,22 +104,9 @@ void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backen void *result; ErrorContextCallback callback; - /* Eliminate double quotes */ - rel = palloc(strlen(table)+1); - local_session_id = pool_get_local_session_id(); if (local_session_id < 0) - { - pfree(rel); return NULL; - } - - for(i=0;*table;table++) - { - if (*table != '"') - rel[i++] = *table; - } - rel[i] = '\0'; /* Obtain database name */ dbname = MASTER_CONNECTION(backend)->sp->database; @@ -140,7 +126,7 @@ void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backen } if (strcasecmp(relcache->cache[i].dbname, dbname) == 0 && - strcasecmp(relcache->cache[i].relname, rel) == 0) + strcasecmp(relcache->cache[i].relname, table) == 0) { if (relcache->cache[i].expire > 0) { @@ -148,7 +134,7 @@ void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backen { ereport(DEBUG1, (errmsg("searching relcache"), - errdetail("relcache for database:%s table:%s expired. now:%ld expiration time:%ld", dbname, rel, now, relcache->cache[i].expire))); + errdetail("relcache for database:%s table:%s expired. now:%ld expiration time:%ld", dbname, table, now, relcache->cache[i].expire))); relcache->cache[i].refcnt = 0; break; @@ -158,13 +144,13 @@ void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backen /* Found */ if (relcache->cache[i].refcnt < INT_MAX) relcache->cache[i].refcnt++; - pfree(rel); + return relcache->cache[i].data; } } /* Not in cache. Check the system catalog */ - snprintf(query, sizeof(query), relcache->sql, rel); + snprintf(query, sizeof(query), relcache->sql, table); per_node_statement_log(backend, MASTER_NODE_ID, query); @@ -224,7 +210,7 @@ void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backen if (!relcache->no_cache_if_zero || result) { strlcpy(relcache->cache[index].dbname, dbname, MAX_ITEM_LENGTH); - strlcpy(relcache->cache[index].relname, rel, MAX_ITEM_LENGTH); + strlcpy(relcache->cache[index].relname, table, MAX_ITEM_LENGTH); relcache->cache[index].refcnt = 1; relcache->cache[index].session_id = local_session_id; if (pool_config->relcache_expire > 0) @@ -241,7 +227,6 @@ void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backen (*relcache->unregister_func)(relcache->cache[index].data); relcache->cache[index].data = result; } - pfree(rel); free_select_result(res); return result; @@ -252,6 +237,29 @@ static void SearchRelCacheErrorCb(void *arg) errcontext("while searching system catalog, When relcache is missed"); } + +char *remove_quotes_and_schema_from_relname(char *table) +{ + static char rel[MAX_ITEM_LENGTH]; + char *p; + int i = 0; + + /* get rid of schema name */ + p = strchr(table, '.'); + if (p) + table = p+1; + + /* get rid of quotation marks */ + for (i=0; *table; table++) + { + if (*table != '"') + rel[i++] = *table; + } + rel[i] = '\0'; + + return rel; +} + /* * Standard register/unregister function for "SELECT count(*)" type * query. Returns row count. diff --git a/src/utils/pool_select_walker.c b/src/utils/pool_select_walker.c index 8993fb449..22e18b9d9 100644 --- a/src/utils/pool_select_walker.c +++ b/src/utils/pool_select_walker.c @@ -43,7 +43,6 @@ static bool insertinto_or_locking_clause_walker(Node *node, void *context); static bool is_immutable_function(char *fname); static bool select_table_walker(Node *node, void *context); static bool non_immutable_function_call_walker(Node *node, void *context); -static char *strip_quote(char *str); static char *make_table_name_from_rangevar(RangeVar *rangevar); /* @@ -433,9 +432,12 @@ static bool is_system_catalog(char *table_name) if (table_name == NULL) { - return false; + return false; } + if (!pool_has_to_regclass() && !pool_has_pgpool_regclass()) + table_name = remove_quotes_and_schema_from_relname(table_name); + backend = pool_get_session_context(false)->backend; /* @@ -623,11 +625,11 @@ bool is_unlogged_table(char *table_name) * Query to know if the target table is a unlogged one. This query * is valid in PostgreSQL 9.1 or later. */ -#define ISUNLOGGEDQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '\"%s\"' AND c.relpersistence = 'u'" +#define ISUNLOGGEDQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '%s' AND c.relpersistence = 'u'" -#define ISUNLOGGEDQUERY2 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = pgpool_regclass('\"%s\"') AND c.relpersistence = 'u'" +#define ISUNLOGGEDQUERY2 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = pgpool_regclass('%s') AND c.relpersistence = 'u'" -#define ISUNLOGGEDQUERY3 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = to_regclass('\"%s\"') AND c.relpersistence = 'u'" +#define ISUNLOGGEDQUERY3 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = to_regclass('%s') AND c.relpersistence = 'u'" int hasrelpersistence; static POOL_RELCACHE *hasrelpersistence_cache; @@ -636,9 +638,12 @@ bool is_unlogged_table(char *table_name) if (table_name == NULL) { - return false; + return false; } + if (!pool_has_to_regclass() && !pool_has_pgpool_regclass()) + table_name = remove_quotes_and_schema_from_relname(table_name); + backend = pool_get_session_context(false)->backend; /* @@ -716,9 +721,9 @@ bool is_view(char *table_name) */ #define ISVIEWQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '%s' AND (c.relkind = 'v' OR c.relkind = 'm')" -#define ISVIEWQUERY2 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = pgpool_regclass('\"%s\"') AND (c.relkind = 'v' OR c.relkind = 'm')" +#define ISVIEWQUERY2 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = pgpool_regclass('%s') AND (c.relkind = 'v' OR c.relkind = 'm')" -#define ISVIEWQUERY3 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = to_regclass('\"%s\"') AND (c.relkind = 'v' OR c.relkind = 'm')" +#define ISVIEWQUERY3 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = to_regclass('%s') AND (c.relkind = 'v' OR c.relkind = 'm')" static POOL_RELCACHE *relcache; POOL_CONNECTION_POOL *backend; @@ -727,9 +732,12 @@ bool is_view(char *table_name) if (table_name == NULL) { - return false; + return false; } + if (!pool_has_to_regclass() && !pool_has_pgpool_regclass()) + table_name = remove_quotes_and_schema_from_relname(table_name); + backend = pool_get_session_context(false)->backend; /* PostgreSQL 9.4 or later has to_regclass() */ @@ -982,9 +990,9 @@ int pool_table_name_to_oid(char *table_name) /* * Query to convert table name to oid */ -#define TABLE_TO_OID_QUERY "SELECT pgpool_regclass('\"%s\"')" -#define TABLE_TO_OID_QUERY2 "SELECT oid FROM pg_class WHERE relname = '\"%s\"'" -#define TABLE_TO_OID_QUERY3 "SELECT COALESCE(to_regclass('\"%s\"')::oid, 0)" +#define TABLE_TO_OID_QUERY "SELECT pgpool_regclass('%s')" +#define TABLE_TO_OID_QUERY2 "SELECT oid FROM pg_class WHERE relname = '%s'" +#define TABLE_TO_OID_QUERY3 "SELECT COALESCE(to_regclass('%s')::oid, 0)" int oid = 0; static POOL_RELCACHE *relcache; @@ -996,6 +1004,9 @@ int pool_table_name_to_oid(char *table_name) return oid; } + if (!pool_has_to_regclass() && !pool_has_pgpool_regclass()) + table_name = remove_quotes_and_schema_from_relname(table_name); + backend = pool_get_session_context(false)->backend; if (pool_has_to_regclass()) @@ -1075,7 +1086,6 @@ select_table_walker(Node *node, void *context) RangeVar *rgv = (RangeVar *)node; char *table; int oid; - char *s; table = make_table_name_from_rangevar(rgv); oid = pool_table_name_to_oid(table); @@ -1094,9 +1104,7 @@ select_table_walker(Node *node, void *context) num_oids = ctx->num_oids++; ctx->table_oids[num_oids] = oid; - s = strip_quote(table); - strlcpy(ctx->table_names[num_oids], s, POOL_NAMEDATALEN); - free(s); + strlcpy(ctx->table_names[num_oids], table, POOL_NAMEDATALEN); ereport(DEBUG1, (errmsg("extracting table oids from SELECT statement"), @@ -1108,26 +1116,6 @@ select_table_walker(Node *node, void *context) return raw_expression_tree_walker(node, select_table_walker, context); } -static char *strip_quote(char *str) -{ - char *after; - int i = 0; - - after = malloc(sizeof(char) * strlen(str) + 1); - - do { - if (*str != '"') - { - after[i] = *str; - i++; - } - str++; - } while (*str != '\0'); - - after[i] = '\0'; - - return after; -} /* * makeRangeVarFromNameList @@ -1173,11 +1161,13 @@ static char *make_table_name_from_rangevar(RangeVar *rangevar) /* * Table name. Max size is calculated as follows: * schema name(POOL_NAMEDATALEN byte) - * + single quote(1 byte) + * + quotation marks for schmea name(2 byte) + * + period(1 byte) * + table name (POOL_NAMEDATALEN byte) + * + quotation marks for table name(2 byte) * + NULL(1 byte) */ - static char tablename[POOL_NAMEDATALEN*2+1+1]; + static char tablename[POOL_NAMEDATALEN*2+1+2*2+1]; if (rangevar == NULL) { @@ -1198,7 +1188,9 @@ static char *make_table_name_from_rangevar(RangeVar *rangevar) if (rangevar->schemaname) { - strncpy(tablename, rangevar->schemaname, POOL_NAMEDATALEN); + strcat(tablename, "\""); + strncat(tablename, rangevar->schemaname, POOL_NAMEDATALEN); + strcat(tablename, "\""); strcat(tablename, "."); } @@ -1210,8 +1202,12 @@ static char *make_table_name_from_rangevar(RangeVar *rangevar) return ""; } + strcat(tablename, "\""); strncat(tablename, rangevar->relname, POOL_NAMEDATALEN); + strcat(tablename, "\""); + ereport(DEBUG1, (errmsg("make table name from rangevar: tablename:\"%s\"", tablename))); + return tablename; }