Commit 3a69c854 authored by Olivier Bertrand's avatar Olivier Bertrand

- Modifies the way indexed UPDATE/DELETE are sorted in order to execute

  them sorted by file position. Firstly a new value is stored in indexes
  to know if they are sorted, preventing to do the sorting when it is not
  needed. Secondly, almost all in now done in connect instead of being
  done by the different file access method classes. This pepares the future
  use of temporary files for all table types and also fix the bug that was
  occuring when partially using a multi-column index because of false MRR
  like call of position followed by unsorted rnd_pos no more using indexing.
modified:
  storage/connect/connect.cc
  storage/connect/filamap.cpp
  storage/connect/filamap.h
  storage/connect/filamdbf.cpp
  storage/connect/filamdbf.h
  storage/connect/filamfix.cpp
  storage/connect/filamfix.h
  storage/connect/filamtxt.cpp
  storage/connect/filamtxt.h
  storage/connect/filamvct.cpp
  storage/connect/filamvct.h
  storage/connect/tabdos.cpp
  storage/connect/tabdos.h
  storage/connect/tabfix.h
  storage/connect/tabfmt.cpp
  storage/connect/tabfmt.h
  storage/connect/xindex.cpp
  storage/connect/xindex.h
  storage/connect/xtable.h
parent 78b1bdd2
...@@ -479,7 +479,7 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp) ...@@ -479,7 +479,7 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp)
/***********************************************************************/ /***********************************************************************/
RCODE CntWriteRow(PGLOBAL g, PTDB tdbp) RCODE CntWriteRow(PGLOBAL g, PTDB tdbp)
{ {
RCODE rc; RCODE rc;
PCOL colp; PCOL colp;
PTDBASE tp= (PTDBASE)tdbp; PTDBASE tp= (PTDBASE)tdbp;
...@@ -503,11 +503,14 @@ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp) ...@@ -503,11 +503,14 @@ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp)
if (!colp->GetColUse(U_VIRTUAL)) if (!colp->GetColUse(U_VIRTUAL))
colp->WriteColumn(g); colp->WriteColumn(g);
// if (tdbp->GetMode() == MODE_INSERT) //if (tp->GetMode() == MODE_UPDATE && tp->IsUsingTemp(g) &&
// tbxp->SetModified(true); // tp->GetKindex() && !tp->GetKindex()->IsSorted())
if (tp->IsIndexed())
// Return result code from write operation // Index values must be sorted before updating
rc= (RCODE)tdbp->WriteDB(g); rc= (RCODE)((PTDBDOS)tp)->GetTxfp()->StoreValues(g, true);
else
// Return result code from write operation
rc= (RCODE)tdbp->WriteDB(g);
err: err:
g->jump_level--; g->jump_level--;
...@@ -517,7 +520,7 @@ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp) ...@@ -517,7 +520,7 @@ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp)
/***********************************************************************/ /***********************************************************************/
/* UpdateRow: Update a row into a table. */ /* UpdateRow: Update a row into a table. */
/***********************************************************************/ /***********************************************************************/
RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp) RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp)
{ {
if (!tdbp || tdbp->GetMode() != MODE_UPDATE) if (!tdbp || tdbp->GetMode() != MODE_UPDATE)
return RC_FX; return RC_FX;
...@@ -531,19 +534,28 @@ RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp) ...@@ -531,19 +534,28 @@ RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp)
/***********************************************************************/ /***********************************************************************/
RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all) RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all)
{ {
RCODE rc; RCODE rc;
PTDBASE tp= (PTDBASE)tdbp;
if (!tdbp || tdbp->GetMode() != MODE_DELETE) if (!tdbp || tdbp->GetMode() != MODE_DELETE)
return RC_FX; return RC_FX;
else if (tdbp->IsReadOnly()) else if (tdbp->IsReadOnly())
return RC_NF; return RC_NF;
if (((PTDBASE)tdbp)->GetDef()->Indexable() && all) if (all) {
((PTDBDOS)tdbp)->Cardinal= 0; if (((PTDBASE)tdbp)->GetDef()->Indexable())
((PTDBDOS)tdbp)->Cardinal= 0;
// Note: if all, this call will be done when closing the table
rc= (RCODE)tdbp->DeleteDB(g, RC_FX);
//} else if (tp->GetKindex() && !tp->GetKindex()->IsSorted() &&
// tp->Txfp->GetAmType() != TYPE_AM_DBF) {
} else if(tp->IsIndexed()) {
// Index values must be sorted before updating
rc= (RCODE)((PTDBDOS)tp)->GetTxfp()->StoreValues(g, false);
} else // Return result code from delete operation
rc= (RCODE)tdbp->DeleteDB(g, RC_OK);
// Return result code from delete operation
// Note: if all, this call will be done when closing the table
rc= (RCODE)tdbp->DeleteDB(g, (all) ? RC_FX : RC_OK);
return rc; return rc;
} // end of CntDeleteRow } // end of CntDeleteRow
...@@ -553,7 +565,7 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all) ...@@ -553,7 +565,7 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all)
int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort) int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
{ {
int rc= RC_OK; int rc= RC_OK;
TDBDOX *tbxp= NULL; TDBASE *tbxp= (PTDBASE)tdbp;
if (!tdbp) if (!tdbp)
return rc; // Nothing to do return rc; // Nothing to do
...@@ -568,8 +580,30 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort) ...@@ -568,8 +580,30 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
printf("CntCloseTable: tdbp=%p mode=%d nox=%d abort=%d\n", printf("CntCloseTable: tdbp=%p mode=%d nox=%d abort=%d\n",
tdbp, tdbp->GetMode(), nox, abort); tdbp, tdbp->GetMode(), nox, abort);
if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN) #if 0
rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine if (tbxp->GetMode() == MODE_UPDATE &&
tbxp->GetKindex() && !tbxp->GetKindex()->IsSorted()) {
rc= tbxp->Txfp->UpdateSortedRows(g);
} else
if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN) {
if (tbxp->GetKindex() && !tbxp->GetKindex()->IsSorted())
rc= tbxp->Txfp->DeleteSortedRows(g);
if (!rc)
rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine
} // endif Mode
#endif // 0
if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN) {
if (tbxp->IsIndexed())
rc= ((PTDBDOS)tdbp)->GetTxfp()->DeleteSortedRows(g);
if (!rc)
rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine
} else if (tbxp->GetMode() == MODE_UPDATE && tbxp->IsIndexed())
rc= ((PTDBDOX)tdbp)->Txfp->UpdateSortedRows(g);
// Prepare error return // Prepare error return
if (g->jump_level == MAX_JUMP) { if (g->jump_level == MAX_JUMP) {
...@@ -606,9 +640,8 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort) ...@@ -606,9 +640,8 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
// Make all the eventual indexes // Make all the eventual indexes
tbxp= (TDBDOX*)tdbp; tbxp= (TDBDOX*)tdbp;
tbxp->ResetKindex(g, NULL); tbxp->ResetKindex(g, NULL);
tbxp->To_Key_Col= NULL; tbxp->SetKey_Col(NULL);
rc= tbxp->ResetTableOpt(g, true, rc= tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1);
((PTDBASE)tdbp)->GetDef()->Indexable() == 1);
err: err:
if (trace > 1) if (trace > 1)
......
...@@ -48,11 +48,6 @@ ...@@ -48,11 +48,6 @@
extern "C" int trace; extern "C" int trace;
/***********************************************************************/
/* Routine called externally by MAPFAM MakeDeletedFile function. */
/***********************************************************************/
PARRAY MakeValueArray(PGLOBAL g, PPARM pp);
/* --------------------------- Class MAPFAM -------------------------- */ /* --------------------------- Class MAPFAM -------------------------- */
/***********************************************************************/ /***********************************************************************/
...@@ -290,6 +285,16 @@ bool MAPFAM::RecordPos(PGLOBAL g) ...@@ -290,6 +285,16 @@ bool MAPFAM::RecordPos(PGLOBAL g)
return false; return false;
} // end of RecordPos } // end of RecordPos
/***********************************************************************/
/* Initialize Fpos and Mempos for indexed DELETE. */
/***********************************************************************/
int MAPFAM::InitDelete(PGLOBAL g, int fpos, int spos)
{
Fpos = Memory + fpos;
Mempos = Memory + spos;
return RC_OK;
} // end of InitDelete
/***********************************************************************/ /***********************************************************************/
/* Skip one record in file. */ /* Skip one record in file. */
/***********************************************************************/ /***********************************************************************/
...@@ -409,13 +414,6 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc) ...@@ -409,13 +414,6 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
/* not required here, just setting of future Spos and Tpos. */ /* not required here, just setting of future Spos and Tpos. */
/*******************************************************************/ /*******************************************************************/
Tpos = Spos = Fpos; Tpos = Spos = Fpos;
Indxd = Tdbp->GetKindex() != NULL;
} // endif Tpos
if (Indxd) {
// Moving will be done later, must be done in sequential order
(void)AddListValue(g, TYPE_PCHAR, Fpos, &To_Pos);
(void)AddListValue(g, TYPE_PCHAR, Mempos, &To_Sos);
} else if ((n = Fpos - Spos) > 0) { } else if ((n = Fpos - Spos) > 0) {
/*****************************************************************/ /*****************************************************************/
/* Non consecutive line to delete. Move intermediate lines. */ /* Non consecutive line to delete. Move intermediate lines. */
...@@ -437,10 +435,6 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc) ...@@ -437,10 +435,6 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
} else if (To_Fb) { // Can be NULL for deleted files } else if (To_Fb) { // Can be NULL for deleted files
/*******************************************************************/ /*******************************************************************/
/* Last call after EOF has been reached. */ /* Last call after EOF has been reached. */
/*******************************************************************/
Abort = (Indxd && MakeDeletedFile(g));
/*******************************************************************/
/* We must firstly Unmap the view and use the saved file handle */ /* We must firstly Unmap the view and use the saved file handle */
/* to put an EOF at the end of the copied part of the file. */ /* to put an EOF at the end of the copied part of the file. */
/*******************************************************************/ /*******************************************************************/
...@@ -495,55 +489,6 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc) ...@@ -495,55 +489,6 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
return RC_OK; // All is correct return RC_OK; // All is correct
} // end of DeleteRecords } // end of DeleteRecords
/***********************************************************************/
/* MakeDeletedFile. When deleting using indexing, the issue is that */
/* record are not necessarily deleted in sequential order. Moving */
/* intermediate lines cannot be done while deleting them. */
/* What we do here is to reorder the deleted records and move the */
/* intermediate files from the ordered deleted record positions. */
/***********************************************************************/
bool MAPFAM::MakeDeletedFile(PGLOBAL g)
{
int *ix, i, n;
/*********************************************************************/
/* Make and order the arrays from the saved values. */
/*********************************************************************/
if (!(Posar = MakeValueArray(g, To_Pos))) {
strcpy(g->Message, "Position array is null");
goto err;
} else if (!(Sosar = MakeValueArray(g, To_Sos))) {
strcpy(g->Message, "Start position array is null");
goto err;
} else if (!(ix = (int*)Posar->GetSortIndex(g))) {
strcpy(g->Message, "Error getting array sort index");
goto err;
} // endif's
for (i = 0; i < Posar->GetNval(); i++) {
Fpos = Posar->GetStringValue(ix[i]);
if (!i) {
Tpos = Fpos;
} else if ((n = Fpos - Spos) >= 0) {
// Move all not deleted lines preceding this one
memmove(Tpos, Spos, n);
Tpos += n;
} // endif n
// New start position
Spos = Sosar->GetStringValue(ix[i]);
} // endfor i
return false;
err:
if (trace)
htrc("%s\n", g->Message);
return true;
} // end of MakeDeletedFile
/***********************************************************************/ /***********************************************************************/
/* Table file close routine for MAP access method. */ /* Table file close routine for MAP access method. */
/***********************************************************************/ /***********************************************************************/
...@@ -734,6 +679,16 @@ bool MPXFAM::SetPos(PGLOBAL g, int pos) ...@@ -734,6 +679,16 @@ bool MPXFAM::SetPos(PGLOBAL g, int pos)
return false; return false;
} // end of SetPos } // end of SetPos
/***********************************************************************/
/* Initialize CurBlk, CurNum, Mempos and Fpos for indexed DELETE. */
/***********************************************************************/
int MPXFAM::InitDelete(PGLOBAL g, int fpos, int spos)
{
Fpos = Memory + Headlen + fpos * Lrecl;
Mempos = Fpos + Lrecl;
return RC_OK;
} // end of InitDelete
/***********************************************************************/ /***********************************************************************/
/* ReadBuffer: Read one line for a mapped Fix file. */ /* ReadBuffer: Read one line for a mapped Fix file. */
/***********************************************************************/ /***********************************************************************/
......
...@@ -47,7 +47,7 @@ class DllExport MAPFAM : public TXTFAM { ...@@ -47,7 +47,7 @@ class DllExport MAPFAM : public TXTFAM {
virtual void Rewind(void); virtual void Rewind(void);
protected: protected:
bool MakeDeletedFile(PGLOBAL g); virtual int InitDelete(PGLOBAL g, int fpos, int spos);
// Members // Members
char *Memory; // Pointer on file mapping view. char *Memory; // Pointer on file mapping view.
...@@ -104,11 +104,14 @@ class DllExport MPXFAM : public MBKFAM { ...@@ -104,11 +104,14 @@ class DllExport MPXFAM : public MBKFAM {
virtual int MaxBlkSize(PGLOBAL g, int s) virtual int MaxBlkSize(PGLOBAL g, int s)
{return TXTFAM::MaxBlkSize(g, s);} {return TXTFAM::MaxBlkSize(g, s);}
virtual bool SetPos(PGLOBAL g, int recpos); virtual bool SetPos(PGLOBAL g, int recpos);
virtual int GetNextPos(void) {return (int)Fpos + Nrec;}
virtual bool DeferReading(void) {return false;} virtual bool DeferReading(void) {return false;}
virtual int ReadBuffer(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g);
protected: protected:
virtual int InitDelete(PGLOBAL g, int fpos, int spos);
// No additional members // No additional members
}; // end of class MPXFAM }; // end of class MPXFAM
......
...@@ -750,6 +750,36 @@ bool DBFFAM::CopyHeader(PGLOBAL g) ...@@ -750,6 +750,36 @@ bool DBFFAM::CopyHeader(PGLOBAL g)
return rc; return rc;
} // end of CopyHeader } // end of CopyHeader
#if 0 // Not useful when UseTemp is false.
/***********************************************************************/
/* Mark the line to delete with '*' (soft delete). */
/* NOTE: this is not ready for UseTemp. */
/***********************************************************************/
int DBFFAM::InitDelete(PGLOBAL g, int fpos, int spos)
{
int rc = RC_FX;
size_t lrecl = (size_t)Lrecl;
if (Nrec != 1)
strcpy(g->Message, "Cannot delete in block mode");
else if (fseek(Stream, Headlen + fpos * Lrecl, SEEK_SET))
sprintf(g->Message, MSG(FSETPOS_ERROR), 0);
else if (fread(To_Buf, 1, lrecl, Stream) != lrecl)
sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
else
*To_Buf = '*';
if (fseek(Stream, Headlen + fpos * Lrecl, SEEK_SET))
sprintf(g->Message, MSG(FSETPOS_ERROR), 0);
else if (fwrite(To_Buf, 1, lrecl, Stream) != lrecl)
sprintf(g->Message, MSG(FWRITE_ERROR), strerror(errno));
else
rc = RC_NF; // Ok, Nothing else to do
return rc;
} // end of InitDelete
#endif // 0
/***********************************************************************/ /***********************************************************************/
/* Data Base delete line routine for DBF access methods. */ /* Data Base delete line routine for DBF access methods. */
/* Deleted lines are just flagged in the first buffer character. */ /* Deleted lines are just flagged in the first buffer character. */
...@@ -760,16 +790,12 @@ int DBFFAM::DeleteRecords(PGLOBAL g, int irc) ...@@ -760,16 +790,12 @@ int DBFFAM::DeleteRecords(PGLOBAL g, int irc)
// T_Stream is the temporary stream or the table file stream itself // T_Stream is the temporary stream or the table file stream itself
if (!T_Stream) if (!T_Stream)
if (UseTemp) { if (UseTemp) {
if ((Indxd = Tdbp->GetKindex() != NULL)) { if (OpenTempFile(g))
strcpy(g->Message, "DBF indexed udate using temp file NIY");
return RC_FX;
} else if (OpenTempFile(g))
return RC_FX; return RC_FX;
if (CopyHeader(g)) // For DBF tables if (CopyHeader(g)) // For DBF tables
return RC_FX; return RC_FX;
// Indxd = Tdbp->GetKindex() != NULL;
} else } else
T_Stream = Stream; T_Stream = Stream;
......
...@@ -40,8 +40,8 @@ class DllExport DBFBASE { ...@@ -40,8 +40,8 @@ class DllExport DBFBASE {
// Members // Members
int Records; /* records in the file */ int Records; /* records in the file */
bool Accept; /* true if bad lines are accepted */ bool Accept; /* true if bad lines are accepted */
int Nerr; /* Number of bad records */ int Nerr; /* Number of bad records */
int Maxerr; /* Maximum number of bad records */ int Maxerr; /* Maximum number of bad records */
int ReadMode; /* 1: ALL 2: DEL 0: NOT DEL */ int ReadMode; /* 1: ALL 2: DEL 0: NOT DEL */
}; // end of class DBFBASE }; // end of class DBFBASE
...@@ -72,6 +72,7 @@ class DllExport DBFFAM : public FIXFAM, public DBFBASE { ...@@ -72,6 +72,7 @@ class DllExport DBFFAM : public FIXFAM, public DBFBASE {
protected: protected:
virtual bool CopyHeader(PGLOBAL g); virtual bool CopyHeader(PGLOBAL g);
//virtual int InitDelete(PGLOBAL g, int fpos, int spos);
// Members // Members
}; // end of class DBFFAM }; // end of class DBFFAM
......
...@@ -55,11 +55,6 @@ ...@@ -55,11 +55,6 @@
extern "C" int trace; extern "C" int trace;
extern int num_read, num_there, num_eq[2]; // Statistics extern int num_read, num_there, num_eq[2]; // Statistics
/***********************************************************************/
/* Routine called externally by BGXFAM MakeDeletedFile function. */
/***********************************************************************/
PARRAY MakeValueArray(PGLOBAL g, PPARM pp);
/* --------------------------- Class FIXFAM -------------------------- */ /* --------------------------- Class FIXFAM -------------------------- */
/***********************************************************************/ /***********************************************************************/
...@@ -105,6 +100,16 @@ bool FIXFAM::SetPos(PGLOBAL g, int pos) ...@@ -105,6 +100,16 @@ bool FIXFAM::SetPos(PGLOBAL g, int pos)
return false; return false;
} // end of SetPos } // end of SetPos
/***********************************************************************/
/* Initialize CurBlk and CurNum for indexed DELETE. */
/***********************************************************************/
int FIXFAM::InitDelete(PGLOBAL g, int fpos, int spos)
{
CurBlk = fpos / Nrec;
CurNum = fpos % Nrec;
return RC_OK;
} // end of InitDelete
/***********************************************************************/ /***********************************************************************/
/* Allocate the block buffer for the table. */ /* Allocate the block buffer for the table. */
/***********************************************************************/ /***********************************************************************/
...@@ -340,15 +345,11 @@ int FIXFAM::WriteBuffer(PGLOBAL g) ...@@ -340,15 +345,11 @@ int FIXFAM::WriteBuffer(PGLOBAL g)
// T_Stream is the temporary stream or the table file stream itself // T_Stream is the temporary stream or the table file stream itself
if (!T_Stream) { if (!T_Stream) {
if (UseTemp) { if (UseTemp) {
if ((Indxd = Tdbp->GetKindex() != NULL)) { if (OpenTempFile(g))
strcpy(g->Message, "FIX indexed udate using temp file NIY");
return RC_FX;
} else if (OpenTempFile(g))
return RC_FX; return RC_FX;
else if (CopyHeader(g)) // For DBF tables else if (CopyHeader(g)) // For DBF tables
return RC_FX; return RC_FX;
// Indxd = Tdbp->GetKindex() != NULL;
} else } else
T_Stream = Stream; T_Stream = Stream;
...@@ -413,17 +414,12 @@ int FIXFAM::DeleteRecords(PGLOBAL g, int irc) ...@@ -413,17 +414,12 @@ int FIXFAM::DeleteRecords(PGLOBAL g, int irc)
Spos = Tpos = Fpos; Spos = Tpos = Fpos;
} // endif UseTemp } // endif UseTemp
Indxd = Tdbp->GetKindex() != NULL;
} // endif Tpos == Spos } // endif Tpos == Spos
/*********************************************************************/ /*********************************************************************/
/* Move any intermediate lines. */ /* Move any intermediate lines. */
/*********************************************************************/ /*********************************************************************/
if (Indxd) { if (MoveIntermediateLines(g, &moved))
// Moving will be done later, must be done in sequential order
(void)AddListValue(g, TYPE_INT, &Fpos, &To_Pos);
moved = false;
} else if (MoveIntermediateLines(g, &moved))
return RC_FX; return RC_FX;
if (irc == RC_OK) { if (irc == RC_OK) {
...@@ -456,9 +452,6 @@ int FIXFAM::DeleteRecords(PGLOBAL g, int irc) ...@@ -456,9 +452,6 @@ int FIXFAM::DeleteRecords(PGLOBAL g, int irc)
return RC_FX; return RC_FX;
} else { } else {
if (Indxd && (Abort = MakeDeletedFile(g)))
return RC_FX;
/*****************************************************************/ /*****************************************************************/
/* Because the chsize functionality is only accessible with a */ /* Because the chsize functionality is only accessible with a */
/* system call we must close the file and reopen it with the */ /* system call we must close the file and reopen it with the */
...@@ -559,59 +552,6 @@ bool FIXFAM::MoveIntermediateLines(PGLOBAL g, bool *b) ...@@ -559,59 +552,6 @@ bool FIXFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
return false; return false;
} // end of MoveIntermediate Lines } // end of MoveIntermediate Lines
/***********************************************************************/
/* MakeDeletedFile. When deleting using indexing, the issue is that */
/* record are not necessarily deleted in sequential order. Moving */
/* intermediate lines cannot be done while deleing them because */
/* this can cause extra wrong records to be included in the new file. */
/* What we do here is to reorder the deleted record and make the new */
/* deleted file from the ordered deleted records. */
/***********************************************************************/
bool FIXFAM::MakeDeletedFile(PGLOBAL g)
{
char *crlf = "\n", *mode = UseTemp ? "rb" : "r+b";
int *ix, i;
bool moved;
/*********************************************************************/
/* Open the temporary file, Spos is at the beginning of file. */
/*********************************************************************/
if (!(Posar = MakeValueArray(g, To_Pos))) {
strcpy(g->Message, "Position array is null");
goto err;
} else if (!(ix = (int*)Posar->GetSortIndex(g))) {
strcpy(g->Message, "Error getting array sort index");
goto err;
} // endif's
Spos = 0;
for (i = 0; i < Posar->GetNval(); i++) {
Fpos = Posar->GetIntValue(ix[i]);
if (i || UseTemp) {
// Copy all not updated lines preceding this one
if (MoveIntermediateLines(g, &moved))
goto err;
} else
Tpos = Fpos;
// New start position
Spos = Fpos + 1;
} // endfor i
if (!PlugCloseFile(g, To_Fbt) && !PlugCloseFile(g, To_Fb))
return false;
err:
if (trace)
htrc("%s\n", g->Message);
PlugCloseFile(g, To_Fbt);
return true;
} // end of MakeDeletedFile
/***********************************************************************/ /***********************************************************************/
/* Table file close routine for FIX access method. */ /* Table file close routine for FIX access method. */
/***********************************************************************/ /***********************************************************************/
...@@ -640,7 +580,6 @@ void FIXFAM::CloseTableFile(PGLOBAL g, bool abort) ...@@ -640,7 +580,6 @@ void FIXFAM::CloseTableFile(PGLOBAL g, bool abort)
// Copy any remaining lines // Copy any remaining lines
bool b; bool b;
// Note: Indxd is not implemented yet
Fpos = Tdbp->Cardinality(g); Fpos = Tdbp->Cardinality(g);
Abort = MoveIntermediateLines(g, &b) != RC_OK; Abort = MoveIntermediateLines(g, &b) != RC_OK;
} // endif Abort } // endif Abort
...@@ -1233,10 +1172,7 @@ int BGXFAM::WriteBuffer(PGLOBAL g) ...@@ -1233,10 +1172,7 @@ int BGXFAM::WriteBuffer(PGLOBAL g)
if (Tfile == INVALID_HANDLE_VALUE) if (Tfile == INVALID_HANDLE_VALUE)
{ {
if (UseTemp /*&& Tdbp->GetMode() == MODE_UPDATE*/) { if (UseTemp /*&& Tdbp->GetMode() == MODE_UPDATE*/) {
if ((Indxd = Tdbp->GetKindex() != NULL)) { if (OpenTempFile(g))
strcpy(g->Message, "FIX indexed udate using temp file NIY");
return RC_FX;
} else if (OpenTempFile(g))
return RC_FX; return RC_FX;
} else } else
...@@ -1303,19 +1239,15 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc) ...@@ -1303,19 +1239,15 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc)
Spos = Tpos = Fpos; Spos = Tpos = Fpos;
} // endif UseTemp } // endif UseTemp
Indxd = Tdbp->GetKindex() != NULL;
} // endif Tpos == Spos } // endif Tpos == Spos
/*********************************************************************/ /*********************************************************************/
/* Move any intermediate lines. */ /* Move any intermediate lines. */
/*********************************************************************/ /*********************************************************************/
if (Indxd) if (MoveIntermediateLines(g, &moved))
// Moving will be done later, must be done in sequential order
(void)AddListValue(g, TYPE_INT, &Fpos, &To_Pos);
else if (MoveIntermediateLines(g, &moved))
return RC_FX; return RC_FX;
if (irc == RC_OK && !Indxd) { if (irc == RC_OK) {
if (trace) if (trace)
assert(Spos == Fpos); assert(Spos == Fpos);
...@@ -1343,9 +1275,6 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc) ...@@ -1343,9 +1275,6 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc)
return RC_FX; return RC_FX;
} else { } else {
if (Indxd && (Abort = MakeDeletedFile(g)))
return RC_FX;
/*****************************************************************/ /*****************************************************************/
/* Remove extra records. */ /* Remove extra records. */
/*****************************************************************/ /*****************************************************************/
...@@ -1469,59 +1398,6 @@ bool BGXFAM::MoveIntermediateLines(PGLOBAL g, bool *b) ...@@ -1469,59 +1398,6 @@ bool BGXFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
return false; return false;
} // end of MoveIntermediateLines } // end of MoveIntermediateLines
/***********************************************************************/
/* MakeDeletedFile. When deleting using indexing, the issue is that */
/* record are not necessarily deleted in sequential order. Moving */
/* intermediate lines cannot be done while deleing them because */
/* this can cause extra wrong records to be included in the new file. */
/* What we do here is to reorder the deleted record and make the new */
/* deleted file from the ordered deleted records. */
/***********************************************************************/
bool BGXFAM::MakeDeletedFile(PGLOBAL g)
{
char *crlf = "\n", *mode = UseTemp ? "rb" : "r+b";
int *ix, i;
bool moved;
/*********************************************************************/
/* Open the temporary file, Spos is at the beginning of file. */
/*********************************************************************/
if (!(Posar = MakeValueArray(g, To_Pos))) {
strcpy(g->Message, "Position array is null");
goto err;
} else if (!(ix = (int*)Posar->GetSortIndex(g))) {
strcpy(g->Message, "Error getting array sort index");
goto err;
} // endif's
Spos = 0;
for (i = 0; i < Posar->GetNval(); i++) {
Fpos = Posar->GetIntValue(ix[i]);
if (i || UseTemp) {
// Copy all not updated lines preceding this one
if (MoveIntermediateLines(g, &moved))
goto err;
} else
Tpos = Fpos;
// New start position
Spos = Fpos + 1;
} // endfor i
if (!PlugCloseFile(g, To_Fbt))
return false;
err:
if (trace)
htrc("%s\n", g->Message);
PlugCloseFile(g, To_Fbt);
return true;
} // end of MakeDeletedFile
/***********************************************************************/ /***********************************************************************/
/* Data Base close routine for BIGFIX access method. */ /* Data Base close routine for BIGFIX access method. */
/***********************************************************************/ /***********************************************************************/
...@@ -1549,7 +1425,6 @@ void BGXFAM::CloseTableFile(PGLOBAL g, bool abort) ...@@ -1549,7 +1425,6 @@ void BGXFAM::CloseTableFile(PGLOBAL g, bool abort)
// Copy any remaining lines // Copy any remaining lines
bool b; bool b;
// Indxd is not implemented yet
Fpos = Tdbp->Cardinality(g); Fpos = Tdbp->Cardinality(g);
Abort = MoveIntermediateLines(g, &b) != RC_OK; Abort = MoveIntermediateLines(g, &b) != RC_OK;
} // endif Abort } // endif Abort
......
...@@ -34,6 +34,7 @@ class DllExport FIXFAM : public BLKFAM { ...@@ -34,6 +34,7 @@ class DllExport FIXFAM : public BLKFAM {
virtual int MaxBlkSize(PGLOBAL g, int s) virtual int MaxBlkSize(PGLOBAL g, int s)
{return TXTFAM::MaxBlkSize(g, s);} {return TXTFAM::MaxBlkSize(g, s);}
virtual bool SetPos(PGLOBAL g, int recpos); virtual bool SetPos(PGLOBAL g, int recpos);
virtual int GetNextPos(void) {return Fpos + 1;}
virtual bool AllocateBuffer(PGLOBAL g); virtual bool AllocateBuffer(PGLOBAL g);
virtual void ResetBuffer(PGLOBAL g); virtual void ResetBuffer(PGLOBAL g);
virtual int ReadBuffer(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g);
...@@ -44,7 +45,7 @@ class DllExport FIXFAM : public BLKFAM { ...@@ -44,7 +45,7 @@ class DllExport FIXFAM : public BLKFAM {
protected: protected:
virtual bool CopyHeader(PGLOBAL g) {return false;} virtual bool CopyHeader(PGLOBAL g) {return false;}
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b); virtual bool MoveIntermediateLines(PGLOBAL g, bool *b);
virtual bool MakeDeletedFile(PGLOBAL g); virtual int InitDelete(PGLOBAL g, int fpos, int spos);
// No additional members // No additional members
}; // end of class FIXFAM }; // end of class FIXFAM
...@@ -77,7 +78,6 @@ class BGXFAM : public FIXFAM { ...@@ -77,7 +78,6 @@ class BGXFAM : public FIXFAM {
protected: protected:
virtual bool OpenTempFile(PGLOBAL g); virtual bool OpenTempFile(PGLOBAL g);
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL); virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL);
virtual bool MakeDeletedFile(PGLOBAL g);
int BigRead(PGLOBAL g, HANDLE h, void *inbuf, int req); int BigRead(PGLOBAL g, HANDLE h, void *inbuf, int req);
bool BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req); bool BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req);
bool BigSeek(PGLOBAL g, HANDLE h, BIGINT pos bool BigSeek(PGLOBAL g, HANDLE h, BIGINT pos
......
This diff is collapsed.
...@@ -69,10 +69,13 @@ class DllExport TXTFAM : public BLOCK { ...@@ -69,10 +69,13 @@ class DllExport TXTFAM : public BLOCK {
virtual int DeleteRecords(PGLOBAL g, int irc) = 0; virtual int DeleteRecords(PGLOBAL g, int irc) = 0;
virtual void CloseTableFile(PGLOBAL g, bool abort) = 0; virtual void CloseTableFile(PGLOBAL g, bool abort) = 0;
virtual void Rewind(void) = 0; virtual void Rewind(void) = 0;
virtual int InitDelete(PGLOBAL g, int fpos, int spos);
protected:
bool AddListValue(PGLOBAL g, int type, void *val, PPARM *top); bool AddListValue(PGLOBAL g, int type, void *val, PPARM *top);
int StoreValues(PGLOBAL g, bool upd);
int UpdateSortedRows(PGLOBAL g);
int DeleteSortedRows(PGLOBAL g);
protected:
// Members // Members
PTDBDOS Tdbp; // To table class PTDBDOS Tdbp; // To table class
PSZ To_File; // Points to table file name PSZ To_File; // Points to table file name
...@@ -107,9 +110,11 @@ class DllExport TXTFAM : public BLOCK { ...@@ -107,9 +110,11 @@ class DllExport TXTFAM : public BLOCK {
int Modif; // Number of modified lines in block int Modif; // Number of modified lines in block
int Blksize; // Size of padded blocks int Blksize; // Size of padded blocks
int Ending; // Length of line end int Ending; // Length of line end
int Fpos; // Position of last read record
int Spos; // Start position for update/delete move
int Tpos; // Target Position for delete move
bool Padded; // true if fixed size blocks are padded bool Padded; // true if fixed size blocks are padded
bool Eof; // true if an EOF (0xA) character exists bool Eof; // true if an EOF (0xA) character exists
bool Indxd; // True for indexed UPDATE/DELETE
bool Abort; // To abort on error bool Abort; // To abort on error
char *CrLf; // End of line character(s) char *CrLf; // End of line character(s)
}; // end of class TXTFAM }; // end of class TXTFAM
...@@ -154,16 +159,12 @@ class DllExport DOSFAM : public TXTFAM { ...@@ -154,16 +159,12 @@ class DllExport DOSFAM : public TXTFAM {
virtual bool OpenTempFile(PGLOBAL g); virtual bool OpenTempFile(PGLOBAL g);
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b); virtual bool MoveIntermediateLines(PGLOBAL g, bool *b);
virtual int RenameTempFile(PGLOBAL g); virtual int RenameTempFile(PGLOBAL g);
virtual bool MakeUpdatedFile(PGLOBAL g); virtual int InitDelete(PGLOBAL g, int fpos, int spos);
virtual bool MakeDeletedFile(PGLOBAL g);
// Members // Members
FILE *Stream; // Points to Dos file structure FILE *Stream; // Points to Dos file structure
FILE *T_Stream; // Points to temporary file structure FILE *T_Stream; // Points to temporary file structure
PFBLOCK To_Fbt; // Pointer to temp file block PFBLOCK To_Fbt; // Pointer to temp file block
int Fpos; // Position of last read record
int Tpos; // Target Position for delete move
int Spos; // Start position for update/delete move
bool UseTemp; // True to use a temporary file in Upd/Del bool UseTemp; // True to use a temporary file in Upd/Del
bool Bin; // True to force binary mode bool Bin; // True to force binary mode
}; // end of class DOSFAM }; // end of class DOSFAM
......
This diff is collapsed.
...@@ -66,7 +66,6 @@ class DllExport VCTFAM : public FIXFAM { ...@@ -66,7 +66,6 @@ class DllExport VCTFAM : public FIXFAM {
virtual bool MoveLines(PGLOBAL g) {return false;} virtual bool MoveLines(PGLOBAL g) {return false;}
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL); virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL);
virtual bool CleanUnusedSpace(PGLOBAL g); virtual bool CleanUnusedSpace(PGLOBAL g);
virtual bool MakeDeletedFile(PGLOBAL g);
virtual int GetBlockInfo(PGLOBAL g); virtual int GetBlockInfo(PGLOBAL g);
virtual bool SetBlockInfo(PGLOBAL g); virtual bool SetBlockInfo(PGLOBAL g);
bool ResetTableSize(PGLOBAL g, int block, int last); bool ResetTableSize(PGLOBAL g, int block, int last);
...@@ -116,7 +115,6 @@ class DllExport VCMFAM : public VCTFAM { ...@@ -116,7 +115,6 @@ class DllExport VCMFAM : public VCTFAM {
protected: protected:
// Specific functions // Specific functions
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL); virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL);
virtual bool MakeDeletedFile(PGLOBAL g);
virtual bool ReadBlock(PGLOBAL g, PVCTCOL colp); virtual bool ReadBlock(PGLOBAL g, PVCTCOL colp);
virtual bool WriteBlock(PGLOBAL g, PVCTCOL colp); virtual bool WriteBlock(PGLOBAL g, PVCTCOL colp);
...@@ -162,7 +160,6 @@ class DllExport VECFAM : public VCTFAM { ...@@ -162,7 +160,6 @@ class DllExport VECFAM : public VCTFAM {
virtual bool MoveLines(PGLOBAL g); virtual bool MoveLines(PGLOBAL g);
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL); virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL);
virtual int RenameTempFile(PGLOBAL g); virtual int RenameTempFile(PGLOBAL g);
virtual bool MakeDeletedFile(PGLOBAL g);
bool OpenColumnFile(PGLOBAL g, char *opmode, int i); bool OpenColumnFile(PGLOBAL g, char *opmode, int i);
// Members // Members
...@@ -199,7 +196,6 @@ class DllExport VMPFAM : public VCMFAM { ...@@ -199,7 +196,6 @@ class DllExport VMPFAM : public VCMFAM {
virtual void CloseTableFile(PGLOBAL g, bool abort); virtual void CloseTableFile(PGLOBAL g, bool abort);
protected: protected:
virtual bool MakeDeletedFile(PGLOBAL g);
bool MapColumnFile(PGLOBAL g, MODE mode, int i); bool MapColumnFile(PGLOBAL g, MODE mode, int i);
// Members // Members
......
...@@ -432,6 +432,7 @@ TDBDOS::TDBDOS(PDOSDEF tdp, PTXF txfp) : TDBASE(tdp) ...@@ -432,6 +432,7 @@ TDBDOS::TDBDOS(PDOSDEF tdp, PTXF txfp) : TDBASE(tdp)
//Xeval = 0; //Xeval = 0;
Beval = 0; Beval = 0;
Abort = false; Abort = false;
Indxd = false;
} // end of TDBDOS standard constructor } // end of TDBDOS standard constructor
TDBDOS::TDBDOS(PGLOBAL g, PTDBDOS tdbp) : TDBASE(tdbp) TDBDOS::TDBDOS(PGLOBAL g, PTDBDOS tdbp) : TDBASE(tdbp)
...@@ -446,6 +447,8 @@ TDBDOS::TDBDOS(PGLOBAL g, PTDBDOS tdbp) : TDBASE(tdbp) ...@@ -446,6 +447,8 @@ TDBDOS::TDBDOS(PGLOBAL g, PTDBDOS tdbp) : TDBASE(tdbp)
SavFil = tdbp->SavFil; SavFil = tdbp->SavFil;
//Xeval = tdbp->Xeval; //Xeval = tdbp->Xeval;
Beval = tdbp->Beval; Beval = tdbp->Beval;
Abort = tdbp->Abort;
Indxd = tdbp->Indxd;
} // end of TDBDOS copy constructor } // end of TDBDOS copy constructor
// Method // Method
...@@ -1807,7 +1810,11 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, PIXDEF xdp) ...@@ -1807,7 +1810,11 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, PIXDEF xdp)
To_BlkFil = NULL; To_BlkFil = NULL;
} // endif AmType } // endif AmType
To_Kindex= kxp; if (!(To_Kindex= kxp)->IsSorted() &&
((Mode == MODE_UPDATE && IsUsingTemp(g)) ||
(Mode == MODE_DELETE && Txfp->GetAmType() != TYPE_AM_DBF)))
Indxd = true;
} // endif brc } // endif brc
} else } else
...@@ -2153,13 +2160,10 @@ int TDBDOS::ReadDB(PGLOBAL g) ...@@ -2153,13 +2160,10 @@ int TDBDOS::ReadDB(PGLOBAL g)
} // end of ReadDB } // end of ReadDB
/***********************************************************************/ /***********************************************************************/
/* WriteDB: Data Base write routine for DOS access method. */ /* PrepareWriting: Prepare the line to write. */
/***********************************************************************/ /***********************************************************************/
int TDBDOS::WriteDB(PGLOBAL g) bool TDBDOS::PrepareWriting(PGLOBAL g)
{ {
if (trace > 1)
htrc("DOS WriteDB: R%d Mode=%d \n", Tdb_No, Mode);
if (!Ftype && (Mode == MODE_INSERT || Txfp->GetUseTemp())) { if (!Ftype && (Mode == MODE_INSERT || Txfp->GetUseTemp())) {
char *p; char *p;
...@@ -2174,6 +2178,20 @@ int TDBDOS::WriteDB(PGLOBAL g) ...@@ -2174,6 +2178,20 @@ int TDBDOS::WriteDB(PGLOBAL g)
*(++p) = '\0'; *(++p) = '\0';
} // endif Mode } // endif Mode
return false;
} // end of WriteDB
/***********************************************************************/
/* WriteDB: Data Base write routine for DOS access method. */
/***********************************************************************/
int TDBDOS::WriteDB(PGLOBAL g)
{
if (trace > 1)
htrc("DOS WriteDB: R%d Mode=%d \n", Tdb_No, Mode);
// Make the line to write
(void)PrepareWriting(g);
if (trace > 1) if (trace > 1)
htrc("Write: line is='%s'\n", To_Line); htrc("Write: line is='%s'\n", To_Line);
......
...@@ -136,6 +136,7 @@ class DllExport TDBDOS : public TDBASE { ...@@ -136,6 +136,7 @@ class DllExport TDBDOS : public TDBASE {
virtual PTDB CopyOne(PTABS t); virtual PTDB CopyOne(PTABS t);
virtual void ResetDB(void) {Txfp->Reset();} virtual void ResetDB(void) {Txfp->Reset();}
virtual bool IsUsingTemp(PGLOBAL g); virtual bool IsUsingTemp(PGLOBAL g);
virtual bool IsIndexed(void) {return Indxd;}
virtual void ResetSize(void) {MaxSize = Cardinal = -1;} virtual void ResetSize(void) {MaxSize = Cardinal = -1;}
virtual int ResetTableOpt(PGLOBAL g, bool dop, bool dox); virtual int ResetTableOpt(PGLOBAL g, bool dop, bool dox);
virtual int MakeBlockValues(PGLOBAL g); virtual int MakeBlockValues(PGLOBAL g);
...@@ -176,6 +177,7 @@ class DllExport TDBDOS : public TDBASE { ...@@ -176,6 +177,7 @@ class DllExport TDBDOS : public TDBASE {
bool GetDistinctColumnValues(PGLOBAL g, int nrec); bool GetDistinctColumnValues(PGLOBAL g, int nrec);
protected: protected:
virtual bool PrepareWriting(PGLOBAL g);
PBF CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv); PBF CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv);
// Members // Members
...@@ -185,6 +187,7 @@ class DllExport TDBDOS : public TDBASE { ...@@ -185,6 +187,7 @@ class DllExport TDBDOS : public TDBASE {
PFIL SavFil; // Saved hidden filter PFIL SavFil; // Saved hidden filter
char *To_Line; // Points to current processed line char *To_Line; // Points to current processed line
bool Abort; // TRUE when aborting UPDATE/DELETE bool Abort; // TRUE when aborting UPDATE/DELETE
bool Indxd; // TRUE for indexed UPDATE/DELETE
int Lrecl; // Logical Record Length int Lrecl; // Logical Record Length
int AvgLen; // Logical Record Average Length int AvgLen; // Logical Record Average Length
//int Xeval; // BlockTest return value //int Xeval; // BlockTest return value
......
...@@ -51,6 +51,8 @@ class DllExport TDBFIX : public TDBDOS { ...@@ -51,6 +51,8 @@ class DllExport TDBFIX : public TDBDOS {
virtual int WriteDB(PGLOBAL g); virtual int WriteDB(PGLOBAL g);
protected: protected:
virtual bool PrepareWriting(PGLOBAL g) {return false;}
// Members are inherited from TDBDOS // Members are inherited from TDBDOS
}; // end of class TDBFIX }; // end of class TDBFIX
......
...@@ -899,9 +899,9 @@ int TDBCSV::ReadBuffer(PGLOBAL g) ...@@ -899,9 +899,9 @@ int TDBCSV::ReadBuffer(PGLOBAL g)
} // end of ReadBuffer } // end of ReadBuffer
/***********************************************************************/ /***********************************************************************/
/* Data Base write routine CSV file access method. */ /* Prepare the line to write. */
/***********************************************************************/ /***********************************************************************/
int TDBCSV::WriteDB(PGLOBAL g) bool TDBCSV::PrepareWriting(PGLOBAL g)
{ {
char sep[2], qot[2]; char sep[2], qot[2];
int i, nlen, oldlen = strlen(To_Line); int i, nlen, oldlen = strlen(To_Line);
...@@ -912,7 +912,7 @@ int TDBCSV::WriteDB(PGLOBAL g) ...@@ -912,7 +912,7 @@ int TDBCSV::WriteDB(PGLOBAL g)
// Before writing the line we must check its length // Before writing the line we must check its length
if ((nlen = CheckWrite(g)) < 0) if ((nlen = CheckWrite(g)) < 0)
return RC_FX; return true;
// Before writing the line we must make it // Before writing the line we must make it
sep[0] = Sep; sep[0] = Sep;
...@@ -975,6 +975,18 @@ int TDBCSV::WriteDB(PGLOBAL g) ...@@ -975,6 +975,18 @@ int TDBCSV::WriteDB(PGLOBAL g)
if (trace > 1) if (trace > 1)
htrc("Write: line is=%s", To_Line); htrc("Write: line is=%s", To_Line);
return false;
} // end of PrepareWriting
/***********************************************************************/
/* Data Base write routine CSV file access method. */
/***********************************************************************/
int TDBCSV::WriteDB(PGLOBAL g)
{
// Before writing the line we must check and prepare it
if (PrepareWriting(g))
return RC_FX;
/*********************************************************************/ /*********************************************************************/
/* Now start the writing process. */ /* Now start the writing process. */
/*********************************************************************/ /*********************************************************************/
......
This diff is collapsed.
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
/***********************************************************************/ /***********************************************************************/
/* Macro or external routine definition */ /* Macro or external routine definition */
/***********************************************************************/ /***********************************************************************/
#define NZ 7 #define NZ 8
#define NW 5 #define NW 5
#define MAX_INDX 10 #define MAX_INDX 10
#ifndef INVALID_SET_FILE_POINTER #ifndef INVALID_SET_FILE_POINTER
...@@ -869,17 +869,18 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp) ...@@ -869,17 +869,18 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
/*********************************************************************/ /*********************************************************************/
/* Write the index values on the index file. */ /* Write the index values on the index file. */
/*********************************************************************/ /*********************************************************************/
n[0] = ID; // To check validity n[0] = ID + MAX_INDX; // To check validity
n[1] = Nk; // The number of indexed columns n[1] = Nk; // The number of indexed columns
n[2] = nof; // The offset array size or 0 n[2] = nof; // The offset array size or 0
n[3] = Num_K; // The index size n[3] = Num_K; // The index size
n[4] = Incr; // Increment of record positions n[4] = Incr; // Increment of record positions
n[5] = Nblk; n[6] = Sblk; n[5] = Nblk; n[6] = Sblk;
n[7] = Srtd ? 1 : 0; // Values are sorted in the file
if (trace) { if (trace) {
htrc("Saving index %s\n", Xdp->GetName()); htrc("Saving index %s\n", Xdp->GetName());
htrc("ID=%d Nk=%d nof=%d Num_K=%d Incr=%d Nblk=%d Sblk=%d\n", htrc("ID=%d Nk=%d nof=%d Num_K=%d Incr=%d Nblk=%d Sblk=%d Srtd=%d\n",
ID, Nk, nof, Num_K, Incr, Nblk, Sblk); ID, Nk, nof, Num_K, Incr, Nblk, Sblk, Srtd);
} // endif trace } // endif trace
size = X->Write(g, n, NZ, sizeof(int), rc); size = X->Write(g, n, NZ, sizeof(int), rc);
...@@ -1019,12 +1020,22 @@ bool XINDEX::Init(PGLOBAL g) ...@@ -1019,12 +1020,22 @@ bool XINDEX::Init(PGLOBAL g)
goto err; // No saved values goto err; // No saved values
// Now start the reading process. // Now start the reading process.
if (X->Read(g, nv, NZ, sizeof(int))) if (X->Read(g, nv, NZ - 1, sizeof(int)))
goto err; goto err;
if (nv[0] >= MAX_INDX) {
// New index format
if (X->Read(g, nv + 7, 1, sizeof(int)))
goto err;
Srtd = nv[7] != 0;
nv[0] -= MAX_INDX;
} else
Srtd = false;
if (trace) if (trace)
htrc("nv=%d %d %d %d %d %d %d\n", htrc("nv=%d %d %d %d %d %d %d (%d)\n",
nv[0], nv[1], nv[2], nv[3], nv[4], nv[5], nv[6]); nv[0], nv[1], nv[2], nv[3], nv[4], nv[5], nv[6], Srtd);
// The test on ID was suppressed because MariaDB can change an index ID // The test on ID was suppressed because MariaDB can change an index ID
// when other indexes are added or deleted // when other indexes are added or deleted
...@@ -1271,11 +1282,20 @@ bool XINDEX::MapInit(PGLOBAL g) ...@@ -1271,11 +1282,20 @@ bool XINDEX::MapInit(PGLOBAL g)
// Now start the mapping process. // Now start the mapping process.
nv = (int*)mbase; nv = (int*)mbase;
mbase += NZ * sizeof(int);
if (nv[0] >= MAX_INDX) {
// New index format
Srtd = nv[7] != 0;
nv[0] -= MAX_INDX;
mbase += NZ * sizeof(int);
} else {
Srtd = false;
mbase += (NZ - 1) * sizeof(int);
} // endif nv
if (trace) if (trace)
htrc("nv=%d %d %d %d %d %d %d\n", htrc("nv=%d %d %d %d %d %d %d %d\n",
nv[0], nv[1], nv[2], nv[3], nv[4], nv[5], nv[6]); nv[0], nv[1], nv[2], nv[3], nv[4], nv[5], nv[6], Srtd);
// The test on ID was suppressed because MariaDB can change an index ID // The test on ID was suppressed because MariaDB can change an index ID
// when other indexes are added or deleted // when other indexes are added or deleted
......
...@@ -192,6 +192,7 @@ class DllExport XXBASE : public CSORT, public BLOCK { ...@@ -192,6 +192,7 @@ class DllExport XXBASE : public CSORT, public BLOCK {
void SetNth(int n) {Nth = n;} void SetNth(int n) {Nth = n;}
int *GetPof(void) {return Pof;} int *GetPof(void) {return Pof;}
int *GetPex(void) {return Pex;} int *GetPex(void) {return Pex;}
bool IsSorted(void) {return Srtd;}
void FreeIndex(void) {PlgDBfree(Index);} void FreeIndex(void) {PlgDBfree(Index);}
// Methods // Methods
......
...@@ -147,6 +147,7 @@ class DllExport TDBASE : public TDB { ...@@ -147,6 +147,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 SetKey_Col(PCOL *cpp) {To_Key_Col = cpp;}
inline void SetXdp(PIXDEF xdp) {To_Xdp = xdp;} inline void SetXdp(PIXDEF xdp) {To_Xdp = xdp;}
inline void SetKindex(PKXBASE kxp) {To_Kindex = kxp;} inline void SetKindex(PKXBASE kxp) {To_Kindex = kxp;}
...@@ -156,6 +157,7 @@ class DllExport TDBASE : public TDB { ...@@ -156,6 +157,7 @@ class DllExport TDBASE : public TDB {
// Methods // Methods
virtual bool IsUsingTemp(PGLOBAL g) {return false;} virtual bool IsUsingTemp(PGLOBAL g) {return false;}
virtual bool IsIndexed(void) {return false;}
virtual PCATLG GetCat(void); virtual PCATLG GetCat(void);
virtual PSZ GetPath(void); virtual PSZ GetPath(void);
virtual void PrintAM(FILE *f, char *m); virtual void PrintAM(FILE *f, char *m);
...@@ -190,6 +192,9 @@ class DllExport TDBASE : public TDB { ...@@ -190,6 +192,9 @@ class DllExport TDBASE : public TDB {
{assert(false); return true;} {assert(false); return true;}
protected: protected:
virtual bool PrepareWriting(PGLOBAL g) {strcpy(g->Message,
"This function should not be called for this table"); return true;}
// Members // Members
PTABDEF To_Def; // Points to catalog description block PTABDEF To_Def; // Points to catalog description block
PXOB *To_Link; // Points to column of previous relations PXOB *To_Link; // Points to column of previous relations
......
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