Fix inconsistency of sequence values in replication mode
authorYugo Nagata <nagata@sraoss.co.jp>
Wed, 19 Aug 2015 07:13:00 +0000 (16:13 +0900)
committerYugo Nagata <nagata@sraoss.co.jp>
Wed, 19 Aug 2015 07:38:32 +0000 (16:38 +0900)
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.

src/include/protocol/protocol_defs.h
src/include/utils/pool_relcache.h
src/protocol/pool_process_query.c
src/rewrite/pool_timestamp.c
src/utils/pool_relcache.c
src/utils/pool_select_walker.c

index 8c413912f8ddb8ee40dc067e08c71acaa06042eb..2e1c6cbcf970ea47d08484d7ab192f3b748367fd 100644 (file)
@@ -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
 
 
index dc6e2ad077dd49c3c017c756b285b6976b2f7242..c7510f429f093b0a85a2ad4b54b03b9340faff07 100644 (file)
@@ -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);
index f4676c8e0cc47ad59bb5a08310b80eaa839626f4..f3c246a69e5c7a708ad749ebd153af32fdf11f29 100644 (file)
@@ -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);
index 8b125736c6b53042130e1bdbc7631bfdcc92f4f1..a169a2959d6f6d8c5bd99c200f0421a8de04b8d9 100644 (file)
@@ -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 *
index f3c19129be40e98c7fefbca97dab57140faeacfc..9872a53c3c0c62bc99e55139b3b677337e49ff40 100644 (file)
@@ -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.
index 8993fb449a5a5b8e5002c4820b9d0cb9c9180eca..22e18b9d943b092db3c5a5e27f5e960a79a1d390 100644 (file)
@@ -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;
 }