summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2014-04-26 00:17:26 +0200
committerOlivier Bertrand <bertrandop@gmail.com>2014-04-26 00:17:26 +0200
commit0e20f02174099e0ee79fd5440c84fae9d2796b86 (patch)
treea31858b925286aa3d3927249698d6c1d2ddde158
parent9d29647487e8170d018413aacc6ec580decd59b1 (diff)
downloadmariadb-git-0e20f02174099e0ee79fd5440c84fae9d2796b86.tar.gz
- Implement dynamic indexing
modified: storage/connect/connect.cc storage/connect/filter.cpp storage/connect/filter.h storage/connect/ha_connect.cc storage/connect/ha_connect.h storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/table.cpp storage/connect/xindex.cpp storage/connect/xindex.h storage/connect/xtable.h
-rw-r--r--storage/connect/connect.cc41
-rw-r--r--storage/connect/filter.cpp2
-rw-r--r--storage/connect/filter.h2
-rw-r--r--storage/connect/ha_connect.cc42
-rw-r--r--storage/connect/ha_connect.h3
-rw-r--r--storage/connect/tabdos.cpp84
-rw-r--r--storage/connect/tabdos.h1
-rw-r--r--storage/connect/table.cpp6
-rwxr-xr-xstorage/connect/xindex.cpp25
-rw-r--r--storage/connect/xindex.h5
-rw-r--r--storage/connect/xtable.h4
11 files changed, 187 insertions, 28 deletions
diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc
index 1433a5c6ce4..f7bba541dfa 100644
--- a/storage/connect/connect.cc
+++ b/storage/connect/connect.cc
@@ -651,6 +651,14 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id)
return 0;
} // endif xdp
+ if (xdp->IsDynamic()) {
+ // This is a dynamically created index (KINDEX)
+ // It cannot be created now, before cond_push is executed
+ tdbp->SetXdp(xdp);
+ return (xdp->IsUnique()) ? 1 : 2;
+ } // endif dynamic
+
+ // Static indexes must be initialized now for records_in_range
// Allocate the key columns definition block
tdbp->Knum= xdp->GetNparts();
tdbp->To_Key_Col= (PCOL*)PlugSubAlloc(g, NULL, tdbp->Knum * sizeof(PCOL));
@@ -738,10 +746,23 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
// Set reference values and index operator
if (!tdbp->To_Link || !tdbp->To_Kindex) {
- sprintf(g->Message, "Index not initialized for table %s", tdbp->Name);
- return RC_FX;
- } else
- xbp= (XXBASE*)tdbp->To_Kindex;
+ if (!tdbp->To_Xdp) {
+ sprintf(g->Message, "Index not initialized for table %s", tdbp->Name);
+ return RC_FX;
+ } // endif !To_Xdp
+
+ // Now it's time to make the dynamic index
+ tdbp->SetFilter(tdbp->To_Def->GetHandler()->CheckFilter(g));
+
+ if (tdbp->MakeDynamicIndex(g)) {
+ sprintf(g->Message, "Fail to make dynamic index %s",
+ tdbp->To_Xdp->GetName());
+ return RC_FX;
+ } // endif MakeDynamicIndex
+
+ } // endif !To_Kindex
+
+ xbp= (XXBASE*)tdbp->To_Kindex;
if (key) {
for (n= 0; n < tdbp->Knum; n++) {
@@ -829,10 +850,14 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
} else
tdbp= (PTDBDOX)ptdb;
- if (!tdbp->To_Link || !tdbp->To_Kindex) {
- sprintf(g->Message, "Index not initialized for table %s", tdbp->Name);
- DBUG_PRINT("Range", ("%s", g->Message));
- return -1;
+ if (!tdbp->To_Kindex || !tdbp->To_Link) {
+ if (!tdbp->To_Xdp) {
+ sprintf(g->Message, "Index not initialized for table %s", tdbp->Name);
+ DBUG_PRINT("Range", ("%s", g->Message));
+ return -1;
+ } else // Dynamic index
+ return tdbp->To_Xdp->GetMaxSame(); // TODO a better estimate
+
} else
xbp= (XXBASE*)tdbp->To_Kindex;
diff --git a/storage/connect/filter.cpp b/storage/connect/filter.cpp
index 62453b7b17b..9b646ca58b9 100644
--- a/storage/connect/filter.cpp
+++ b/storage/connect/filter.cpp
@@ -1711,7 +1711,7 @@ PFIL PrepareFilter(PGLOBAL g, PFIL fp, bool having)
/* New algorithm: evaluate from the root a de-linearized filter so */
/* AND/OR clauses can be optimized throughout the whole tree. */
/***********************************************************************/
-DllExport bool ApplyFilter(PGLOBAL g, PFIL filp, PTDB tdbp)
+DllExport bool ApplyFilter(PGLOBAL g, PFIL filp)
{
if (!filp)
return TRUE;
diff --git a/storage/connect/filter.h b/storage/connect/filter.h
index 301b3a128de..85dc6dd4795 100644
--- a/storage/connect/filter.h
+++ b/storage/connect/filter.h
@@ -26,7 +26,7 @@ PFIL MakeFilter(PGLOBAL g, PCOL *colp, POPER pop, PPARM pfirst, bool neg);
/***********************************************************************/
class DllExport FILTER : public XOBJECT { /* Filter description block */
//friend PFIL PrepareFilter(PGLOBAL, PFIL, bool);
- friend DllExport bool ApplyFilter(PGLOBAL, PFIL, PTDB = NULL);
+ friend DllExport bool ApplyFilter(PGLOBAL, PFIL);
public:
// Constructors
FILTER(PGLOBAL g, POPER pop, PPARM *tp = NULL);
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 32caa185140..e9e53144e76 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -170,7 +170,7 @@
#define SZWMIN 4194304 // Minimum work area size 4M
extern "C" {
- char version[]= "Version 1.02.0002 March 16, 2014";
+ char version[]= "Version 1.03.0002 April 23, 2014";
#if defined(XMSG)
char msglang[]; // Default message language
@@ -324,7 +324,7 @@ ha_create_table_option connect_field_option_list[]=
*/
ha_create_table_option connect_index_option_list[]=
{
- HA_IOPTION_BOOL("DYN", kindx, 0),
+ HA_IOPTION_BOOL("DYNAMIC", kindx, 0),
HA_IOPTION_BOOL("MAPPED", mapped, 0),
};
@@ -658,7 +658,7 @@ TABTYPE ha_connect::GetRealType(PTOS pos)
const char *ha_connect::index_type(uint inx)
{
switch (GetIndexType(GetRealType())) {
- case 1: return "XPLUG";
+ case 1: return "XINDEX";
case 2: return "REMOTE";
} // endswitch
@@ -1143,6 +1143,14 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
} // end of GetColumnOption
/****************************************************************************/
+/* Return an index option structure. */
+/****************************************************************************/
+PXOS ha_connect::GetIndexOptionStruct(KEY *kp)
+{
+ return kp->option_struct;
+} // end of GetIndexOptionStruct
+
+/****************************************************************************/
/* Returns the index description structure used to make the index. */
/****************************************************************************/
PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s)
@@ -1151,6 +1159,7 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s)
bool unique;
PIXDEF xdp, pxd=NULL, toidx= NULL;
PKPDEF kpp, pkp;
+ PXOS xosp;
KEY kp;
PGLOBAL& g= xp->g;
@@ -1163,6 +1172,7 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s)
// Find the index to describe
kp= s->key_info[n];
+ xosp= kp.option_struct;
// Now get index information
pn= (char*)s->keynames.type_names[n];
@@ -1205,6 +1215,20 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s)
xdp->SetNParts(kp.user_defined_key_parts);
+ if (xosp) {
+ xdp->Dynamic= xosp->kindx;
+ xdp->Mapped= xosp->mapped;
+ } else if (kp.comment.str != NULL) {
+ char *pv, *oplist= kp.comment.str;
+
+ if ((pv= GetListOption(g, "Dynamic", oplist)))
+ xdp->Dynamic= (!*pv || *pv == 'y' || *pv == 'Y' || atoi(pv) != 0);
+
+ if ((pv= GetListOption(g, "Mapped", oplist)))
+ xdp->Mapped= (!*pv || *pv == 'y' || *pv == 'Y' || atoi(pv) != 0);
+
+ } // endif comment
+
if (pxd)
pxd->SetNext(xdp);
else
@@ -1847,6 +1871,15 @@ const char *ha_connect::GetValStr(OPVAL vop, bool neg)
/***********************************************************************/
/* Check the WHERE condition and return a CONNECT filter. */
/***********************************************************************/
+PFIL ha_connect::CheckFilter(PGLOBAL g)
+{
+ return CondFilter(g, (Item *)pushed_cond);
+} // end of CheckFilter
+
+
+/***********************************************************************/
+/* Check the WHERE condition and return a CONNECT filter. */
+/***********************************************************************/
PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
{
unsigned int i;
@@ -2680,7 +2713,7 @@ int ha_connect::index_init(uint idx, bool sorted)
htrc("index_init CONNECT: %s\n", g->Message);
active_index= MAX_KEY;
rc= HA_ERR_INTERNAL_ERROR;
- } else {
+ } else if (((PTDBDOX)tdbp)->To_Kindex) {
if (((PTDBDOX)tdbp)->To_Kindex->GetNum_K()) {
if (((PTDBASE)tdbp)->GetFtype() != RECFM_NAF)
((PTDBDOX)tdbp)->GetTxfp()->ResetBuffer(g);
@@ -2689,7 +2722,6 @@ int ha_connect::index_init(uint idx, bool sorted)
} else // Void table
indexing= 0;
- rc= 0;
} // endif indexing
if (xtrace)
diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h
index e7aac7a5915..40815a1a9ea 100644
--- a/storage/connect/ha_connect.h
+++ b/storage/connect/ha_connect.h
@@ -72,6 +72,7 @@ typedef class XCHK *PCHK;
typedef class user_connect *PCONNECT;
typedef struct ha_table_option_struct TOS, *PTOS;
typedef struct ha_field_option_struct FOS, *PFOS;
+typedef struct ha_index_option_struct XOS, *PXOS;
extern handlerton *connect_hton;
@@ -195,6 +196,7 @@ public:
bool NoFieldOptionChange(TABLE *tab);
PFOS GetFieldOptionStruct(Field *fp);
void *GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf);
+ PXOS GetIndexOptionStruct(KEY *kp);
PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL);
const char *GetDBName(const char *name);
const char *GetTableName(void);
@@ -345,6 +347,7 @@ virtual const COND *cond_push(const COND *cond);
PCFIL CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond);
const char *GetValStr(OPVAL vop, bool neg);
PFIL CondFilter(PGLOBAL g, Item *cond);
+PFIL CheckFilter(PGLOBAL g);
/**
Number of rows in table. It will only be called if
diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp
index 3427f7b76a7..a23ce388184 100644
--- a/storage/connect/tabdos.cpp
+++ b/storage/connect/tabdos.cpp
@@ -1477,12 +1477,17 @@ PBF TDBDOS::CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv)
} // end of CheckBlockFilari
/***********************************************************************/
-/* ResetBlkFil: reset the block filter and restore filtering. */
+/* ResetBlkFil: reset the block filter and restore filtering, or make */
+/* the block filter if To_Filter was not set when opening the table. */
/***********************************************************************/
void TDBDOS::ResetBlockFilter(PGLOBAL g)
{
- if (!To_BlkFil)
+ if (!To_BlkFil) {
+ if (To_Filter)
+ To_BlkFil = InitBlockFilter(g, To_Filter);
+
return;
+ } // endif To_BlkFil
To_BlkFil->Reset(g);
@@ -1590,7 +1595,7 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
// Allocate all columns that will be used by indexes.
// This must be done before opening the table so specific
- // column initialization can be done ( in particular by TDBVCT)
+ // column initialization can be done (in particular by TDBVCT)
for (n = 0, xdp = pxdf; xdp; xdp = xdp->GetNext())
for (kdp = xdp->GetToKeyParts(); kdp; kdp = kdp->GetNext()) {
if (!(colp = ColDB(g, kdp->GetName(), 0))) {
@@ -1688,6 +1693,79 @@ err:
} // end of MakeIndex
/***********************************************************************/
+/* Make a dynamic index. */
+/***********************************************************************/
+bool TDBDOS::MakeDynamicIndex(PGLOBAL g)
+ {
+ int k, rc;
+ bool brc;
+ PCOL colp;
+ PCOLDEF cdp;
+ PVAL valp;
+ PIXDEF xdp;
+ PKXBASE kxp;
+ PKPDEF kdp;
+
+ if (!(xdp = To_Xdp)) {
+ strcpy(g->Message, "NULL dynamic index");
+ return true;
+ } // endif To_Xdp
+
+ // Allocate the key columns definition block
+ Knum = xdp->GetNparts();
+ To_Key_Col = (PCOL*)PlugSubAlloc(g, NULL, Knum * sizeof(PCOL));
+
+ // Get the key column description list
+ for (k = 0, kdp = xdp->GetToKeyParts(); kdp; kdp = kdp->GetNext())
+ if (!(colp = ColDB(g, kdp->GetName(), 0)) || colp->InitValue(g)) {
+ sprintf(g->Message, "Wrong column %s", kdp->GetName());
+ return true;
+ } else
+ To_Key_Col[k++] = colp;
+
+#if defined(_DEBUG)
+ if (k != Knum) {
+ sprintf(g->Message, "Key part number mismatch for %s",
+ xdp->GetName());
+ return 0;
+ } // endif k
+#endif // _DEBUG
+
+ // Allocate the pseudo constants that will contain the key values
+ To_Link = (PXOB*)PlugSubAlloc(g, NULL, Knum * sizeof(PXOB));
+
+ for (k = 0, kdp = xdp->GetToKeyParts(); kdp; k++, kdp = kdp->GetNext()) {
+ cdp = Key(k)->GetCdp();
+ valp = AllocateValue(g, cdp->GetType(), cdp->GetLength());
+ To_Link[k]= new(g) CONSTANT(valp);
+ } // endfor k
+
+ // Make the index on xdp
+ if (!xdp->IsAuto()) {
+ if (Knum == 1) // Single index
+ kxp= new(g) XINDXS(this, xdp, NULL, To_Key_Col, To_Link);
+ else // Multi-Column index
+ kxp= new(g) XINDEX(this, xdp, NULL, To_Key_Col, To_Link);
+
+ } else // Column contains same values as ROWID
+ kxp= new(g) XXROW(this);
+
+ // Prepare error return
+ if (g->jump_level == MAX_JUMP) {
+ strcpy(g->Message, MSG(TOO_MANY_JUMPS));
+ return true;
+ } // endif
+
+ if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) {
+ brc = true;
+ } else if (!(brc = kxp->Make(g, xdp)))
+ To_Kindex= kxp;
+
+ g->jump_level--;
+ return brc;
+ } // end of MakeDynamicIndex
+
+/***********************************************************************/
/* DOS GetProgMax: get the max value for progress information. */
/***********************************************************************/
int TDBDOS::GetProgMax(PGLOBAL g)
diff --git a/storage/connect/tabdos.h b/storage/connect/tabdos.h
index 17220a52962..4db28f78868 100644
--- a/storage/connect/tabdos.h
+++ b/storage/connect/tabdos.h
@@ -169,6 +169,7 @@ class DllExport TDBDOS : public TDBASE {
// Optimization routines
virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add);
+ bool MakeDynamicIndex(PGLOBAL g);
void ResetBlockFilter(PGLOBAL g);
bool GetDistinctColumnValues(PGLOBAL g, int nrec);
diff --git a/storage/connect/table.cpp b/storage/connect/table.cpp
index cb7e732d2dd..f550420ef3a 100644
--- a/storage/connect/table.cpp
+++ b/storage/connect/table.cpp
@@ -139,6 +139,7 @@ TDBASE::TDBASE(PTABDEF tdp) : TDB(tdp)
To_Link = NULL;
To_Key_Col = NULL;
To_Kindex = NULL;
+ To_Xdp = NULL;
To_SetCols = NULL;
MaxSize = -1;
Knum = 0;
@@ -149,8 +150,13 @@ TDBASE::TDBASE(PTABDEF tdp) : TDB(tdp)
TDBASE::TDBASE(PTDBASE tdbp) : TDB(tdbp)
{
To_Def = tdbp->To_Def;
+ To_Link = tdbp->To_Link;
+ To_Key_Col = tdbp->To_Key_Col;
+ To_Kindex = tdbp->To_Kindex;
+ To_Xdp = tdbp->To_Xdp;
To_SetCols = tdbp->To_SetCols; // ???
MaxSize = tdbp->MaxSize;
+ Knum = tdbp->Knum;
Read_Only = tdbp->Read_Only;
m_data_charset= tdbp->m_data_charset;
} // end of TDBASE copy constructor
diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp
index 66b8abe2e9b..5039f2d7aee 100755
--- a/storage/connect/xindex.cpp
+++ b/storage/connect/xindex.cpp
@@ -112,6 +112,8 @@ INDEXDEF::INDEXDEF(char *name, bool uniq, int n)
Unique = uniq;
Invalid = false;
AutoInc = false;
+ Dynamic = false;
+ Mapped = false;
Nparts = 0;
ID = n;
//Offset = 0;
@@ -242,7 +244,8 @@ void XINDEX::Reset(void)
void XINDEX::Close(void)
{
// Close file or view of file
- X->Close();
+ if (X)
+ X->Close();
// De-allocate data
PlgDBfree(Record);
@@ -286,7 +289,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
int k, rc = RC_OK;
int *bof, i, j, n, ndf, nkey;
PKPDEF kdfp = Xdp->GetToKeyParts();
- bool brc = true;
+ bool brc = false;
PCOL colp;
PXCOL kp, prev = NULL, kcp = NULL;
PDBUSER dup = (PDBUSER)g->Activityp->Aptr;
@@ -378,11 +381,14 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
// Check return code and do whatever must be done according to it
switch (rc) {
case RC_OK:
- break;
- case RC_EF:
- goto end_of_file;
+ if (ApplyFilter(g, Tdbp->GetFilter()))
+ break;
+
+ // passthru
case RC_NF:
continue;
+ case RC_EF:
+ goto end_of_file;
default:
sprintf(g->Message, MSG(RC_READING), rc, Tdbp->Name);
goto err;
@@ -579,14 +585,15 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
Cur_K = Num_K;
/*********************************************************************/
- /* Save the index so it has not to be recalculated. */
+ /* Save the xindex so it has not to be recalculated. */
/*********************************************************************/
- if (!SaveIndex(g, sxp))
- brc = false;
+ if (X && SaveIndex(g, sxp))
+ brc = true;
err:
// We don't need the index anymore
- Close();
+ if (X || brc)
+ Close();
if (brc)
printf("%s\n", g->Message);
diff --git a/storage/connect/xindex.h b/storage/connect/xindex.h
index 6ed0416bad5..f447051a517 100644
--- a/storage/connect/xindex.h
+++ b/storage/connect/xindex.h
@@ -87,6 +87,7 @@ class DllExport INDEXDEF : public BLOCK { /* Index description block */
void SetNext(PIXDEF pxdf) {Next = pxdf;}
PSZ GetName(void) {return (PSZ)Name;}
bool IsUnique(void) {return Unique;}
+ bool IsDynamic(void) {return Dynamic;}
bool IsAuto(void) {return AutoInc;}
void SetAuto(bool b) {AutoInc = b;}
void SetInvalid(bool b) {Invalid = b;}
@@ -115,6 +116,8 @@ class DllExport INDEXDEF : public BLOCK { /* Index description block */
bool Unique; /* true if defined as unique */
bool Invalid; /* true if marked as Invalid */
bool AutoInc; /* true if unique key in auto increment */
+ bool Dynamic; /* KINDEX style */
+ bool Mapped; /* Use file mapping */
int Nparts; /* Number of key parts */
int ID; /* Index ID number */
int MaxSame; /* Max number of same values */
@@ -192,6 +195,7 @@ class DllExport XXBASE : public CSORT, public BLOCK {
virtual void Print(PGLOBAL g, FILE *f, uint n);
virtual void Print(PGLOBAL g, char *ps, uint z);
virtual bool Init(PGLOBAL g) = 0;
+ virtual bool Make(PGLOBAL g, PIXDEF sxp) = 0;
#if defined(XMAP)
virtual bool MapInit(PGLOBAL g) = 0;
#endif // XMAP
@@ -420,6 +424,7 @@ class DllExport XXROW : public XXBASE {
virtual int MaxRange(void) {return 1;}
virtual int Range(PGLOBAL g, int limit = 0, bool incl = true);
virtual int Qcompare(int *, int *) {assert(false); return 0;}
+ virtual bool Make(PGLOBAL g, PIXDEF sxp) {return false;}
virtual void Close(void) {}
protected:
diff --git a/storage/connect/xtable.h b/storage/connect/xtable.h
index daaa40f2224..f6c5a0fbfdd 100644
--- a/storage/connect/xtable.h
+++ b/storage/connect/xtable.h
@@ -145,6 +145,7 @@ class DllExport TDBASE : public TDB {
inline PKXBASE GetKindex(void) {return To_Kindex;}
inline PCOL GetSetCols(void) {return To_SetCols;}
inline void SetSetCols(PCOL colp) {To_SetCols = colp;}
+ inline void SetXdp(PIXDEF xdp) {To_Xdp = xdp;}
// Properties
void SetKindex(PKXBASE kxp);
@@ -191,8 +192,9 @@ class DllExport TDBASE : public TDB {
PXOB *To_Link; // Points to column of previous relations
PCOL *To_Key_Col; // Points to key columns in current file
PKXBASE To_Kindex; // Points to table key index
+ PIXDEF To_Xdp; // To the index definition block
PCOL To_SetCols; // Points to updated columns
- int MaxSize; // Max size in number of lines
+ int MaxSize; // Max size in number of lines
int Knum; // Size of key arrays
bool Read_Only; // True for read only tables
const CHARSET_INFO *m_data_charset;