Commit e7c7256d authored by Olivier Bertrand's avatar Olivier Bertrand

- Implementation of adding selected columns to dynamic indexes.

modified:
  storage/connect/connect.cc
  storage/connect/ha_connect.cc
  storage/connect/ha_connect.h
  storage/connect/tabdos.cpp
  storage/connect/tabdos.h
  storage/connect/tabvct.cpp
  storage/connect/tabvct.h
  storage/connect/xindex.cpp
  storage/connect/xindex.h
parent 883c37a8
...@@ -604,15 +604,8 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp) ...@@ -604,15 +604,8 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
/***********************************************************************/ /***********************************************************************/
int CntIndexInit(PGLOBAL g, PTDB ptdb, int id) int CntIndexInit(PGLOBAL g, PTDB ptdb, int id)
{ {
int k;
PCOL colp;
PVAL valp;
PKXBASE xp;
PXLOAD pxp;
PIXDEF xdp; PIXDEF xdp;
XKPDEF *kdp;
PTDBDOX tdbp; PTDBDOX tdbp;
PCOLDEF cdp;
DOXDEF *dfp; DOXDEF *dfp;
if (!ptdb) if (!ptdb)
...@@ -651,64 +644,20 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id) ...@@ -651,64 +644,20 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id)
return 0; return 0;
} // endif xdp } // endif xdp
#if 0
if (xdp->IsDynamic()) { if (xdp->IsDynamic()) {
// This is a dynamically created index (KINDEX) // This is a dynamically created index (KINDEX)
// It cannot be created now, before cond_push is executed // It should not be created now, if called by index range
tdbp->SetXdp(xdp); tdbp->SetXdp(xdp);
return (xdp->IsUnique()) ? 1 : 2; return (xdp->IsUnique()) ? 1 : 2;
} // endif dynamic } // endif dynamic
#endif // 0
// Static indexes must be initialized now for records_in_range // Static indexes must be initialized now for records_in_range
// Allocate the key columns definition block if (tdbp->InitialyzeIndex(g, xdp))
tdbp->Knum= xdp->GetNparts();
tdbp->To_Key_Col= (PCOL*)PlugSubAlloc(g, NULL, tdbp->Knum * sizeof(PCOL));
// Get the key column description list
for (k= 0, kdp= (XKPDEF*)xdp->GetToKeyParts(); kdp; kdp= (XKPDEF*)kdp->Next)
if (!(colp= tdbp->ColDB(g, kdp->Name, 0)) || colp->InitValue(g)) {
sprintf(g->Message, "Wrong column %s", kdp->Name);
return 0;
} else
tdbp->To_Key_Col[k++]= colp;
#if defined(_DEBUG)
if (k != tdbp->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
tdbp->To_Link= (PXOB*)PlugSubAlloc(g, NULL, tdbp->Knum * sizeof(PXOB));
for (k= 0, kdp= (XKPDEF*)xdp->GetToKeyParts();
kdp; k++, kdp= (XKPDEF*)kdp->Next) {
cdp= tdbp->Key(k)->GetCdp();
valp= AllocateValue(g, cdp->GetType(), cdp->GetLength());
tdbp->To_Link[k]= new(g) CONSTANT(valp);
} // endfor k
// Make the index on xdp
if (!xdp->IsAuto()) {
if (dfp->Huge)
pxp= new(g) XHUGE;
else
pxp= new(g) XFILE;
if (tdbp->Knum == 1) // Single index
xp= new(g) XINDXS(tdbp, xdp, pxp, tdbp->To_Key_Col, tdbp->To_Link);
else // Multi-Column index
xp= new(g) XINDEX(tdbp, xdp, pxp, tdbp->To_Key_Col, tdbp->To_Link);
} else // Column contains same values as ROWID
xp= new(g) XXROW(tdbp);
if (xp->Init(g))
return 0; return 0;
tdbp->To_Kindex= xp; return (tdbp->To_Kindex->IsMul()) ? 2 : 1;
return (xp->IsMul()) ? 2 : 1;
} // end of CntIndexInit } // end of CntIndexInit
/***********************************************************************/ /***********************************************************************/
...@@ -746,20 +695,18 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op, ...@@ -746,20 +695,18 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
// Set reference values and index operator // Set reference values and index operator
if (!tdbp->To_Link || !tdbp->To_Kindex) { if (!tdbp->To_Link || !tdbp->To_Kindex) {
if (!tdbp->To_Xdp) { // if (!tdbp->To_Xdp) {
sprintf(g->Message, "Index not initialized for table %s", tdbp->Name); sprintf(g->Message, "Index not initialized for table %s", tdbp->Name);
return RC_FX; return RC_FX;
#if 0
} // endif !To_Xdp } // endif !To_Xdp
// Now it's time to make the dynamic index // Now it's time to make the dynamic index
tdbp->SetFilter(tdbp->To_Def->GetHandler()->CheckFilter(g)); if (tdbp->InitialyzeIndex(g, NULL)) {
if (tdbp->MakeDynamicIndex(g)) {
sprintf(g->Message, "Fail to make dynamic index %s", sprintf(g->Message, "Fail to make dynamic index %s",
tdbp->To_Xdp->GetName()); tdbp->To_Xdp->GetName());
return RC_FX; return RC_FX;
} // endif MakeDynamicIndex } // endif MakeDynamicIndex
#endif // 0
} // endif !To_Kindex } // endif !To_Kindex
xbp= (XXBASE*)tdbp->To_Kindex; xbp= (XXBASE*)tdbp->To_Kindex;
......
...@@ -324,8 +324,10 @@ ha_create_table_option connect_field_option_list[]= ...@@ -324,8 +324,10 @@ ha_create_table_option connect_field_option_list[]=
*/ */
ha_create_table_option connect_index_option_list[]= ha_create_table_option connect_index_option_list[]=
{ {
HA_IOPTION_BOOL("DYNAMIC", kindx, 0), HA_IOPTION_BOOL("DYNAMIC", dynamic, 0),
HA_IOPTION_BOOL("DYNAM", dynamic, 0),
HA_IOPTION_BOOL("MAPPED", mapped, 0), HA_IOPTION_BOOL("MAPPED", mapped, 0),
HA_IOPTION_END
}; };
/***********************************************************************/ /***********************************************************************/
...@@ -435,6 +437,7 @@ static int connect_init_func(void *p) ...@@ -435,6 +437,7 @@ static int connect_init_func(void *p)
connect_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED | HTON_NO_PARTITION; connect_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED | HTON_NO_PARTITION;
connect_hton->table_options= connect_table_option_list; connect_hton->table_options= connect_table_option_list;
connect_hton->field_options= connect_field_option_list; connect_hton->field_options= connect_field_option_list;
connect_hton->index_options= connect_index_option_list;
connect_hton->tablefile_extensions= ha_connect_exts; connect_hton->tablefile_extensions= ha_connect_exts;
connect_hton->discover_table_structure= connect_assisted_discovery; connect_hton->discover_table_structure= connect_assisted_discovery;
...@@ -658,7 +661,13 @@ TABTYPE ha_connect::GetRealType(PTOS pos) ...@@ -658,7 +661,13 @@ TABTYPE ha_connect::GetRealType(PTOS pos)
const char *ha_connect::index_type(uint inx) const char *ha_connect::index_type(uint inx)
{ {
switch (GetIndexType(GetRealType())) { switch (GetIndexType(GetRealType())) {
case 1: return "XINDEX"; case 1:
if (table_share)
return (GetIndexOption(&table_share->key_info[inx], "Dynamic"))
? "KINDEX" : "XINDEX";
else
return "XINDEX";
case 2: return "REMOTE"; case 2: return "REMOTE";
} // endswitch } // endswitch
...@@ -1150,6 +1159,31 @@ PXOS ha_connect::GetIndexOptionStruct(KEY *kp) ...@@ -1150,6 +1159,31 @@ PXOS ha_connect::GetIndexOptionStruct(KEY *kp)
return kp->option_struct; return kp->option_struct;
} // end of GetIndexOptionStruct } // end of GetIndexOptionStruct
/****************************************************************************/
/* Return a Boolean index option or false if not specified. */
/****************************************************************************/
bool ha_connect::GetIndexOption(KEY *kp, char *opname)
{
bool opval= false;
PXOS options= GetIndexOptionStruct(kp);
if (options) {
if (!stricmp(opname, "Dynamic"))
opval= options->dynamic;
else if (!stricmp(opname, "Mapped"))
opval= options->mapped;
} else if (kp->comment.str != NULL) {
char *pv, *oplist= kp->comment.str;
if ((pv= GetListOption(xp->g, opname, oplist)))
opval= (!*pv || *pv == 'y' || *pv == 'Y' || atoi(pv) != 0);
} // endif comment
return opval;
} // end of GetIndexOption
/****************************************************************************/ /****************************************************************************/
/* Returns the index description structure used to make the index. */ /* Returns the index description structure used to make the index. */
/****************************************************************************/ /****************************************************************************/
...@@ -1159,7 +1193,6 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s) ...@@ -1159,7 +1193,6 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s)
bool unique; bool unique;
PIXDEF xdp, pxd=NULL, toidx= NULL; PIXDEF xdp, pxd=NULL, toidx= NULL;
PKPDEF kpp, pkp; PKPDEF kpp, pkp;
PXOS xosp;
KEY kp; KEY kp;
PGLOBAL& g= xp->g; PGLOBAL& g= xp->g;
...@@ -1172,7 +1205,6 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s) ...@@ -1172,7 +1205,6 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s)
// Find the index to describe // Find the index to describe
kp= s->key_info[n]; kp= s->key_info[n];
xosp= kp.option_struct;
// Now get index information // Now get index information
pn= (char*)s->keynames.type_names[n]; pn= (char*)s->keynames.type_names[n];
...@@ -1214,20 +1246,8 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s) ...@@ -1214,20 +1246,8 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s)
} // endfor k } // endfor k
xdp->SetNParts(kp.user_defined_key_parts); xdp->SetNParts(kp.user_defined_key_parts);
xdp->Dynamic= GetIndexOption(&kp, "Dynamic");
if (xosp) { xdp->Mapped= GetIndexOption(&kp, "Mapped");
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) if (pxd)
pxd->SetNext(xdp); pxd->SetNext(xdp);
...@@ -1867,7 +1887,7 @@ const char *ha_connect::GetValStr(OPVAL vop, bool neg) ...@@ -1867,7 +1887,7 @@ const char *ha_connect::GetValStr(OPVAL vop, bool neg)
return val; return val;
} // end of GetValStr } // end of GetValStr
#if 0
/***********************************************************************/ /***********************************************************************/
/* Check the WHERE condition and return a CONNECT filter. */ /* Check the WHERE condition and return a CONNECT filter. */
/***********************************************************************/ /***********************************************************************/
...@@ -1875,7 +1895,7 @@ PFIL ha_connect::CheckFilter(PGLOBAL g) ...@@ -1875,7 +1895,7 @@ PFIL ha_connect::CheckFilter(PGLOBAL g)
{ {
return CondFilter(g, (Item *)pushed_cond); return CondFilter(g, (Item *)pushed_cond);
} // end of CheckFilter } // end of CheckFilter
#endif // 0
/***********************************************************************/ /***********************************************************************/
/* Check the WHERE condition and return a CONNECT filter. */ /* Check the WHERE condition and return a CONNECT filter. */
......
...@@ -140,7 +140,7 @@ struct ha_field_option_struct ...@@ -140,7 +140,7 @@ struct ha_field_option_struct
*/ */
struct ha_index_option_struct struct ha_index_option_struct
{ {
bool kindx; bool dynamic;
bool mapped; bool mapped;
}; };
...@@ -187,6 +187,7 @@ class ha_connect: public handler ...@@ -187,6 +187,7 @@ class ha_connect: public handler
bool GetBooleanOption(char *opname, bool bdef); bool GetBooleanOption(char *opname, bool bdef);
bool SetBooleanOption(char *opname, bool b); bool SetBooleanOption(char *opname, bool b);
int GetIntegerOption(char *opname); int GetIntegerOption(char *opname);
bool GetIndexOption(KEY *kp, char *opname);
bool CheckString(const char *str1, const char *str2); bool CheckString(const char *str1, const char *str2);
bool SameString(TABLE *tab, char *opn); bool SameString(TABLE *tab, char *opn);
bool SetIntegerOption(char *opname, int n); bool SetIntegerOption(char *opname, int n);
...@@ -347,7 +348,7 @@ virtual const COND *cond_push(const COND *cond); ...@@ -347,7 +348,7 @@ virtual const COND *cond_push(const COND *cond);
PCFIL CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond); PCFIL CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond);
const char *GetValStr(OPVAL vop, bool neg); const char *GetValStr(OPVAL vop, bool neg);
PFIL CondFilter(PGLOBAL g, Item *cond); PFIL CondFilter(PGLOBAL g, Item *cond);
PFIL CheckFilter(PGLOBAL g); //PFIL CheckFilter(PGLOBAL g);
/** /**
Number of rows in table. It will only be called if Number of rows in table. It will only be called if
......
...@@ -1695,21 +1695,23 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add) ...@@ -1695,21 +1695,23 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
/***********************************************************************/ /***********************************************************************/
/* Make a dynamic index. */ /* Make a dynamic index. */
/***********************************************************************/ /***********************************************************************/
bool TDBDOS::MakeDynamicIndex(PGLOBAL g) bool TDBDOS::InitialyzeIndex(PGLOBAL g, PIXDEF xdp)
{ {
int k, rc; int k, rc;
bool brc; bool brc, dynamic;
PCOL colp; PCOL colp;
PCOLDEF cdp; PCOLDEF cdp;
PVAL valp; PVAL valp;
PIXDEF xdp; PXLOAD pxp;
PKXBASE kxp; PKXBASE kxp;
PKPDEF kdp; PKPDEF kdp;
if (!(xdp = To_Xdp)) { if (!xdp && !(xdp = To_Xdp)) {
strcpy(g->Message, "NULL dynamic index"); strcpy(g->Message, "NULL dynamic index");
return true; return true;
} // endif To_Xdp } else
dynamic = To_Filter && xdp->IsUnique() && xdp->IsDynamic();
// dynamic = To_Filter && xdp->IsDynamic(); NIY
// Allocate the key columns definition block // Allocate the key columns definition block
Knum = xdp->GetNparts(); Knum = xdp->GetNparts();
...@@ -1742,13 +1744,22 @@ bool TDBDOS::MakeDynamicIndex(PGLOBAL g) ...@@ -1742,13 +1744,22 @@ bool TDBDOS::MakeDynamicIndex(PGLOBAL g)
// Make the index on xdp // Make the index on xdp
if (!xdp->IsAuto()) { if (!xdp->IsAuto()) {
if (!dynamic) {
if (((PDOSDEF)To_Def)->Huge)
pxp = new(g) XHUGE;
else
pxp = new(g) XFILE;
} else
pxp = NULL;
if (Knum == 1) // Single index if (Knum == 1) // Single index
kxp= new(g) XINDXS(this, xdp, NULL, To_Key_Col, To_Link); kxp = new(g) XINDXS(this, xdp, pxp, To_Key_Col, To_Link);
else // Multi-Column index else // Multi-Column index
kxp= new(g) XINDEX(this, xdp, NULL, To_Key_Col, To_Link); kxp = new(g) XINDEX(this, xdp, pxp, To_Key_Col, To_Link);
} else // Column contains same values as ROWID } else // Column contains same values as ROWID
kxp= new(g) XXROW(this); kxp = new(g) XXROW(this);
// Prepare error return // Prepare error return
if (g->jump_level == MAX_JUMP) { if (g->jump_level == MAX_JUMP) {
...@@ -1758,12 +1769,15 @@ bool TDBDOS::MakeDynamicIndex(PGLOBAL g) ...@@ -1758,12 +1769,15 @@ bool TDBDOS::MakeDynamicIndex(PGLOBAL g)
if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) { if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) {
brc = true; brc = true;
} else if (!(brc = kxp->Make(g, xdp))) } else
To_Kindex= kxp; if (!(brc = (dynamic) ? kxp->Make(g, xdp) : kxp->Init(g))) {
kxp->SetDynamic(dynamic);
To_Kindex= kxp;
} // endif brc
g->jump_level--; g->jump_level--;
return brc; return brc;
} // end of MakeDynamicIndex } // end of InitialyzeIndex
/***********************************************************************/ /***********************************************************************/
/* DOS GetProgMax: get the max value for progress information. */ /* DOS GetProgMax: get the max value for progress information. */
......
...@@ -170,7 +170,7 @@ class DllExport TDBDOS : public TDBASE { ...@@ -170,7 +170,7 @@ class DllExport TDBDOS : public TDBASE {
// Optimization routines // Optimization routines
virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add); virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add);
bool MakeDynamicIndex(PGLOBAL g); bool InitialyzeIndex(PGLOBAL g, PIXDEF xdp);
void ResetBlockFilter(PGLOBAL g); void ResetBlockFilter(PGLOBAL g);
bool GetDistinctColumnValues(PGLOBAL g, int nrec); bool GetDistinctColumnValues(PGLOBAL g, int nrec);
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
/***********************************************************************/ /***********************************************************************/
/***********************************************************************/ /***********************************************************************/
/* Include relevant MariaDB header file. */ /* Include relevant MariaDB header file. */
/***********************************************************************/ /***********************************************************************/
#include "my_global.h" #include "my_global.h"
#if defined(WIN32) #if defined(WIN32)
......
...@@ -20,6 +20,7 @@ typedef class VCTCOL *PVCTCOL; ...@@ -20,6 +20,7 @@ typedef class VCTCOL *PVCTCOL;
/* VCT table. */ /* VCT table. */
/***********************************************************************/ /***********************************************************************/
class DllExport VCTDEF : public DOSDEF { /* Logical table description */ class DllExport VCTDEF : public DOSDEF { /* Logical table description */
friend class TDBVCT;
friend class VCTFAM; friend class VCTFAM;
friend class VECFAM; friend class VECFAM;
friend class VMPFAM; friend class VMPFAM;
...@@ -64,6 +65,7 @@ class DllExport TDBVCT : public TDBFIX { ...@@ -64,6 +65,7 @@ class DllExport TDBVCT : public TDBFIX {
virtual AMT GetAmType(void) {return TYPE_AM_VCT;} virtual AMT GetAmType(void) {return TYPE_AM_VCT;}
virtual PTDB Duplicate(PGLOBAL g) virtual PTDB Duplicate(PGLOBAL g)
{return (PTDB)new(g) TDBVCT(g, this);} {return (PTDB)new(g) TDBVCT(g, this);}
bool IsSplit(void) {return ((VCTDEF*)To_Def)->Split;}
// Methods // Methods
virtual PTDB CopyOne(PTABS t); virtual PTDB CopyOne(PTABS t);
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
//nclude "array.h" //nclude "array.h"
#include "filamtxt.h" #include "filamtxt.h"
#include "tabdos.h" #include "tabdos.h"
#include "tabvct.h"
/***********************************************************************/ /***********************************************************************/
/* Macro or external routine definition */ /* Macro or external routine definition */
...@@ -167,6 +168,8 @@ XXBASE::XXBASE(PTDBDOS tbxp, bool b) : CSORT(b), ...@@ -167,6 +168,8 @@ XXBASE::XXBASE(PTDBDOS tbxp, bool b) : CSORT(b),
Op = OP_EQ; Op = OP_EQ;
To_KeyCol = NULL; To_KeyCol = NULL;
Mul = false; Mul = false;
Srtd = false;
Dynamic = false;
Val_K = -1; Val_K = -1;
Nblk = Sblk = 0; Nblk = Sblk = 0;
Thresh = 7; Thresh = 7;
...@@ -252,13 +255,14 @@ void XINDEX::Close(void) ...@@ -252,13 +255,14 @@ void XINDEX::Close(void)
PlgDBfree(Index); PlgDBfree(Index);
PlgDBfree(Offset); PlgDBfree(Offset);
// De-allocate Key data for (PXCOL kcp = To_KeyCol; kcp; kcp = kcp->Next) {
for (PXCOL kcp = To_KeyCol; kcp; kcp = kcp->Next) // Column values cannot be retrieved from key anymore
kcp->FreeData(); if (kcp->Colp)
kcp->Colp->SetKcol(NULL);
// Column values cannot be retrieved from key anymore // De-allocate Key data
for (int k = 0; k < Nk; k++) kcp->FreeData();
To_Cols[k]->SetKcol(NULL); } // endfor kcp
} // end of Close } // end of Close
...@@ -278,6 +282,25 @@ int XINDEX::Qcompare(int *i1, int *i2) ...@@ -278,6 +282,25 @@ int XINDEX::Qcompare(int *i1, int *i2)
return k; return k;
} // end of Qcompare } // end of Qcompare
/***********************************************************************/
/* AddColumns: here we try to determine whether it is worthwhile to */
/* add to the keys the values of the columns selected for this table. */
/* Sure enough, it is done while records are read and permit to avoid */
/* reading the table while doing the join (Dynamic index only) */
/***********************************************************************/
bool XINDEX::AddColumns(void)
{
if (!Dynamic)
return false; // Not applying to static index
else if (IsMul())
return false; // Not done yet for multiple index
else if (Tbxp->GetAmType() == TYPE_AM_VCT && ((PTDBVCT)Tbxp)->IsSplit())
return false; // This would require to read additional files
else
return true;
} // end of AddColumns
/***********************************************************************/ /***********************************************************************/
/* Make: Make and index on key column(s). */ /* Make: Make and index on key column(s). */
/***********************************************************************/ /***********************************************************************/
...@@ -291,8 +314,13 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -291,8 +314,13 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
PKPDEF kdfp = Xdp->GetToKeyParts(); PKPDEF kdfp = Xdp->GetToKeyParts();
bool brc = false; bool brc = false;
PCOL colp; PCOL colp;
PXCOL kp, prev = NULL, kcp = NULL; PFIL filp = Tdbp->GetFilter();
PDBUSER dup = (PDBUSER)g->Activityp->Aptr; PXCOL kp, addcolp, prev = NULL, kcp = NULL;
//PDBUSER dup = (PDBUSER)g->Activityp->Aptr;
#if defined(_DEBUG)
assert(X || Nk == 1);
#endif // _DEBUG
/*********************************************************************/ /*********************************************************************/
/* Allocate the storage that will contain the keys and the file */ /* Allocate the storage that will contain the keys and the file */
...@@ -350,6 +378,50 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -350,6 +378,50 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
To_LastCol = prev; To_LastCol = prev;
if (AddColumns()) {
PCOL kolp = To_Cols[0]; // Temporary while imposing Nk = 1
i = 0;
// Allocate the accompanying
for (colp = Tbxp->GetColumns(); colp; colp = colp->GetNext()) {
// Count how many columns to add
// for (k = 0; k < Nk; k++)
// if (colp == To_Cols[k])
// break;
// if (k == nk)
if (colp != kolp)
i++;
} // endfor colp
if (i && i < 10) // Should be a parameter
for (colp = Tbxp->GetColumns(); colp; colp = colp->GetNext()) {
// for (k = 0; k < Nk; k++)
// if (colp == To_Cols[k])
// break;
// if (k < nk)
if (colp == kolp)
continue; // This is a key column
kcp = new(g) KXYCOL(this);
if (kcp->Init(g, colp, n, true, NULL))
return true;
if (trace)
htrc("Adding colp=%p Buf_Type=%d size=%d\n",
colp, colp->GetResultType(), n);
prev->Next = kcp;
prev = kcp;
} // endfor colp
} // endif AddColumns
#if 0
/*********************************************************************/ /*********************************************************************/
/* Get the starting information for progress. */ /* Get the starting information for progress. */
/*********************************************************************/ /*********************************************************************/
...@@ -357,18 +429,19 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -357,18 +429,19 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
sprintf((char*)dup->Step, MSG(BUILD_INDEX), Xdp->GetName(), Tdbp->Name); sprintf((char*)dup->Step, MSG(BUILD_INDEX), Xdp->GetName(), Tdbp->Name);
dup->ProgMax = Tdbp->GetProgMax(g); dup->ProgMax = Tdbp->GetProgMax(g);
dup->ProgCur = 0; dup->ProgCur = 0;
#endif // 0
/*********************************************************************/ /*********************************************************************/
/* Standard init: read the file and construct the index table. */ /* Standard init: read the file and construct the index table. */
/* Note: reading will be sequential as To_Kindex is not set. */ /* Note: reading will be sequential as To_Kindex is not set. */
/*********************************************************************/ /*********************************************************************/
for (i = nkey = 0; i < n && rc != RC_EF; i++) { for (i = nkey = 0; i < n && rc != RC_EF; i++) {
#if defined(THREAD) #if 0
if (!dup->Step) { if (!dup->Step) {
strcpy(g->Message, MSG(QUERY_CANCELLED)); strcpy(g->Message, MSG(QUERY_CANCELLED));
longjmp(g->jumper[g->jump_level], 99); longjmp(g->jumper[g->jump_level], 99);
} // endif Step } // endif Step
#endif // THREAD #endif // 0
/*******************************************************************/ /*******************************************************************/
/* Read a valid record from table file. */ /* Read a valid record from table file. */
...@@ -376,12 +449,12 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -376,12 +449,12 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
rc = Tdbp->ReadDB(g); rc = Tdbp->ReadDB(g);
// Update progress information // Update progress information
dup->ProgCur = Tdbp->GetProgCur(); // dup->ProgCur = Tdbp->GetProgCur();
// Check return code and do whatever must be done according to it // Check return code and do whatever must be done according to it
switch (rc) { switch (rc) {
case RC_OK: case RC_OK:
if (ApplyFilter(g, Tdbp->GetFilter())) if (ApplyFilter(g, filp))
break; break;
// passthru // passthru
...@@ -398,7 +471,11 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -398,7 +471,11 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
/* Get and Store the file position of the last read record for */ /* Get and Store the file position of the last read record for */
/* future direct access. */ /* future direct access. */
/*******************************************************************/ /*******************************************************************/
To_Rec[nkey] = Tdbp->GetRecpos(); if (nkey == n) {
sprintf(g->Message, MSG(TOO_MANY_KEYS), nkey);
return true;
} else
To_Rec[nkey] = Tdbp->GetRecpos();
/*******************************************************************/ /*******************************************************************/
/* Get the keys and place them in the key blocks. */ /* Get the keys and place them in the key blocks. */
...@@ -407,11 +484,11 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -407,11 +484,11 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
k < Nk && kcp; k < Nk && kcp;
k++, kcp = kcp->Next) { k++, kcp = kcp->Next) {
colp = To_Cols[k]; colp = To_Cols[k];
colp->Reset();
colp->ReadColumn(g); if (!colp->GetStatus(BUF_READ))
// if (colp->ReadColumn(g)) colp->ReadColumn(g);
// goto err; else
colp->Reset();
kcp->SetValue(colp, nkey); kcp->SetValue(colp, nkey);
} // endfor k } // endfor k
...@@ -422,7 +499,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -422,7 +499,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
end_of_file: end_of_file:
// Update progress information // Update progress information
dup->ProgCur = Tdbp->GetProgMax(g); //dup->ProgCur = Tdbp->GetProgMax(g);
/*********************************************************************/ /*********************************************************************/
/* Record the Index size and eventually resize memory allocation. */ /* Record the Index size and eventually resize memory allocation. */
...@@ -457,6 +534,10 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -457,6 +534,10 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
goto err; // Error goto err; // Error
} // endif alloc } // endif alloc
// We must separate keys and added columns before sorting
addcolp = To_LastCol->Next;
To_LastCol->Next = NULL;
// Call the sort program, it returns the number of distinct values // Call the sort program, it returns the number of distinct values
if ((Ndif = Qsort(g, Num_K)) < 0) if ((Ndif = Qsort(g, Num_K)) < 0)
goto err; // Error during sort goto err; // Error during sort
...@@ -469,6 +550,9 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -469,6 +550,9 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
} else } else
PlgDBfree(Offset); // Not used anymore PlgDBfree(Offset); // Not used anymore
// Restore kcp list
To_LastCol->Next = addcolp;
// Use the index to physically reorder the xindex // Use the index to physically reorder the xindex
Srtd = Reorder(g); Srtd = Reorder(g);
...@@ -493,7 +577,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -493,7 +577,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
} else { } else {
Mul = false; // Current index is unique Mul = false; // Current index is unique
PlgDBfree(Offset); // Not used anymore PlgDBfree(Offset); // Not used anymore
MaxSame = 1; // Reset it when remaking an index MaxSame = 1; // Reset it when remaking an index
} // endif Ndif } // endif Ndif
/*********************************************************************/ /*********************************************************************/
...@@ -508,7 +592,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -508,7 +592,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
/* except if the subset originally contains unique values. */ /* except if the subset originally contains unique values. */
/*********************************************************************/ /*********************************************************************/
// Update progress information // Update progress information
dup->Step = STEP(REDUCE_INDEX); //dup->Step = STEP(REDUCE_INDEX);
ndf = Ndif; ndf = Ndif;
To_LastCol->Mxs = MaxSame; To_LastCol->Mxs = MaxSame;
...@@ -558,7 +642,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -558,7 +642,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
/* calculated, so the Record array can be discarted. */ /* calculated, so the Record array can be discarted. */
/* Note: for Num_K = 1 any non null value is Ok. */ /* Note: for Num_K = 1 any non null value is Ok. */
/*********************************************************************/ /*********************************************************************/
if (Srtd && Tdbp->Ftype != RECFM_VAR) { if (Srtd && !filp && Tdbp->Ftype != RECFM_VAR) {
Incr = (Num_K > 1) ? To_Rec[1] : Num_K; Incr = (Num_K > 1) ? To_Rec[1] : Num_K;
PlgDBfree(Record); PlgDBfree(Record);
} // endif Srtd } // endif Srtd
...@@ -587,8 +671,14 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -587,8 +671,14 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
/*********************************************************************/ /*********************************************************************/
/* Save the xindex so it has not to be recalculated. */ /* Save the xindex so it has not to be recalculated. */
/*********************************************************************/ /*********************************************************************/
if (X && SaveIndex(g, sxp)) if (X) {
brc = true; if (SaveIndex(g, sxp))
brc = true;
} else // Dynamic index
// Indicate that key column values can be found from KEYCOL's
for (kcp = To_KeyCol; kcp; kcp = kcp->Next)
kcp->Colp->SetKcol(kcp);
err: err:
// We don't need the index anymore // We don't need the index anymore
...@@ -637,6 +727,7 @@ bool XINDEX::Reorder(PGLOBAL g) ...@@ -637,6 +727,7 @@ bool XINDEX::Reorder(PGLOBAL g)
register int i, j, k, n; register int i, j, k, n;
bool sorted = true; bool sorted = true;
PXCOL kcp; PXCOL kcp;
#if 0
PDBUSER dup = (PDBUSER)g->Activityp->Aptr; PDBUSER dup = (PDBUSER)g->Activityp->Aptr;
if (Num_K > 500000) { if (Num_K > 500000) {
...@@ -646,6 +737,7 @@ bool XINDEX::Reorder(PGLOBAL g) ...@@ -646,6 +737,7 @@ bool XINDEX::Reorder(PGLOBAL g)
dup->ProgCur = 0; dup->ProgCur = 0;
} else } else
dup = NULL; dup = NULL;
#endif // 0
if (!Pex) if (!Pex)
return Srtd; return Srtd;
...@@ -654,8 +746,8 @@ bool XINDEX::Reorder(PGLOBAL g) ...@@ -654,8 +746,8 @@ bool XINDEX::Reorder(PGLOBAL g)
if (Pex[i] == Num_K) { // Already moved if (Pex[i] == Num_K) { // Already moved
continue; continue;
} else if (Pex[i] == i) { // Already placed } else if (Pex[i] == i) { // Already placed
if (dup) // if (dup)
dup->ProgCur++; // dup->ProgCur++;
continue; continue;
} // endif's Pex } // endif's Pex
...@@ -684,8 +776,8 @@ bool XINDEX::Reorder(PGLOBAL g) ...@@ -684,8 +776,8 @@ bool XINDEX::Reorder(PGLOBAL g)
To_Rec[j] = To_Rec[k]; To_Rec[j] = To_Rec[k];
} // endif k } // endif k
if (dup) // if (dup)
dup->ProgCur++; // dup->ProgCur++;
} // endfor j } // endfor j
...@@ -2834,7 +2926,7 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln) ...@@ -2834,7 +2926,7 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
int len = colp->GetLength(), prec = colp->GetScale(); int len = colp->GetLength(), prec = colp->GetScale();
// Currently no indexing on NULL columns // Currently no indexing on NULL columns
if (colp->IsNullable()) { if (colp->IsNullable() && kln) {
sprintf(g->Message, "Cannot index nullable column %s", colp->GetName()); sprintf(g->Message, "Cannot index nullable column %s", colp->GetName());
return true; return true;
} // endif nullable } // endif nullable
...@@ -2877,6 +2969,7 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln) ...@@ -2877,6 +2969,7 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
IsSorted = colp->GetOpt() == 2; IsSorted = colp->GetOpt() == 2;
//SetNulls(colp->IsNullable()); for when null columns will be indexable //SetNulls(colp->IsNullable()); for when null columns will be indexable
Colp = colp;
return false; return false;
} // end of Init } // end of Init
......
...@@ -177,6 +177,8 @@ class DllExport XXBASE : public CSORT, public BLOCK { ...@@ -177,6 +177,8 @@ class DllExport XXBASE : public CSORT, public BLOCK {
virtual void Reset(void) = 0; virtual void Reset(void) = 0;
virtual bool IsMul(void) {return false;} virtual bool IsMul(void) {return false;}
virtual bool IsRandom(void) {return true;} virtual bool IsRandom(void) {return true;}
virtual bool IsDynamic(void) {return Dynamic;}
virtual void SetDynamic(bool dyn) {Dynamic = dyn;}
virtual bool HaveSame(void) {return false;} virtual bool HaveSame(void) {return false;}
virtual int GetCurPos(void) {return Cur_K;} virtual int GetCurPos(void) {return Cur_K;}
virtual void SetNval(int n) {assert(n == 1);} virtual void SetNval(int n) {assert(n == 1);}
...@@ -227,6 +229,7 @@ class DllExport XXBASE : public CSORT, public BLOCK { ...@@ -227,6 +229,7 @@ class DllExport XXBASE : public CSORT, public BLOCK {
OPVAL Op; // Search operator OPVAL Op; // Search operator
bool Mul; // true if multiple bool Mul; // true if multiple
bool Srtd; // true for sorted column bool Srtd; // true for sorted column
bool Dynamic; // true when dynamically made
int Val_K; // Index of current value int Val_K; // Index of current value
int Nblk; // Number of blocks int Nblk; // Number of blocks
int Sblk; // Block size int Sblk; // Block size
...@@ -275,6 +278,7 @@ class DllExport XINDEX : public XXBASE { ...@@ -275,6 +278,7 @@ class DllExport XINDEX : public XXBASE {
bool GetAllSizes(PGLOBAL g, int &ndif, int &numk); bool GetAllSizes(PGLOBAL g, int &ndif, int &numk);
protected: protected:
bool AddColumns(void);
bool NextValDif(void); bool NextValDif(void);
// Members // 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