- 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
This commit is contained in:
parent
0f6bcf73de
commit
bb597a765d
@ -3722,6 +3722,25 @@ static void add_option(THD* thd, HA_CREATE_INFO *create_info,
|
||||
#endif // NEW_WAY
|
||||
} // 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
|
||||
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,
|
||||
{
|
||||
char spc= ',', qch= 0;
|
||||
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;
|
||||
char *tab, *dsn;
|
||||
#if defined(WIN32)
|
||||
@ -3767,7 +3786,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
||||
if (!g)
|
||||
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
|
||||
ttp= GetTypeID(topt->type);
|
||||
@ -3795,14 +3814,13 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
||||
fcl= GetListOption(g, "fnccol", topt->oplist, NULL);
|
||||
rnk= GetListOption(g, "rankcol", topt->oplist, NULL);
|
||||
pwd= GetListOption(g, "password", topt->oplist);
|
||||
prt= GetListOption(g, "port", topt->oplist);
|
||||
port= (prt) ? atoi(prt) : 0;
|
||||
#if defined(WIN32)
|
||||
nsp= GetListOption(g, "namespace", topt->oplist);
|
||||
cls= GetListOption(g, "class", topt->oplist);
|
||||
#endif // WIN32
|
||||
port= atoi(GetListOption(g, "port", 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 {
|
||||
host= "localhost";
|
||||
user= "root";
|
||||
@ -3848,7 +3866,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
||||
} // endif p
|
||||
|
||||
} 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)
|
||||
add_option(thd, create_info, "tabname", tab);
|
||||
@ -3863,12 +3881,10 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
||||
if (fnc & (FNC_DSN | FNC_DRIVER))
|
||||
ok= true;
|
||||
else if (!stricmp(thd->main_security_ctx.host, "localhost")
|
||||
&& cop != 2) {
|
||||
&& cop == 1) {
|
||||
if ((dsn = ODBCCheckConnection(g, dsn, cop)) != NULL) {
|
||||
create_info->connect_string.str= dsn;
|
||||
create_info->connect_string.length= strlen(dsn);
|
||||
thd->make_lex_string(&create_info->connect_string, dsn, strlen(dsn));
|
||||
ok= true;
|
||||
|
||||
} // endif dsn
|
||||
|
||||
} else if (!dsn)
|
||||
@ -3893,31 +3909,46 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
||||
case TAB_MYSQL:
|
||||
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();
|
||||
PDBUSER dup= PlgGetUser(g);
|
||||
PCATLG cat= (dup) ? dup->Catalog : NULL;
|
||||
|
||||
dsn= (char*)PlugSubAlloc(g, NULL, strlen(dsn) + 1);
|
||||
strncpy(dsn, create_info->connect_string.str,
|
||||
create_info->connect_string.length);
|
||||
dsn[create_info->connect_string.length]= 0;
|
||||
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)) {
|
||||
host= mydef->GetHostname();
|
||||
user= mydef->GetUsername();
|
||||
pwd= mydef->GetPassword();
|
||||
db= mydef->GetDatabase();
|
||||
tab= mydef->GetTabname();
|
||||
port= mydef->GetPortnumber();
|
||||
if (!mydef->ParseURL(g, dsn, false)) {
|
||||
if (mydef->GetHostname())
|
||||
host= mydef->GetHostname();
|
||||
|
||||
if (mydef->GetUsername())
|
||||
user= mydef->GetUsername();
|
||||
|
||||
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
|
||||
ok= false;
|
||||
|
||||
} else if (!user)
|
||||
user= "root";
|
||||
|
||||
if (CheckSelf(g, table_s, host, db, tab, src, port))
|
||||
ok= false;
|
||||
|
||||
break;
|
||||
#endif // MYSQL_SUPPORT
|
||||
#if defined(WIN32)
|
||||
@ -4276,6 +4307,54 @@ int ha_connect::create(const char *name, TABLE *table_arg,
|
||||
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
|
||||
} // 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 */;
|
||||
break;
|
||||
} // endswitch ttp
|
||||
|
@ -10,7 +10,7 @@ let $PORT= `select @@port`;
|
||||
--disable_query_log
|
||||
--replace_result $PORT PORT
|
||||
--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
|
||||
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'
|
||||
AND ENGINE='CONNECT'
|
||||
|
@ -1,78 +1,78 @@
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
let $PORT= `select @@port`;
|
||||
|
||||
--disable_query_log
|
||||
--replace_result $PORT PORT
|
||||
--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'
|
||||
if (!`SELECT count(*) FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'
|
||||
AND ENGINE='CONNECT'
|
||||
AND CREATE_OPTIONS LIKE '%`table_type`=MySQL%'`)
|
||||
{
|
||||
Skip Need MySQL support;
|
||||
}
|
||||
DROP TABLE t1;
|
||||
--enable_query_log
|
||||
|
||||
--echo #
|
||||
--echo # Testing FILE privilege
|
||||
--echo #
|
||||
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
|
||||
REVOKE FILE ON *.* FROM user@localhost;
|
||||
--connect(user,localhost,user,,)
|
||||
--connection user
|
||||
SELECT user();
|
||||
--replace_result $PORT PORT
|
||||
--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'
|
||||
--connection default
|
||||
SELECT user();
|
||||
CREATE TABLE t1remote (a INT NOT NULL);
|
||||
INSERT INTO t1remote VALUES (10),(20),(30);
|
||||
--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'
|
||||
SELECT * FROM t1;
|
||||
--connection user
|
||||
SELECT user();
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
SELECT * FROM t1;
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
INSERT INTO t1 VALUES ('xxx');
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
DELETE FROM t1 WHERE a='xxx';
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
UPDATE t1 SET a='yyy' WHERE a='xxx';
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
TRUNCATE TABLE t1;
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
ALTER TABLE t1 READONLY=1;
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
|
||||
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE
|
||||
--connection default
|
||||
SELECT user();
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
--connection user
|
||||
SELECT user();
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
SELECT * FROM v1;
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
INSERT INTO v1 VALUES (2);
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
UPDATE v1 SET a=123;
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
DELETE FROM v1;
|
||||
|
||||
--disconnect user
|
||||
--connection default
|
||||
SELECT user();
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1, t1remote;
|
||||
DROP USER user@localhost;
|
||||
--echo #
|
||||
--echo # Testing FILE privileges done
|
||||
--echo #
|
||||
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
let $PORT= `select @@port`;
|
||||
|
||||
--disable_query_log
|
||||
--replace_result $PORT PORT
|
||||
--error 0,ER_UNKNOWN_ERROR
|
||||
--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
|
||||
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'
|
||||
AND ENGINE='CONNECT'
|
||||
AND CREATE_OPTIONS LIKE '%`table_type`=MySQL%'`)
|
||||
{
|
||||
Skip Need MySQL support;
|
||||
}
|
||||
DROP TABLE t1;
|
||||
--enable_query_log
|
||||
|
||||
--echo #
|
||||
--echo # Testing FILE privilege
|
||||
--echo #
|
||||
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
|
||||
REVOKE FILE ON *.* FROM user@localhost;
|
||||
--connect(user,localhost,user,,)
|
||||
--connection user
|
||||
SELECT user();
|
||||
--replace_result $PORT PORT
|
||||
--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'
|
||||
--connection default
|
||||
SELECT user();
|
||||
CREATE TABLE t1remote (a INT NOT NULL);
|
||||
INSERT INTO t1remote VALUES (10),(20),(30);
|
||||
--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'
|
||||
SELECT * FROM t1;
|
||||
--connection user
|
||||
SELECT user();
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
SELECT * FROM t1;
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
INSERT INTO t1 VALUES ('xxx');
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
DELETE FROM t1 WHERE a='xxx';
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
UPDATE t1 SET a='yyy' WHERE a='xxx';
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
TRUNCATE TABLE t1;
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
ALTER TABLE t1 READONLY=1;
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
|
||||
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE
|
||||
--connection default
|
||||
SELECT user();
|
||||
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||
--connection user
|
||||
SELECT user();
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
SELECT * FROM v1;
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
INSERT INTO v1 VALUES (2);
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
UPDATE v1 SET a=123;
|
||||
--error ER_ACCESS_DENIED_ERROR
|
||||
DELETE FROM v1;
|
||||
|
||||
--disconnect user
|
||||
--connection default
|
||||
SELECT user();
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1, t1remote;
|
||||
DROP USER user@localhost;
|
||||
--echo #
|
||||
--echo # Testing FILE privileges done
|
||||
--echo #
|
||||
|
||||
|
@ -172,7 +172,7 @@ bool MYSQLDEF::GetServerInfo(PGLOBAL g, const char *server_name)
|
||||
/* true error */
|
||||
/* */
|
||||
/***********************************************************************/
|
||||
bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
|
||||
bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b)
|
||||
{
|
||||
if ((!strstr(url, "://") && (!strchr(url, '@')))) {
|
||||
// No :// or @ in connection string. Must be a straight
|
||||
@ -249,34 +249,41 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
|
||||
if ((Database = strchr(Hostname, '/'))) {
|
||||
*Database++ = 0;
|
||||
|
||||
if ((Tabname = strchr(Database, '/')))
|
||||
if ((Tabname = strchr(Database, '/'))) {
|
||||
*Tabname++ = 0;
|
||||
|
||||
// Make sure there's not an extra /
|
||||
if ((strchr(Tabname, '/'))) {
|
||||
strcpy(g->Message, "Syntax error in URL");
|
||||
return true;
|
||||
} // endif /
|
||||
// Make sure there's not an extra /
|
||||
if ((strchr(Tabname, '/'))) {
|
||||
strcpy(g->Message, "Syntax error in URL");
|
||||
return true;
|
||||
} // endif /
|
||||
|
||||
} // endif Tabname
|
||||
|
||||
} // endif database
|
||||
|
||||
if ((sport = strchr(Hostname, ':')))
|
||||
*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)
|
||||
Username = Cat->GetStringCatInfo(g, "User", "*");
|
||||
Username = (b) ? Cat->GetStringCatInfo(g, "User", "*") : NULL;
|
||||
|
||||
if (Hostname[0] == 0)
|
||||
Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
|
||||
Hostname = (b) ? Cat->GetStringCatInfo(g, "Host", "localhost") : NULL;
|
||||
|
||||
if (!Database || !*Database)
|
||||
Database = Cat->GetStringCatInfo(g, "Database", "*");
|
||||
Database = (b) ? Cat->GetStringCatInfo(g, "Database", "*") : NULL;
|
||||
|
||||
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
|
||||
|
||||
#if 0
|
||||
|
@ -40,7 +40,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
|
||||
// Methods
|
||||
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
|
||||
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);
|
||||
|
||||
protected:
|
||||
|
Loading…
x
Reference in New Issue
Block a user