diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2014-04-26 00:17:26 +0200 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2014-04-26 00:17:26 +0200 |
commit | 0e20f02174099e0ee79fd5440c84fae9d2796b86 (patch) | |
tree | a31858b925286aa3d3927249698d6c1d2ddde158 | |
parent | 9d29647487e8170d018413aacc6ec580decd59b1 (diff) | |
download | mariadb-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.cc | 41 | ||||
-rw-r--r-- | storage/connect/filter.cpp | 2 | ||||
-rw-r--r-- | storage/connect/filter.h | 2 | ||||
-rw-r--r-- | storage/connect/ha_connect.cc | 42 | ||||
-rw-r--r-- | storage/connect/ha_connect.h | 3 | ||||
-rw-r--r-- | storage/connect/tabdos.cpp | 84 | ||||
-rw-r--r-- | storage/connect/tabdos.h | 1 | ||||
-rw-r--r-- | storage/connect/table.cpp | 6 | ||||
-rwxr-xr-x | storage/connect/xindex.cpp | 25 | ||||
-rw-r--r-- | storage/connect/xindex.h | 5 | ||||
-rw-r--r-- | storage/connect/xtable.h | 4 |
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; |