#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
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);
* 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;
*/
/* 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.
*/
* 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;
}
*/
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];
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)
{
}
}
+ if (!pool_has_to_regclass() && !pool_has_pgpool_regclass())
+ table = remove_quotes_and_schema_from_relname(table);
+
/*
* Search relcache.
*/
{
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
{
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);
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
{
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
{
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);
" , 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())
{
else
{
query = ATTRDEFQUERY;
+ table_name = remove_quotes_and_schema_from_relname(table_name);
}
if (!ts_relcache)
}
}
- return (TSRel *) pool_search_relcache(ts_relcache, ctx->backend, ctx->relname);
+ return (TSRel *) pool_search_relcache(ts_relcache, ctx->backend, table_name);
}
static Node *
*/
void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backend, char *table)
{
- char *rel;
char *dbname;
int i;
int maxrefcnt = INT_MAX;
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;
}
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)
{
{
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;
/* 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);
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)
(*relcache->unregister_func)(relcache->cache[index].data);
relcache->cache[index].data = result;
}
- pfree(rel);
free_select_result(res);
return result;
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.
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);
/*
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;
/*
* 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;
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;
/*
*/
#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;
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() */
/*
* 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;
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())
RangeVar *rgv = (RangeVar *)node;
char *table;
int oid;
- char *s;
table = make_table_name_from_rangevar(rgv);
oid = pool_table_name_to_oid(table);
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"),
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
/*
* 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)
{
if (rangevar->schemaname)
{
- strncpy(tablename, rangevar->schemaname, POOL_NAMEDATALEN);
+ strcat(tablename, "\"");
+ strncat(tablename, rangevar->schemaname, POOL_NAMEDATALEN);
+ strcat(tablename, "\"");
strcat(tablename, ".");
}
return "";
}
+ strcat(tablename, "\"");
strncat(tablename, rangevar->relname, POOL_NAMEDATALEN);
+ strcat(tablename, "\"");
+
ereport(DEBUG1,
(errmsg("make table name from rangevar: tablename:\"%s\"", tablename)));
+
return tablename;
}