Commit bb597a76 authored by Olivier Bertrand's avatar Olivier Bertrand

- Add test on MYSQL table self reference during CREATE TABLE

  Fix option other ignored when parsing URL

modified:
  storage/connect/ha_connect.cc
  storage/connect/mysql-test/connect/t/mysql.test
  storage/connect/mysql-test/connect/t/mysql_grant.test
  storage/connect/tabmysql.cpp
  storage/connect/tabmysql.h
parent 0f6bcf73
...@@ -3722,6 +3722,25 @@ static void add_option(THD* thd, HA_CREATE_INFO *create_info, ...@@ -3722,6 +3722,25 @@ static void add_option(THD* thd, HA_CREATE_INFO *create_info,
#endif // NEW_WAY #endif // NEW_WAY
} // end of add_option } // end of add_option
// Used to check whether a MYSQL table is created on itself
static bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host,
const char *db, char *tab, const char *src, int port)
{
if (src)
return false;
else if (host && stricmp(host, "localhost") && strcmp(host, "127.0.0.1"))
return false;
else if (db && stricmp(db, s->db.str))
return false;
else if (tab && stricmp(tab, s->table_name.str))
return false;
else if (port && port != GetDefaultPort())
return false;
strcpy(g->Message, "This MySQL table is defined on itself");
return true;
} // end of CheckSelf
/** /**
@brief @brief
connect_assisted_discovery() is called when creating a table with no columns. connect_assisted_discovery() is called when creating a table with no columns.
...@@ -3740,7 +3759,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -3740,7 +3759,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
{ {
char spc= ',', qch= 0; char spc= ',', qch= 0;
const char *fncn= "?"; const char *fncn= "?";
const char *user, *fn, *db, *host, *pwd, *prt, *sep, *tbl, *src; const char *user, *fn, *db, *host, *pwd, *sep, *tbl, *src;
const char *col, *ocl, *rnk, *pic, *fcl; const char *col, *ocl, *rnk, *pic, *fcl;
char *tab, *dsn; char *tab, *dsn;
#if defined(WIN32) #if defined(WIN32)
...@@ -3767,7 +3786,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -3767,7 +3786,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
if (!g) if (!g)
return HA_ERR_INTERNAL_ERROR; return HA_ERR_INTERNAL_ERROR;
user= host= pwd= prt= tbl= src= col= ocl= pic= fcl= rnk= dsn= NULL; user= host= pwd= tbl= src= col= ocl= pic= fcl= rnk= dsn= NULL;
// Get the useful create options // Get the useful create options
ttp= GetTypeID(topt->type); ttp= GetTypeID(topt->type);
...@@ -3795,14 +3814,13 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -3795,14 +3814,13 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
fcl= GetListOption(g, "fnccol", topt->oplist, NULL); fcl= GetListOption(g, "fnccol", topt->oplist, NULL);
rnk= GetListOption(g, "rankcol", topt->oplist, NULL); rnk= GetListOption(g, "rankcol", topt->oplist, NULL);
pwd= GetListOption(g, "password", topt->oplist); pwd= GetListOption(g, "password", topt->oplist);
prt= GetListOption(g, "port", topt->oplist);
port= (prt) ? atoi(prt) : 0;
#if defined(WIN32) #if defined(WIN32)
nsp= GetListOption(g, "namespace", topt->oplist); nsp= GetListOption(g, "namespace", topt->oplist);
cls= GetListOption(g, "class", topt->oplist); cls= GetListOption(g, "class", topt->oplist);
#endif // WIN32 #endif // WIN32
port= atoi(GetListOption(g, "port", topt->oplist, "0"));
mxr= atoi(GetListOption(g,"maxerr", topt->oplist, "0")); mxr= atoi(GetListOption(g,"maxerr", topt->oplist, "0"));
cop= atoi(GetListOption(g, "createopt", topt->oplist, "0")); cop= atoi(GetListOption(g, "checkdsn", topt->oplist, "0"));
} else { } else {
host= "localhost"; host= "localhost";
user= "root"; user= "root";
...@@ -3848,7 +3866,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -3848,7 +3866,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
} // endif p } // endif p
} else if (ttp != TAB_ODBC || !(fnc & (FNC_TABLE | FNC_COL))) } else if (ttp != TAB_ODBC || !(fnc & (FNC_TABLE | FNC_COL)))
tab= (char*)create_info->alias; tab= table_s->table_name.str; // Default value
#if defined(NEW_WAY) #if defined(NEW_WAY)
add_option(thd, create_info, "tabname", tab); add_option(thd, create_info, "tabname", tab);
...@@ -3863,12 +3881,10 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -3863,12 +3881,10 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
if (fnc & (FNC_DSN | FNC_DRIVER)) if (fnc & (FNC_DSN | FNC_DRIVER))
ok= true; ok= true;
else if (!stricmp(thd->main_security_ctx.host, "localhost") else if (!stricmp(thd->main_security_ctx.host, "localhost")
&& cop != 2) { && cop == 1) {
if ((dsn = ODBCCheckConnection(g, dsn, cop)) != NULL) { if ((dsn = ODBCCheckConnection(g, dsn, cop)) != NULL) {
create_info->connect_string.str= dsn; thd->make_lex_string(&create_info->connect_string, dsn, strlen(dsn));
create_info->connect_string.length= strlen(dsn);
ok= true; ok= true;
} // endif dsn } // endif dsn
} else if (!dsn) } else if (!dsn)
...@@ -3893,31 +3909,46 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, ...@@ -3893,31 +3909,46 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
case TAB_MYSQL: case TAB_MYSQL:
ok= true; ok= true;
if ((dsn= create_info->connect_string.str)) { if (create_info->connect_string.str) {
int len= create_info->connect_string.length;
PMYDEF mydef= new(g) MYSQLDEF(); PMYDEF mydef= new(g) MYSQLDEF();
PDBUSER dup= PlgGetUser(g); PDBUSER dup= PlgGetUser(g);
PCATLG cat= (dup) ? dup->Catalog : NULL; PCATLG cat= (dup) ? dup->Catalog : NULL;
dsn= (char*)PlugSubAlloc(g, NULL, strlen(dsn) + 1); dsn= (char*)PlugSubAlloc(g, NULL, len + 1);
strncpy(dsn, create_info->connect_string.str, strncpy(dsn, create_info->connect_string.str, len);
create_info->connect_string.length); dsn[len]= 0;
dsn[create_info->connect_string.length]= 0;
mydef->SetName(create_info->alias); mydef->SetName(create_info->alias);
mydef->SetCat(cat); mydef->SetCat(cat);
if (!mydef->ParseURL(g, dsn)) { if (!mydef->ParseURL(g, dsn, false)) {
host= mydef->GetHostname(); if (mydef->GetHostname())
user= mydef->GetUsername(); host= mydef->GetHostname();
pwd= mydef->GetPassword();
db= mydef->GetDatabase(); if (mydef->GetUsername())
tab= mydef->GetTabname(); user= mydef->GetUsername();
port= mydef->GetPortnumber();
if (mydef->GetPassword())
pwd= mydef->GetPassword();
if (mydef->GetDatabase())
db= mydef->GetDatabase();
if (mydef->GetTabname())
tab= mydef->GetTabname();
if (mydef->GetPortnumber())
port= mydef->GetPortnumber();
} else } else
ok= false; ok= false;
} else if (!user) } else if (!user)
user= "root"; user= "root";
if (CheckSelf(g, table_s, host, db, tab, src, port))
ok= false;
break; break;
#endif // MYSQL_SUPPORT #endif // MYSQL_SUPPORT
#if defined(WIN32) #if defined(WIN32)
...@@ -4276,6 +4307,54 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -4276,6 +4307,54 @@ int ha_connect::create(const char *name, TABLE *table_arg,
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
} // endif tabname } // endif tabname
case TAB_MYSQL:
{const char *src= options->srcdef;
char *host, *db, *tab= (char*)options->tabname;
int port;
host= GetListOption(g, "host", options->oplist, NULL);
db= GetListOption(g, "database", options->oplist, NULL);
port= atoi(GetListOption(g, "port", options->oplist, "0"));
if (create_info->connect_string.str) {
char *dsn;
int len= create_info->connect_string.length;
PMYDEF mydef= new(g) MYSQLDEF();
PDBUSER dup= PlgGetUser(g);
PCATLG cat= (dup) ? dup->Catalog : NULL;
dsn= (char*)PlugSubAlloc(g, NULL, len + 1);
strncpy(dsn, create_info->connect_string.str, len);
dsn[len]= 0;
mydef->SetName(create_info->alias);
mydef->SetCat(cat);
if (!mydef->ParseURL(g, dsn, false)) {
if (mydef->GetHostname())
host= mydef->GetHostname();
if (mydef->GetDatabase())
db= mydef->GetDatabase();
if (mydef->GetTabname())
tab= mydef->GetTabname();
if (mydef->GetPortnumber())
port= mydef->GetPortnumber();
} else {
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
} // endif ParseURL
} // endif connect_string
if (CheckSelf(g, table_arg->s, host, db, tab, src, port)) {
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
} // endif CheckSelf
}break;
default: /* do nothing */; default: /* do nothing */;
break; break;
} // endswitch ttp } // endswitch ttp
......
...@@ -10,7 +10,7 @@ let $PORT= `select @@port`; ...@@ -10,7 +10,7 @@ let $PORT= `select @@port`;
--disable_query_log --disable_query_log
--replace_result $PORT PORT --replace_result $PORT PORT
--error 0,ER_UNKNOWN_ERROR --error 0,ER_UNKNOWN_ERROR
--eval CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT' --eval CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='tx1' OPTION_LIST='host=localhost,user=root,port=$PORT'
if (!`SELECT count(*) FROM INFORMATION_SCHEMA.TABLES if (!`SELECT count(*) FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1' WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'
AND ENGINE='CONNECT' AND ENGINE='CONNECT'
......
-- source include/not_embedded.inc -- source include/not_embedded.inc
let $PORT= `select @@port`; let $PORT= `select @@port`;
--disable_query_log --disable_query_log
--replace_result $PORT PORT --replace_result $PORT PORT
--error 0,ER_UNKNOWN_ERROR --error 0,ER_UNKNOWN_ERROR
--eval CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT' --eval CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='tx1' OPTION_LIST='host=localhost,user=root,port=$PORT'
if (!`SELECT count(*) FROM INFORMATION_SCHEMA.TABLES if (!`SELECT count(*) FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1' WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'
AND ENGINE='CONNECT' AND ENGINE='CONNECT'
AND CREATE_OPTIONS LIKE '%`table_type`=MySQL%'`) AND CREATE_OPTIONS LIKE '%`table_type`=MySQL%'`)
{ {
Skip Need MySQL support; Skip Need MySQL support;
} }
DROP TABLE t1; DROP TABLE t1;
--enable_query_log --enable_query_log
--echo # --echo #
--echo # Testing FILE privilege --echo # Testing FILE privilege
--echo # --echo #
GRANT ALL PRIVILEGES ON *.* TO user@localhost; GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost; REVOKE FILE ON *.* FROM user@localhost;
--connect(user,localhost,user,,) --connect(user,localhost,user,,)
--connection user --connection user
SELECT user(); SELECT user();
--replace_result $PORT PORT --replace_result $PORT PORT
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
--eval CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=MySQL OPTION_LIST='host=localhost,user=root1,port=$PORT' --eval CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=MySQL OPTION_LIST='host=localhost,user=root1,port=$PORT'
--connection default --connection default
SELECT user(); SELECT user();
CREATE TABLE t1remote (a INT NOT NULL); CREATE TABLE t1remote (a INT NOT NULL);
INSERT INTO t1remote VALUES (10),(20),(30); INSERT INTO t1remote VALUES (10),(20),(30);
--replace_result $PORT PORT --replace_result $PORT PORT
--eval CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=MySQL TABNAME=t1remote OPTION_LIST='host=localhost,user=root,port=$PORT' --eval CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=MySQL TABNAME=t1remote OPTION_LIST='host=localhost,user=root,port=$PORT'
SELECT * FROM t1; SELECT * FROM t1;
--connection user --connection user
SELECT user(); SELECT user();
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
SELECT * FROM t1; SELECT * FROM t1;
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
INSERT INTO t1 VALUES ('xxx'); INSERT INTO t1 VALUES ('xxx');
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
DELETE FROM t1 WHERE a='xxx'; DELETE FROM t1 WHERE a='xxx';
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
UPDATE t1 SET a='yyy' WHERE a='xxx'; UPDATE t1 SET a='yyy' WHERE a='xxx';
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
ALTER TABLE t1 READONLY=1; ALTER TABLE t1 READONLY=1;
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
CREATE VIEW v1 AS SELECT * FROM t1; CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE --echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--connection default --connection default
SELECT user(); SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1; CREATE VIEW v1 AS SELECT * FROM t1;
--connection user --connection user
SELECT user(); SELECT user();
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
SELECT * FROM v1; SELECT * FROM v1;
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
INSERT INTO v1 VALUES (2); INSERT INTO v1 VALUES (2);
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
UPDATE v1 SET a=123; UPDATE v1 SET a=123;
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
DELETE FROM v1; DELETE FROM v1;
--disconnect user --disconnect user
--connection default --connection default
SELECT user(); SELECT user();
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1, t1remote; DROP TABLE t1, t1remote;
DROP USER user@localhost; DROP USER user@localhost;
--echo # --echo #
--echo # Testing FILE privileges done --echo # Testing FILE privileges done
--echo # --echo #
...@@ -172,7 +172,7 @@ bool MYSQLDEF::GetServerInfo(PGLOBAL g, const char *server_name) ...@@ -172,7 +172,7 @@ bool MYSQLDEF::GetServerInfo(PGLOBAL g, const char *server_name)
/* true error */ /* true error */
/* */ /* */
/***********************************************************************/ /***********************************************************************/
bool MYSQLDEF::ParseURL(PGLOBAL g, char *url) bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b)
{ {
if ((!strstr(url, "://") && (!strchr(url, '@')))) { if ((!strstr(url, "://") && (!strchr(url, '@')))) {
// No :// or @ in connection string. Must be a straight // No :// or @ in connection string. Must be a straight
...@@ -249,34 +249,41 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url) ...@@ -249,34 +249,41 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
if ((Database = strchr(Hostname, '/'))) { if ((Database = strchr(Hostname, '/'))) {
*Database++ = 0; *Database++ = 0;
if ((Tabname = strchr(Database, '/'))) if ((Tabname = strchr(Database, '/'))) {
*Tabname++ = 0; *Tabname++ = 0;
// Make sure there's not an extra / // Make sure there's not an extra /
if ((strchr(Tabname, '/'))) { if ((strchr(Tabname, '/'))) {
strcpy(g->Message, "Syntax error in URL"); strcpy(g->Message, "Syntax error in URL");
return true; return true;
} // endif / } // endif /
} // endif Tabname
} // endif database } // endif database
if ((sport = strchr(Hostname, ':'))) if ((sport = strchr(Hostname, ':')))
*sport++ = 0; *sport++ = 0;
Portnumber = (sport && sport[0]) ? atoi(sport) : GetDefaultPort(); // For unspecified values, get the values of old style options
// but only if called from MYSQLDEF, else set them to NULL
Portnumber = (sport && sport[0]) ? atoi(sport)
: (b) ? Cat->GetIntCatInfo("Port", GetDefaultPort()) : 0;
if (Username[0] == 0) if (Username[0] == 0)
Username = Cat->GetStringCatInfo(g, "User", "*"); Username = (b) ? Cat->GetStringCatInfo(g, "User", "*") : NULL;
if (Hostname[0] == 0) if (Hostname[0] == 0)
Hostname = Cat->GetStringCatInfo(g, "Host", "localhost"); Hostname = (b) ? Cat->GetStringCatInfo(g, "Host", "localhost") : NULL;
if (!Database || !*Database) if (!Database || !*Database)
Database = Cat->GetStringCatInfo(g, "Database", "*"); Database = (b) ? Cat->GetStringCatInfo(g, "Database", "*") : NULL;
if (!Tabname || !*Tabname) if (!Tabname || !*Tabname)
Tabname = Name; Tabname = (b) ? Cat->GetStringCatInfo(g, "Tabname", Name) : NULL;
if (!Password)
Password = (b) ? Cat->GetStringCatInfo(g, "Password", NULL) : NULL;
} // endif URL } // endif URL
#if 0 #if 0
......
...@@ -40,7 +40,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */ ...@@ -40,7 +40,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
// Methods // Methods
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m); virtual PTDB GetTable(PGLOBAL g, MODE m);
bool ParseURL(PGLOBAL g, char *url); bool ParseURL(PGLOBAL g, char *url, bool b = true);
bool GetServerInfo(PGLOBAL g, const char *server_name); bool GetServerInfo(PGLOBAL g, const char *server_name);
protected: protected:
......
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