Commit f930f4ed authored by Olivier Bertrand's avatar Olivier Bertrand

- Add a new CONNECT global variable allowing to tell whether or not

  a temporary file should be used for UPDATE/DELETE of file tables.
  Also use the "sorted" argument of index_init to help decide if
  sorting of positions must be done.
modified:
  storage/connect/checklvl.h
  storage/connect/connect.cc
  storage/connect/connect.h
  storage/connect/filamdbf.cpp
  storage/connect/filamfix.cpp
  storage/connect/filamfix.h
  storage/connect/filamtxt.cpp
  storage/connect/ha_connect.cc
  storage/connect/mysql-test/connect/r/part_table.result
  storage/connect/plgdbsem.h
  storage/connect/plgdbutl.cpp
  storage/connect/reldef.cpp
  storage/connect/tabdos.cpp
  storage/connect/tabdos.h
  storage/connect/tabfix.cpp
  storage/connect/tabfmt.cpp
  storage/connect/tabvct.cpp
  storage/connect/tabvct.h
  storage/connect/xindex.cpp

- Fix a bug in TDBASE::ColDB that caused some special columns not to
  be found in the column list and reallocated without their Value
  causing a crash of some queries.
modified:
  storage/connect/table.cpp

- Fix a bug causing RestoreNrec to be called before closing a table
  causing a wrong value given to Spos
modified:
  storage/connect/tabdos.cpp
  storage/connect/xindex.cpp

- Add a new CONNECT global variable connect_exact_info. Set to ON, it
  tells CONNECT to return exact record numbers on info queries. If OFF
  it just gives an estimate. In version 10.0.13 this was unconditionally
  ON and caused info queries on remote tables to be extremely long and
  was the subject of MDEV-6612.
modified:
  storage/connect/ha_connect.cc
  storage/connect/tabdos.cpp
  storage/connect/tabmysql.cpp
  storage/connect/tabodbc.cpp
