Commit 0e20f021 authored by Olivier Bertrand's avatar Olivier Bertrand

- 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
parent 9d296474
...@@ -651,6 +651,14 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id) ...@@ -651,6 +651,14 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id)
return 0; return 0;
} // endif xdp } // 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 // Allocate the key columns definition block
tdbp->Knum= xdp->GetNparts(); tdbp->Knum= xdp->GetNparts();
tdbp->To_Key_Col= (PCOL*)PlugSubAlloc(g, NULL, tdbp->Knum * sizeof(PCOL)); tdbp->To_Key_Col= (PCOL*)PlugSubAlloc(g, NULL, tdbp->Knum * sizeof(PCOL));
...@@ -738,10 +746,23 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op, ...@@ -738,10 +746,23 @@ 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) {
sprintf(g->Message, "Index not initialized for table %s", tdbp->Name); if (!tdbp->To_Xdp) {
return RC_FX; sprintf(g->Message, "Index not initialized for table %s", tdbp->Name);
} else return RC_FX;
xbp= (XXBASE*)tdbp->To_Kindex; } // 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) { if (key) {
for (n= 0; n < tdbp->Knum; n++) { for (n= 0; n < tdbp->Knum; n++) {
...@@ -829,10 +850,14 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len, ...@@ -829,10 +850,14 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
} else } else
tdbp= (PTDBDOX)ptdb; tdbp= (PTDBDOX)ptdb;
if (!tdbp->To_Link || !tdbp->To_Kindex) { if (!tdbp->To_Kindex || !tdbp->To_Link) {
sprintf(g->Message, "Index not initialized for table %s", tdbp->Name); if (!tdbp->To_Xdp) {
DBUG_PRINT("Range", ("%s", g->Message)); sprintf(g->Message, "Index not initialized for table %s", tdbp->Name);
return -1; DBUG_PRINT("Range", ("%s", g->Message));
return -1;
} else // Dynamic index
return tdbp->To_Xdp->GetMaxSame(); // TODO a better estimate
} else } else
xbp= (XXBASE*)tdbp->To_Kindex; xbp= (XXBASE*)tdbp->To_Kindex;
......
...@@ -1711,7 +1711,7 @@ PFIL PrepareFilter(PGLOBAL g, PFIL fp, bool having) ...@@ -1711,7 +1711,7 @@ PFIL PrepareFilter(PGLOBAL g, PFIL fp, bool having)
/* New algorithm: evaluate from the root a de-linearized filter so */ /* New algorithm: evaluate from the root a de-linearized filter so */
/* AND/OR clauses can be optimized throughout the whole tree. */ /* 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) if (!filp)
return TRUE; return TRUE;
......
...@@ -26,7 +26,7 @@ PFIL MakeFilter(PGLOBAL g, PCOL *colp, POPER pop, PPARM pfirst, bool neg); ...@@ -26,7 +26,7 @@ PFIL MakeFilter(PGLOBAL g, PCOL *colp, POPER pop, PPARM pfirst, bool neg);
/***********************************************************************/ /***********************************************************************/
class DllExport FILTER : public XOBJECT { /* Filter description block */ class DllExport FILTER : public XOBJECT { /* Filter description block */
//friend PFIL PrepareFilter(PGLOBAL, PFIL, bool); //friend PFIL PrepareFilter(PGLOBAL, PFIL, bool);
friend DllExport bool ApplyFilter(PGLOBAL, PFIL, PTDB = NULL); friend DllExport bool ApplyFilter(PGLOBAL, PFIL);
public: public:
// Constructors // Constructors
FILTER(PGLOBAL g, POPER pop, PPARM *tp = NULL); FILTER(PGLOBAL g, POPER pop, PPARM *tp = NULL);
......
...@@ -170,7 +170,7 @@ ...@@ -170,7 +170,7 @@
#define SZWMIN 4194304 // Minimum work area size 4M #define SZWMIN 4194304 // Minimum work area size 4M
extern "C" { extern "C" {
char version[]= "Version 1.02.0002 March 16, 2014"; char version[]= "Version 1.03.0002 April 23, 2014";
#if defined(XMSG) #if defined(XMSG)
char msglang[]; // Default message language char msglang[]; // Default message language
...@@ -324,7 +324,7 @@ ha_create_table_option connect_field_option_list[]= ...@@ -324,7 +324,7 @@ 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("DYN", kindx, 0), HA_IOPTION_BOOL("DYNAMIC", kindx, 0),
HA_IOPTION_BOOL("MAPPED", mapped, 0), HA_IOPTION_BOOL("MAPPED", mapped, 0),
}; };
...@@ -658,7 +658,7 @@ TABTYPE ha_connect::GetRealType(PTOS pos) ...@@ -658,7 +658,7 @@ 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 "XPLUG"; case 1: return "XINDEX";
case 2: return "REMOTE"; case 2: return "REMOTE";
} // endswitch } // endswitch
...@@ -1142,6 +1142,14 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf) ...@@ -1142,6 +1142,14 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
return fldp; return fldp;
} // end of GetColumnOption } // 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. */ /* Returns the index description structure used to make the index. */
/****************************************************************************/ /****************************************************************************/
...@@ -1151,6 +1159,7 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s) ...@@ -1151,6 +1159,7 @@ 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;
...@@ -1163,6 +1172,7 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s) ...@@ -1163,6 +1172,7 @@ 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];
...@@ -1205,6 +1215,20 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s) ...@@ -1205,6 +1215,20 @@ PIXDEF ha_connect::GetIndexInfo(TABLE_SHARE *s)
xdp->SetNParts(kp.user_defined_key_parts); 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) if (pxd)
pxd->SetNext(xdp); pxd->SetNext(xdp);
else else
...@@ -1844,6 +1868,15 @@ const char *ha_connect::GetValStr(OPVAL vop, bool neg) ...@@ -1844,6 +1868,15 @@ const char *ha_connect::GetValStr(OPVAL vop, bool neg)
} // end of GetValStr } // end of GetValStr
/***********************************************************************/
/* 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. */ /* Check the WHERE condition and return a CONNECT filter. */
/***********************************************************************/ /***********************************************************************/
...@@ -2680,7 +2713,7 @@ int ha_connect::index_init(uint idx, bool sorted) ...@@ -2680,7 +2713,7 @@ int ha_connect::index_init(uint idx, bool sorted)
htrc("index_init CONNECT: %s\n", g->Message); htrc("index_init CONNECT: %s\n", g->Message);
active_index= MAX_KEY; active_index= MAX_KEY;
rc= HA_ERR_INTERNAL_ERROR; rc= HA_ERR_INTERNAL_ERROR;
} else { } else if (((PTDBDOX)tdbp)->To_Kindex) {
if (((PTDBDOX)tdbp)->To_Kindex->GetNum_K()) { if (((PTDBDOX)tdbp)->To_Kindex->GetNum_K()) {
if (((PTDBASE)tdbp)->GetFtype() != RECFM_NAF) if (((PTDBASE)tdbp)->GetFtype() != RECFM_NAF)
((PTDBDOX)tdbp)->GetTxfp()->ResetBuffer(g); ((PTDBDOX)tdbp)->GetTxfp()->ResetBuffer(g);
...@@ -2689,7 +2722,6 @@ int ha_connect::index_init(uint idx, bool sorted) ...@@ -2689,7 +2722,6 @@ int ha_connect::index_init(uint idx, bool sorted)
} else // Void table } else // Void table
indexing= 0; indexing= 0;
rc= 0;
} // endif indexing } // endif indexing
if (xtrace) if (xtrace)
......
...@@ -72,6 +72,7 @@ typedef class XCHK *PCHK; ...@@ -72,6 +72,7 @@ typedef class XCHK *PCHK;
typedef class user_connect *PCONNECT; typedef class user_connect *PCONNECT;
typedef struct ha_table_option_struct TOS, *PTOS; typedef struct ha_table_option_struct TOS, *PTOS;
typedef struct ha_field_option_struct FOS, *PFOS; typedef struct ha_field_option_struct FOS, *PFOS;
typedef struct ha_index_option_struct XOS, *PXOS;
extern handlerton *connect_hton; extern handlerton *connect_hton;
...@@ -195,6 +196,7 @@ public: ...@@ -195,6 +196,7 @@ public:
bool NoFieldOptionChange(TABLE *tab); bool NoFieldOptionChange(TABLE *tab);
PFOS GetFieldOptionStruct(Field *fp); PFOS GetFieldOptionStruct(Field *fp);
void *GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf); void *GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf);
PXOS GetIndexOptionStruct(KEY *kp);
PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL); PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL);
const char *GetDBName(const char *name); const char *GetDBName(const char *name);
const char *GetTableName(void); const char *GetTableName(void);
...@@ -345,6 +347,7 @@ virtual const COND *cond_push(const COND *cond); ...@@ -345,6 +347,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);
/** /**
Number of rows in table. It will only be called if Number of rows in table. It will only be called if
......
...@@ -1477,12 +1477,17 @@ PBF TDBDOS::CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv) ...@@ -1477,12 +1477,17 @@ PBF TDBDOS::CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv)
} // end of CheckBlockFilari } // 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) void TDBDOS::ResetBlockFilter(PGLOBAL g)
{ {
if (!To_BlkFil) if (!To_BlkFil) {
if (To_Filter)
To_BlkFil = InitBlockFilter(g, To_Filter);
return; return;
} // endif To_BlkFil
To_BlkFil->Reset(g); To_BlkFil->Reset(g);
...@@ -1590,7 +1595,7 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add) ...@@ -1590,7 +1595,7 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
// Allocate all columns that will be used by indexes. // Allocate all columns that will be used by indexes.
// This must be done before opening the table so specific // 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 (n = 0, xdp = pxdf; xdp; xdp = xdp->GetNext())
for (kdp = xdp->GetToKeyParts(); kdp; kdp = kdp->GetNext()) { for (kdp = xdp->GetToKeyParts(); kdp; kdp = kdp->GetNext()) {
if (!(colp = ColDB(g, kdp->GetName(), 0))) { if (!(colp = ColDB(g, kdp->GetName(), 0))) {
...@@ -1687,6 +1692,79 @@ err: ...@@ -1687,6 +1692,79 @@ err:
return RC_FX; return RC_FX;
} // end of MakeIndex } // 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. */ /* DOS GetProgMax: get the max value for progress information. */
/***********************************************************************/ /***********************************************************************/
......
...@@ -169,6 +169,7 @@ class DllExport TDBDOS : public TDBASE { ...@@ -169,6 +169,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);
void ResetBlockFilter(PGLOBAL g); void ResetBlockFilter(PGLOBAL g);
bool GetDistinctColumnValues(PGLOBAL g, int nrec); bool GetDistinctColumnValues(PGLOBAL g, int nrec);
......
...@@ -139,6 +139,7 @@ TDBASE::TDBASE(PTABDEF tdp) : TDB(tdp) ...@@ -139,6 +139,7 @@ TDBASE::TDBASE(PTABDEF tdp) : TDB(tdp)
To_Link = NULL; To_Link = NULL;
To_Key_Col = NULL; To_Key_Col = NULL;
To_Kindex = NULL; To_Kindex = NULL;
To_Xdp = NULL;
To_SetCols = NULL; To_SetCols = NULL;
MaxSize = -1; MaxSize = -1;
Knum = 0; Knum = 0;
...@@ -149,8 +150,13 @@ TDBASE::TDBASE(PTABDEF tdp) : TDB(tdp) ...@@ -149,8 +150,13 @@ TDBASE::TDBASE(PTABDEF tdp) : TDB(tdp)
TDBASE::TDBASE(PTDBASE tdbp) : TDB(tdbp) TDBASE::TDBASE(PTDBASE tdbp) : TDB(tdbp)
{ {
To_Def = tdbp->To_Def; 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; // ??? To_SetCols = tdbp->To_SetCols; // ???
MaxSize = tdbp->MaxSize; MaxSize = tdbp->MaxSize;
Knum = tdbp->Knum;
Read_Only = tdbp->Read_Only; Read_Only = tdbp->Read_Only;
m_data_charset= tdbp->m_data_charset; m_data_charset= tdbp->m_data_charset;
} // end of TDBASE copy constructor } // end of TDBASE copy constructor
......
...@@ -112,6 +112,8 @@ INDEXDEF::INDEXDEF(char *name, bool uniq, int n) ...@@ -112,6 +112,8 @@ INDEXDEF::INDEXDEF(char *name, bool uniq, int n)
Unique = uniq; Unique = uniq;
Invalid = false; Invalid = false;
AutoInc = false; AutoInc = false;
Dynamic = false;
Mapped = false;
Nparts = 0; Nparts = 0;
ID = n; ID = n;
//Offset = 0; //Offset = 0;
...@@ -242,7 +244,8 @@ void XINDEX::Reset(void) ...@@ -242,7 +244,8 @@ void XINDEX::Reset(void)
void XINDEX::Close(void) void XINDEX::Close(void)
{ {
// Close file or view of file // Close file or view of file
X->Close(); if (X)
X->Close();
// De-allocate data // De-allocate data
PlgDBfree(Record); PlgDBfree(Record);
...@@ -286,7 +289,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -286,7 +289,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
int k, rc = RC_OK; int k, rc = RC_OK;
int *bof, i, j, n, ndf, nkey; int *bof, i, j, n, ndf, nkey;
PKPDEF kdfp = Xdp->GetToKeyParts(); PKPDEF kdfp = Xdp->GetToKeyParts();
bool brc = true; bool brc = false;
PCOL colp; PCOL colp;
PXCOL kp, prev = NULL, kcp = NULL; PXCOL kp, prev = NULL, kcp = NULL;
PDBUSER dup = (PDBUSER)g->Activityp->Aptr; PDBUSER dup = (PDBUSER)g->Activityp->Aptr;
...@@ -378,11 +381,14 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -378,11 +381,14 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
// 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:
break; if (ApplyFilter(g, Tdbp->GetFilter()))
case RC_EF: break;
goto end_of_file;
// passthru
case RC_NF: case RC_NF:
continue; continue;
case RC_EF:
goto end_of_file;
default: default:
sprintf(g->Message, MSG(RC_READING), rc, Tdbp->Name); sprintf(g->Message, MSG(RC_READING), rc, Tdbp->Name);
goto err; goto err;
...@@ -579,14 +585,15 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -579,14 +585,15 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
Cur_K = Num_K; 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)) if (X && SaveIndex(g, sxp))
brc = false; brc = true;
err: err:
// We don't need the index anymore // We don't need the index anymore
Close(); if (X || brc)
Close();
if (brc) if (brc)
printf("%s\n", g->Message); printf("%s\n", g->Message);
......
...@@ -87,6 +87,7 @@ class DllExport INDEXDEF : public BLOCK { /* Index description block */ ...@@ -87,6 +87,7 @@ class DllExport INDEXDEF : public BLOCK { /* Index description block */
void SetNext(PIXDEF pxdf) {Next = pxdf;} void SetNext(PIXDEF pxdf) {Next = pxdf;}
PSZ GetName(void) {return (PSZ)Name;} PSZ GetName(void) {return (PSZ)Name;}
bool IsUnique(void) {return Unique;} bool IsUnique(void) {return Unique;}
bool IsDynamic(void) {return Dynamic;}
bool IsAuto(void) {return AutoInc;} bool IsAuto(void) {return AutoInc;}
void SetAuto(bool b) {AutoInc = b;} void SetAuto(bool b) {AutoInc = b;}
void SetInvalid(bool b) {Invalid = b;} void SetInvalid(bool b) {Invalid = b;}
...@@ -115,6 +116,8 @@ class DllExport INDEXDEF : public BLOCK { /* Index description block */ ...@@ -115,6 +116,8 @@ class DllExport INDEXDEF : public BLOCK { /* Index description block */
bool Unique; /* true if defined as unique */ bool Unique; /* true if defined as unique */
bool Invalid; /* true if marked as Invalid */ bool Invalid; /* true if marked as Invalid */
bool AutoInc; /* true if unique key in auto increment */ 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 Nparts; /* Number of key parts */
int ID; /* Index ID number */ int ID; /* Index ID number */
int MaxSame; /* Max number of same values */ int MaxSame; /* Max number of same values */
...@@ -192,6 +195,7 @@ class DllExport XXBASE : public CSORT, public BLOCK { ...@@ -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, FILE *f, uint n);
virtual void Print(PGLOBAL g, char *ps, uint z); virtual void Print(PGLOBAL g, char *ps, uint z);
virtual bool Init(PGLOBAL g) = 0; virtual bool Init(PGLOBAL g) = 0;
virtual bool Make(PGLOBAL g, PIXDEF sxp) = 0;
#if defined(XMAP) #if defined(XMAP)
virtual bool MapInit(PGLOBAL g) = 0; virtual bool MapInit(PGLOBAL g) = 0;
#endif // XMAP #endif // XMAP
...@@ -420,6 +424,7 @@ class DllExport XXROW : public XXBASE { ...@@ -420,6 +424,7 @@ class DllExport XXROW : public XXBASE {
virtual int MaxRange(void) {return 1;} virtual int MaxRange(void) {return 1;}
virtual int Range(PGLOBAL g, int limit = 0, bool incl = true); virtual int Range(PGLOBAL g, int limit = 0, bool incl = true);
virtual int Qcompare(int *, int *) {assert(false); return 0;} virtual int Qcompare(int *, int *) {assert(false); return 0;}
virtual bool Make(PGLOBAL g, PIXDEF sxp) {return false;}
virtual void Close(void) {} virtual void Close(void) {}
protected: protected:
......
...@@ -145,6 +145,7 @@ class DllExport TDBASE : public TDB { ...@@ -145,6 +145,7 @@ class DllExport TDBASE : public TDB {
inline PKXBASE GetKindex(void) {return To_Kindex;} inline PKXBASE GetKindex(void) {return To_Kindex;}
inline PCOL GetSetCols(void) {return To_SetCols;} inline PCOL GetSetCols(void) {return To_SetCols;}
inline void SetSetCols(PCOL colp) {To_SetCols = colp;} inline void SetSetCols(PCOL colp) {To_SetCols = colp;}
inline void SetXdp(PIXDEF xdp) {To_Xdp = xdp;}
// Properties // Properties
void SetKindex(PKXBASE kxp); void SetKindex(PKXBASE kxp);
...@@ -191,8 +192,9 @@ class DllExport TDBASE : public TDB { ...@@ -191,8 +192,9 @@ class DllExport TDBASE : public TDB {
PXOB *To_Link; // Points to column of previous relations PXOB *To_Link; // Points to column of previous relations
PCOL *To_Key_Col; // Points to key columns in current file PCOL *To_Key_Col; // Points to key columns in current file
PKXBASE To_Kindex; // Points to table key index PKXBASE To_Kindex; // Points to table key index
PIXDEF To_Xdp; // To the index definition block
PCOL To_SetCols; // Points to updated columns 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 int Knum; // Size of key arrays
bool Read_Only; // True for read only tables bool Read_Only; // True for read only tables
const CHARSET_INFO *m_data_charset; const CHARSET_INFO *m_data_charset;
......
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