summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--storage/connect/connect.cc30
-rw-r--r--storage/connect/ha_connect.cc320
-rw-r--r--storage/connect/ha_connect.h2
-rw-r--r--storage/connect/mycat.cc5
-rw-r--r--storage/connect/plgdbsem.h1
-rw-r--r--storage/connect/reldef.h3
-rw-r--r--storage/connect/tabdos.h6
-rw-r--r--storage/connect/tabmysql.cpp67
-rw-r--r--storage/connect/tabmysql.h4
-rw-r--r--storage/connect/tabodbc.cpp4
-rw-r--r--storage/connect/tabodbc.h3
-rwxr-xr-xstorage/connect/xindex.cpp6
-rw-r--r--storage/connect/xtable.h6
13 files changed, 287 insertions, 170 deletions
diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc
index 879814833d4..77f23edb79c 100644
--- a/storage/connect/connect.cc
+++ b/storage/connect/connect.cc
@@ -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;
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 79ee89e854b..bf11d59c0ce 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -1217,10 +1217,11 @@ PTDB ha_connect::GetTDB(PGLOBAL g)
if (!xp->CheckQuery(valid_query_id) && tdbp
&& !stricmp(tdbp->GetName(), table_name)
- && (tdbp->GetMode() == xmod
+ && (tdbp->GetMode() == xmod
+ || (tdbp->GetMode() == MODE_READ && xmod == MODE_READX)
|| tdbp->GetAmType() == TYPE_AM_XML)) {
tp= tdbp;
-// tp->SetMode(xmod);
+ tp->SetMode(xmod);
} else if ((tp= CntGetTDB(g, table_name, xmod, this))) {
valid_query_id= xp->last_query_id;
tp->SetMode(xmod);
@@ -1614,6 +1615,88 @@ int ha_connect::CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf)
/***********************************************************************/
+/* Return the where clause for remote indexed read. */
+/***********************************************************************/
+bool ha_connect::MakeKeyWhere(PGLOBAL g, char *qry, OPVAL op, char *q,
+ const void *key, int klen)
+{
+ const uchar *ptr;
+ uint rem, len, stlen; //, prtlen;
+ bool nq, b= false;
+ Field *fp;
+ KEY *kfp;
+ KEY_PART_INFO *kpart;
+
+ if (active_index == MAX_KEY)
+ return 0;
+
+ strcat(qry, " WHERE (");
+ kfp= &table->key_info[active_index];
+ rem= kfp->user_defined_key_parts,
+ len= klen,
+ ptr= (const uchar *)key;
+
+ for (kpart= kfp->key_part; rem; rem--, kpart++) {
+ fp= kpart->field;
+ stlen= kpart->store_length;
+// prtlen= min(stlen, len);
+ nq= fp->str_needs_quotes();
+
+ if (b)
+ strcat(qry, " AND ");
+ else
+ b= true;
+
+ strcat(strncat(strcat(qry, q), fp->field_name, strlen(fp->field_name)), q);
+
+ switch (op) {
+ case OP_EQ:
+ case OP_GT:
+ case OP_GE:
+ strcat(qry, GetValStr(op, false));
+ break;
+ default:
+ strcat(qry, " ??? ");
+ } // endwitch op
+
+ if (nq)
+ strcat(qry, "'");
+
+ if (kpart->key_part_flag & HA_VAR_LENGTH_PART) {
+ String varchar;
+ uint var_length= uint2korr(ptr);
+
+ varchar.set_quick((char*) ptr+HA_KEY_BLOB_LENGTH,
+ var_length, &my_charset_bin);
+ strncat(qry, varchar.ptr(), varchar.length());
+ } else {
+ char strbuff[MAX_FIELD_WIDTH];
+ String str(strbuff, sizeof(strbuff), kpart->field->charset()), *res;
+
+ res= fp->val_str(&str, ptr);
+ strncat(qry, res->ptr(), res->length());
+ } // endif flag
+
+ if (nq)
+ strcat(qry, "'");
+
+ if (stlen >= len)
+ break;
+
+ len-= stlen;
+
+ /* For nullable columns, null-byte is already skipped before, that is
+ ptr was incremented by 1. Since store_length still counts null-byte,
+ we need to subtract 1 from store_length. */
+ ptr+= stlen - test(kpart->null_bit);
+ } // endfor kpart
+
+ strcat(qry, ")");
+ return false;
+} // end of MakeKeyWhere
+
+
+/***********************************************************************/
/* Return the string representing an operator. */
/***********************************************************************/
const char *ha_connect::GetValStr(OPVAL vop, bool neg)
@@ -1738,7 +1821,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
} else {
p1= p2 + strlen(p2);
- strcpy(p1, GetValStr(vop, FALSE));
+ strcpy(p1, GetValStr(vop, false));
p2= p1 + strlen(p1);
} // endif CheckCond
@@ -2092,7 +2175,9 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT* check_opt)
dup->Check |= CHK_OPT;
if (tdbp) {
- if (!((PTDBASE)tdbp)->GetDef()->Indexable()) {
+ if (((PTDBASE)tdbp)->GetDef()->Indexable() == 2) {
+ // Nothing to do for remote index
+ } else if (!((PTDBASE)tdbp)->GetDef()->Indexable()) {
sprintf(g->Message, "optimize: Table %s is not indexable", tdbp->GetName());
my_message(ER_INDEX_REBUILD, g->Message, MYF(0));
rc= HA_ERR_UNSUPPORTED;
@@ -2306,6 +2391,18 @@ int ha_connect::index_init(uint idx, bool sorted)
if (xtrace)
htrc("index_init: this=%p idx=%u sorted=%d\n", this, idx, sorted);
+ if (GetIndexType(GetRealType()) == 2) {
+ // This is a remote index
+ xmod= MODE_READX;
+
+ if (!(rc= rnd_init(0))) {
+ active_index= idx;
+ indexing= 2; // TO DO: mul?
+ } //endif rc
+
+ DBUG_RETURN(rc);
+ } // endif index type
+
if ((rc= rnd_init(0)))
return rc;
@@ -2821,12 +2918,16 @@ int ha_connect::info(uint flag)
if (cat && table)
cat->SetDataPath(g, table->s->db.str);
else
- return HA_ERR_INTERNAL_ERROR; // Should never happen
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen
tdbp= GetTDB(g);
} // endif tdbp
valid_info= CntInfo(g, tdbp, &xinfo);
+
+ if (((signed)xinfo.records) < 0)
+ DBUG_RETURN(HA_ERR_INITIALIZATION); // Error in Cardinality
+
} // endif valid_info
if (flag & HA_STATUS_VARIABLE) {
@@ -3086,7 +3187,7 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
newmode= MODE_ALTER;
break;
default:
- htrc("Unsupported sql_command=%d", thd_sql_command(thd));
+ htrc("Unsupported sql_command=%d\n", thd_sql_command(thd));
strcpy(g->Message, "CONNECT Unsupported command");
my_message(ER_NOT_ALLOWED_COMMAND, g->Message, MYF(0));
newmode= MODE_ERROR;
@@ -3131,7 +3232,7 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
newmode= MODE_ALTER;
break;
default:
- htrc("Unsupported sql_command=%d", thd_sql_command(thd));
+ htrc("Unsupported sql_command=%d\n", thd_sql_command(thd));
strcpy(g->Message, "CONNECT Unsupported command");
my_message(ER_NOT_ALLOWED_COMMAND, g->Message, MYF(0));
newmode= MODE_ERROR;
@@ -3255,87 +3356,88 @@ int ha_connect::external_lock(THD *thd, int lock_type)
// DBUG_RETURN(HA_ERR_INTERNAL_ERROR); causes assert error
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
DBUG_RETURN(0);
- } // endif Indexable
-
- bool oldsep= ((PCHK)g->Xchk)->oldsep;
- bool newsep= ((PCHK)g->Xchk)->newsep;
- PTDBDOS tdp= (PTDBDOS)tdbp;
-
- PDOSDEF ddp= (PDOSDEF)tdp->GetDef();
- PIXDEF xp, xp1, xp2, drp=NULL, adp= NULL;
- PIXDEF oldpix= ((PCHK)g->Xchk)->oldpix;
- PIXDEF newpix= ((PCHK)g->Xchk)->newpix;
- PIXDEF *xlst, *xprc;
-
- ddp->SetIndx(oldpix);
-
- if (oldsep != newsep) {
- // All indexes have to be remade
- ddp->DeleteIndexFile(g, NULL);
- oldpix= NULL;
- ddp->SetIndx(NULL);
- SetBooleanOption("Sepindex", newsep);
- } else if (newsep) {
- // Make the list of dropped indexes
- xlst= &drp; xprc= &oldpix;
+ } else if (((PTDBASE)tdbp)->GetDef()->Indexable() == 1) {
+ bool oldsep= ((PCHK)g->Xchk)->oldsep;
+ bool newsep= ((PCHK)g->Xchk)->newsep;
+ PTDBDOS tdp= (PTDBDOS)tdbp;
+
+ PDOSDEF ddp= (PDOSDEF)tdp->GetDef();
+ PIXDEF xp, xp1, xp2, drp=NULL, adp= NULL;
+ PIXDEF oldpix= ((PCHK)g->Xchk)->oldpix;
+ PIXDEF newpix= ((PCHK)g->Xchk)->newpix;
+ PIXDEF *xlst, *xprc;
+
+ ddp->SetIndx(oldpix);
+
+ if (oldsep != newsep) {
+ // All indexes have to be remade
+ ddp->DeleteIndexFile(g, NULL);
+ oldpix= NULL;
+ ddp->SetIndx(NULL);
+ SetBooleanOption("Sepindex", newsep);
+ } else if (newsep) {
+ // Make the list of dropped indexes
+ xlst= &drp; xprc= &oldpix;
+
+ for (xp2= oldpix; xp2; xp2= xp) {
+ for (xp1= newpix; xp1; xp1= xp1->Next)
+ if (IsSameIndex(xp1, xp2))
+ break; // Index not to drop
- for (xp2= oldpix; xp2; xp2= xp) {
- for (xp1= newpix; xp1; xp1= xp1->Next)
+ xp= xp2->GetNext();
+
+ if (!xp1) {
+ *xlst= xp2;
+ *xprc= xp;
+ *(xlst= &xp2->Next)= NULL;
+ } else
+ xprc= &xp2->Next;
+
+ } // endfor xp2
+
+ if (drp) {
+ // Here we erase the index files
+ ddp->DeleteIndexFile(g, drp);
+ } // endif xp1
+
+ } else if (oldpix) {
+ // TODO: optimize the case of just adding new indexes
+ if (!newpix)
+ ddp->DeleteIndexFile(g, NULL);
+
+ oldpix= NULL; // To remake all indexes
+ ddp->SetIndx(NULL);
+ } // endif sepindex
+
+ // Make the list of new created indexes
+ xlst= &adp; xprc= &newpix;
+
+ for (xp1= newpix; xp1; xp1= xp) {
+ for (xp2= oldpix; xp2; xp2= xp2->Next)
if (IsSameIndex(xp1, xp2))
- break; // Index not to drop
+ break; // Index already made
- xp= xp2->GetNext();
+ xp= xp1->Next;
- if (!xp1) {
- *xlst= xp2;
+ if (!xp2) {
+ *xlst= xp1;
*xprc= xp;
- *(xlst= &xp2->Next)= NULL;
+ *(xlst= &xp1->Next)= NULL;
} else
- xprc= &xp2->Next;
+ xprc= &xp1->Next;
- } // endfor xp2
+ } // endfor xp1
- if (drp) {
- // Here we erase the index files
- ddp->DeleteIndexFile(g, drp);
- } // endif xp1
-
- } else if (oldpix) {
- // TODO: optimize the case of just adding new indexes
- if (!newpix)
- ddp->DeleteIndexFile(g, NULL);
-
- oldpix= NULL; // To remake all indexes
- ddp->SetIndx(NULL);
- } // endif sepindex
-
- // Make the list of new created indexes
- xlst= &adp; xprc= &newpix;
-
- for (xp1= newpix; xp1; xp1= xp) {
- for (xp2= oldpix; xp2; xp2= xp2->Next)
- if (IsSameIndex(xp1, xp2))
- break; // Index already made
-
- xp= xp1->Next;
-
- if (!xp2) {
- *xlst= xp1;
- *xprc= xp;
- *(xlst= &xp1->Next)= NULL;
- } else
- xprc= &xp1->Next;
-
- } // endfor xp1
-
- if (adp)
- // Here we do make the new indexes
- if (tdp->MakeIndex(g, adp, true) == RC_FX) {
- // Make it a warning to avoid crash
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
- 0, g->Message);
- rc= 0;
- } // endif MakeIndex
+ if (adp)
+ // Here we do make the new indexes
+ if (tdp->MakeIndex(g, adp, true) == RC_FX) {
+ // Make it a warning to avoid crash
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
+ 0, g->Message);
+ rc= 0;
+ } // endif MakeIndex
+
+ } // endif indexable
} // endif Tdbp
@@ -4831,7 +4933,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
sprintf(g->Message, "Table type %s is not indexable", options->type);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
rc= HA_ERR_UNSUPPORTED;
- } // endif Indexable
+ } // endif index type
} // endif xdp
@@ -4840,62 +4942,6 @@ int ha_connect::create(const char *name, TABLE *table_arg,
my_message(ER_UNKNOWN_ERROR,
"CONNECT index modification should be in-place", MYF(0));
DBUG_RETURN(HA_ERR_UNSUPPORTED);
-#if 0
- PIXDEF xdp= GetIndexInfo();
- PCHK xcp= (PCHK)g->Xchk;
-
- if (xdp) {
- if (!IsTypeIndexable(type)) {
- g->Xchk= NULL;
- sprintf(g->Message, "Table type %s is not indexable", options->type);
- my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
- rc= HA_ERR_INTERNAL_ERROR;
- } else {
- xcp->newpix= xdp;
- xcp->newsep= GetBooleanOption("Sepindex", false);
- } // endif Indexable
-
- } else if (!xcp->oldpix)
- g->Xchk= NULL;
-
- if (xtrace && g->Xchk)
- htrc("oldsep=%d newsep=%d oldpix=%p newpix=%p\n",
- xcp->oldsep, xcp->newsep, xcp->oldpix, xcp->newpix);
-
-// if (g->Xchk &&
-// (sqlcom != SQLCOM_CREATE_INDEX && sqlcom != SQLCOM_DROP_INDEX)) {
- if (g->Xchk) {
- PIXDEF xp1, xp2;
- bool b= false; // true if index changes
-
- if (xcp->oldsep == xcp->newsep) {
- for (xp1= xcp->newpix, xp2= xcp->oldpix;
- xp1 || xp2;
- xp1= xp1->Next, xp2= xp2->Next)
- if (!xp1 || !xp2 || !IsSameIndex(xp1, xp2)) {
- b= true;
- break;
- } // endif xp1
-
- } else
- b= true;
-
- if (!b)
- g->Xchk= NULL;
-
-#if 0
- if (b) {
- // CONNECT does not support indexing via ALTER TABLE
- my_message(ER_UNKNOWN_ERROR,
- "CONNECT does not support index modification via ALTER TABLE",
- MYF(0));
- DBUG_RETURN(HA_ERR_UNSUPPORTED);
- } // endif b
-#endif // 0
-
- } // endif Xchk
-
-#endif // 0
} // endif Xchk
table= st;
diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h
index 88e8de43ba6..ae7ae010c7d 100644
--- a/storage/connect/ha_connect.h
+++ b/storage/connect/ha_connect.h
@@ -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.
diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc
index 7a6f317526a..10b12c0809b 100644
--- a/storage/connect/mycat.cc
+++ b/storage/connect/mycat.cc
@@ -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;
diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h
index 6d80b8207c5..9466bd83bea 100644
--- a/storage/connect/plgdbsem.h
+++ b/storage/connect/plgdbsem.h
@@ -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 */
diff --git a/storage/connect/reldef.h b/storage/connect/reldef.h
index b46c30317fa..6f6853d9f17 100644
--- a/storage/connect/reldef.h
+++ b/storage/connect/reldef.h
@@ -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;
diff --git a/storage/connect/tabdos.h b/storage/connect/tabdos.h
index a213dd142bf..5ea7847d2c9 100644
--- a/storage/connect/tabdos.h
+++ b/storage/connect/tabdos.h
@@ -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
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index 84a070f1ddf..67eba4061bf 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -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) {
@@ -995,6 +1004,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. */
/***********************************************************************/
int TDBMYSQL::ReadDB(PGLOBAL g)
@@ -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
diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h
index 2ecfe800f88..0387fcc7da9 100644
--- a/storage/connect/tabmysql.h
+++ b/storage/connect/tabmysql.h
@@ -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);
diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp
index 10ac1fda211..4231c5550e0 100644
--- a/storage/connect/tabodbc.cpp
+++ b/storage/connect/tabodbc.cpp
@@ -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
diff --git a/storage/connect/tabodbc.h b/storage/connect/tabodbc.h
index 34c2bb8cfc7..5db8cbb8cff 100644
--- a/storage/connect/tabodbc.h
+++ b/storage/connect/tabodbc.h
@@ -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
diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp
index e2a2020c8c3..1006f0ed17c 100755
--- a/storage/connect/xindex.cpp
+++ b/storage/connect/xindex.cpp
@@ -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
diff --git a/storage/connect/xtable.h b/storage/connect/xtable.h
index 74c0b986d82..027e22f5e01 100644
--- a/storage/connect/xtable.h
+++ b/storage/connect/xtable.h
@@ -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