Commit 86957d41 authored by Sergei Golubchik's avatar Sergei Golubchik

10.0-connect merge

parents b23af856 a1c3656e
......@@ -127,6 +127,10 @@ PARRAY MakeValueArray(PGLOBAL g, PPARM pp)
case TYPE_PCHAR:
par->AddValue(g, parmp->Value);
break;
case TYPE_VOID:
// Integer stored inside pp->Value
par->AddValue(g, (int)parmp->Value);
break;
} // endswitch valtyp
/*********************************************************************/
......@@ -152,14 +156,17 @@ ARRAY::ARRAY(PGLOBAL g, int type, int size, int length, int prec)
Xsize = -1;
Len = 1;
switch ((Type = type)) {
switch (type) {
case TYPE_STRING:
Len = length;
break;
case TYPE_SHORT:
case TYPE_INT:
case TYPE_DOUBLE:
case TYPE_PCHAR:
Type = type;
break;
case TYPE_VOID:
Type = TYPE_INT;
break;
#if 0
case TYPE_TOKEN:
......@@ -973,7 +980,7 @@ PSZ ARRAY::MakeArrayList(PGLOBAL g)
size_t z, len = 2;
if (Type == TYPE_LIST)
return "(???)"; // To be implemented
return "(?" "?" "?)"; // To be implemented
z = MY_MAX(24, GetTypeSize(Type, Len) + 4);
tp = (char*)PlugSubAlloc(g, NULL, z);
......
/*************** Catalog H Declares Source Code File (.H) **************/
/* Name: CATALOG.H Version 3.2 */
/* Name: CATALOG.H Version 3.3 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2000-2012 */
/* (C) Copyright to the author Olivier BERTRAND 2000-2014 */
/* */
/* This file contains the CATALOG PlugDB classes definitions. */
/***********************************************************************/
......@@ -68,11 +68,11 @@ class DllExport CATALOG {
bool GetDefHuge(void) {return DefHuge;}
void SetDefHuge(bool b) {DefHuge = b;}
char *GetCbuf(void) {return Cbuf;}
char *GetDataPath(void) {return (char*)DataPath;}
//char *GetDataPath(void) {return (char*)DataPath;}
// Methods
virtual void Reset(void) {}
virtual void SetDataPath(PGLOBAL g, const char *path) {}
//virtual void SetDataPath(PGLOBAL g, const char *path) {}
virtual bool CheckName(PGLOBAL g, char *name) {return true;}
virtual bool ClearName(PGLOBAL g, PSZ name) {return true;}
virtual PRELDEF MakeOneTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am) {return NULL;}
......@@ -106,7 +106,7 @@ class DllExport CATALOG {
int Cblen; /* Length of suballoc. buffer */
CURTAB Ctb; /* Used to enumerate tables */
bool DefHuge; /* true: tables default to huge */
LPCSTR DataPath; /* Is the Path of DB data dir */
//LPCSTR DataPath; /* Is the Path of DB data dir */
}; // end of class CATALOG
#endif // __CATALOG__H
......@@ -34,9 +34,10 @@ enum XMOD {XMOD_EXECUTE = 0, /* DOS execution mode */
/***********************************************************************/
/* Following definitions indicate the use of a temporay file. */
/***********************************************************************/
enum USETEMP {TMP_AUTO = 0, /* Best choice */
TMP_NO = 1, /* Never */
enum USETEMP {TMP_NO = 0, /* Never */
TMP_AUTO = 1, /* Best choice */
TMP_YES = 2, /* Always */
TMP_FORCE = 3}; /* Forced for MAP tables */
TMP_FORCE = 3, /* Forced for MAP tables */
TMP_TEST = 4}; /* Testing value */
#endif // _CHKLVL_DEFINED_
......@@ -122,9 +122,12 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname)
(dbuserp->Catalog) ? ((MYCAT*)dbuserp->Catalog)->GetHandler() : NULL,
handler);
// Set the database path for this table
handler->SetDataPath(g, pathname);
if (dbuserp->Catalog) {
// ((MYCAT *)dbuserp->Catalog)->SetHandler(handler); done later
((MYCAT *)dbuserp->Catalog)->SetDataPath(g, pathname);
// ((MYCAT *)dbuserp->Catalog)->SetDataPath(g, pathname);
return false; // Nothing else to do
} // endif Catalog
......@@ -141,8 +144,8 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname)
if (!(dbuserp->Catalog= new MYCAT(handler)))
return true;
((MYCAT *)dbuserp->Catalog)->SetDataPath(g, pathname);
dbuserp->UseTemp= TMP_AUTO;
//((MYCAT *)dbuserp->Catalog)->SetDataPath(g, pathname);
//dbuserp->UseTemp= TMP_AUTO;
/*********************************************************************/
/* All is correct. */
......@@ -479,7 +482,7 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp)
/***********************************************************************/
RCODE CntWriteRow(PGLOBAL g, PTDB tdbp)
{
RCODE rc;
RCODE rc;
PCOL colp;
PTDBASE tp= (PTDBASE)tdbp;
......@@ -503,11 +506,12 @@ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp)
if (!colp->GetColUse(U_VIRTUAL))
colp->WriteColumn(g);
// if (tdbp->GetMode() == MODE_INSERT)
// tbxp->SetModified(true);
// Return result code from write operation
rc= (RCODE)tdbp->WriteDB(g);
if (tp->IsIndexed())
// Index values must be sorted before updating
rc= (RCODE)((PTDBDOS)tp)->GetTxfp()->StoreValues(g, true);
else
// Return result code from write operation
rc= (RCODE)tdbp->WriteDB(g);
err:
g->jump_level--;
......@@ -517,7 +521,7 @@ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp)
/***********************************************************************/
/* 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)
return RC_FX;
......@@ -531,19 +535,28 @@ RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp)
/***********************************************************************/
RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all)
{
RCODE rc;
RCODE rc;
PTDBASE tp= (PTDBASE)tdbp;
if (!tdbp || tdbp->GetMode() != MODE_DELETE)
return RC_FX;
else if (tdbp->IsReadOnly())
return RC_NF;
if (((PTDBASE)tdbp)->GetDef()->Indexable() && all)
((PTDBDOS)tdbp)->Cardinal= 0;
if (all) {
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;
} // end of CntDeleteRow
......@@ -553,7 +566,7 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all)
int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
{
int rc= RC_OK;
TDBDOX *tbxp= NULL;
TDBASE *tbxp= (PTDBASE)tdbp;
if (!tdbp)
return rc; // Nothing to do
......@@ -568,8 +581,24 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
printf("CntCloseTable: tdbp=%p mode=%d nox=%d abort=%d\n",
tdbp, tdbp->GetMode(), nox, abort);
if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN)
rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine
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);
switch(rc) {
case RC_FX:
abort= true;
break;
case RC_INFO:
PushWarning(g, tbxp);
break;
} // endswitch rc
// Prepare error return
if (g->jump_level == MAX_JUMP) {
......@@ -606,9 +635,8 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
// Make all the eventual indexes
tbxp= (TDBDOX*)tdbp;
tbxp->ResetKindex(g, NULL);
tbxp->To_Key_Col= NULL;
rc= tbxp->ResetTableOpt(g, true,
((PTDBASE)tdbp)->GetDef()->Indexable() == 1);
tbxp->SetKey_Col(NULL);
rc= tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1);
err:
if (trace > 1)
......@@ -622,7 +650,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
/* This is the condition(s) for doing indexing. */
/* Note: FIX table are not reset here to Nrec= 1. */
/***********************************************************************/
int CntIndexInit(PGLOBAL g, PTDB ptdb, int id)
int CntIndexInit(PGLOBAL g, PTDB ptdb, int id, bool sorted)
{
PIXDEF xdp;
PTDBDOX tdbp;
......@@ -674,7 +702,7 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id)
#endif // 0
// Static indexes must be initialized now for records_in_range
if (tdbp->InitialyzeIndex(g, xdp))
if (tdbp->InitialyzeIndex(g, xdp, sorted))
return 0;
return (tdbp->To_Kindex->IsMul()) ? 2 : 1;
......@@ -721,7 +749,7 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
#if 0
} // endif !To_Xdp
// Now it's time to make the dynamic index
if (tdbp->InitialyzeIndex(g, NULL)) {
if (tdbp->InitialyzeIndex(g, NULL, false)) {
sprintf(g->Message, "Fail to make dynamic index %s",
tdbp->To_Xdp->GetName());
return RC_FX;
......
......@@ -34,7 +34,7 @@ PTDB CntGetTDB(PGLOBAL g, const char *name, MODE xmod, PHC);
bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE, char *, char *, bool, PHC);
bool CntRewindTable(PGLOBAL g, PTDB tdbp);
int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort);
int CntIndexInit(PGLOBAL g, PTDB tdbp, int id);
int CntIndexInit(PGLOBAL g, PTDB tdbp, int id, bool sorted);
RCODE CntReadNext(PGLOBAL g, PTDB tdbp);
RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const void *k, int n, bool mrr);
RCODE CntWriteRow(PGLOBAL g, PTDB tdbp);
......@@ -50,7 +50,7 @@ PGLOBAL CntExit(PGLOBAL g);
/* These classes purpose is chiefly to access protected items! */
/***********************************************************************/
class DOXDEF: public DOSDEF {
friend int CntIndexInit(PGLOBAL, PTDB, int);
friend int CntIndexInit(PGLOBAL, PTDB, int, bool);
}; // end of class DOXDEF
/***********************************************************************/
......@@ -59,7 +59,7 @@ class DOXDEF: public DOSDEF {
class TDBDOX: public TDBDOS {
friend int MakeIndex(PGLOBAL, PTDB, PIXDEF);
friend int CntCloseTable(PGLOBAL, PTDB, bool, bool);
friend int CntIndexInit(PGLOBAL, PTDB, int);
friend int CntIndexInit(PGLOBAL, PTDB, int, bool);
friend RCODE CntIndexRead(PGLOBAL, PTDB, OPVAL, const void*, int, bool);
friend RCODE CntDeleteRow(PGLOBAL, PTDB, bool);
friend int CntIndexRange(PGLOBAL, PTDB, const uchar**, uint*,
......@@ -70,7 +70,7 @@ class TDBDOX: public TDBDOS {
class XKPDEF: public KPARTDEF {
friend class TDBDOX;
friend class ha_connect;
friend int CntIndexInit(PGLOBAL, PTDB, int);
friend int CntIndexInit(PGLOBAL, PTDB, int, bool);
public:
XKPDEF(const char *name, int n) : KPARTDEF((PSZ)name, n) {}
}; // end of class XKPDEF
......@@ -48,11 +48,6 @@
extern "C" int trace;
/***********************************************************************/
/* Routine called externally by MAPFAM MakeDeletedFile function. */
/***********************************************************************/
PARRAY MakeValueArray(PGLOBAL g, PPARM pp);
/* --------------------------- Class MAPFAM -------------------------- */
/***********************************************************************/
......@@ -134,9 +129,9 @@ bool MAPFAM::OpenTableFile(PGLOBAL g)
&& fp->Count && fp->Mode == mode)
break;
#ifdef DEBTRACE
htrc("Mapping file, fp=%p\n", fp);
#endif
if (trace)
htrc("Mapping file, fp=%p\n", fp);
} else
fp = NULL;
......@@ -290,6 +285,16 @@ bool MAPFAM::RecordPos(PGLOBAL g)
return false;
} // 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. */
/***********************************************************************/
......@@ -342,11 +347,12 @@ int MAPFAM::ReadBuffer(PGLOBAL g)
return RC_EF;
case RC_NF:
// Skip this record
if ((rc = SkipRecord(g, FALSE)) != RC_OK)
if ((rc = SkipRecord(g, false)) != RC_OK)
return rc;
goto next;
} // endswitch rc
} else
Placed = false;
......@@ -409,17 +415,10 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
/* not required here, just setting of future Spos and Tpos. */
/*******************************************************************/
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) {
/*****************************************************************/
/* Non consecutive line to delete. Move intermediate lines. */
/*****************************************************************/
/*******************************************************************/
/* Non consecutive line to delete. Move intermediate lines. */
/*******************************************************************/
memmove(Tpos, Spos, n);
Tpos += n;
......@@ -437,10 +436,6 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
} else if (To_Fb) { // Can be NULL for deleted files
/*******************************************************************/
/* Last call after EOF has been reached. */
/*******************************************************************/
Abort = (Indxd && MakeDeletedFile(g));
/*******************************************************************/
/* 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. */
/*******************************************************************/
......@@ -495,55 +490,6 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
return RC_OK; // All is correct
} // 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. */
/***********************************************************************/
......@@ -734,6 +680,16 @@ bool MPXFAM::SetPos(PGLOBAL g, int pos)
return false;
} // 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. */
/***********************************************************************/
......
......@@ -47,7 +47,7 @@ class DllExport MAPFAM : public TXTFAM {
virtual void Rewind(void);
protected:
bool MakeDeletedFile(PGLOBAL g);
virtual int InitDelete(PGLOBAL g, int fpos, int spos);
// Members
char *Memory; // Pointer on file mapping view.
......@@ -104,11 +104,14 @@ class DllExport MPXFAM : public MBKFAM {
virtual int MaxBlkSize(PGLOBAL g, int s)
{return TXTFAM::MaxBlkSize(g, s);}
virtual bool SetPos(PGLOBAL g, int recpos);
virtual int GetNextPos(void) {return (int)Fpos + Nrec;}
virtual bool DeferReading(void) {return false;}
virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g);
protected:
virtual int InitDelete(PGLOBAL g, int fpos, int spos);
// No additional members
}; // end of class MPXFAM
......
......@@ -176,7 +176,7 @@ static int dbfhead(PGLOBAL g, FILE *file, PSZ fn, DBFHEADER *buf)
/* DBFColumns: constructs the result blocks containing the description */
/* of all the columns of a DBF file that will be retrieved by #GetData. */
/****************************************************************************/
PQRYRES DBFColumns(PGLOBAL g, const char *fn, BOOL info)
PQRYRES DBFColumns(PGLOBAL g, char *dp, const char *fn, bool info)
{
int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
TYPE_INT, TYPE_INT, TYPE_SHORT};
......@@ -186,7 +186,7 @@ PQRYRES DBFColumns(PGLOBAL g, const char *fn, BOOL info)
char buf[2], filename[_MAX_PATH];
int ncol = sizeof(buftyp) / sizeof(int);
int rc, type, len, field, fields;
BOOL bad;
bool bad;
DBFHEADER mainhead;
DESCRIPTOR thisfield;
FILE *infile = NULL;
......@@ -205,7 +205,7 @@ PQRYRES DBFColumns(PGLOBAL g, const char *fn, BOOL info)
/************************************************************************/
/* Open the input file. */
/************************************************************************/
PlugSetPath(filename, fn, PlgGetDataPath(g));
PlugSetPath(filename, fn, dp);
if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb")))
return NULL;
......@@ -750,6 +750,36 @@ bool DBFFAM::CopyHeader(PGLOBAL g)
return rc;
} // 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. */
/* Deleted lines are just flagged in the first buffer character. */
......@@ -760,16 +790,12 @@ int DBFFAM::DeleteRecords(PGLOBAL g, int irc)
// T_Stream is the temporary stream or the table file stream itself
if (!T_Stream)
if (UseTemp) {
if ((Indxd = Tdbp->GetKindex() != NULL)) {
strcpy(g->Message, "DBF indexed udate using temp file NIY");
return RC_FX;
} else if (OpenTempFile(g))
if (OpenTempFile(g))
return RC_FX;
if (CopyHeader(g)) // For DBF tables
return RC_FX;
// Indxd = Tdbp->GetKindex() != NULL;
} else
T_Stream = Stream;
......@@ -809,7 +835,7 @@ void DBFFAM::CloseTableFile(PGLOBAL g, bool abort)
if (Modif && !Closing) {
// Last updated block remains to be written
Closing = true;
wrc = ReadBuffer(g);
wrc = WriteModifiedBlock(g);
} // endif Modif
if (UseTemp && T_Stream && wrc == RC_OK) {
......
/***************** FilAmDbf H Declares Source Code File (.H) ****************/
/* Name: filamdbf.h Version 1.3 */
/* Name: filamdbf.h Version 1.4 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2005-2012 */
/* (C) Copyright to the author Olivier BERTRAND 2005-2014 */
/* */
/* This file contains the DBF file access method classes declares. */
/****************************************************************************/
......@@ -19,7 +19,7 @@ typedef class DBMFAM *PDBMFAM;
/****************************************************************************/
/* Functions used externally. */
/****************************************************************************/
PQRYRES DBFColumns(PGLOBAL g, const char *fn, BOOL info);
PQRYRES DBFColumns(PGLOBAL g, char *dp, const char *fn, bool info);
/****************************************************************************/
/* This is the base class for dBASE file access methods. */
......@@ -40,8 +40,8 @@ class DllExport DBFBASE {
// Members
int Records; /* records in the file */
bool Accept; /* true if bad lines are accepted */
int Nerr; /* Number of bad records */
int Maxerr; /* Maximum number of bad records */
int Nerr; /* Number of bad records */
int Maxerr; /* Maximum number of bad records */
int ReadMode; /* 1: ALL 2: DEL 0: NOT DEL */
}; // end of class DBFBASE
......@@ -72,6 +72,7 @@ class DllExport DBFFAM : public FIXFAM, public DBFBASE {
protected:
virtual bool CopyHeader(PGLOBAL g);
//virtual int InitDelete(PGLOBAL g, int fpos, int spos);
// Members
}; // end of class DBFFAM
......
This diff is collapsed.
......@@ -34,8 +34,10 @@ class DllExport FIXFAM : public BLKFAM {
virtual int MaxBlkSize(PGLOBAL g, int s)
{return TXTFAM::MaxBlkSize(g, s);}
virtual bool SetPos(PGLOBAL g, int recpos);
virtual int GetNextPos(void) {return Fpos + 1;}
virtual bool AllocateBuffer(PGLOBAL g);
virtual void ResetBuffer(PGLOBAL g);
virtual int WriteModifiedBlock(PGLOBAL g);
virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc);
......@@ -44,7 +46,7 @@ class DllExport FIXFAM : public BLKFAM {
protected:
virtual bool CopyHeader(PGLOBAL g) {return false;}
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b);
virtual bool MakeDeletedFile(PGLOBAL g);
virtual int InitDelete(PGLOBAL g, int fpos, int spos);
// No additional members
}; // end of class FIXFAM
......@@ -68,6 +70,7 @@ class BGXFAM : public FIXFAM {
// Methods
virtual int Cardinality(PGLOBAL g);
virtual bool OpenTableFile(PGLOBAL g);
virtual int WriteModifiedBlock(PGLOBAL g);
virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc);
......@@ -77,7 +80,6 @@ class BGXFAM : public FIXFAM {
protected:
virtual bool OpenTempFile(PGLOBAL g);
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL);
virtual bool MakeDeletedFile(PGLOBAL g);
int BigRead(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
......
This diff is collapsed.
......@@ -69,10 +69,13 @@ class DllExport TXTFAM : public BLOCK {
virtual int DeleteRecords(PGLOBAL g, int irc) = 0;
virtual void CloseTableFile(PGLOBAL g, bool abort) = 0;
virtual void Rewind(void) = 0;
protected:
virtual int InitDelete(PGLOBAL g, int fpos, int spos);
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
PTDBDOS Tdbp; // To table class
PSZ To_File; // Points to table file name
......@@ -107,9 +110,11 @@ class DllExport TXTFAM : public BLOCK {
int Modif; // Number of modified lines in block
int Blksize; // Size of padded blocks
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 Eof; // true if an EOF (0xA) character exists
bool Indxd; // True for indexed UPDATE/DELETE
bool Abort; // To abort on error
char *CrLf; // End of line character(s)
}; // end of class TXTFAM
......@@ -154,16 +159,12 @@ class DllExport DOSFAM : public TXTFAM {
virtual bool OpenTempFile(PGLOBAL g);
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b);
virtual int RenameTempFile(PGLOBAL g);
virtual bool MakeUpdatedFile(PGLOBAL g);
virtual bool MakeDeletedFile(PGLOBAL g);
virtual int InitDelete(PGLOBAL g, int fpos, int spos);
// Members
FILE *Stream; // Points to Dos file structure
FILE *T_Stream; // Points to temporary file structure
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 Bin; // True to force binary mode
}; // end of class DOSFAM
......
This diff is collapsed.
......@@ -66,7 +66,6 @@ class DllExport VCTFAM : public FIXFAM {
virtual bool MoveLines(PGLOBAL g) {return false;}
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL);
virtual bool CleanUnusedSpace(PGLOBAL g);
virtual bool MakeDeletedFile(PGLOBAL g);
virtual int GetBlockInfo(PGLOBAL g);
virtual bool SetBlockInfo(PGLOBAL g);
bool ResetTableSize(PGLOBAL g, int block, int last);
......@@ -116,7 +115,6 @@ class DllExport VCMFAM : public VCTFAM {
protected:
// Specific functions
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL);
virtual bool MakeDeletedFile(PGLOBAL g);
virtual bool ReadBlock(PGLOBAL g, PVCTCOL colp);
virtual bool WriteBlock(PGLOBAL g, PVCTCOL colp);
......@@ -162,7 +160,6 @@ class DllExport VECFAM : public VCTFAM {
virtual bool MoveLines(PGLOBAL g);
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL);
virtual int RenameTempFile(PGLOBAL g);
virtual bool MakeDeletedFile(PGLOBAL g);
bool OpenColumnFile(PGLOBAL g, char *opmode, int i);
// Members
......@@ -199,7 +196,6 @@ class DllExport VMPFAM : public VCMFAM {
virtual void CloseTableFile(PGLOBAL g, bool abort);
protected:
virtual bool MakeDeletedFile(PGLOBAL g);
bool MapColumnFile(PGLOBAL g, MODE mode, int i);
// Members
......
This diff is collapsed.
......@@ -210,7 +210,9 @@ public:
bool IsSameIndex(PIXDEF xp1, PIXDEF xp2);
bool IsPartitioned(void);
bool IsUnique(uint n);
char *GetDataPath(void) {return (char*)datapath;}
void SetDataPath(PGLOBAL g, const char *path);
PTDB GetTDB(PGLOBAL g);
int OpenTable(PGLOBAL g, bool del= false);
bool CheckColumnList(PGLOBAL g);
......@@ -521,6 +523,7 @@ protected:
ulong hnum; // The number of this handler
query_id_t valid_query_id; // The one when tdbp was allocated
query_id_t creat_query_id; // The one when handler was allocated
char *datapath; // Is the Path of DB data directory
PTDB tdbp; // To table class object
PVAL sdvalin; // Used to convert date values
PVAL sdvalout; // Used to convert date values
......
......@@ -154,7 +154,7 @@ HANDLE CreateFileMap(PGLOBAL g, LPCSTR fileName,
} // endswitch
// Try to open the addressed file.
fd= global_open(g, MSGID_NONE, fileName, openMode);
fd= global_open(g, MSGID_NONE, fileName, openMode);
if (fd != INVALID_HANDLE_VALUE && mode != MODE_INSERT) {
/* We must know about the size of the file. */
......@@ -164,17 +164,19 @@ HANDLE CreateFileMap(PGLOBAL g, LPCSTR fileName,
return INVALID_HANDLE_VALUE;
} // endif fstat
filesize = st.st_size;
// Now we are ready to load the file. If mmap() is available we try
// this first. If not available or it failed we try to load it.
mm->memory = mmap(NULL, filesize, protmode, MAP_SHARED, fd, 0);
if ((filesize = st.st_size))
// Now we are ready to load the file. If mmap() is available we try
// this first. If not available or it failed we try to load it.
mm->memory = mmap(NULL, filesize, protmode, MAP_SHARED, fd, 0);
else
mm->memory = 0;
if (mm->memory != MAP_FAILED) {
mm->lenL = (mm->memory != 0) ? filesize : 0;
mm->lenH = 0;
} else {
strcpy(g->Message, "Memory mapping failed");
close(fd);
return INVALID_HANDLE_VALUE;
} // endif memory
......
......@@ -405,9 +405,9 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info)
CATALOG::CATALOG(void)
{
#if defined(WIN32)
DataPath= ".\\";
//DataPath= ".\\";
#else // !WIN32
DataPath= "./";
//DataPath= "./";
#endif // !WIN32
memset(&Ctb, 0, sizeof(CURTAB));
Cbuf= NULL;
......@@ -433,6 +433,7 @@ void MYCAT::Reset(void)
{
} // end of Reset
#if 0
/***********************************************************************/
/* This function sets the current database path. */
/***********************************************************************/
......@@ -463,6 +464,7 @@ void MYCAT::SetPath(PGLOBAL g, LPCSTR *datapath, const char *path)
} // endif path
} // end of SetDataPath
#endif // 0
/***********************************************************************/
/* GetTableDesc: retrieve a table descriptor. */
......@@ -560,7 +562,7 @@ PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type)
printf("tdb=%p type=%s\n", tdp, tdp->GetType());
if (tablep->GetQualifier())
SetPath(g, &tdp->Database, tablep->GetQualifier());
tdp->Database = SetPath(g, tablep->GetQualifier());
tdbp= tdp->GetTable(g, mode);
} // endif tdp
......
......@@ -56,8 +56,8 @@ class MYCAT : public CATALOG {
// Methods
void Reset(void);
void SetDataPath(PGLOBAL g, const char *path)
{SetPath(g, &DataPath, path);}
//void SetDataPath(PGLOBAL g, const char *path)
// {SetPath(g, &DataPath, path);}
bool StoreIndex(PGLOBAL g, PTABDEF defp) {return false;} // Temporary
PRELDEF GetTableDesc(PGLOBAL g, LPCSTR name,
LPCSTR type, PRELDEF *prp = NULL);
......@@ -67,7 +67,7 @@ class MYCAT : public CATALOG {
protected:
PRELDEF MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am);
void SetPath(PGLOBAL g, LPCSTR *datapath, const char *path);
//void SetPath(PGLOBAL g, LPCSTR *datapath, const char *path);
// Members
ha_connect *Hc; // The Connect handler
......
set @@global.connect_exact_info=ON;
# This will be used to see what data files are created
CREATE TABLE dr1 (
fname VARCHAR(256) NOT NULL FLAG=2,
......@@ -342,3 +343,4 @@ part2 .txt
part3 .txt
DROP TABLE t1;
DROP TABLE dr1;
set @@global.connect_exact_info=OFF;
set @@global.connect_exact_info=ON;
CREATE TABLE xt1 (
id INT KEY NOT NULL,
msg VARCHAR(32))
......@@ -193,3 +194,4 @@ DROP TABLE t1;
DROP TABLE xt1;
DROP TABLE xt2;
DROP TABLE xt3;
set @@global.connect_exact_info=OFF;
This diff is collapsed.
--source include/have_partition.inc
let $MYSQLD_DATADIR= `select @@datadir`;
set @@global.connect_exact_info=ON;
--echo # This will be used to see what data files are created
CREATE TABLE dr1 (
fname VARCHAR(256) NOT NULL FLAG=2,
......@@ -153,6 +155,8 @@ DROP TABLE dr1;
#
# Clean up
#
set @@global.connect_exact_info=OFF;
--remove_file $MYSQLD_DATADIR/test/part1.txt
--remove_file $MYSQLD_DATADIR/test/part2.txt
--remove_file $MYSQLD_DATADIR/test/part3.txt
......
--source include/not_embedded.inc
--source include/have_partition.inc
set @@global.connect_exact_info=ON;
#
# These will be used by the t1 table partition table
#
......@@ -83,3 +85,8 @@ DROP TABLE t1;
DROP TABLE xt1;
DROP TABLE xt2;
DROP TABLE xt3;
#
# Clean up
#
set @@global.connect_exact_info=OFF;
DELETE FROM t1;
INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight');
SELECT * FROM t1;
UPDATE t1 SET msg = 'bof' WHERE id = 35;
SELECT * FROM t1;
UPDATE t1 SET msg = 'big' WHERE id > 50;
SELECT * FROM t1;
UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72);
SELECT * FROM t1;
UPDATE t1 SET msg = 'twin' WHERE id IN (81,10);
SELECT * FROM t1;
UPDATE t1 SET msg = 'sixty' WHERE id = 60;
SELECT * FROM t1 WHERE id = 60;
DELETE FROM t1 WHERE id = 4;
SELECT * FROM t1;
DELETE FROM t1 WHERE id IN (40,11,35);
SELECT * FROM t1;
DELETE FROM t1 WHERE id IN (4,60,1);
SELECT msg FROM t1;
DELETE FROM t1 WHERE id IN (81,72);
SELECT id FROM t1;
DELETE FROM t1 WHERE id IN (7,10);
SELECT * FROM t1;
DELETE FROM t1 WHERE id = 8;
SELECT * FROM t1;
-- source include/not_embedded.inc
let $MYSQLD_DATADIR= `select @@datadir`;
--echo #
--echo # Testing indexed UPDATE and DELETE for all table types
--echo #
--echo # CSV table
CREATE TABLE t1 (
id INT KEY NOT NULL,
msg VARCHAR(32))
ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=6;
-- source updelx.inc
ALTER TABLE t1 MAPPED=YES;
-- source updelx.inc
ALTER TABLE t1 MAPPED=NO BLOCK_SIZE=6;
-- source updelx.inc
ALTER TABLE t1 MAPPED=YES;
-- source updelx.inc
DROP TABLE t1;
--echo # DOS table
CREATE TABLE t1 (
id INT(4) KEY NOT NULL,
msg VARCHAR(16))
ENGINE=CONNECT TABLE_TYPE=DOS;
-- source updelx.inc
ALTER TABLE t1 MAPPED=YES;
-- source updelx.inc
ALTER TABLE t1 MAPPED=NO BLOCK_SIZE=4;
-- source updelx.inc
ALTER TABLE t1 MAPPED=YES;
-- source updelx.inc
DROP TABLE t1;
--echo # FIX table
CREATE TABLE t1 (
id INT(4) KEY NOT NULL,
msg VARCHAR(16) CHARSET BINARY DISTRIB=CLUSTERED)
ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=4;
-- source updelx.inc
ALTER TABLE t1 MAPPED=YES;
-- source updelx.inc
ALTER TABLE t1 MAPPED=NO HUGE=YES;
-- source updelx.inc
DROP TABLE t1;
--echo # BIN table
CREATE TABLE t1 (
id INT(4) KEY NOT NULL,
msg VARCHAR(16) CHARSET BINARY DISTRIB=CLUSTERED)
ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=8;
-- source updelx.inc
ALTER TABLE t1 MAPPED=YES;
-- source updelx.inc
ALTER TABLE t1 MAPPED=NO HUGE=YES;
-- source updelx.inc
DROP TABLE t1;
--echo # DBF table
CREATE TABLE t1 (
id INT(4) KEY NOT NULL,
msg VARCHAR(16))
ENGINE=CONNECT TABLE_TYPE=DBF BLOCK_SIZE=12;
-- source updelx.inc
ALTER TABLE t1 MAPPED=YES;
-- source updelx.inc
#ALTER TABLE t1 MAPPED=NO HUGE=YES;
#-- source updelx.inc
DROP TABLE t1;
--echo # VEC table
CREATE TABLE t1 (
id INT(4) KEY NOT NULL,
msg VARCHAR(16))
ENGINE=CONNECT TABLE_TYPE=VEC BLOCK_SIZE=6 MAX_ROWS=16;
-- source updelx.inc
ALTER TABLE t1 MAPPED=YES;
-- source updelx.inc
ALTER TABLE t1 MAPPED=NO HUGE=YES;
-- source updelx.inc
DROP TABLE t1;
--echo # Split VEC table (outward)
CREATE TABLE t1 (
id INT(4) KEY NOT NULL,
msg VARCHAR(16))
ENGINE=CONNECT TABLE_TYPE=VEC BLOCK_SIZE=6 FILE_NAME='tx.vec';
-- source updelx.inc
ALTER TABLE t1 MAPPED=YES;
-- source updelx.inc
DROP TABLE t1;
# Cleanup
--remove_file $MYSQLD_DATADIR/test/tx1.vec
--remove_file $MYSQLD_DATADIR/test/tx2.vec
......@@ -423,7 +423,7 @@ typedef struct { /* User application block */
int Maxbmp; /* Maximum XDB2 bitmap size */
int Check; /* General level of checking */
int Numlines; /* Number of lines involved */
USETEMP UseTemp; /* Use temporary file */
//USETEMP UseTemp; /* Use temporary file */
int Vtdbno; /* Used for TDB number setting */
bool Remote; /* true: if remotely called */
bool Proginfo; /* true: return progress info */
......@@ -549,7 +549,8 @@ typedef struct _colres {
PPARM Vcolist(PGLOBAL, PTDB, PSZ, bool);
void PlugPutOut(PGLOBAL, FILE *, short, void *, uint);
void PlugLineDB(PGLOBAL, PSZ, short, void *, uint);
char *PlgGetDataPath(PGLOBAL g);
//ar *PlgGetDataPath(PGLOBAL g);
char *SetPath(PGLOBAL g, const char *path);
char *ExtractFromPath(PGLOBAL, char *, char *, OPVAL);
void AddPointer(PTABS, void *);
PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int);
......
......@@ -337,7 +337,7 @@ PDBUSER PlgMakeUser(PGLOBAL g)
memset(dbuserp, 0, sizeof(DBUSERBLK));
dbuserp->Maxbmp = MAXBMP;
dbuserp->UseTemp = TMP_AUTO;
//dbuserp->UseTemp = TMP_AUTO;
dbuserp->Check = CHK_ALL;
strcpy(dbuserp->Server, "CONNECT");
return dbuserp;
......@@ -373,6 +373,7 @@ PCATLG PlgGetCatalog(PGLOBAL g, bool jump)
return cat;
} // end of PlgGetCatalog
#if 0
/***********************************************************************/
/* PlgGetDataPath: returns the default data path. */
/***********************************************************************/
......@@ -382,6 +383,39 @@ char *PlgGetDataPath(PGLOBAL g)
return (cat) ? cat->GetDataPath() : NULL;
} // end of PlgGetDataPath
#endif // 0
/***********************************************************************/
/* This function returns a database path. */
/***********************************************************************/
char *SetPath(PGLOBAL g, const char *path)
{
char *buf= NULL;
if (path) {
size_t len= strlen(path) + (*path != '.' ? 4 : 1);
buf= (char*)PlugSubAlloc(g, NULL, len);
if (PlugIsAbsolutePath(path)) {
strcpy(buf, path);
return buf;
} // endif path
if (*path != '.') {
#if defined(WIN32)
char *s= "\\";
#else // !WIN32
char *s= "/";
#endif // !WIN32
strcat(strcat(strcat(strcpy(buf, "."), s), path), s);
} else
strcpy(buf, path);
} // endif path
return buf;
} // end of SetPath
/***********************************************************************/
/* Extract from a path name the required component. */
......
......@@ -49,6 +49,8 @@
#include "tabmul.h"
#include "ha_connect.h"
extern "C" int trace;
extern "C" USETEMP Use_Temp;
/* --------------------------- Class RELDEF -------------------------- */
......@@ -225,6 +227,14 @@ bool TABDEF::Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am)
return DefineAM(g, am, poff);
} // end of Define
/***********************************************************************/
/* This function returns the database data path. */
/***********************************************************************/
PSZ TABDEF::GetPath(void)
{
return (Database) ? (PSZ)Database : Hc->GetDataPath();
} // end of GetPath
/***********************************************************************/
/* This function returns column table information. */
/***********************************************************************/
......@@ -561,7 +571,7 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
PTXF txfp = NULL;
PDOSDEF defp = (PDOSDEF)Pxdef;
bool map = defp->Mapped && mode != MODE_INSERT &&
!(PlgGetUser(g)->UseTemp == TMP_FORCE &&
!(Use_Temp == TMP_FORCE &&
(mode == MODE_UPDATE || mode == MODE_DELETE));
int cmpr = defp->Compressed;
......
/*************** RelDef H Declares Source Code File (.H) ***************/
/* Name: RELDEF.H Version 1.4 */
/* Name: RELDEF.H Version 1.5 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2004-2014 */
/* */
......@@ -79,8 +79,9 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
void SetNext(PTABDEF tdfp) {Next = tdfp;}
int GetMultiple(void) {return Multiple;}
int GetPseudo(void) {return Pseudo;}
PSZ GetPath(void)
{return (Database) ? (PSZ)Database : Cat->GetDataPath();}
PSZ GetPath(void);
//PSZ GetPath(void)
// {return (Database) ? (PSZ)Database : Cat->GetDataPath();}
bool SepIndex(void) {return GetBoolCatInfo("SepIndex", false);}
bool IsReadOnly(void) {return Read_Only;}
virtual AMT GetDefType(void) {return TYPE_AM_TAB;}
......
......@@ -64,7 +64,10 @@
/* DB static variables. */
/***********************************************************************/
int num_read, num_there, num_eq[2]; // Statistics
extern "C" int trace;
extern "C" int trace;
extern "C" USETEMP Use_Temp;
extern bool xinfo;
/***********************************************************************/
/* Size of optimize file header. */
......@@ -75,8 +78,8 @@ extern "C" int trace;
/* Min and Max blocks contains zero ended fields (blank = false). */
/* No conversion of block values (check = true). */
/***********************************************************************/
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int len = 0, int prec = 0,
bool check = true, bool blank = false, bool un = false);
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int len= 0, int prec= 0,
bool check= true, bool blank= false, bool un= false);
/* --------------------------- Class DOSDEF -------------------------- */
......@@ -313,7 +316,7 @@ bool DOSDEF::InvalidateIndex(PGLOBAL g)
PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode)
{
// Mapping not used for insert
USETEMP tmp = PlgGetUser(g)->UseTemp;
USETEMP tmp = Use_Temp;
bool map = Mapped && mode != MODE_INSERT &&
!(tmp != TMP_NO && Recfm == RECFM_VAR
&& mode == MODE_UPDATE) &&
......@@ -432,6 +435,7 @@ TDBDOS::TDBDOS(PDOSDEF tdp, PTXF txfp) : TDBASE(tdp)
//Xeval = 0;
Beval = 0;
Abort = false;
Indxd = false;
} // end of TDBDOS standard constructor
TDBDOS::TDBDOS(PGLOBAL g, PTDBDOS tdbp) : TDBASE(tdbp)
......@@ -446,6 +450,8 @@ TDBDOS::TDBDOS(PGLOBAL g, PTDBDOS tdbp) : TDBASE(tdbp)
SavFil = tdbp->SavFil;
//Xeval = tdbp->Xeval;
Beval = tdbp->Beval;
Abort = tdbp->Abort;
Indxd = tdbp->Indxd;
} // end of TDBDOS copy constructor
// Method
......@@ -542,8 +548,8 @@ int TDBDOS::ResetTableOpt(PGLOBAL g, bool dop, bool dox)
if (dox && (rc == RC_OK || rc == RC_INFO)) {
// Remake eventual indexes
if (Mode != MODE_UPDATE)
To_SetCols = NULL; // Only used on Update
// if (Mode != MODE_UPDATE)
To_SetCols = NULL; // Positions are changed
Columns = NULL; // Not used anymore
Txfp->Reset(); // New start
......@@ -659,6 +665,13 @@ int TDBDOS::MakeBlockValues(PGLOBAL g)
cdp->SetMin(PlugSubAlloc(g, NULL, block * lg));
cdp->SetMax(PlugSubAlloc(g, NULL, block * lg));
// Valgrind complains if there are uninitialised bytes
// after the null character ending
if (IsTypeChar(cdp->GetType())) {
memset(cdp->GetMin(), 0, block * lg);
memset(cdp->GetMax(), 0, block * lg);
} // endif Type
if (trace)
htrc("min(%p) max(%p) col(%d) %s Block=%d lg=%d\n",
cdp->GetMin(), cdp->GetMax(), i, cdp->GetName(), block, lg);
......@@ -837,6 +850,8 @@ bool TDBDOS::SaveBlockValues(PGLOBAL g)
return true;
} // endif opfile
memset(n, 0, sizeof(n)); // To avoid valgrind warning
if (Ftype == RECFM_VAR || defp->Compressed == 2) {
/*******************************************************************/
/* Write block starting positions into the opt file. */
......@@ -1722,7 +1737,7 @@ err:
/***********************************************************************/
/* Make a dynamic index. */
/***********************************************************************/
bool TDBDOS::InitialyzeIndex(PGLOBAL g, PIXDEF xdp)
bool TDBDOS::InitialyzeIndex(PGLOBAL g, PIXDEF xdp, bool sorted)
{
int k, rc;
bool brc, dynamic;
......@@ -1811,6 +1826,12 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, PIXDEF xdp)
} // endif AmType
To_Kindex= kxp;
if (!(sorted && To_Kindex->IsSorted()) &&
((Mode == MODE_UPDATE && IsUsingTemp(g)) ||
(Mode == MODE_DELETE && Txfp->GetAmType() != TYPE_AM_DBF)))
Indxd = true;
} // endif brc
} else
......@@ -1887,7 +1908,7 @@ int TDBDOS::Cardinality(PGLOBAL g)
} // endif Mode
if (Mode == MODE_ANY) {
if (Mode == MODE_ANY && xinfo) {
// Using index impossible or failed, do it the hard way
Mode = MODE_READ;
To_Line = (char*)PlugSubAlloc(g, NULL, Lrecl + 1);
......@@ -2000,10 +2021,8 @@ int TDBDOS::EstimatedLength(PGLOBAL g)
/***********************************************************************/
bool TDBDOS::IsUsingTemp(PGLOBAL g)
{
USETEMP usetemp = PlgGetUser(g)->UseTemp;
return (usetemp == TMP_YES || usetemp == TMP_FORCE ||
(usetemp == TMP_AUTO && Mode == MODE_UPDATE));
return (Use_Temp == TMP_YES || Use_Temp == TMP_FORCE ||
(Use_Temp == TMP_AUTO && Mode == MODE_UPDATE));
} // end of IsUsingTemp
/***********************************************************************/
......@@ -2043,7 +2062,7 @@ bool TDBDOS::OpenDB(PGLOBAL g)
Txfp = new(g) DOSFAM((PDOSDEF)To_Def);
Txfp->SetTdbp(this);
} else if (Txfp->Blocked && (Mode == MODE_DELETE ||
(Mode == MODE_UPDATE && PlgGetUser(g)->UseTemp != TMP_NO))) {
(Mode == MODE_UPDATE && Use_Temp != TMP_NO))) {
/*******************************************************************/
/* Delete is not currently handled in block mode neither Update */
/* when using a temporary file. */
......@@ -2156,13 +2175,10 @@ int TDBDOS::ReadDB(PGLOBAL g)
} // 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())) {
char *p;
......@@ -2177,6 +2193,20 @@ int TDBDOS::WriteDB(PGLOBAL g)
*(++p) = '\0';
} // 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)
htrc("Write: line is='%s'\n", To_Line);
......@@ -2204,6 +2234,7 @@ void TDBDOS::CloseDB(PGLOBAL g)
} // endif
Txfp->CloseTableFile(g, Abort);
RestoreNrec();
} // end of CloseDB
// ------------------------ DOSCOL functions ----------------------------
......@@ -2232,8 +2263,8 @@ DOSCOL::DOSCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am)
Deplac = cdp->GetOffset();
Long = cdp->GetLong();
To_Val = NULL;
Clustered = 0;
Sorted = 0;
Clustered = cdp->GetOpt();
Sorted = (cdp->GetOpt() == 2) ? 1 : 0;
Ndv = 0; // Currently used only for XDB2
Nbm = 0; // Currently used only for XDB2
Min = NULL;
......
......@@ -136,6 +136,7 @@ class DllExport TDBDOS : public TDBASE {
virtual PTDB CopyOne(PTABS t);
virtual void ResetDB(void) {Txfp->Reset();}
virtual bool IsUsingTemp(PGLOBAL g);
virtual bool IsIndexed(void) {return Indxd;}
virtual void ResetSize(void) {MaxSize = Cardinal = -1;}
virtual int ResetTableOpt(PGLOBAL g, bool dop, bool dox);
virtual int MakeBlockValues(PGLOBAL g);
......@@ -171,11 +172,12 @@ class DllExport TDBDOS : public TDBASE {
// Optimization routines
virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add);
bool InitialyzeIndex(PGLOBAL g, PIXDEF xdp);
bool InitialyzeIndex(PGLOBAL g, PIXDEF xdp, bool sorted);
void ResetBlockFilter(PGLOBAL g);
bool GetDistinctColumnValues(PGLOBAL g, int nrec);
protected:
virtual bool PrepareWriting(PGLOBAL g);
PBF CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv);
// Members
......@@ -185,6 +187,7 @@ class DllExport TDBDOS : public TDBASE {
PFIL SavFil; // Saved hidden filter
char *To_Line; // Points to current processed line
bool Abort; // TRUE when aborting UPDATE/DELETE
bool Indxd; // TRUE for indexed UPDATE/DELETE
int Lrecl; // Logical Record Length
int AvgLen; // Logical Record Average Length
//int Xeval; // BlockTest return value
......
......@@ -51,7 +51,9 @@
/***********************************************************************/
/* DB static variables. */
/***********************************************************************/
extern "C" int trace;
extern "C" int trace;
extern "C" USETEMP Use_Temp;
extern int num_read, num_there, num_eq[2]; // Statistics
static const longlong M2G = 0x80000000;
static const longlong M4G = (longlong)2 * M2G;
......@@ -135,6 +137,10 @@ int TDBFIX::ResetTableOpt(PGLOBAL g, bool dop, bool dox)
MaxSize = -1; // Size must be recalculated
Cardinal = -1; // as well as Cardinality
// After the table was modified the indexes
// are invalid and we should mark them as such...
rc = ((PDOSDEF)To_Def)->InvalidateIndex(g);
if (dop) {
Columns = NULL; // Not used anymore
Txfp->Reset();
......@@ -153,12 +159,8 @@ int TDBFIX::ResetTableOpt(PGLOBAL g, bool dop, bool dox)
Mode = MODE_READ; // New mode
prc = rc;
if (!(PlgGetUser(g)->Check & CHK_OPT)) {
// After the table was modified the indexes
// are invalid and we should mark them as such...
rc = ((PDOSDEF)To_Def)->InvalidateIndex(g);
} else
// ... or we should remake them.
if (PlgGetUser(g)->Check & CHK_OPT)
// We must remake indexes.
rc = MakeIndex(g, NULL, FALSE);
rc = (rc == RC_INFO) ? prc : rc;
......@@ -269,9 +271,11 @@ int TDBFIX::RowNumber(PGLOBAL g, bool b)
/***********************************************************************/
bool TDBFIX::IsUsingTemp(PGLOBAL g)
{
USETEMP usetemp = PlgGetUser(g)->UseTemp;
return (usetemp == TMP_YES || usetemp == TMP_FORCE);
// Not ready yet to handle using a temporary file with mapping
// or while deleting from DBF files.
return ((Use_Temp == TMP_YES && Txfp->GetAmType() != TYPE_AM_MAP &&
!(Mode == MODE_DELETE && Txfp->GetAmType() == TYPE_AM_DBF)) ||
Use_Temp == TMP_FORCE || Use_Temp == TMP_TEST);
} // end of IsUsingTemp
/***********************************************************************/
......@@ -302,8 +306,9 @@ bool TDBFIX::OpenDB(PGLOBAL g)
return false;
} // endif use
if (Mode == MODE_DELETE && !Next && Txfp->GetAmType() == TYPE_AM_MAP) {
// Delete all lines. Not handled in MAP mode
if (Mode == MODE_DELETE && Txfp->GetAmType() == TYPE_AM_MAP &&
(!Next || Use_Temp == TMP_FORCE)) {
// Delete all lines or using temp. Not handled in MAP mode
Txfp = new(g) FIXFAM((PDOSDEF)To_Def);
Txfp->SetTdbp(this);
} // endif Mode
......
......@@ -51,6 +51,8 @@ class DllExport TDBFIX : public TDBDOS {
virtual int WriteDB(PGLOBAL g);
protected:
virtual bool PrepareWriting(PGLOBAL g) {return false;}
// Members are inherited from TDBDOS
}; // end of class TDBFIX
......@@ -89,7 +91,8 @@ class TDBDCL : public TDBCAT {
protected:
// Specific routines
virtual PQRYRES GetResult(PGLOBAL g) {return DBFColumns(g, Fn, false);}
virtual PQRYRES GetResult(PGLOBAL g)
{return DBFColumns(g, ((PTABDEF)To_Def)->GetPath(), Fn, false);}
// Members
char *Fn; // The DBF file (path) name
......
......@@ -66,7 +66,8 @@
#define MAXCOL 200 /* Default max column nb in result */
#define TYPE_UNKNOWN 10 /* Must be greater than other types */
extern "C" int trace;
extern "C" int trace;
extern "C" USETEMP Use_Temp;
/***********************************************************************/
/* CSVColumns: constructs the result blocks containing the description */
......@@ -75,8 +76,8 @@ extern "C" int trace;
/* of types (TYPE_STRING < TYPE_DOUBLE < TYPE_INT) (1 < 2 < 7). */
/* If these values are changed, this will have to be revisited. */
/***********************************************************************/
PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
int hdr, int mxr, bool info)
PQRYRES CSVColumns(PGLOBAL g, char *dp, const char *fn, char sep,
char q, int hdr, int mxr, bool info)
{
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
TYPE_INT, TYPE_INT, TYPE_SHORT};
......@@ -130,7 +131,7 @@ PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
/*********************************************************************/
/* Open the input file. */
/*********************************************************************/
PlugSetPath(filename, fn, PlgGetDataPath(g));
PlugSetPath(filename, fn, dp);
if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "r")))
return NULL;
......@@ -441,7 +442,7 @@ PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode)
PTDBASE tdbp;
if (Catfunc != FNC_COL) {
USETEMP tmp = PlgGetUser(g)->UseTemp;
USETEMP tmp = Use_Temp;
bool map = Mapped && mode != MODE_INSERT &&
!(tmp != TMP_NO && mode == MODE_UPDATE) &&
!(tmp == TMP_FORCE &&
......@@ -479,6 +480,36 @@ PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode)
if (Multiple)
tdbp = new(g) TDBMUL(tdbp);
else
/*****************************************************************/
/* For block tables, get eventually saved optimization values. */
/*****************************************************************/
if (tdbp->GetBlockValues(g)) {
PushWarning(g, tdbp);
// return NULL; // causes a crash when deleting index
} else {
if (IsOptimized()) {
if (map) {
txfp = new(g) MBKFAM(this);
} else if (Compressed) {
#if defined(ZIP_SUPPORT)
if (Compressed == 1)
txfp = new(g) ZBKFAM(this);
else {
txfp->SetBlkPos(To_Pos);
((PZLBFAM)txfp)->SetOptimized(To_Pos != NULL);
} // endelse
#else
sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
return NULL;
#endif
} else
txfp = new(g) BLKFAM(this);
((PTDBDOS)tdbp)->SetTxfp(txfp);
} // endif Optimized
} // endelse
} else
tdbp = new(g)TDBCCL(this);
......@@ -605,14 +636,12 @@ int TDBCSV::EstimatedLength(PGLOBAL g)
#if 0
/***********************************************************************/
/* CSV tables favor the use temporary files for Update. */
/* CSV tables needs the use temporary files for Update. */
/***********************************************************************/
bool TDBCSV::IsUsingTemp(PGLOBAL g)
{
USETEMP usetemp = PlgGetUser(g)->UseTemp;
return (usetemp == TMP_YES || usetemp == TMP_FORCE ||
(usetemp == TMP_AUTO && Mode == MODE_UPDATE));
return (Use_Temp == TMP_YES || Use_Temp == TMP_FORCE ||
(Use_Temp == TMP_AUTO && Mode == MODE_UPDATE));
} // end of IsUsingTemp
#endif // 0 (Same as TDBDOS one)
......@@ -899,9 +928,9 @@ int TDBCSV::ReadBuffer(PGLOBAL g)
} // 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];
int i, nlen, oldlen = strlen(To_Line);
......@@ -912,7 +941,7 @@ int TDBCSV::WriteDB(PGLOBAL g)
// Before writing the line we must check its length
if ((nlen = CheckWrite(g)) < 0)
return RC_FX;
return true;
// Before writing the line we must make it
sep[0] = Sep;
......@@ -975,6 +1004,18 @@ int TDBCSV::WriteDB(PGLOBAL g)
if (trace > 1)
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. */
/*********************************************************************/
......@@ -1430,7 +1471,8 @@ TDBCCL::TDBCCL(PCSVDEF tdp) : TDBCAT(tdp)
/***********************************************************************/
PQRYRES TDBCCL::GetResult(PGLOBAL g)
{
return CSVColumns(g, Fn, Sep, Qtd, Hdr, Mxr, false);
return CSVColumns(g, ((PTABDEF)To_Def)->GetPath(),
Fn, Sep, Qtd, Hdr, Mxr, false);
} // end of GetResult
/* ------------------------ End of TabFmt ---------------------------- */
This diff is collapsed.
......@@ -216,10 +216,11 @@ PCOL TDBASE::ColDB(PGLOBAL g, PSZ name, int num)
/* Also find where to insert the new block. */
/*****************************************************************/
for (cp = Columns; cp; cp = cp->GetNext())
if (cp->GetIndex() < i)
if ((num && cp->GetIndex() == i) ||
(name && !stricmp(cp->GetName(), name)))
break; // Found
else if (cp->GetIndex() < i)
cprec = cp;
else if (cp->GetIndex() == i)
break;
if (trace)
htrc("cdp(%d).Name=%s cp=%p\n", i, cdp->GetName(), cp);
......
......@@ -680,7 +680,7 @@ char* TDBDIR::Path(PGLOBAL g)
#if defined(WIN32)
if (!*Drive) {
PlugSetPath(Fpath, To_File, cat->GetDataPath());
PlugSetPath(Fpath, To_File, ((PTABDEF)To_Def)->GetPath());
_splitpath(Fpath, Drive, Direc, Fname, Ftype);
} else
_makepath(Fpath, Drive, Direc, Fname, Ftype); // Usefull ???
......@@ -688,7 +688,7 @@ char* TDBDIR::Path(PGLOBAL g)
return Fpath;
#else // !WIN32
if (!Done) {
PlugSetPath(Fpath, To_File, cat->GetDataPath());
PlugSetPath(Fpath, To_File, ((PTABDEF)To_Def)->GetPath());
_splitpath(Fpath, NULL, Direc, Fname, Ftype);
strcat(strcpy(Pattern, Fname), Ftype);
Done = true;
......
......@@ -68,6 +68,7 @@ void PrintResult(PGLOBAL, PSEM, PQRYRES);
#endif // _CONSOLE
extern "C" int trace;
extern bool xinfo;
// Used to check whether a MYSQL table is created on itself
bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host,
......@@ -754,7 +755,7 @@ int TDBMYSQL::Cardinality(PGLOBAL g)
if (!g)
return (Mode == MODE_ANY && !Srcdef) ? 1 : 0;
if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef) {
if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef && xinfo) {
// Info command, we must return the exact table row number
char query[96];
MYSQLC myc;
......
/************* Tabodbc C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABODBC */
/* ------------- */
/* Version 2.7 */
/* Version 2.8 */
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 2000-2013 */
/* (C) Copyright to the author Olivier BERTRAND 2000-2014 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
......@@ -76,6 +76,7 @@
#include "sql_string.h"
extern "C" int trace;
extern bool xinfo;
/***********************************************************************/
/* DB static variables. */
......@@ -671,7 +672,7 @@ int TDBODBC::Cardinality(PGLOBAL g)
if (!g)
return (Mode == MODE_ANY && !Srcdef) ? 1 : 0;
if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef) {
if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef && xinfo) {
// Info command, we must return the exact table row number
char qry[96], tbn[64];
ODBConn *ocp = new(g) ODBConn(g, this);
......
......@@ -76,7 +76,8 @@
char *strerror(int num);
#endif // UNIX
extern "C" int trace;
extern "C" int trace;
extern "C" USETEMP Use_Temp;
/***********************************************************************/
/* Char VCT column blocks are right filled with blanks (blank = true) */
......@@ -208,7 +209,7 @@ PTDB VCTDEF::GetTable(PGLOBAL g, MODE mode)
// Mapping not used for insert (except for true VEC not split tables)
// or when UseTemp is forced
bool map = Mapped && (Estimate || mode != MODE_INSERT) &&
!(PlgGetUser(g)->UseTemp == TMP_FORCE &&
!(Use_Temp == TMP_FORCE &&
(mode == MODE_UPDATE || mode == MODE_DELETE));
PTXF txfp;
PTDB tdbp;
......@@ -284,6 +285,15 @@ PCOL TDBVCT::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
return new(g) VCTCOL(g, cdp, this, cprec, n);
} // end of MakeCol
/***********************************************************************/
/* VEC tables are not ready yet to use temporary files. */
/***********************************************************************/
bool TDBVCT::IsUsingTemp(PGLOBAL g)
{
// For developpers
return (Use_Temp == TMP_TEST);
} // end of IsUsingTemp
/***********************************************************************/
/* VCT Access Method opening routine. */
/* New method now that this routine is called recursively (last table */
......
/*************** TabVct H Declares Source Code File (.H) ***************/
/* Name: TABVCT.H Version 3.4 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 1999-2011 */
/* */
/* This file contains the TDBVCT class declares. */
/***********************************************************************/
#ifndef __TABVCT__
#define __TABVCT__
#include "tabfix.h"
#if defined(UNIX)
//#include <string.h.SUNWCCh>
#endif
typedef class TDBVCT *PTDBVCT;
typedef class VCTCOL *PVCTCOL;
/***********************************************************************/
/* VCT table. */
/***********************************************************************/
class DllExport VCTDEF : public DOSDEF { /* Logical table description */
friend class TDBVCT;
friend class VCTFAM;
friend class VECFAM;
friend class VMPFAM;
public:
// Constructor
VCTDEF(void) {Split = false; Estimate = Header = 0;}
// Implementation
virtual const char *GetType(void) {return "VCT";}
int GetEstimate(void) {return Estimate;}
// Methods
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE mode);
protected:
int MakeFnPattern(char *fpat);
// Members
bool Split; /* Columns in separate files */
int Estimate; /* Estimated maximum size of table */
int Header; /* 0: no, 1: separate, 2: in data file */
}; // end of VCTDEF
/***********************************************************************/
/* This is the DOS/UNIX Access Method class declaration for files */
/* in blocked vector format. In each block containing "Elements" */
/* records, values of each columns are consecutively stored (vector). */
/***********************************************************************/
class DllExport TDBVCT : public TDBFIX {
friend class VCTCOL;
friend class VCTFAM;
friend class VCMFAM;
friend class VECFAM;
friend class VMPFAM;
public:
// Constructors
TDBVCT(PVCTDEF tdp, PTXF txfp);
TDBVCT(PGLOBAL g, PTDBVCT tdbp);
// Implementation
virtual AMT GetAmType(void) {return TYPE_AM_VCT;}
virtual PTDB Duplicate(PGLOBAL g)
{return (PTDB)new(g) TDBVCT(g, this);}
bool IsSplit(void) {return ((VCTDEF*)To_Def)->Split;}
// Methods
virtual PTDB CopyOne(PTABS t);
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual void CloseDB(PGLOBAL g);
protected:
// Members
}; // end of class TDBVCT
/***********************************************************************/
/* Class VCTCOL: VCT access method column descriptor. */
/* This A.M. is used for file having column wise organization. */
/***********************************************************************/
class DllExport VCTCOL : public DOSCOL {
friend class TDBVCT;
friend class VCTFAM;
friend class VCMFAM;
friend class VECFAM;
friend class VMPFAM;
friend class BGVFAM;
public:
// Constructors
VCTCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i);
VCTCOL(VCTCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
virtual int GetAmType(void) {return TYPE_AM_VCT;}
// Methods
virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g);
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
virtual void SetOk(void);
protected:
virtual void ReadBlock(PGLOBAL g);
virtual void WriteBlock(PGLOBAL g);
VCTCOL(void) {} // Default constructor not to be used
// Members
PVBLK Blk; // Block buffer
int Clen; // Internal length in table
int ColBlk; // Block pointed by column
int ColPos; // Last position read
int Modif; // Number of modified lines in block
}; // end of class VCTCOL
#endif // __TABVCT__
/*************** TabVct H Declares Source Code File (.H) ***************/
/* Name: TABVCT.H Version 3.4 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 1999-2011 */
/* */
/* This file contains the TDBVCT class declares. */
/***********************************************************************/
#ifndef __TABVCT__
#define __TABVCT__
#include "tabfix.h"
#if defined(UNIX)
//#include <string.h.SUNWCCh>
#endif
typedef class TDBVCT *PTDBVCT;
typedef class VCTCOL *PVCTCOL;
/***********************************************************************/
/* VCT table. */
/***********************************************************************/
class DllExport VCTDEF : public DOSDEF { /* Logical table description */
friend class TDBVCT;
friend class VCTFAM;
friend class VECFAM;
friend class VMPFAM;
public:
// Constructor
VCTDEF(void) {Split = false; Estimate = Header = 0;}
// Implementation
virtual const char *GetType(void) {return "VCT";}
int GetEstimate(void) {return Estimate;}
// Methods
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE mode);
protected:
int MakeFnPattern(char *fpat);
// Members
bool Split; /* Columns in separate files */
int Estimate; /* Estimated maximum size of table */
int Header; /* 0: no, 1: separate, 2: in data file */
}; // end of VCTDEF
/***********************************************************************/
/* This is the DOS/UNIX Access Method class declaration for files */
/* in blocked vector format. In each block containing "Elements" */
/* records, values of each columns are consecutively stored (vector). */
/***********************************************************************/
class DllExport TDBVCT : public TDBFIX {
friend class VCTCOL;
friend class VCTFAM;
friend class VCMFAM;
friend class VECFAM;
friend class VMPFAM;
public:
// Constructors
TDBVCT(PVCTDEF tdp, PTXF txfp);
TDBVCT(PGLOBAL g, PTDBVCT tdbp);
// Implementation
virtual AMT GetAmType(void) {return TYPE_AM_VCT;}
virtual PTDB Duplicate(PGLOBAL g)
{return (PTDB)new(g) TDBVCT(g, this);}
bool IsSplit(void) {return ((VCTDEF*)To_Def)->Split;}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual bool IsUsingTemp(PGLOBAL g);
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual void CloseDB(PGLOBAL g);
protected:
// Members
}; // end of class TDBVCT
/***********************************************************************/
/* Class VCTCOL: VCT access method column descriptor. */
/* This A.M. is used for file having column wise organization. */
/***********************************************************************/
class DllExport VCTCOL : public DOSCOL {
friend class TDBVCT;
friend class VCTFAM;
friend class VCMFAM;
friend class VECFAM;
friend class VMPFAM;
friend class BGVFAM;
public:
// Constructors
VCTCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i);
VCTCOL(VCTCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
virtual int GetAmType(void) {return TYPE_AM_VCT;}
// Methods
virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g);
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
virtual void SetOk(void);
protected:
virtual void ReadBlock(PGLOBAL g);
virtual void WriteBlock(PGLOBAL g);
VCTCOL(void) {} // Default constructor not to be used
// Members
PVBLK Blk; // Block buffer
int Clen; // Internal length in table
int ColBlk; // Block pointed by column
int ColPos; // Last position read
int Modif; // Number of modified lines in block
}; // end of class VCTCOL
#endif // __TABVCT__
......@@ -827,12 +827,12 @@ void CHRBLK::SetValue(PVBLK pv, int n1, int n2)
longjmp(g->jumper[g->jump_level], Type);
} // endif Type
if (!(b = pv->IsNull(n2) && Nullable))
if (!(b = pv->IsNull(n2)))
memcpy(Chrp + n1 * Long, ((CHRBLK*)pv)->Chrp + n2 * Long, Long);
else
Reset(n1);
SetNull(n1, b);
SetNull(n1, b && Nullable);
} // end of SetValue
/***********************************************************************/
......
......@@ -52,6 +52,7 @@ DllExport PVAL AllocateValue(PGLOBAL, int, int len = 0, int prec = 0,
bool uns = false, PSZ fmt = NULL);
DllExport ulonglong CharToNumber(char *, int, ulonglong, bool,
bool *minus = NULL, bool *rc = NULL);
DllExport BYTE OpBmp(PGLOBAL g, OPVAL opc);
/***********************************************************************/
/* Class VALUE represents a constant or variable of any valid type. */
......
......@@ -50,7 +50,7 @@
/***********************************************************************/
/* Macro or external routine definition */
/***********************************************************************/
#define NZ 7
#define NZ 8
#define NW 5
#define MAX_INDX 10
#ifndef INVALID_SET_FILE_POINTER
......@@ -264,9 +264,6 @@ void XINDEX::Close(void)
kcp->FreeData();
} // endfor kcp
if (Tdbp)
Tdbp->RestoreNrec();
} // end of Close
/***********************************************************************/
......@@ -547,7 +544,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp)
if ((Ndif = Qsort(g, Num_K)) < 0)
goto err; // Error during sort
// if (trace)
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);
......@@ -820,11 +817,11 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
bool sep, rc = false;
PXCOL kcp = To_KeyCol;
PDOSDEF defp = (PDOSDEF)Tdbp->To_Def;
PDBUSER dup = PlgGetUser(g);
//PDBUSER dup = PlgGetUser(g);
dup->Step = STEP(SAVING_INDEX);
dup->ProgMax = 15 + 16 * Nk;
dup->ProgCur = 0;
//dup->Step = STEP(SAVING_INDEX);
//dup->ProgMax = 15 + 16 * Nk;
//dup->ProgCur = 0;
switch (Tdbp->Ftype) {
case RECFM_VAR: ftype = ".dnx"; break;
......@@ -869,31 +866,32 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
/*********************************************************************/
/* 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[2] = nof; // The offset array size or 0
n[3] = Num_K; // The index size
n[4] = Incr; // Increment of record positions
n[5] = Nblk; n[6] = Sblk;
n[7] = Srtd ? 1 : 0; // Values are sorted in the file
if (trace) {
htrc("Saving index %s\n", Xdp->GetName());
htrc("ID=%d Nk=%d nof=%d Num_K=%d Incr=%d Nblk=%d Sblk=%d\n",
ID, Nk, nof, Num_K, Incr, Nblk, Sblk);
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, Srtd);
} // endif trace
size = X->Write(g, n, NZ, sizeof(int), rc);
dup->ProgCur = 1;
//dup->ProgCur = 1;
if (Mul) // Write the offset array
size += X->Write(g, Pof, nof, sizeof(int), rc);
dup->ProgCur = 5;
//dup->ProgCur = 5;
if (!Incr) // Write the record position array(s)
size += X->Write(g, To_Rec, Num_K, sizeof(int), rc);
dup->ProgCur = 15;
//dup->ProgCur = 15;
for (; kcp; kcp = kcp->Next) {
n[0] = kcp->Ndf; // Number of distinct sub-values
......@@ -903,20 +901,20 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp)
n[4] = kcp->Type; // To be checked later
size += X->Write(g, n, NW, sizeof(int), rc);
dup->ProgCur += 1;
// dup->ProgCur += 1;
if (n[2])
size += X->Write(g, kcp->To_Bkeys, Nblk, kcp->Klen, rc);
dup->ProgCur += 5;
// dup->ProgCur += 5;
size += X->Write(g, kcp->To_Keys, n[0], kcp->Klen, rc);
dup->ProgCur += 5;
// dup->ProgCur += 5;
if (n[1])
size += X->Write(g, kcp->Kof, n[1], sizeof(int), rc);
dup->ProgCur += 5;
// dup->ProgCur += 5;
} // endfor kcp
if (trace)
......@@ -1019,12 +1017,22 @@ bool XINDEX::Init(PGLOBAL g)
goto err; // No saved values
// Now start the reading process.
if (X->Read(g, nv, NZ, sizeof(int)))
if (X->Read(g, nv, NZ - 1, sizeof(int)))
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)
htrc("nv=%d %d %d %d %d %d %d\n",
nv[0], nv[1], nv[2], nv[3], nv[4], nv[5], nv[6]);
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], Srtd);
// The test on ID was suppressed because MariaDB can change an index ID
// when other indexes are added or deleted
......@@ -1271,11 +1279,20 @@ bool XINDEX::MapInit(PGLOBAL g)
// Now start the mapping process.
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)
htrc("nv=%d %d %d %d %d %d %d\n",
nv[0], nv[1], nv[2], nv[3], nv[4], nv[5], nv[6]);
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], Srtd);
// The test on ID was suppressed because MariaDB can change an index ID
// when other indexes are added or deleted
......@@ -2453,7 +2470,7 @@ void *XFILE::FileView(PGLOBAL g, char *fn)
/***********************************************************************/
bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
{
IOFF noff[MAX_INDX];
IOFF noff[MAX_INDX];
if (Hfile != INVALID_HANDLE_VALUE) {
sprintf(g->Message, MSG(FILE_OPEN_YET), filename);
......@@ -2461,7 +2478,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
} // endif
if (trace)
htrc(" Xopen: filename=%s mode=%d\n", filename, mode);
htrc(" Xopen: filename=%s id=%d mode=%d\n", filename, id, mode);
#if defined(WIN32)
LONG high = 0;
......@@ -2553,7 +2570,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
#else // UNIX
int oflag = O_LARGEFILE; // Enable file size > 2G
mode_t pmod = 0;
mode_t pmod = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
/*********************************************************************/
/* Create the file object according to access mode */
......@@ -2564,7 +2581,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
break;
case MODE_WRITE:
oflag |= O_WRONLY | O_CREAT | O_TRUNC;
pmod = S_IREAD | S_IWRITE;
// pmod = S_IREAD | S_IWRITE;
break;
case MODE_INSERT:
oflag |= (O_WRONLY | O_APPEND);
......@@ -2597,6 +2614,9 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
return true;
} // endif
if (trace)
htrc("INSERT: NewOff=%lld\n", NewOff.Val);
} else if (mode == MODE_WRITE) {
if (id >= 0) {
// New not sep index file. Write the header.
......@@ -2604,18 +2624,26 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode)
NewOff.Low = write(Hfile, &noff, sizeof(noff));
} // endif id
if (trace)
htrc("WRITE: NewOff=%lld\n", NewOff.Val);
} else if (mode == MODE_READ && id >= 0) {
// Get offset from the header
if (read(Hfile, noff, sizeof(noff)) != sizeof(noff)) {
sprintf(g->Message, MSG(READ_ERROR), "Index file", strerror(errno));
return true;
} // endif MAX_INDX
} // endif read
if (trace)
htrc("noff[%d]=%lld\n", id, noff[id].Val);
// Position the cursor at the offset of this index
if (!lseek64(Hfile, noff[id].Val, SEEK_SET)) {
sprintf(g->Message, MSG(FUNC_ERRNO), errno, "Hseek");
if (lseek64(Hfile, noff[id].Val, SEEK_SET) < 0) {
sprintf(g->Message, "(XHUGE)lseek64: %s (%lld)", strerror(errno), noff[id].Val);
printf("%s\n", g->Message);
// sprintf(g->Message, MSG(FUNC_ERRNO), errno, "Hseek");
return true;
} // endif
} // endif lseek64
} // endif mode
#endif // UNIX
......@@ -2749,6 +2777,9 @@ int XHUGE::Write(PGLOBAL g, void *buf, int n, int size, bool& rc)
/***********************************************************************/
void XHUGE::Close(char *fn, int id)
{
if (trace)
htrc("XHUGE::Close: fn=%s id=%d NewOff=%lld\n", fn, id, NewOff.Val);
#if defined(WIN32)
if (id >= 0 && fn) {
CloseFileHandle(Hfile);
......@@ -2766,10 +2797,18 @@ void XHUGE::Close(char *fn, int id)
} // endif id
#else // !WIN32
if (id >= 0 && fn) {
fcntl(Hfile, F_SETFD, O_WRONLY);
if (lseek(Hfile, id * sizeof(IOFF), SEEK_SET))
write(Hfile, &NewOff, sizeof(IOFF));
if (Hfile != INVALID_HANDLE_VALUE) {
if (lseek64(Hfile, id * sizeof(IOFF), SEEK_SET) >= 0) {
ssize_t nbw = write(Hfile, &NewOff, sizeof(IOFF));
if (nbw != (signed)sizeof(IOFF))
htrc("Error writing index file header: %s\n", strerror(errno));
} else
htrc("(XHUGE::Close)lseek64: %s (%d)\n", strerror(errno), id);
} else
htrc("(XHUGE)error reopening %s: %s\n", fn, strerror(errno));
} // endif id
#endif // !WIN32
......@@ -2795,6 +2834,7 @@ void *XHUGE::FileView(PGLOBAL g, char *fn)
/***********************************************************************/
XXROW::XXROW(PTDBDOS tdbp) : XXBASE(tdbp, false)
{
Srtd = true;
Tdbp = tdbp;
Valp = NULL;
} // end of XXROW constructor
......
......@@ -192,6 +192,7 @@ class DllExport XXBASE : public CSORT, public BLOCK {
void SetNth(int n) {Nth = n;}
int *GetPof(void) {return Pof;}
int *GetPex(void) {return Pex;}
bool IsSorted(void) {return Srtd;}
void FreeIndex(void) {PlgDBfree(Index);}
// Methods
......
......@@ -147,6 +147,7 @@ class DllExport TDBASE : public TDB {
inline PKXBASE GetKindex(void) {return To_Kindex;}
inline PCOL GetSetCols(void) {return To_SetCols;}
inline void SetSetCols(PCOL colp) {To_SetCols = colp;}
inline void SetKey_Col(PCOL *cpp) {To_Key_Col = cpp;}
inline void SetXdp(PIXDEF xdp) {To_Xdp = xdp;}
inline void SetKindex(PKXBASE kxp) {To_Kindex = kxp;}
......@@ -156,6 +157,7 @@ class DllExport TDBASE : public TDB {
// Methods
virtual bool IsUsingTemp(PGLOBAL g) {return false;}
virtual bool IsIndexed(void) {return false;}
virtual PCATLG GetCat(void);
virtual PSZ GetPath(void);
virtual void PrintAM(FILE *f, char *m);
......@@ -190,6 +192,9 @@ class DllExport TDBASE : public TDB {
{assert(false); return true;}
protected:
virtual bool PrepareWriting(PGLOBAL g) {strcpy(g->Message,
"This function should not be called for this table"); return true;}
// Members
PTABDEF To_Def; // Points to catalog description block
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