mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
- 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:
@@ -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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
} // 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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`;
|
|||||||
--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'
|
||||||
|
@@ -5,7 +5,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'
|
||||||
|
@@ -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)
|
|||||||
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 */
|
|||||||
// 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:
|
||||||
|
Reference in New Issue
Block a user