summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroshi Inoue2017-07-24 07:53:37 +0000
committerHiroshi Inoue2017-07-24 23:00:34 +0000
commitfc5cd3a9207795d38cb940325fc1e284286ff2f8 (patch)
tree076be1740e58cb8474413a5275ec0e75633d59e4
parente6499dc0b8bc46f4f1575b4b6a460fb04db91619 (diff)
Make quote_table() and ti_quote() thread safe.
This change fixes "relation does not exist" errors reported by Scott Beil. Original patch by Scott Beil, modified by me.
-rw-r--r--misc.c8
-rw-r--r--misc.h2
-rw-r--r--results.c37
3 files changed, 28 insertions, 19 deletions
diff --git a/misc.c b/misc.c
index 8617080..3f164fc 100644
--- a/misc.c
+++ b/misc.c
@@ -284,12 +284,10 @@ strlcat(char *dst, const char *src, size_t size)
/*
* Proprly quote and escape a possibly schema-qualified table name.
- * Returns a statically allocated buffer.
*/
char *
-quote_table(const pgNAME schema, const pgNAME table)
+quote_table(const pgNAME schema, const pgNAME table, char *buf, int buf_size)
{
- static char buf[200];
const char *ptr;
int i;
@@ -298,7 +296,7 @@ quote_table(const pgNAME schema, const pgNAME table)
if (NAME_IS_VALID(schema))
{
buf[i++] = '"';
- for (ptr = SAFE_NAME(schema); *ptr != '\0' && i < sizeof(buf) - 6; ptr++)
+ for (ptr = SAFE_NAME(schema); *ptr != '\0' && i < buf_size - 6; ptr++)
{
buf[i++] = *ptr;
if (*ptr == '"')
@@ -309,7 +307,7 @@ quote_table(const pgNAME schema, const pgNAME table)
}
buf[i++] = '"';
- for (ptr = SAFE_NAME(table); *ptr != '\0' && i < sizeof(buf) - 3; ptr++)
+ for (ptr = SAFE_NAME(table); *ptr != '\0' && i < buf_size - 3; ptr++)
{
buf[i++] = *ptr;
if (*ptr == '"')
diff --git a/misc.h b/misc.h
index 07c44c4..dda2758 100644
--- a/misc.h
+++ b/misc.h
@@ -28,7 +28,7 @@ size_t snprintf_len(char *buf, size_t size, const char *format, ...);
char *my_trim(char *string);
char *make_string(const SQLCHAR *s, SQLINTEGER len, char *buf, size_t bufsize);
/* #define GET_SCHEMA_NAME(nspname) (stricmp(nspname, "public") ? nspname : "") */
-char *quote_table(const pgNAME schema, const pgNAME table);
+char *quote_table(const pgNAME schema, const pgNAME table, char *buf, int nuf_size);
#define GET_SCHEMA_NAME(nspname) (nspname)
diff --git a/results.c b/results.c
index 2142ce4..82d8a5b 100644
--- a/results.c
+++ b/results.c
@@ -2161,13 +2161,13 @@ inolog("[%d,%d] %s copied\n", i / num_fields, i % num_fields, otuple->value);
}
static const char *
-ti_quote(StatementClass *stmt, OID tableoid)
+ti_quote(StatementClass *stmt, OID tableoid, char *buf, int buf_size)
{
TABLE_INFO *ti = stmt->ti[0];
pgNAME rNAME;
if (0 == tableoid || !TI_has_subclass(ti))
- return quote_table(ti->schema_name, ti->table_name);
+ return quote_table(ti->schema_name, ti->table_name, buf, buf_size);
else if (NAME_IS_VALID(rNAME = TI_From_IH(ti, tableoid)))
return SAFE_NAME(rNAME);
else
@@ -2185,7 +2185,7 @@ ti_quote(StatementClass *stmt, OID tableoid)
SET_NAME_DIRECTLY(schema_name, QR_get_value_backend_text(res, 0, 1));
SET_NAME_DIRECTLY(table_name, QR_get_value_backend_text(res, 0, 0));
- ret = quote_table(schema_name, table_name);
+ ret = quote_table(schema_name, table_name, buf, buf_size);
TI_Ins_IH(ti, tableoid, ret);
}
QR_Destructor(res);
@@ -2200,10 +2200,11 @@ static BOOL tupleExists(StatementClass *stmt, const KeySet *keyset)
QResultClass *res;
RETCODE ret = FALSE;
const char *bestqual = GET_NAME(ti->bestqual);
+ char table_fqn[256];
SPRINTF_FIXED(selstr,
"select 1 from %s where ctid = '(%u,%u)'",
- ti_quote(stmt, keyset->oid),
+ ti_quote(stmt, keyset->oid, table_fqn, sizeof(table_fqn)),
keyset->blocknum, keyset->offset);
if (NULL != bestqual && 0 != keyset->oid && !TI_has_subclass(ti))
{
@@ -3036,7 +3037,10 @@ inolog("%s bestitem=%s bestqual=%s\n", func, SAFE_NAME(ti->bestitem), SAFE_NAME(
if (TI_has_subclass(ti))
{
OID tableoid = *oidint;
+ char table_fqn[256];
+ const char *quoted_table;
+ quoted_table = ti_quote(stmt, tableoid, table_fqn, sizeof(table_fqn));
if (tidval)
{
if (latest)
@@ -3044,15 +3048,15 @@ inolog("%s bestitem=%s bestqual=%s\n", func, SAFE_NAME(ti->bestitem), SAFE_NAME(
snprintf(selstr, len,
"%.*sfrom %s where ctid = currtid2('%s', '%s')",
(int) from_pos, load_stmt,
- ti_quote(stmt, tableoid),
- ti_quote(stmt, tableoid),
+ quoted_table,
+ quoted_table,
tidval);
}
else
- snprintf(selstr, len, "%.*sfrom %s where ctid = '%s'", (int) from_pos, load_stmt, ti_quote(stmt, tableoid), tidval);
+ snprintf(selstr, len, "%.*sfrom %s where ctid = '%s'", (int) from_pos, load_stmt, quoted_table, tidval);
}
else if ((flag & USE_INSERTED_TID) != 0)
- snprintf(selstr, len, "%.*sfrom %s where ctid = currtid(0, '(0,0)')", (int) from_pos, load_stmt, ti_quote(stmt, tableoid));
+ snprintf(selstr, len, "%.*sfrom %s where ctid = currtid(0, '(0,0)')", (int) from_pos, load_stmt, quoted_table);
/*
else if (bestitem && oidint)
{
@@ -3070,10 +3074,12 @@ inolog("%s bestitem=%s bestqual=%s\n", func, SAFE_NAME(ti->bestitem), SAFE_NAME(
{
if (latest)
{
+ char table_fqn[256];
+
snprintf(selstr, len,
"%s where ctid = currtid2('%s', '%s') %s",
load_stmt,
- ti_quote(stmt, 0),
+ ti_quote(stmt, 0, table_fqn, sizeof(table_fqn)),
tidval, oideqstr);
}
else
@@ -3539,6 +3545,8 @@ mylog(" %s in rows_per_fetch=%d limitrow=%d\n", __FUNCTION__, rows_per_fetch, li
}
if (!rowc)
{
+ char table_fqn[256];
+
if (!qval)
{
if (rows_per_fetch >= pre_fetch_count * 2)
@@ -3554,7 +3562,7 @@ mylog(" %s in rows_per_fetch=%d limitrow=%d\n", __FUNCTION__, rows_per_fetch, li
SC_MALLOC_return_with_error(qval, char, allen,
stmt, "Couldn't alloc qval", -1);
}
- snprintf(qval, allen, "%.*sfrom %s where ctid in (", (int) from_pos, load_stmt, ti_quote(stmt, new_oid));
+ snprintf(qval, allen, "%.*sfrom %s where ctid in (", (int) from_pos, load_stmt, ti_quote(stmt, new_oid, table_fqn, sizeof(table_fqn)));
}
if (new_oid != oid)
oid = new_oid;
@@ -3920,6 +3928,7 @@ SC_pos_update(StatementClass *stmt,
SQLLEN *used, kres_ridx;
Int4 bind_size = opts->bind_size;
BOOL idx_exist = TRUE;
+ char table_fqn[256];
s.stmt = stmt;
s.irow = irow;
@@ -3974,7 +3983,7 @@ SC_pos_update(StatementClass *stmt,
ti = s.stmt->ti[0];
SPRINTF_FIXED(updstr,
- "update %s set", ti_quote(stmt, oid));
+ "update %s set", ti_quote(stmt, oid, table_fqn, sizeof(table_fqn)));
num_cols = s.irdflds->nfields;
offset = opts->row_offset_ptr ? *opts->row_offset_ptr : 0;
@@ -4120,6 +4129,7 @@ SC_pos_delete(StatementClass *stmt,
const char *bestitem;
const char *bestqual;
BOOL idx_exist = TRUE;
+ char table_fqn[256];
mylog("POS DELETE ti=%p\n", stmt->ti);
if (!(res = SC_get_Curres(stmt)))
@@ -4169,7 +4179,7 @@ SC_pos_delete(StatementClass *stmt,
}
SPRINTF_FIXED(dltstr,
"delete from %s where ctid = '(%u, %u)'",
- ti_quote(stmt, oid), blocknum, offset);
+ ti_quote(stmt, oid, table_fqn, sizeof(table_fqn)), blocknum, offset);
if (bestqual && !TI_has_subclass(ti))
{
SPRINTFCAT_FIXED(dltstr, " and ");
@@ -4409,6 +4419,7 @@ SC_pos_add(StatementClass *stmt,
OID fieldtype;
int unknown_sizes;
int func_cs_count = 0;
+ char table_fqn[256];
mylog("POS ADD fi=%p ti=%p\n", fi, stmt->ti);
s.stmt = stmt;
@@ -4432,7 +4443,7 @@ SC_pos_add(StatementClass *stmt,
SPRINTF_FIXED(addstr,
"insert into %s (",
- ti_quote(s.stmt, 0));
+ ti_quote(s.stmt, 0, table_fqn, sizeof(table_fqn)));
if (PGAPI_AllocStmt(conn, &hstmt, 0) != SQL_SUCCESS)
{
SC_set_error(s.stmt, STMT_NO_MEMORY_ERROR, "internal AllocStmt error", func);