Commit cdbb7958 authored by Olivier Bertrand's avatar Olivier Bertrand

- Adding fetched columns to Dynamic index key (unique only)

  Fix two bugs concerning added KXYCOL's:
  1 - Not set during reading
  2 - Val_K not set in FastFind
modified:
  storage/connect/connect.cc
  storage/connect/filamtxt.h
  storage/connect/tabdos.cpp
  storage/connect/tabfix.cpp
  storage/connect/table.cpp
  storage/connect/valblk.h
  storage/connect/xindex.cpp
  storage/connect/xindex.h
  storage/connect/xtable.h
parent 006dfe52
...@@ -442,7 +442,7 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp) ...@@ -442,7 +442,7 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp)
for (PCOL colp= tdbp->GetColumns(); colp; colp= colp->GetNext()) for (PCOL colp= tdbp->GetColumns(); colp; colp= colp->GetNext())
colp->SetKcol(NULL); colp->SetKcol(NULL);
((PTDBASE)tdbp)->SetKindex(NULL); ((PTDBASE)tdbp)->SetKindex(g, NULL);
} // endif index } // endif index
// Save stack and allocation environment and prepare error return // Save stack and allocation environment and prepare error return
...@@ -585,7 +585,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp) ...@@ -585,7 +585,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
// Make all the eventual indexes // Make all the eventual indexes
tbxp= (TDBDOX*)tdbp; tbxp= (TDBDOX*)tdbp;
tbxp->SetKindex(NULL); tbxp->SetKindex(g, NULL);
tbxp->To_Key_Col= NULL; tbxp->To_Key_Col= NULL;
rc= tbxp->ResetTableOpt(g, true, rc= tbxp->ResetTableOpt(g, true,
((PTDBASE)tdbp)->GetDef()->Indexable() == 1); ((PTDBASE)tdbp)->GetDef()->Indexable() == 1);
......
...@@ -65,7 +65,7 @@ class DllExport TXTFAM : public BLOCK { ...@@ -65,7 +65,7 @@ class DllExport TXTFAM : public BLOCK {
virtual bool DeferReading(void) {IsRead = false; return true;} virtual bool DeferReading(void) {IsRead = false; return true;}
virtual int ReadBuffer(PGLOBAL g) = 0; virtual int ReadBuffer(PGLOBAL g) = 0;
virtual int WriteBuffer(PGLOBAL g) = 0; virtual int WriteBuffer(PGLOBAL g) = 0;
virtual int DeleteRecords(PGLOBAL g, int irc) = 0; virtual int DeleteRecords(PGLOBAL g, int irc) = 0;
virtual void CloseTableFile(PGLOBAL g) = 0; virtual void CloseTableFile(PGLOBAL g) = 0;
virtual void Rewind(void) = 0; virtual void Rewind(void) = 0;
......
...@@ -1377,15 +1377,10 @@ PBF TDBDOS::CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv) ...@@ -1377,15 +1377,10 @@ PBF TDBDOS::CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv)
if (n == 3 || n == 6) { if (n == 3 || n == 6) {
if (conv) { if (conv) {
// The constant has not the good type and will not match // The constant has not the good type and will not match
// the block min/max values. What we can do here is either // the block min/max values. Warn and abort.
// abort with an error message or simply not do the block
// optimization (as column values can be converted when
// evaluating the filter.) Currently we prefer aborting
// because the user may count on the performance enhancing
// and silently not doing it is probably worse than just
// telling him to fix his query.
sprintf(g->Message, "Block opt: %s", MSG(VALTYPE_NOMATCH)); sprintf(g->Message, "Block opt: %s", MSG(VALTYPE_NOMATCH));
longjmp(g->jumper[g->jump_level], 99); PushWarning(g, this);
return NULL;
} // endif Conv } // endif Conv
if (type[0] == 1) { if (type[0] == 1) {
...@@ -1484,7 +1479,10 @@ void TDBDOS::ResetBlockFilter(PGLOBAL g) ...@@ -1484,7 +1479,10 @@ void TDBDOS::ResetBlockFilter(PGLOBAL g)
{ {
if (!To_BlkFil) { if (!To_BlkFil) {
if (To_Filter) if (To_Filter)
To_BlkFil = InitBlockFilter(g, To_Filter); if ((To_BlkFil = InitBlockFilter(g, To_Filter))) {
htrc("BlkFil=%p\n", To_BlkFil);
MaxSize = -1; // To be recalculated
} // endif To_BlkFil
return; return;
} // endif To_BlkFil } // endif To_BlkFil
...@@ -1767,13 +1765,19 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, PIXDEF xdp) ...@@ -1767,13 +1765,19 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, PIXDEF xdp)
return true; return true;
} // endif } // endif
if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) { if (!(rc = setjmp(g->jumper[++g->jump_level])) != 0) {
brc = true; if (dynamic) {
} else ResetBlockFilter(g);
if (!(brc = (dynamic) ? kxp->Make(g, xdp) : kxp->Init(g))) {
kxp->SetDynamic(dynamic); kxp->SetDynamic(dynamic);
brc = kxp->Make(g, xdp);
} else
brc = kxp->Init(g);
if (!brc)
To_Kindex= kxp; To_Kindex= kxp;
} // endif brc
} else
brc = true;
g->jump_level--; g->jump_level--;
return brc; return brc;
......
...@@ -133,8 +133,8 @@ int TDBFIX::ResetTableOpt(PGLOBAL g, bool dop, bool dox) ...@@ -133,8 +133,8 @@ int TDBFIX::ResetTableOpt(PGLOBAL g, bool dop, bool dox)
//To_BlkIdx = NULL; // and block filtering //To_BlkIdx = NULL; // and block filtering
To_BlkFil = NULL; // and index filtering To_BlkFil = NULL; // and index filtering
RestoreNrec(); // May have been modified RestoreNrec(); // May have been modified
MaxSize = -1; // Size must be recalculated MaxSize = -1; // Size must be recalculated
Cardinal = -1; // as well as Cardinality Cardinal = -1; // as well as Cardinality
if (dop) { if (dop) {
Columns = NULL; // Not used anymore Columns = NULL; // Not used anymore
...@@ -177,6 +177,9 @@ void TDBFIX::RestoreNrec(void) ...@@ -177,6 +177,9 @@ void TDBFIX::RestoreNrec(void)
Txfp->Nrec = (To_Def && To_Def->GetElemt()) ? To_Def->GetElemt() Txfp->Nrec = (To_Def && To_Def->GetElemt()) ? To_Def->GetElemt()
: DOS_BUFF_LEN; : DOS_BUFF_LEN;
Txfp->Blksize = Txfp->Nrec * Txfp->Lrecl; Txfp->Blksize = Txfp->Nrec * Txfp->Lrecl;
assert(Cardinal >= 0);
Txfp->Block = (Cardinal > 0)
? (Cardinal + Txfp->Nrec - 1) / Txfp->Nrec : 0;
} // endif Padded } // endif Padded
} // end of RestoreNrec } // end of RestoreNrec
...@@ -332,7 +335,7 @@ bool TDBFIX::OpenDB(PGLOBAL g) ...@@ -332,7 +335,7 @@ bool TDBFIX::OpenDB(PGLOBAL g)
To_BlkFil = InitBlockFilter(g, To_Filter); To_BlkFil = InitBlockFilter(g, To_Filter);
if (trace) if (trace)
htrc("OpenDos: R%hd mode=%d\n", Tdb_No, Mode); htrc("OpenFix: R%hd mode=%d BlkFil=%p\n", Tdb_No, Mode, To_BlkFil);
/*********************************************************************/ /*********************************************************************/
/* Reset buffer access according to indexing and to mode. */ /* Reset buffer access according to indexing and to mode. */
......
...@@ -314,10 +314,14 @@ int TDBASE::ResetTableOpt(PGLOBAL g, bool dop, bool dox) ...@@ -314,10 +314,14 @@ int TDBASE::ResetTableOpt(PGLOBAL g, bool dop, bool dox)
/***********************************************************************/ /***********************************************************************/
/* SetKindex: set or reset the index pointer. */ /* SetKindex: set or reset the index pointer. */
/***********************************************************************/ /***********************************************************************/
void TDBASE::SetKindex(PKXBASE kxp) void TDBASE::SetKindex(PGLOBAL g, PKXBASE kxp)
{ {
if (To_Kindex) if (To_Kindex) {
int pos = GetRecpos(); // To be reset in Txfp
To_Kindex->Close(); // Discard old index To_Kindex->Close(); // Discard old index
SetRecpos(g, pos); // Ignore return value
} // endif To_Kindex
To_Kindex = kxp; To_Kindex = kxp;
} // end of SetKindex } // end of SetKindex
......
...@@ -22,36 +22,36 @@ DllExport PVBLK AllocValBlock(PGLOBAL, void*, int, int, int, int, ...@@ -22,36 +22,36 @@ DllExport PVBLK AllocValBlock(PGLOBAL, void*, int, int, int, int,
bool, bool, bool); bool, bool, bool);
const char *GetFmt(int type, bool un = false); const char *GetFmt(int type, bool un = false);
/***********************************************************************/ /***********************************************************************/
/* DB static external variables. */ /* DB static external variables. */
/***********************************************************************/ /***********************************************************************/
extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */ extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */
/***********************************************************************/ /***********************************************************************/
/* Class MBVALS is a utility class for (re)allocating VALBLK's. */ /* Class MBVALS is a utility class for (re)allocating VALBLK's. */
/***********************************************************************/ /***********************************************************************/
class MBVALS : public BLOCK { class MBVALS : public BLOCK {
//friend class LSTBLK; //friend class LSTBLK;
friend class ARRAY; friend class ARRAY;
public: public:
// Constructors // Constructors
MBVALS(void) {Vblk = NULL; Mblk = Nmblk;} MBVALS(void) {Vblk = NULL; Mblk = Nmblk;}
// Methods // Methods
void *GetMemp(void) {return Mblk.Memp;} void *GetMemp(void) {return Mblk.Memp;}
PVBLK Allocate(PGLOBAL g, int type, int len, int prec, PVBLK Allocate(PGLOBAL g, int type, int len, int prec,
int n, bool sub = FALSE); int n, bool sub = FALSE);
bool ReAllocate(PGLOBAL g, int n); bool ReAllocate(PGLOBAL g, int n);
void Free(void); void Free(void);
protected: protected:
// Members // Members
PVBLK Vblk; // Pointer to VALBLK PVBLK Vblk; // Pointer to VALBLK
MBLOCK Mblk; // The memory block MBLOCK Mblk; // The memory block
}; // end of class MBVALS }; // end of class MBVALS
typedef class MBVALS *PMBV; typedef class MBVALS *PMBV;
/***********************************************************************/ /***********************************************************************/
/* Class VALBLK represent a base class for variable blocks. */ /* Class VALBLK represent a base class for variable blocks. */
/***********************************************************************/ /***********************************************************************/
......
...@@ -242,7 +242,7 @@ void XINDEX::Reset(void) ...@@ -242,7 +242,7 @@ void XINDEX::Reset(void)
/***********************************************************************/ /***********************************************************************/
/* XINDEX Close: terminate index and free all allocated data. */ /* XINDEX Close: terminate index and free all allocated data. */
/* Do not reset other values that are used at return to make. */ /* Do not reset values that are used at return to make. */
/***********************************************************************/ /***********************************************************************/
void XINDEX::Close(void) void XINDEX::Close(void)
{ {
...@@ -264,6 +264,9 @@ void XINDEX::Close(void) ...@@ -264,6 +264,9 @@ void XINDEX::Close(void)
kcp->FreeData(); kcp->FreeData();
} // endfor kcp } // endfor kcp
if (Tdbp)
Tdbp->RestoreNrec();
} // end of Close } // end of Close
/***********************************************************************/ /***********************************************************************/
...@@ -288,7 +291,7 @@ int XINDEX::Qcompare(int *i1, int *i2) ...@@ -288,7 +291,7 @@ int XINDEX::Qcompare(int *i1, int *i2)
/* Sure enough, it is done while records are read and permit to avoid */ /* Sure enough, it is done while records are read and permit to avoid */
/* reading the table while doing the join (Dynamic index only) */ /* reading the table while doing the join (Dynamic index only) */
/***********************************************************************/ /***********************************************************************/
bool XINDEX::AddColumns(void) bool XINDEX::AddColumns(PIXDEF xdp)
{ {
if (!Dynamic) if (!Dynamic)
return false; // Not applying to static index return false; // Not applying to static index
...@@ -309,7 +312,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -309,7 +312,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
/*********************************************************************/ /*********************************************************************/
/* Table can be accessed through an index. */ /* Table can be accessed through an index. */
/*********************************************************************/ /*********************************************************************/
int k, rc = RC_OK; int k, nk = Nk, 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 = false; bool brc = false;
...@@ -378,7 +381,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -378,7 +381,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
To_LastCol = prev; To_LastCol = prev;
if (AddColumns()) { if (AddColumns(sxp)) {
PCOL kolp = To_Cols[0]; // Temporary while imposing Nk = 1 PCOL kolp = To_Cols[0]; // Temporary while imposing Nk = 1
i = 0; i = 0;
...@@ -415,6 +418,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -415,6 +418,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
htrc("Adding colp=%p Buf_Type=%d size=%d\n", htrc("Adding colp=%p Buf_Type=%d size=%d\n",
colp, colp->GetResultType(), n); colp, colp->GetResultType(), n);
nk++;
prev->Next = kcp; prev->Next = kcp;
prev = kcp; prev = kcp;
} // endfor colp } // endfor colp
...@@ -481,9 +485,10 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -481,9 +485,10 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
/* Get the keys and place them in the key blocks. */ /* Get the keys and place them in the key blocks. */
/*******************************************************************/ /*******************************************************************/
for (k = 0, kcp = To_KeyCol; for (k = 0, kcp = To_KeyCol;
k < Nk && kcp; k < nk && kcp;
k++, kcp = kcp->Next) { k++, kcp = kcp->Next) {
colp = To_Cols[k]; // colp = To_Cols[k];
colp = kcp->Colp;
if (!colp->GetStatus(BUF_READ)) if (!colp->GetStatus(BUF_READ))
colp->ReadColumn(g); colp->ReadColumn(g);
...@@ -542,6 +547,10 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) ...@@ -542,6 +547,10 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
if ((Ndif = Qsort(g, Num_K)) < 0) if ((Ndif = Qsort(g, Num_K)) < 0)
goto err; // Error during sort goto err; // Error during sort
// if (trace)
htrc("Make: Nk=%d n=%d Num_K=%d Ndif=%d addcolp=%p BlkFil=%p X=%p\n",
Nk, n, Num_K, Ndif, addcolp, Tdbp->To_BlkFil, X);
// Check whether the unique index is unique indeed // Check whether the unique index is unique indeed
if (!Mul) if (!Mul)
if (Ndif < Num_K) { if (Ndif < Num_K) {
...@@ -2210,7 +2219,10 @@ int XINDXS::FastFind(int nk) ...@@ -2210,7 +2219,10 @@ int XINDXS::FastFind(int nk)
n = 0; n = 0;
} // endif sup } // endif sup
kcp->Val_K = i; // Used by FillValue // Loop on kcp because of dynamic indexing
for (; kcp; kcp = kcp->Next)
kcp->Val_K = i; // Used by FillValue
return ((n) ? Num_K : (Mul) ? Pof[i] : i); return ((n) ? Num_K : (Mul) ? Pof[i] : i);
} // end of FastFind } // end of FastFind
......
...@@ -278,7 +278,7 @@ class DllExport XINDEX : public XXBASE { ...@@ -278,7 +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 AddColumns(PIXDEF xdp);
bool NextValDif(void); bool NextValDif(void);
// Members // Members
......
...@@ -148,7 +148,7 @@ class DllExport TDBASE : public TDB { ...@@ -148,7 +148,7 @@ class DllExport TDBASE : public TDB {
inline void SetXdp(PIXDEF xdp) {To_Xdp = xdp;} inline void SetXdp(PIXDEF xdp) {To_Xdp = xdp;}
// Properties // Properties
void SetKindex(PKXBASE kxp); void SetKindex(PGLOBAL g, PKXBASE kxp);
PCOL Key(int i) {return (To_Key_Col) ? To_Key_Col[i] : NULL;} PCOL Key(int i) {return (To_Key_Col) ? To_Key_Col[i] : NULL;}
// Methods // Methods
......
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