Commit 8cf33505 authored by Olivier Bertrand's avatar Olivier Bertrand

- Extend the TBL type to support sub-tables of any engines. Not CONNECT

  sub-tables are accessed via the MySQL API like the MYSQL CONNECT tables.

modified:
  mysql-test/suite/connect/r/tbl.result
  mysql-test/suite/connect/t/tbl.test
  storage/connect/catalog.h
  storage/connect/ha_connect.cc
  storage/connect/mycat.cc
  storage/connect/mycat.h
  storage/connect/tabmysql.h
  storage/connect/tabtbl.cpp
parent 1357bffb
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
CREATE TABLE t1 ( CREATE TABLE t1 (
a INT NOT NULL, a INT NOT NULL,
message CHAR(10) NOT NULL) ENGINE=connect; message CHAR(10)) ENGINE=connect;
Warnings: Warnings:
Warning 1105 No table_type. Was set to DOS Warning 1105 No table_type. Was set to DOS
Warning 1105 No file name. Table will use t1.dos Warning 1105 No file name. Table will use t1.dos
...@@ -15,18 +15,18 @@ a message ...@@ -15,18 +15,18 @@ a message
3 t1 3 t1
CREATE TABLE t2 ( CREATE TABLE t2 (
a INT NOT NULL, a INT NOT NULL,
message CHAR(10) NOT NULL) ENGINE=connect TABLE_TYPE=BIN; message CHAR(10)) ENGINE=connect TABLE_TYPE=BIN;
Warnings: Warnings:
Warning 1105 No file name. Table will use t2.bin Warning 1105 No file name. Table will use t2.bin
INSERT INTO t2 VALUES (1,'Testing'),(2,'bin table'),(3,'t2'); INSERT INTO t2 VALUES (1,'Testing'),(2,NULL),(3,'t2');
SELECT * FROM t2; SELECT * FROM t2;
a message a message
1 Testing 1 Testing
2 bin table 2 NULL
3 t2 3 t2
CREATE TABLE t3 ( CREATE TABLE t3 (
a INT NOT NULL, a INT NOT NULL,
message CHAR(10) NOT NULL) ENGINE=connect TABLE_TYPE=CSV; message CHAR(10)) ENGINE=connect TABLE_TYPE=CSV;
Warnings: Warnings:
Warning 1105 No file name. Table will use t3.csv Warning 1105 No file name. Table will use t3.csv
INSERT INTO t3 VALUES (1,'Testing'),(2,'csv table'),(3,'t3'); INSERT INTO t3 VALUES (1,'Testing'),(2,'csv table'),(3,'t3');
...@@ -35,38 +35,50 @@ a message ...@@ -35,38 +35,50 @@ a message
1 Testing 1 Testing
2 csv table 2 csv table
3 t3 3 t3
CREATE TABLE t4 (
ta INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
message CHAR(20)) ENGINE=MyISAM;
INSERT INTO t4 (message) VALUES ('Testing'),('myisam table'),('t4');
SELECT * FROM t4;
ta message
1 Testing
2 myisam table
3 t4
CREATE TABLE total ( CREATE TABLE total (
tabname CHAR(8) NOT NULL SPECIAL='TABID', tabname CHAR(8) NOT NULL SPECIAL='TABID',
ta TINYINT NOT NULL FLAG=1, ta TINYINT NOT NULL FLAG=1,
message CHAR(20) NOT NULL) message CHAR(20))
engine=CONNECT table_type=TBL table_list='t1,t2,t3'; engine=CONNECT table_type=TBL table_list='t1,t2,t3,t4';
select * from total; select * from total;
tabname ta message tabname ta message
t1 1 Testing t1 1 Testing
t1 2 dos table t1 2 dos table
t1 3 t1 t1 3 t1
t2 1 Testing t2 1 Testing
t2 2 bin table t2 2 NULL
t2 3 t2 t2 3 t2
t3 1 Testing t3 1 Testing
t3 2 csv table t3 2 csv table
t3 3 t3 t3 3 t3
t4 1 Testing
t4 2 myisam table
t4 3 t4
select * from total where tabname = 't2'; select * from total where tabname = 't2';
tabname ta message tabname ta message
t2 1 Testing t2 1 Testing
t2 2 bin table t2 2 NULL
t2 3 t2 t2 3 t2
select * from total where tabname = 't2' and ta = 3; select * from total where tabname = 't2' and ta = 3;
tabname ta message tabname ta message
t2 3 t2 t2 3 t2
select * from total where tabname in ('t1','t3'); select * from total where tabname in ('t1','t4');
tabname ta message tabname ta message
t1 1 Testing t1 1 Testing
t1 2 dos table t1 2 dos table
t1 3 t1 t1 3 t1
t3 1 Testing t4 1 Testing
t3 2 csv table t4 2 myisam table
t3 3 t3 t4 3 t4
select * from total where ta = 3 and tabname in ('t1','t2'); select * from total where ta = 3 and tabname in ('t1','t2');
tabname ta message tabname ta message
t1 3 t1 t1 3 t1
...@@ -79,28 +91,36 @@ t1 3 t1 ...@@ -79,28 +91,36 @@ t1 3 t1
t3 1 Testing t3 1 Testing
t3 2 csv table t3 2 csv table
t3 3 t3 t3 3 t3
t4 1 Testing
t4 2 myisam table
t4 3 t4
select * from total where tabname != 't2' and ta = 3; select * from total where tabname != 't2' and ta = 3;
tabname ta message tabname ta message
t1 3 t1 t1 3 t1
t3 3 t3 t3 3 t3
t4 3 t4
select * from total where tabname not in ('t2','t3'); select * from total where tabname not in ('t2','t3');
tabname ta message tabname ta message
t1 1 Testing t1 1 Testing
t1 2 dos table t1 2 dos table
t1 3 t1 t1 3 t1
t4 1 Testing
t4 2 myisam table
t4 3 t4
select * from total where ta = 3 and tabname in ('t2','t3'); select * from total where ta = 3 and tabname in ('t2','t3');
tabname ta message tabname ta message
t2 3 t2 t2 3 t2
t3 3 t3 t3 3 t3
select * from total where ta = 3 or tabname in ('t2','t3'); select * from total where ta = 3 or tabname in ('t2','t4');
tabname ta message tabname ta message
t1 3 t1 t1 3 t1
t2 1 Testing t2 1 Testing
t2 2 bin table t2 2 NULL
t2 3 t2 t2 3 t2
t3 1 Testing
t3 2 csv table
t3 3 t3 t3 3 t3
t4 1 Testing
t4 2 myisam table
t4 3 t4
select * from total where not tabname = 't2'; select * from total where not tabname = 't2';
tabname ta message tabname ta message
t1 1 Testing t1 1 Testing
...@@ -109,15 +129,19 @@ t1 3 t1 ...@@ -109,15 +129,19 @@ t1 3 t1
t3 1 Testing t3 1 Testing
t3 2 csv table t3 2 csv table
t3 3 t3 t3 3 t3
t4 1 Testing
t4 2 myisam table
t4 3 t4
select * from total where tabname = 't2' or tabname = 't1'; select * from total where tabname = 't2' or tabname = 't1';
tabname ta message tabname ta message
t1 1 Testing t1 1 Testing
t1 2 dos table t1 2 dos table
t1 3 t1 t1 3 t1
t2 1 Testing t2 1 Testing
t2 2 bin table t2 2 NULL
t2 3 t2 t2 3 t2
DROP TABLE total; DROP TABLE total;
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t3; DROP TABLE t3;
DROP TABLE t4;
let $MYSQLD_DATADIR= `select @@datadir`; let $MYSQLD_DATADIR= `select @@datadir`;
--echo # --echo #
--echo # Checking TBL tables --echo # Checking TBL tables
--echo # --echo #
CREATE TABLE t1 ( CREATE TABLE t1 (
a INT NOT NULL, a INT NOT NULL,
message CHAR(10) NOT NULL) ENGINE=connect; message CHAR(10)) ENGINE=connect;
INSERT INTO t1 VALUES (1,'Testing'),(2,'dos table'),(3,'t1'); INSERT INTO t1 VALUES (1,'Testing'),(2,'dos table'),(3,'t1');
SELECT * FROM t1; SELECT * FROM t1;
CREATE TABLE t2 ( CREATE TABLE t2 (
a INT NOT NULL, a INT NOT NULL,
message CHAR(10) NOT NULL) ENGINE=connect TABLE_TYPE=BIN; message CHAR(10)) ENGINE=connect TABLE_TYPE=BIN;
INSERT INTO t2 VALUES (1,'Testing'),(2,'bin table'),(3,'t2'); INSERT INTO t2 VALUES (1,'Testing'),(2,NULL),(3,'t2');
SELECT * FROM t2; SELECT * FROM t2;
CREATE TABLE t3 ( CREATE TABLE t3 (
a INT NOT NULL, a INT NOT NULL,
message CHAR(10) NOT NULL) ENGINE=connect TABLE_TYPE=CSV; message CHAR(10)) ENGINE=connect TABLE_TYPE=CSV;
INSERT INTO t3 VALUES (1,'Testing'),(2,'csv table'),(3,'t3'); INSERT INTO t3 VALUES (1,'Testing'),(2,'csv table'),(3,'t3');
SELECT * FROM t3; SELECT * FROM t3;
CREATE TABLE total ( CREATE TABLE t4 (
tabname CHAR(8) NOT NULL SPECIAL='TABID', ta INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
ta TINYINT NOT NULL FLAG=1, message CHAR(20)) ENGINE=MyISAM;
message CHAR(20) NOT NULL) INSERT INTO t4 (message) VALUES ('Testing'),('myisam table'),('t4');
engine=CONNECT table_type=TBL table_list='t1,t2,t3'; SELECT * FROM t4;
select * from total; CREATE TABLE total (
select * from total where tabname = 't2'; tabname CHAR(8) NOT NULL SPECIAL='TABID',
select * from total where tabname = 't2' and ta = 3; ta TINYINT NOT NULL FLAG=1,
select * from total where tabname in ('t1','t3'); message CHAR(20))
select * from total where ta = 3 and tabname in ('t1','t2'); engine=CONNECT table_type=TBL table_list='t1,t2,t3,t4';
select * from total where tabname <> 't2';
select * from total where tabname != 't2' and ta = 3; select * from total;
select * from total where tabname not in ('t2','t3'); select * from total where tabname = 't2';
select * from total where ta = 3 and tabname in ('t2','t3'); select * from total where tabname = 't2' and ta = 3;
select * from total where ta = 3 or tabname in ('t2','t3'); select * from total where tabname in ('t1','t4');
select * from total where not tabname = 't2'; select * from total where ta = 3 and tabname in ('t1','t2');
select * from total where tabname = 't2' or tabname = 't1'; select * from total where tabname <> 't2';
select * from total where tabname != 't2' and ta = 3;
DROP TABLE total; select * from total where tabname not in ('t2','t3');
DROP TABLE t1; select * from total where ta = 3 and tabname in ('t2','t3');
DROP TABLE t2; select * from total where ta = 3 or tabname in ('t2','t4');
DROP TABLE t3; select * from total where not tabname = 't2';
select * from total where tabname = 't2' or tabname = 't1';
DROP TABLE total;
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
...@@ -90,13 +90,16 @@ class DllExport CATALOG { ...@@ -90,13 +90,16 @@ class DllExport CATALOG {
virtual bool ClearName(PGLOBAL g, PSZ name) {return true;} virtual bool ClearName(PGLOBAL g, PSZ name) {return true;}
virtual PRELDEF MakeOneTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am) {return NULL;} virtual PRELDEF MakeOneTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am) {return NULL;}
virtual PRELDEF GetTableDescEx(PGLOBAL g, PTABLE tablep) {return NULL;} virtual PRELDEF GetTableDescEx(PGLOBAL g, PTABLE tablep) {return NULL;}
virtual PRELDEF GetTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am, virtual PRELDEF GetTableDesc(PGLOBAL g, LPCSTR name, LPCSTR type,
PRELDEF *prp = NULL) {return NULL;} PRELDEF *prp = NULL) {return NULL;}
virtual PRELDEF GetFirstTable(PGLOBAL g) {return NULL;} virtual PRELDEF GetFirstTable(PGLOBAL g) {return NULL;}
virtual PRELDEF GetNextTable(PGLOBAL g) {return NULL;} virtual PRELDEF GetNextTable(PGLOBAL g) {return NULL;}
virtual bool TestCond(PGLOBAL g, const char *name, const char *type) {return true;} virtual bool TestCond(PGLOBAL g, const char *name, const char *type)
{return true;}
virtual bool DropTable(PGLOBAL g, PSZ name, bool erase) {return true;} virtual bool DropTable(PGLOBAL g, PSZ name, bool erase) {return true;}
virtual PTDB GetTable(PGLOBAL g, PTABLE tablep, MODE mode = MODE_READ) {return NULL;} virtual PTDB GetTable(PGLOBAL g, PTABLE tablep,
MODE mode = MODE_READ, LPCSTR type = NULL)
{return NULL;}
virtual void TableNames(PGLOBAL g, char *buffer, int maxbuf, int info[]) {} virtual void TableNames(PGLOBAL g, char *buffer, int maxbuf, int info[]) {}
virtual void ColumnNames(PGLOBAL g, char *tabname, char *buffer, virtual void ColumnNames(PGLOBAL g, char *tabname, char *buffer,
int maxbuf, int info[]) {} int maxbuf, int info[]) {}
......
...@@ -832,7 +832,7 @@ char *ha_connect::GetStringOption(char *opname, char *sdef) ...@@ -832,7 +832,7 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
else if (!stricmp(opname, "Data_charset")) else if (!stricmp(opname, "Data_charset"))
opval= (char*)options->data_charset; opval= (char*)options->data_charset;
if (!opval && options->oplist) if (!opval && options && options->oplist)
opval= GetListOption(opname, options->oplist); opval= GetListOption(opname, options->oplist);
if (!opval) { if (!opval) {
...@@ -931,7 +931,7 @@ int ha_connect::GetIntegerOption(char *opname) ...@@ -931,7 +931,7 @@ int ha_connect::GetIntegerOption(char *opname)
else if (!stricmp(opname, "Compressed")) else if (!stricmp(opname, "Compressed"))
opval= (options->compressed); opval= (options->compressed);
if (opval == NO_IVAL && options->oplist) if (opval == NO_IVAL && options && options->oplist)
if ((pv= GetListOption(opname, options->oplist))) if ((pv= GetListOption(opname, options->oplist)))
opval= atoi(pv); opval= atoi(pv);
......
...@@ -581,19 +581,17 @@ bool MYCAT::GetIndexInfo(PGLOBAL g, PTABDEF defp) ...@@ -581,19 +581,17 @@ bool MYCAT::GetIndexInfo(PGLOBAL g, PTABDEF defp)
/* found, make and add the descriptor and return a pointer to it. */ /* found, make and add the descriptor and return a pointer to it. */
/***********************************************************************/ /***********************************************************************/
PRELDEF MYCAT::GetTableDesc(PGLOBAL g, LPCSTR name, PRELDEF MYCAT::GetTableDesc(PGLOBAL g, LPCSTR name,
LPCSTR am, PRELDEF *prp) LPCSTR type, PRELDEF *prp)
{ {
LPCSTR type;
if (xtrace) if (xtrace)
printf("GetTableDesc: name=%s am=%s\n", name, SVP(am)); printf("GetTableDesc: name=%s am=%s\n", name, SVP(type));
// Firstly check whether this table descriptor is in memory // Firstly check whether this table descriptor is in memory
if (To_Desc) if (To_Desc)
return To_Desc; return To_Desc;
// Here get the type of this table // If not specified get the type of this table
if (!(type= Hc->GetStringOption("Type"))) if (!type && !(type= Hc->GetStringOption("Type")))
type= "DOS"; type= "DOS";
return MakeTableDesc(g, name, type); return MakeTableDesc(g, name, type);
...@@ -658,7 +656,7 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am) ...@@ -658,7 +656,7 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am)
/***********************************************************************/ /***********************************************************************/
/* Initialize a Table Description Block construction. */ /* Initialize a Table Description Block construction. */
/***********************************************************************/ /***********************************************************************/
PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode) PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type)
{ {
PRELDEF tdp; PRELDEF tdp;
PTDB tdbp= NULL; PTDB tdbp= NULL;
...@@ -668,7 +666,7 @@ PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode) ...@@ -668,7 +666,7 @@ PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode)
printf("GetTableDB: name=%s\n", name); printf("GetTableDB: name=%s\n", name);
// Look for the description of the requested table // Look for the description of the requested table
tdp= GetTableDesc(g, name, NULL); tdp= GetTableDesc(g, name, type);
if (tdp) { if (tdp) {
if (xtrace) if (xtrace)
......
...@@ -65,8 +65,9 @@ class MYCAT : public CATALOG { ...@@ -65,8 +65,9 @@ class MYCAT : public CATALOG {
bool GetIndexInfo(PGLOBAL g, PTABDEF defp); bool GetIndexInfo(PGLOBAL g, PTABDEF defp);
bool StoreIndex(PGLOBAL g, PTABDEF defp) {return false;} // Temporary bool StoreIndex(PGLOBAL g, PTABDEF defp) {return false;} // Temporary
PRELDEF GetTableDesc(PGLOBAL g, LPCSTR name, PRELDEF GetTableDesc(PGLOBAL g, LPCSTR name,
LPCSTR am, PRELDEF *prp = NULL); LPCSTR type, PRELDEF *prp = NULL);
PTDB GetTable(PGLOBAL g, PTABLE tablep, MODE mode = MODE_READ); PTDB GetTable(PGLOBAL g, PTABLE tablep,
MODE mode = MODE_READ, LPCSTR type = NULL);
void ClearDB(PGLOBAL g); void ClearDB(PGLOBAL g);
protected: protected:
......
...@@ -72,6 +72,7 @@ class TDBMYSQL : public TDBASE { ...@@ -72,6 +72,7 @@ class TDBMYSQL : public TDBASE {
virtual int GetProgMax(PGLOBAL g); virtual int GetProgMax(PGLOBAL g);
virtual void ResetDB(void) {N = 0;} virtual void ResetDB(void) {N = 0;}
virtual int RowNumber(PGLOBAL g, bool b = FALSE); virtual int RowNumber(PGLOBAL g, bool b = FALSE);
void SetDatabase(LPCSTR db) {Database = (char*)db;}
// Database routines // Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
......
...@@ -71,6 +71,9 @@ ...@@ -71,6 +71,9 @@
#include "tabcol.h" #include "tabcol.h"
#include "tabdos.h" // TDBDOS and DOSCOL class dcls #include "tabdos.h" // TDBDOS and DOSCOL class dcls
#include "tabtbl.h" // TDBTBL and TBLCOL classes dcls #include "tabtbl.h" // TDBTBL and TBLCOL classes dcls
#if defined(MYSQL_SUPPORT)
#include "tabmysql.h"
#endif // MYSQL_SUPPORT
#include "ha_connect.h" #include "ha_connect.h"
#include "mycat.h" // For GetHandler #include "mycat.h" // For GetHandler
...@@ -222,8 +225,8 @@ PTDB TDBTBL::GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp) ...@@ -222,8 +225,8 @@ PTDB TDBTBL::GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp)
TABLE_LIST table_list; TABLE_LIST table_list;
TABLE_SHARE *s; TABLE_SHARE *s;
PCATLG cat = To_Def->GetCat(); PCATLG cat = To_Def->GetCat();
PHC hc = ((MYCAT*)cat)->GetHandler(); PHC hc = ((MYCAT*)cat)->GetHandler();
THD *thd = (hc->GetTable())->in_use; THD *thd = (hc->GetTable())->in_use;
if (!thd) if (!thd)
return NULL; // Should not happen anymore return NULL; // Should not happen anymore
...@@ -251,9 +254,29 @@ PTDB TDBTBL::GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp) ...@@ -251,9 +254,29 @@ PTDB TDBTBL::GetSubTable(PGLOBAL g, PTBL tblp, PTABLE tabp)
flags = 24; flags = 24;
if (!open_table_def(thd, s, flags)) { if (!open_table_def(thd, s, flags)) {
hc->tshp = s; if (stricmp((*s->db_plugin)->name.str, "connect")) {
tdbp = cat->GetTable(g, tabp); #if defined(MYSQL_SUPPORT)
hc->tshp = NULL; // Access sub-table via MySQL API
if (!(tdbp= cat->GetTable(g, tabp, MODE_READ, "MYSQL"))) {
sprintf(g->Message, "Cannot access %s.%s", db, tblp->Name);
return NULL;
} // endif Define
if (tabp->GetQualifier())
((PTDBMY)tdbp)->SetDatabase(tabp->GetQualifier());
#else // !MYSQL_SUPPORT
sprintf(g->Message, "%s.%s is not a CONNECT table",
db, tblp->Name);
return NULL;
#endif // MYSQL_SUPPORT
} else {
// Sub-table is a CONNECT table
hc->tshp = s;
tdbp = cat->GetTable(g, tabp);
hc->tshp = NULL;
} // endif plugin
} else } else
sprintf(g->Message, "Error %d opening share\n", s->error); sprintf(g->Message, "Error %d opening share\n", s->error);
...@@ -742,8 +765,12 @@ bool TBLCOL::Init(PGLOBAL g) ...@@ -742,8 +765,12 @@ bool TBLCOL::Init(PGLOBAL g)
} else if (!tdbp->Accept) { } else if (!tdbp->Accept) {
sprintf(g->Message, MSG(NO_MATCHING_COL), Name, tdbp->Tdbp->GetName()); sprintf(g->Message, MSG(NO_MATCHING_COL), Name, tdbp->Tdbp->GetName());
return TRUE; return TRUE;
} else } else {
if (Nullable)
Value->SetNull(true);
Value->Reset(); Value->Reset();
} // endif's
return FALSE; return FALSE;
} // end of Init } // end of Init
...@@ -761,8 +788,8 @@ void TBLCOL::ReadColumn(PGLOBAL g) ...@@ -761,8 +788,8 @@ void TBLCOL::ReadColumn(PGLOBAL g)
Value->SetValue_pval(To_Val); Value->SetValue_pval(To_Val);
// Set null when applicable // Set null when applicable
if (Colp->IsNullable()) if (Nullable)
Value->SetNull(Value->IsZero()); Value->SetNull(Value->IsNull());
} // endif Colp } // endif Colp
......
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