Commit 187e4169 authored by Olivier Bertrand's avatar Olivier Bertrand

- Implement "remote" index (similar to FEDERATED ones) for MYSQL tables.

  Not yet done for ODBC tables.
modified:
  storage/connect/connect.cc
  storage/connect/ha_connect.cc
  storage/connect/ha_connect.h
  storage/connect/mycat.cc
  storage/connect/plgdbsem.h
  storage/connect/reldef.h
  storage/connect/tabdos.h
  storage/connect/tabmysql.cpp
  storage/connect/tabmysql.h
  storage/connect/tabodbc.cpp
  storage/connect/tabodbc.h
  storage/connect/xindex.cpp
  storage/connect/xtable.h

- Return error in "info" on Cardinality error.
modified:
  storage/connect/ha_connect.cc
parent 213ecbbb
......@@ -587,7 +587,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
tbxp= (TDBDOX*)tdbp;
tbxp->SetKindex(NULL);
tbxp->To_Key_Col= NULL;
rc= tbxp->ResetTableOpt(g, ((PTDBASE)tdbp)->GetDef()->Indexable());
rc= tbxp->ResetTableOpt(g, ((PTDBASE)tdbp)->GetDef()->Indexable() == 1);
err:
if (trace > 1)
......@@ -709,7 +709,7 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
const void *key, int len)
{
char *kp= (char*)key;
int n;
int n, x;
short lg;
bool rcb;
RCODE rc;
......@@ -720,9 +720,18 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
if (!ptdb)
return RC_FX;
if (!((PTDBASE)ptdb)->GetDef()->Indexable()) {
else
x= ((PTDBASE)ptdb)->GetDef()->Indexable();
if (!x) {
sprintf(g->Message, "CntIndexRead: Table %s is not indexable", ptdb->GetName());
return RC_FX;
} else if (x == 2) {
// Remote index
if (ptdb->ReadKey(g, op, key, len))
return RC_FX;
goto rnd;
} else
tdbp= (PTDBDOX)ptdb;
......@@ -782,8 +791,9 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
xbp->SetOp(op);
xbp->SetNth(0);
if ((rc= (RCODE)tdbp->ReadDB(g)) == RC_OK)
rc= EvalColumns(g, tdbp);
rnd:
if ((rc= (RCODE)ptdb->ReadDB(g)) == RC_OK)
rc= EvalColumns(g, ptdb);
return rc;
} // end of CntIndexRead
......@@ -795,7 +805,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
bool *incl, key_part_map *kmap)
{
const uchar *p, *kp;
int i, n, k[2];
int i, n, x, k[2];
short lg;
bool b, rcb;
PVAL valp;
......@@ -805,10 +815,16 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
if (!ptdb)
return -1;
else if (!((PTDBASE)ptdb)->GetDef()->Indexable()) {
x= ((PTDBASE)ptdb)->GetDef()->Indexable();
if (!x) {
sprintf(g->Message, "CntIndexRange: Table %s is not indexable", ptdb->GetName());
DBUG_PRINT("Range", ("%s", g->Message));
return -1;
} else if (x == 2) {
// Remote index
return 2;
} else
tdbp= (PTDBDOX)ptdb;
......
This diff is collapsed.
......@@ -198,6 +198,8 @@ public:
int CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf);
int ReadIndexed(uchar *buf, OPVAL op, const uchar* key= NULL,
uint key_len= 0);
bool MakeKeyWhere(PGLOBAL g, char *qry, OPVAL op, char *q,
const void *key, int klen);
/** @brief
The name that will be used for display purposes.
......
......@@ -275,9 +275,10 @@ int GetIndexType(TABTYPE type)
xtyp= 1;
break;
case TAB_MYSQL:
// case TAB_ODBC:
xtyp= 2;
break;
case TAB_ODBC:
// xtyp= 2; Remote indexes not implemented yet
// break;
default:
xtyp= 0;
break;
......
......@@ -158,6 +158,7 @@ enum ALGMOD {AMOD_AUTO = 0, /* PLG chooses best algorithm */
enum MODE {MODE_ERROR = -1, /* Invalid mode */
MODE_ANY = 0, /* Unspecified mode */
MODE_READ = 10, /* Input/Output mode */
MODE_READX = 11, /* Read indexed mode */
MODE_WRITE = 20, /* Input/Output mode */
MODE_UPDATE = 30, /* Input/Output mode */
MODE_INSERT = 40, /* Input/Output mode */
......
......@@ -31,6 +31,7 @@ class DllExport RELDEF : public BLOCK { // Relation definition block
PSZ GetName(void) {return Name;}
PSZ GetDB(void) {return (PSZ)Database;}
PCOLDEF GetCols(void) {return To_Cols;}
PHC GetHandler(void) {return Hc;}
void SetCols(PCOLDEF pcd) {To_Cols = pcd;}
PCATLG GetCat(void) {return Cat;}
virtual const char *GetType(void) = 0;
......@@ -45,7 +46,7 @@ class DllExport RELDEF : public BLOCK { // Relation definition block
int GetSizeCatInfo(PSZ what, PSZ sdef);
int GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size);
char *GetStringCatInfo(PGLOBAL g, PSZ what, PSZ sdef);
virtual bool Indexable(void) {return false;}
virtual int Indexable(void) {return 0;}
virtual bool Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am) = 0;
virtual PTDB GetTable(PGLOBAL g, MODE mode) = 0;
......
......@@ -49,7 +49,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
int GetEnding(void) {return Ending;}
// Methods
virtual bool Indexable(void) {return Compressed != 1;}
virtual int Indexable(void) {return (Compressed != 1) ? 1 : 0;}
virtual bool DeleteIndexFile(PGLOBAL g, PIXDEF pxdf);
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE mode);
......@@ -146,10 +146,10 @@ class DllExport TDBDOS : public TDBASE {
virtual int ReadBuffer(PGLOBAL g) {return Txfp->ReadBuffer(g);}
// Specific routine
virtual int EstimatedLength(PGLOBAL g);
virtual int EstimatedLength(PGLOBAL g);
// Optimization routines
int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add);
virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add);
protected:
// Members
......
......@@ -61,6 +61,7 @@
#include "tabmysql.h"
#include "valblk.h"
#include "tabutil.h"
#include "ha_connect.h"
#if defined(_CONSOLE)
void PrintResult(PGLOBAL, PSEM, PQRYRES);
......@@ -481,16 +482,16 @@ PCOL TDBMYSQL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
/* Note: when implementing EOM filtering, column only used in local */
/* filter should be removed from column list. */
/***********************************************************************/
bool TDBMYSQL::MakeSelect(PGLOBAL g)
bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
{
char *tk = "`";
int rank = 0;
bool b = FALSE;
int len = 0, rank = 0;
bool b = false;
PCOL colp;
//PDBUSER dup = PlgGetUser(g);
if (Query)
return FALSE; // already done
return false; // already done
if (Srcdef) {
Query = Srcdef;
......@@ -506,12 +507,12 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g)
if (!colp->IsSpecial()) {
// if (colp->IsSpecial()) {
// strcpy(g->Message, MSG(NO_SPEC_COL));
// return TRUE;
// return true;
// } else {
if (b)
strcat(Query, ", ");
else
b = TRUE;
b = true;
strcat(strcat(strcat(Query, tk), colp->GetName()), tk);
((PMYCOL)colp)->Rank = rank++;
......@@ -526,16 +527,24 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g)
} // endif ncol
strcat(strcat(strcat(strcat(Query, " FROM "), tk), Tabname), tk);
len = strlen(Query);
if (To_CondFil) {
if (!mx) {
strcat(strcat(Query, " WHERE "), To_CondFil->Body);
len = strlen(Query) + 1;
} else
len += (strlen(To_CondFil->Body) + 256);
if (To_CondFil)
strcat(strcat(Query, " WHERE "), To_CondFil->Body);
} else
len += (mx ? 256 : 1);
if (trace)
htrc("Query=%s\n", Query);
// Now we know how much to suballocate
PlugSubAlloc(g, NULL, strlen(Query) + 1);
return FALSE;
PlugSubAlloc(g, NULL, len);
return false;
} // end of MakeSelect
/***********************************************************************/
......@@ -833,9 +842,9 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
/*********************************************************************/
/* Allocate whatever is used for getting results. */
/*********************************************************************/
if (Mode == MODE_READ) {
if (!MakeSelect(g))
m_Rc = Myc.ExecSQL(g, Query);
if (Mode == MODE_READ || Mode == MODE_READX) {
MakeSelect(g, Mode == MODE_READX);
m_Rc = (Mode == MODE_READ) ? Myc.ExecSQL(g, Query) : RC_OK;
#if 0
if (!Myc.m_Res || !Myc.m_Fields) {
......@@ -994,6 +1003,36 @@ int TDBMYSQL::SendCommand(PGLOBAL g)
} // end of SendCommand
/***********************************************************************/
/* Data Base indexed read routine for MYSQL access method. */
/***********************************************************************/
bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
{
int oldlen = strlen(Query);
bool rc;
if (op == OP_NEXT)
return false;
else if (op == OP_FIRST) {
if (To_CondFil)
strcat(strcat(Query, " WHERE "), To_CondFil->Body);
} else {
if (Myc.m_Res)
Myc.FreeResult();
rc = To_Def->GetHandler()->MakeKeyWhere(g, Query, op, "`", key, len);
if (To_CondFil)
strcat(strcat(strcat(Query, " AND ("), To_CondFil->Body), ")");
} // endif's op
m_Rc = Myc.ExecSQL(g, Query);
Query[oldlen] = 0;
return false;
} // end of ReadKey
/***********************************************************************/
/* Data Base read routine for MYSQL access method. */
/***********************************************************************/
......@@ -1451,7 +1490,7 @@ bool TDBMYEXC::OpenDB(PGLOBAL g)
Use = USE_OPEN; // Do it now in case we are recursively called
if (Mode != MODE_READ) {
if (Mode != MODE_READ && Mode != MODE_READX) {
strcpy(g->Message, "No INSERT/DELETE/UPDATE of MYSQL EXEC tables");
return true;
} // endif Mode
......
......@@ -39,6 +39,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
inline int GetPortnumber(void) {return Portnumber;}
// Methods
virtual int Indexable(void) {return 2;}
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m);
bool ParseURL(PGLOBAL g, char *url, bool b = true);
......@@ -96,6 +97,7 @@ class TDBMYSQL : public TDBASE {
virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g);
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len);
// Specific routines
bool SetColumnRanks(PGLOBAL g);
......@@ -104,7 +106,7 @@ class TDBMYSQL : public TDBASE {
protected:
// Internal functions
bool MakeSelect(PGLOBAL g);
bool MakeSelect(PGLOBAL g, bool mx);
bool MakeInsert(PGLOBAL g);
int BindColumns(PGLOBAL g);
int MakeCommand(PGLOBAL g);
......
......@@ -752,7 +752,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
/*********************************************************************/
/* Make the command and allocate whatever is used for getting results. */
/*********************************************************************/
if (Mode == MODE_READ) {
if (Mode == MODE_READ || Mode == MODE_READX) {
if ((Query = MakeSQL(g, false))) {
for (PODBCCOL colp = (PODBCCOL)Columns; colp;
colp = (PODBCCOL)colp->GetNext())
......@@ -1315,7 +1315,7 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
Use = USE_OPEN; // Do it now in case we are recursively called
if (Mode != MODE_READ) {
if (Mode != MODE_READ && Mode != MODE_READX) {
strcpy(g->Message, "No INSERT/DELETE/UPDATE of XDBC tables");
return true;
} // endif Mode
......
......@@ -90,6 +90,7 @@ class TDBODBC : public TDBASE {
virtual void ResetSize(void);
virtual int GetAffectedRows(void) {return AftRows;}
virtual PSZ GetServer(void) {return "ODBC";}
virtual int Indexable(void) {return 2;}
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
......@@ -100,6 +101,8 @@ class TDBODBC : public TDBASE {
virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g);
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
{return true;}
protected:
// Internal functions
......
......@@ -79,7 +79,7 @@ int PlgMakeIndex(PGLOBAL g, PSZ name, PIXDEF pxdf, bool add)
{
int rc;
PTABLE tablep;
PTDBDOS tdbp;
PTDBASE tdbp;
PCATLG cat = PlgGetCatalog(g, true);
/*********************************************************************/
......@@ -87,13 +87,13 @@ int PlgMakeIndex(PGLOBAL g, PSZ name, PIXDEF pxdf, bool add)
/*********************************************************************/
tablep = new(g) XTAB(name);
if (!(tdbp = (PTDBDOS)cat->GetTable(g, tablep)))
if (!(tdbp = (PTDBASE)cat->GetTable(g, tablep)))
rc = RC_NF;
else if (!tdbp->GetDef()->Indexable()) {
sprintf(g->Message, MSG(TABLE_NO_INDEX), name);
rc = RC_NF;
} else if ((rc = tdbp->MakeIndex(g, pxdf, add)) == RC_INFO)
rc = RC_OK; // No index
rc = RC_OK; // No or remote index
return rc;
} // end of PlgMakeIndex
......
......@@ -107,6 +107,7 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
virtual int DeleteDB(PGLOBAL, int) = 0;
virtual void CloseDB(PGLOBAL) = 0;
virtual int CheckWrite(PGLOBAL g) {return 0;}
virtual bool ReadKey(PGLOBAL, OPVAL, const void *, int) = 0;
protected:
// Members
......@@ -176,6 +177,11 @@ class DllExport TDBASE : public TDB {
virtual PCOL InsertSpecialColumn(PGLOBAL g, PCOL colp);
virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp);
virtual void MarkDB(PGLOBAL g, PTDB tdb2);
virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
{strcpy(g->Message, "Remote index"); return RC_INFO;}
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
{assert(false); return true;}
protected:
// Members
......
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