parent 8b9ed85b
......@@ -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_
......@@ -142,7 +142,7 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname)
return true;
((MYCAT *)dbuserp->Catalog)->SetDataPath(g, pathname);
dbuserp->UseTemp= TMP_AUTO;
//dbuserp->UseTemp= TMP_AUTO;
/*********************************************************************/
/* All is correct. */
......@@ -503,8 +503,6 @@ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp)
if (!colp->GetColUse(U_VIRTUAL))
colp->WriteColumn(g);
//if (tp->GetMode() == MODE_UPDATE && tp->IsUsingTemp(g) &&
// tp->GetKindex() && !tp->GetKindex()->IsSorted())
if (tp->IsIndexed())
// Index values must be sorted before updating
rc= (RCODE)((PTDBDOS)tp)->GetTxfp()->StoreValues(g, true);
......@@ -580,21 +578,6 @@ 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 0
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);
......@@ -605,6 +588,15 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
} 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) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
......@@ -655,7 +647,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;
......@@ -707,7 +699,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;
......@@ -754,7 +746,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
......@@ -835,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) {
......
......@@ -171,6 +171,45 @@ void FIXFAM::ResetBuffer(PGLOBAL g)
} // end of ResetBuffer
/***********************************************************************/
/* WriteModifiedBlock: Used when updating. */
/***********************************************************************/
int FIXFAM::WriteModifiedBlock(PGLOBAL g)
{
/*********************************************************************/
/* The old block was modified in Update mode. */
/* In Update mode we simply rewrite the old block on itself. */
/*********************************************************************/
int rc = RC_OK;
bool moved = false;
// Using temp copy any intermediate lines.
if (UseTemp && MoveIntermediateLines(g, &moved))
rc = RC_FX;
// Fpos is last position, Headlen is DBF file header length
else if (!moved && fseek(Stream, Headlen + Fpos * Lrecl, SEEK_SET)) {
sprintf(g->Message, MSG(FSETPOS_ERROR), 0);
rc = RC_FX;
} else if (fwrite(To_Buf, Lrecl, Rbuf, T_Stream) != (size_t)Rbuf) {
sprintf(g->Message, MSG(FWRITE_ERROR), strerror(errno));
rc = RC_FX;
} else
Spos = Fpos + Nrec; // + Rbuf ???
if (Closing || rc != RC_OK) { // Error or called from CloseDB
Closing = true; // To tell CloseDB about error
return rc;
} // endif Closing
// NOTE: Next line was added to avoid a very strange fread bug.
// When the fseek is not executed (even the file has the good
// pointer position) the next read can happen anywhere in the file.
OldBlk = CurBlk; // This will force fseek to be executed
Modif = 0;
return rc;
} // end of WriteModifiedBlock
/***********************************************************************/
/* ReadBuffer: Read one line for a FIX file. */
/***********************************************************************/
......@@ -178,84 +217,48 @@ int FIXFAM::ReadBuffer(PGLOBAL g)
{
int n, rc = RC_OK;
if (!Closing) {
/*********************************************************************/
/* Sequential reading when Placed is not true. */
/*********************************************************************/
if (Placed) {
Tdbp->SetLine(To_Buf + CurNum * Lrecl);
Placed = false;
} else if (++CurNum < Rbuf) {
Tdbp->IncLine(Lrecl); // Used by DOSCOL functions
return RC_OK;
} else if (Rbuf < Nrec && CurBlk != -1) {
return RC_EF;
} else {
/*******************************************************************/
/* Sequential reading when Placed is not true. */
/* New block. */
/*******************************************************************/
if (Placed) {
Tdbp->SetLine(To_Buf + CurNum * Lrecl);
Placed = false;
} else if (++CurNum < Rbuf) {
Tdbp->IncLine(Lrecl); // Used by DOSCOL functions
return RC_OK;
} else if (Rbuf < Nrec && CurBlk != -1) {
return RC_EF;
} else {
/*****************************************************************/
/* New block. */
/*****************************************************************/
CurNum = 0;
Tdbp->SetLine(To_Buf);
CurNum = 0;
Tdbp->SetLine(To_Buf);
next:
if (++CurBlk >= Block)
return RC_EF;
next:
if (++CurBlk >= Block)
return RC_EF;
/*****************************************************************/
/* Before reading a new block, check whether block indexing */
/* can be done, as well as for join as for local filtering. */
/*****************************************************************/
switch (Tdbp->TestBlock(g)) {
case RC_EF:
return RC_EF;
case RC_NF:
goto next;
} // endswitch rc
} // endif's
if (OldBlk == CurBlk) {
IsRead = true; // Was read indeed
return RC_OK; // Block is already there
} // endif OldBlk
} // endif !Closing
if (Modif) {
/*******************************************************************/
/* The old block was modified in Update mode. */
/* In Update mode we simply rewrite the old block on itself. */
/* Before reading a new block, check whether block indexing */
/* can be done, as well as for join as for local filtering. */
/*******************************************************************/
bool moved = false;
switch (Tdbp->TestBlock(g)) {
case RC_EF:
return RC_EF;
case RC_NF:
goto next;
} // endswitch rc
} // endif's
if (UseTemp) // Copy any intermediate lines.
if (MoveIntermediateLines(g, &moved))
rc = RC_FX;
if (OldBlk == CurBlk) {
IsRead = true; // Was read indeed
return RC_OK; // Block is already there
} // endif OldBlk
if (rc == RC_OK) {
// Fpos is last position, Headlen is DBF file header length
if (!moved && fseek(Stream, Headlen + Fpos * Lrecl, SEEK_SET)) {
sprintf(g->Message, MSG(FSETPOS_ERROR), 0);
rc = RC_FX;
} else if (fwrite(To_Buf, Lrecl, Rbuf, T_Stream) != (size_t)Rbuf) {
sprintf(g->Message, MSG(FWRITE_ERROR), strerror(errno));
rc = RC_FX;
} // endif fwrite
Spos = Fpos + Nrec; // + Rbuf ???
} // endif rc
if (Closing || rc != RC_OK) { // Error or called from CloseDB
Closing = true; // To tell CloseDB about error
return rc;
} // endif Closing
// NOTE: Next line was added to avoid a very strange fread bug.
// When the fseek is not executed (even the file has the good
// pointer position) the next read can happen anywhere in the file.
OldBlk = CurBlk; // This will force fseek to be executed
Modif = 0;
// Spos = Fpos + Nrec; done above
} // endif Mode
// Write modified block in mode UPDATE
if (Modif && (rc = WriteModifiedBlock(g)) != RC_OK)
return rc;
// This could be done only for new block. However note that FPOS
// is used as block position when updating and as line position
......@@ -273,8 +276,6 @@ int FIXFAM::ReadBuffer(PGLOBAL g)
if (trace > 1)
htrc("File position is now %d\n", ftell(Stream));
//long tell = ftell(Stream); not used
if (Padded)
n = fread(To_Buf, (size_t)Blksize, 1, Stream);
else
......@@ -355,7 +356,11 @@ int FIXFAM::WriteBuffer(PGLOBAL g)
} // endif T_Stream
Modif++; // Modified line in Update mode
if (Nrec > 1)
Modif++; // Modified line in blocked mode
else if (WriteModifiedBlock(g)) // Indexed update
return RC_FX;
} // endif Mode
return RC_OK;
......@@ -566,13 +571,12 @@ void FIXFAM::CloseTableFile(PGLOBAL g, bool abort)
if (mode == MODE_INSERT && CurNum && !Closing) {
// Some more inserted lines remain to be written
Rbuf = CurNum--;
// Closing = true;
wrc = WriteBuffer(g);
} else if (mode == MODE_UPDATE) {
if (Modif && !Closing) {
// Last updated block remains to be written
Closing = true;
wrc = ReadBuffer(g);
Closing = true; // ???
wrc = WriteModifiedBlock(g);
} // endif Modif
if (UseTemp && T_Stream && wrc == RC_OK) {
......@@ -1028,6 +1032,43 @@ int BGXFAM::Cardinality(PGLOBAL g)
} // end of Cardinality
/***********************************************************************/
/* WriteModifiedBlock: Used when updating. */
/***********************************************************************/
int BGXFAM::WriteModifiedBlock(PGLOBAL g)
{
/*********************************************************************/
/* The old block was modified in Update mode. */
/* In Update mode we simply rewrite the old block on itself. */
/*********************************************************************/
int rc = RC_OK;
bool moved = false;
if (UseTemp) // Copy any intermediate lines.
if (MoveIntermediateLines(g, &moved))
rc = RC_FX;
if (rc == RC_OK) {
// Set file position to OldBlk position (Fpos)
if (!moved && BigSeek(g, Hfile, (BIGINT)Fpos * (BIGINT)Lrecl))
rc = RC_FX;
else if (BigWrite(g, Tfile, To_Buf, Lrecl * Rbuf))
rc = RC_FX;
Spos = Fpos + Nrec; // + Rbuf ???
} // endif rc
if (Closing || rc != RC_OK) // Error or called from CloseDB
return rc;
// NOTE: Next line was added to avoid a very strange fread bug.
// When the fseek is not executed (even the file has the good
// pointer position) the next read can happen anywhere in the file.
OldBlk = CurBlk; // This will force fseek to be executed
Modif = 0;
return rc;
} // end of WriteModifiedBlock
/***********************************************************************/
/* ReadBuffer: Read Nrec lines for a big fixed/binary file. */
/***********************************************************************/
......@@ -1035,79 +1076,49 @@ int BGXFAM::ReadBuffer(PGLOBAL g)
{
int nbr, rc = RC_OK;
if (!Closing) {
/*********************************************************************/
/* Sequential reading when Placed is not true. */
/*********************************************************************/
if (Placed) {
Tdbp->SetLine(To_Buf + CurNum * Lrecl);
Placed = false;
} else if (++CurNum < Rbuf) {
Tdbp->IncLine(Lrecl); // Used by DOSCOL functions
return RC_OK;
} else if (Rbuf < Nrec && CurBlk != -1) {
return RC_EF;
} else {
/*******************************************************************/
/* Sequential reading when Placed is not true. */
/* New block. */
/*******************************************************************/
if (Placed) {
Tdbp->SetLine(To_Buf + CurNum * Lrecl);
Placed = false;
} else if (++CurNum < Rbuf) {
Tdbp->IncLine(Lrecl); // Used by DOSCOL functions
return RC_OK;
} else if (Rbuf < Nrec && CurBlk != -1) {
CurNum = 0;
Tdbp->SetLine(To_Buf);
next:
if (++CurBlk >= Block)
return RC_EF;
} else {
/*****************************************************************/
/* New block. */
/*****************************************************************/
CurNum = 0;
Tdbp->SetLine(To_Buf);
next:
if (++CurBlk >= Block)
/*******************************************************************/
/* Before reading a new block, check whether block optimization */
/* can be done, as well as for join as for local filtering. */
/*******************************************************************/
switch (Tdbp->TestBlock(g)) {
case RC_EF:
return RC_EF;
case RC_NF:
goto next;
} // endswitch rc
/*****************************************************************/
/* Before reading a new block, check whether block optimization */
/* can be done, as well as for join as for local filtering. */
/*****************************************************************/
switch (Tdbp->TestBlock(g)) {
case RC_EF:
return RC_EF;
case RC_NF:
goto next;
} // endswitch rc
} // endif's
if (OldBlk == CurBlk) {
IsRead = true; // Was read indeed
return RC_OK; // Block is already there
} // endif OldBlk
} // endif's
} // endif !Closing
if (OldBlk == CurBlk) {
IsRead = true; // Was read indeed
return RC_OK; // Block is already there
} // endif OldBlk
if (Modif) {
/*******************************************************************/
/* The old block was modified in Update mode. */
/* In Update mode we simply rewrite the old block on itself. */
/*******************************************************************/
bool moved = false;
if (UseTemp) // Copy any intermediate lines.
if (MoveIntermediateLines(g, &moved))
rc = RC_FX;
if (rc == RC_OK) {
// Set file position to OldBlk position (Fpos)
if (!moved && BigSeek(g, Hfile, (BIGINT)Fpos * (BIGINT)Lrecl))
rc = RC_FX;
else if (BigWrite(g, Tfile, To_Buf, Lrecl * Rbuf))
rc = RC_FX;
Spos = Fpos + Nrec; // + Rbuf ???
} // endif rc
if (Closing || rc != RC_OK) // Error or called from CloseDB
return rc;
// NOTE: Next line was added to avoid a very strange fread bug.
// When the fseek is not executed (even the file has the good
// pointer position) the next read can happen anywhere in the file.
OldBlk = CurBlk; // This will force fseek to be executed
Modif = 0;
} // endif Mode
// Write modified block in mode UPDATE
if (Modif && (rc = WriteModifiedBlock(g)) != RC_OK)
return rc;
Fpos = CurBlk * Nrec;
......@@ -1169,16 +1180,21 @@ int BGXFAM::WriteBuffer(PGLOBAL g)
} else { // Mode == MODE_UPDATE
// Tfile is the temporary file or the table file handle itself
if (Tfile == INVALID_HANDLE_VALUE)
{
if (Tfile == INVALID_HANDLE_VALUE) {
if (UseTemp /*&& Tdbp->GetMode() == MODE_UPDATE*/) {
if (OpenTempFile(g))
return RC_FX;
} else
Tfile = Hfile;
}
Modif++; // Modified line in Update mode
} // endif Tfile
if (Nrec > 1)
Modif++; // Modified line in blocked mode
else if (WriteModifiedBlock(g)) // Indexed update
return RC_FX;
} // endif Mode
return RC_OK;
......@@ -1417,7 +1433,7 @@ void BGXFAM::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 && Tfile && wrc == RC_OK) {
......
......@@ -37,6 +37,7 @@ class DllExport FIXFAM : public BLKFAM {
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);
......@@ -69,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);
......
......@@ -337,14 +337,14 @@ int TXTFAM::StoreValues(PGLOBAL g, bool upd)
/***********************************************************************/
int TXTFAM::UpdateSortedRows(PGLOBAL g)
{
int *ix, i, rc = RC_OK;
int *ix, i;
/*********************************************************************/
/* Get the stored update values and sort them. */
/*********************************************************************/
if (!(Posar = MakeValueArray(g, To_Pos))) {
strcpy(g->Message, "Position array is null");
goto err;
return RC_INFO;
} else if (!(Sosar = MakeValueArray(g, To_Sos))) {
strcpy(g->Message, "Start position array is null");
goto err;
......@@ -364,16 +364,18 @@ int TXTFAM::UpdateSortedRows(PGLOBAL g)
strcpy(Tdbp->To_Line, Updar->GetStringValue(ix[i]));
// Now write the updated line.
if ((rc = WriteBuffer(g)))
if (WriteBuffer(g))
goto err;
} // endfor i
return RC_OK;
err:
if (trace && rc)
if (trace)
htrc("%s\n", g->Message);
return rc;
return RC_FX;
} // end of UpdateSortedRows
/***********************************************************************/
......@@ -386,14 +388,14 @@ int TXTFAM::UpdateSortedRows(PGLOBAL g)
/***********************************************************************/
int TXTFAM::DeleteSortedRows(PGLOBAL g)
{
int *ix, i, irc, rc = RC_OK;
int *ix, i, irc;
/*********************************************************************/
/* Get the stored delete values and sort them. */
/*********************************************************************/
if (!(Posar = MakeValueArray(g, To_Pos))) {
strcpy(g->Message, "Position array is null");
goto err;
return RC_INFO;
} else if (!(Sosar = MakeValueArray(g, To_Sos))) {
strcpy(g->Message, "Start position array is null");
goto err;
......@@ -410,16 +412,18 @@ int TXTFAM::DeleteSortedRows(PGLOBAL g)
goto err;
// Now delete the sorted rows
if ((rc = DeleteRecords(g, irc)))
if (DeleteRecords(g, irc))
goto err;
} // endfor i
return RC_OK;
err:
if (trace && rc)
if (trace)
htrc("%s\n", g->Message);
return rc;
return RC_FX;
} // end of DeleteSortedRows
/***********************************************************************/
......
......@@ -170,8 +170,8 @@
#define SZWMIN 4194304 // Minimum work area size 4M
extern "C" {
char version[]= "Version 1.03.0002 July 17, 2014";
char compver[]= "Version 1.03.0002 " __DATE__ " " __TIME__;
char version[]= "Version 1.03.0003 August 22, 2014";
char compver[]= "Version 1.03.0003 " __DATE__ " " __TIME__;
#if defined(WIN32)
char slash= '\\';
......@@ -185,11 +185,13 @@ extern "C" {
int trace= 0; // The general trace value
int xconv= 0; // The type conversion option
int zconv= SZCONV; // The text conversion size
USETEMP Use_Temp= TMP_AUTO; // The temporary file use
} // extern "C"
#if defined(XMAP)
bool xmap= false;
#endif // XMAP
bool xinfo= false;
uint worksize= SZWORK;
ulong ha_connect::num= 0;
......@@ -200,9 +202,11 @@ static int xtrace= 0;
static int conv_size= SZCONV;
static uint work_size= SZWORK;
static ulong type_conv= 0;
static ulong use_tempfile= 1;
#if defined(XMAP)
static my_bool indx_map= 0;
#endif // XMAP
static my_bool exact_info= 0;
/***********************************************************************/
/* Utility functions. */
......@@ -224,11 +228,14 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
TABLE_SHARE *table_s,
HA_CREATE_INFO *info);
/***********************************************************************/
/* Global variables update functions. */
/***********************************************************************/
static void update_connect_xtrace(MYSQL_THD thd,
struct st_mysql_sys_var *var,
void *var_ptr, const void *save)
{
xtrace= *(int *)var_ptr= *(int *)save;
trace= *(int *)var_ptr= *(int *)save;
} // end of update_connect_xtrace
static void update_connect_zconv(MYSQL_THD thd,
......@@ -252,6 +259,13 @@ static void update_connect_worksize(MYSQL_THD thd,
worksize= (uint)(*(ulong *)var_ptr= *(ulong *)save);
} // end of update_connect_worksize
static void update_connect_usetemp(MYSQL_THD thd,
struct st_mysql_sys_var *var,
void *var_ptr, const void *save)
{
Use_Temp= (USETEMP)(*(ulong *)var_ptr= *(ulong *)save);
} // end of update_connect_usetemp
#if defined(XMAP)
static void update_connect_xmap(MYSQL_THD thd,
struct st_mysql_sys_var *var,
......@@ -261,6 +275,13 @@ static void update_connect_xmap(MYSQL_THD thd,
} // end of update_connect_xmap
#endif // XMAP
static void update_connect_xinfo(MYSQL_THD thd,
struct st_mysql_sys_var *var,
void *var_ptr, const void *save)
{
xinfo= (bool)(*(my_bool *)var_ptr= *(my_bool *)save);
} // end of update_connect_xinfo
/***********************************************************************/
/* The CONNECT handlerton object. */
/***********************************************************************/
......@@ -555,7 +576,7 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg)
stop= false;
alter= false;
mrr= false;
nox= false;
nox= true;
abort= false;
indexing= -1;
locked= 0;
......@@ -1590,7 +1611,7 @@ int ha_connect::CloseTable(PGLOBAL g)
sdvalout=NULL;
valid_info= false;
indexing= -1;
nox= false;
nox= true;
abort= false;
return rc;
} // end of CloseTable
......@@ -2642,7 +2663,6 @@ int ha_connect::open(const char *name, int mode, uint test_if_locked)
int ha_connect::optimize(THD* thd, HA_CHECK_OPT* check_opt)
{
int rc= 0;
bool dop= (check_opt != NULL);
PGLOBAL& g= xp->g;
PDBUSER dup= PlgGetUser(g);
......@@ -2652,9 +2672,10 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT* check_opt)
dup->Check |= CHK_OPT;
if (tdbp) {
bool b= (((PTDBASE)tdbp)->GetDef()->Indexable() == 1);
bool dop= IsTypeIndexable(GetRealType(NULL));
bool dox= (((PTDBASE)tdbp)->GetDef()->Indexable() == 1);
if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, dop, b))) {
if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, dop, dox))) {
if (rc == RC_INFO) {
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
rc= 0;
......@@ -2771,7 +2792,8 @@ int ha_connect::write_row(uchar *buf)
DBUG_PRINT("write_row", ("%s", g->Message));
htrc("write_row: %s\n", g->Message);
rc= HA_ERR_INTERNAL_ERROR;
} // endif RC
} else // Table is modified
nox= false; // Indexes to be remade
DBUG_RETURN(rc);
} // end of write_row
......@@ -2816,7 +2838,8 @@ int ha_connect::update_row(const uchar *old_data, uchar *new_data)
DBUG_PRINT("update_row", ("%s", g->Message));
htrc("update_row CONNECT: %s\n", g->Message);
rc= HA_ERR_INTERNAL_ERROR;
} // endif RC
} else
nox= false; // Table is modified
DBUG_RETURN(rc);
} // end of update_row
......@@ -2849,7 +2872,8 @@ int ha_connect::delete_row(const uchar *buf)
if (CntDeleteRow(xp->g, tdbp, false)) {
rc= HA_ERR_INTERNAL_ERROR;
htrc("delete_row CONNECT: %s\n", xp->g->Message);
} // endif DeleteRow
} else
nox= false; // To remake indexes
DBUG_RETURN(rc);
} // end of delete_row
......@@ -2896,7 +2920,7 @@ int ha_connect::index_init(uint idx, bool sorted)
DBUG_RETURN(0);
} // endif locked
indexing= CntIndexInit(g, tdbp, (signed)idx);
indexing= CntIndexInit(g, tdbp, (signed)idx, sorted);
if (indexing <= 0) {
DBUG_PRINT("index_init", ("%s", g->Message));
......@@ -3533,7 +3557,8 @@ int ha_connect::delete_all_rows()
if (CntDeleteRow(g, tdbp, true)) {
htrc("%s\n", g->Message);
rc= HA_ERR_INTERNAL_ERROR;
} // endif
} else
nox= false;
} // endif rc
......@@ -6194,6 +6219,9 @@ Item *ha_connect::idx_cond_push(uint keyno_arg, Item* idx_cond_arg)
struct st_mysql_storage_engine connect_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
/***********************************************************************/
/* CONNECT global variables definitions. */
/***********************************************************************/
// Tracing: 0 no, 1 yes, >1 more tracing
static MYSQL_SYSVAR_INT(xtrace, xtrace,
PLUGIN_VAR_RQCMDARG, "Console trace value.",
......@@ -6231,6 +6259,35 @@ static MYSQL_SYSVAR_ENUM(
0, // def (no)
&xconv_typelib); // typelib
/**
Temporary file usage:
no: Not using temporary file
auto: Using temporary file when needed
yes: Allways using temporary file
force: Force using temporary file (no MAP)
test: Reserved
*/
const char *usetemp_names[]=
{
"NO", "AUTO", "YES", "FORCE", "TEST", NullS
};
TYPELIB usetemp_typelib=
{
array_elements(usetemp_names) - 1, "usetemp_typelib",
usetemp_names, NULL
};
static MYSQL_SYSVAR_ENUM(
use_tempfile, // name
use_tempfile, // varname
PLUGIN_VAR_RQCMDARG, // opt
"Temporary file use.", // comment
NULL, // check
update_connect_usetemp, // update function
1, // def (AUTO)
&usetemp_typelib); // typelib
#if defined(XMAP)
// Using file mapping for indexes if true
static MYSQL_SYSVAR_BOOL(indx_map, indx_map, PLUGIN_VAR_RQCMDARG,
......@@ -6243,6 +6300,11 @@ static MYSQL_SYSVAR_UINT(work_size, work_size,
PLUGIN_VAR_RQCMDARG, "Size of the CONNECT work area.",
NULL, update_connect_worksize, SZWORK, SZWMIN, UINT_MAX, 1);
// Getting exact info values
static MYSQL_SYSVAR_BOOL(exact_info, exact_info, PLUGIN_VAR_RQCMDARG,
"Getting exact info values",
NULL, update_connect_xinfo, 0);
static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(xtrace),
MYSQL_SYSVAR(conv_size),
......@@ -6251,6 +6313,8 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(indx_map),
#endif // XMAP
MYSQL_SYSVAR(work_size),
MYSQL_SYSVAR(use_tempfile),
MYSQL_SYSVAR(exact_info),
NULL
};
......
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))
......@@ -147,6 +148,7 @@ UPDATE t1 SET msg = 'number' WHERE id in (60,72);
Warnings:
Note 1105 xt3: 2 affected rows
Note 1105 xt3: 0 affected rows
Warning 1105 xt3: (1105) Position array is null
UPDATE t1 SET msg = 'soixante' WHERE id = 60;
Warnings:
Note 1105 xt3: 1 affected rows
......@@ -193,3 +195,4 @@ DROP TABLE t1;
DROP TABLE xt1;
DROP TABLE xt2;
DROP TABLE xt3;
set @@global.connect_exact_info=OFF;
--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;
......@@ -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 */
......
......@@ -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;
......
......@@ -49,6 +49,8 @@
#include "tabmul.h"
#include "ha_connect.h"
extern "C" int trace;
extern "C" USETEMP Use_Temp;
/* --------------------------- Class RELDEF -------------------------- */
......@@ -561,7 +563,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;
......
......@@ -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) &&
......@@ -545,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
......@@ -1722,7 +1725,7 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
/***********************************************************************/
/* 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;
......@@ -1810,7 +1813,9 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, PIXDEF xdp)
To_BlkFil = NULL;
} // endif AmType
if (!(To_Kindex= kxp)->IsSorted() &&
To_Kindex= kxp;
if (!(sorted && To_Kindex->IsSorted()) &&
((Mode == MODE_UPDATE && IsUsingTemp(g)) ||
(Mode == MODE_DELETE && Txfp->GetAmType() != TYPE_AM_DBF)))
Indxd = true;
......@@ -1891,7 +1896,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);
......@@ -2004,10 +2009,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
/***********************************************************************/
......@@ -2047,7 +2050,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. */
......@@ -2219,6 +2222,7 @@ void TDBDOS::CloseDB(PGLOBAL g)
} // endif
Txfp->CloseTableFile(g, Abort);
RestoreNrec();
} // end of CloseDB
// ------------------------ DOSCOL functions ----------------------------
......@@ -2247,8 +2251,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;
......
......@@ -172,7 +172,7 @@ 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);
......
......@@ -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
......
......@@ -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 */
......@@ -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)
......
......@@ -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);
......
......@@ -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 */
......
......@@ -69,6 +69,7 @@ class DllExport TDBVCT : public TDBFIX {
// Methods
virtual PTDB CopyOne(PTABS t);
virtual bool IsUsingTemp(PGLOBAL g);
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
......
......@@ -264,9 +264,6 @@ void XINDEX::Close(void)
kcp->FreeData();
} // endfor kcp
if (Tdbp)
Tdbp->RestoreNrec();
} // end of Close
/***********************************************************************/
......
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