Commit 0c06320a authored by Anel's avatar Anel Committed by GitHub

MDEV-29687:ODBC tables do not quote identifier names correctly (#2295)

Reviewer: andrew@mariadb.org
parent e1414fc7
......@@ -15,6 +15,7 @@ Table_Cat Table_Schema Table_Name Table_Type Remark
mtr public t1 TABLE
mtr public t2 TABLE
mtr public v1 VIEW
mtr schema1 space_in_column_name TABLE
mtr schema1 t1 TABLE
mtr schema1 t2 TABLE
mtr schema1 t3 TABLE
......@@ -27,6 +28,7 @@ Table_Cat Table_Schema Table_Name Table_Type Remark
mtr public t1 TABLE
mtr public t2 TABLE
mtr public v1 VIEW
mtr schema1 space_in_column_name TABLE
mtr schema1 t1 TABLE
mtr schema1 t2 TABLE
mtr schema1 t3 TABLE
......@@ -39,6 +41,7 @@ Table_Cat Table_Schema Table_Name Table_Type Remark
mtr public t1 TABLE
mtr public t2 TABLE
mtr public v1 VIEW
mtr schema1 space_in_column_name TABLE
mtr schema1 t1 TABLE
mtr schema1 t2 TABLE
mtr schema1 t3 TABLE
......@@ -102,6 +105,7 @@ Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Bu
mtr public t1 a 4 int4 10 4 0 10 0
mtr public t2 a 4 int4 10 4 0 10 0
mtr public v1 a 4 int4 10 4 0 10 1
mtr schema1 space_in_column_name my space column 1 bpchar 20 80 NULL NULL 0
mtr schema1 t1 a 1 bpchar 10 40 NULL NULL 0
mtr schema1 t2 a 1 bpchar 10 40 NULL NULL 0
mtr schema1 t3 a 1 bpchar 10 40 NULL NULL 0
......@@ -115,6 +119,7 @@ Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Bu
mtr public t1 a 4 int4 10 4 0 10 0
mtr public t2 a 4 int4 10 4 0 10 0
mtr public v1 a 4 int4 10 4 0 10 1
mtr schema1 space_in_column_name my space column 1 bpchar 20 80 NULL NULL 0
mtr schema1 t1 a 1 bpchar 10 40 NULL NULL 0
mtr schema1 t2 a 1 bpchar 10 40 NULL NULL 0
mtr schema1 t3 a 1 bpchar 10 40 NULL NULL 0
......@@ -306,3 +311,11 @@ DELETE FROM t1 WHERE a='20';
Warnings:
Note 1105 schema1.t3: 0 affected rows
DROP TABLE t1;
#
# MDEV-29687 ODBC tables do not quote identifier names correctly
#
CREATE TABLE pg_in_maria ENGINE=CONNECT TABNAME='schema1.space_in_column_name' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' quoted=1;
SELECT * from pg_in_maria;
my space column
My value
DROP TABLE pg_in_maria;
......@@ -27,4 +27,6 @@ CREATE TABLE schema1.t2 (a CHAR(10) NOT NULL);
INSERT INTO schema1.t2 VALUES ('xxx'),('yyy'),('zzz'),('ÄÖÜ');
CREATE TABLE schema1.t3 (a CHAR(10) NOT NULL, b CHAR(10) NOT NULL);
INSERT INTO schema1.t3 VALUES ('xxx', 'aaa'),('yyy', 'bbb'),('zzz', 'ccc'),('ÄÖÜ', 'яяя');
CREATE TABLE schema1.space_in_column_name ("my space column" CHAR(20) NOT NULL);
INSERT INTO schema1.space_in_column_name VALUES ('My value');
\dt schema1.*
......@@ -216,3 +216,10 @@ DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(6), b VARCHAR(6), PRIMARY KEY(a, b)) ENGINE=CONNECT TABNAME='schema1.t3' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr';
DELETE FROM t1 WHERE a='20';
DROP TABLE t1;
--echo #
--echo # MDEV-29687 ODBC tables do not quote identifier names correctly
--echo #
CREATE TABLE pg_in_maria ENGINE=CONNECT TABNAME='schema1.space_in_column_name' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' quoted=1;
SELECT * from pg_in_maria;
DROP TABLE pg_in_maria;
......@@ -997,6 +997,11 @@ ODBConn::ODBConn(PGLOBAL g, TDBODBC *tdbp)
m_Full = false;
m_UseCnc = false;
m_IDQuoteChar[0] = '"';
if (tdbp)
{
if (tdbp->Quoted && tdbp->Quote)
m_IDQuoteChar[0] = *tdbp->Quote;
}
m_IDQuoteChar[1] = 0;
//*m_ErrMsg = '\0';
} // end of ODBConn
......@@ -1179,6 +1184,7 @@ int ODBConn::Open(PCSZ ConnectString, POPARM sop, DWORD options)
// Verify support for required functionality and cache info
// VerifyConnect(); Deprecated
GetConnectInfo();
// Still we want to use the set QChar
} catch(DBX *xp) {
snprintf(g->Message, sizeof(g->Message), "%s: %s", xp->m_Msg, xp->GetErrorMessage(0));
Close();
......
......@@ -159,6 +159,9 @@ bool EXTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Maxerr = GetIntCatInfo("Maxerr", 0);
Maxres = GetIntCatInfo("Maxres", 0);
Quoted = GetIntCatInfo("Quoted", 0);
Qchar = GetStringCatInfo(g,"Qchar", NULL);
if (Qchar && !Quoted)
Quoted = 1;
Options = 0;
Cto = 0;
Qto = 0;
......@@ -198,6 +201,7 @@ TDBEXT::TDBEXT(EXTDEF *tdp) : TDB(tdp)
Cto = tdp->Cto;
Qto = tdp->Qto;
Quoted = MY_MAX(0, tdp->GetQuoted());
Quote = tdp->GetQchar();
Rows = tdp->GetElemt();
Memory = tdp->Memory;
Scrollable = tdp->Scrollable;
......@@ -214,12 +218,12 @@ TDBEXT::TDBEXT(EXTDEF *tdp) : TDB(tdp)
Cto = 0;
Qto = 0;
Quoted = 0;
Quote = NULL;
Rows = 0;
Memory = 0;
Scrollable = false;
} // endif tdp
Quote = NULL;
Query = NULL;
Count = NULL;
//Where = NULL;
......@@ -252,6 +256,7 @@ TDBEXT::TDBEXT(PTDBEXT tdbp) : TDB(tdbp)
Cto = tdbp->Cto;
Qto = tdbp->Qto;
Quoted = tdbp->Quoted;
Quote = tdbp->Quote;
Rows = tdbp->Rows;
Memory = tdbp->Memory;
Scrollable = tdbp->Scrollable;
......@@ -390,6 +395,8 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
bool first = true;
PTABLE tablep = To_Table;
PCOL colp;
char *res= NULL, *my_schema_table= NULL;
size_t my_len= 0;
if (Srcdef)
return MakeSrcdef(g);
......@@ -459,10 +466,37 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
Decode(TableName, buf, sizeof(buf));
if (Quote) {
// Tabname can have both database and table identifiers, we need to parse
if (res= strstr(buf, "."))
{
// Parse schema
my_len= res - buf + 1;
my_schema_table= (char *) malloc(my_len);
memcpy(my_schema_table, buf, my_len - 1);
my_schema_table[my_len] = 0;
Query->Append(Quote);
Query->Append(my_schema_table);
Query->Append(Quote);
free(my_schema_table);
Query->Append(".");
// Parse table
my_len= strlen(buf) - my_len + 1;
my_schema_table= (char *) malloc(my_len);
memcpy(my_schema_table, ++res, my_len);
my_schema_table[my_len] = 0;
Query->Append(Quote);
Query->Append(my_schema_table);
Query->Append(Quote);
free(my_schema_table);
}
else
{
// Put table name between identifier quotes in case in contains blanks
Query->Append(Quote);
Query->Append(buf);
Query->Append(Quote);
}
} else
Query->Append(buf);
......
......@@ -68,6 +68,7 @@ class DllExport EXTDEF : public TABDEF { /* EXT table */
inline PSZ GetSrcdef(void) { return Srcdef; }
inline char GetSep(void) { return (Sep) ? *Sep : 0; }
inline int GetQuoted(void) { return Quoted; }
inline PSZ GetQchar(void) { return Qchar; }
inline int GetOptions(void) { return Options; }
// Methods
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment