1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

This commit brings many changes, in particular two important ones:

1) Support of partitioning by connect. A table can be partitioned
   by files, this is an enhanced MULTIPLE table. It can be also
   partitioned by sub-tables like TBL and this enables table sharding.
2) Handling a CONNECT bug that causes in some cases extraneous rows
   to remain in the table after an UPDATE or DELETE when the command
   uses indexing (for not fixed file tables). Until a real fix is
   done, CONNECT tries to ignore indexing and if it cannot do it
   abort the command with an error message.

- Add tests on partitioning
added:
  storage/connect/mysql-test/connect/r/part_file.result
  storage/connect/mysql-test/connect/r/part_table.result
  storage/connect/mysql-test/connect/t/part_file.test
  storage/connect/mysql-test/connect/t/part_table.test

- Temporary fix
modified:
  sql/sql_partition.cc

- Add partition support
modified:
  storage/connect/ha_connect.cc
  storage/connect/ha_connect.h
  storage/connect/reldef.cpp
  storage/connect/reldef.h
  storage/connect/tabdos.cpp

- Add functions ha_connect::IsUnique and ha_connect::CheckColumnList
modified:
  storage/connect/ha_connect.cc
  storage/connect/ha_connect.h

- Prevent updating a partition table column that is part of
  the partition function (outward tables only)
modified:
  storage/connect/ha_connect.cc

- Support INSERT/UPDATE/DELETE for PROXY tables
modified:
  storage/connect/tabutil.cpp

- Handle the bug on updating rows via indexing. Waiting for a real fix,
  Don't use indexing when possible else raise an error and abort.
modified:
  storage/connect/ha_connect.cc

- dbuserp->UseTemp set to TMP_AUTO
modified:
  storage/connect/connect.cc

- Add members nox, abort and only
modified:
  storage/connect/ha_connect.cc
  storage/connect/ha_connect.h

- Add arguments nox and abort to CntCloseTable
modified:
  storage/connect/connect.cc
  storage/connect/connect.h
  storage/connect/filamap.cpp
  storage/connect/filamap.h
  storage/connect/filamdbf.cpp
  storage/connect/filamdbf.h
  storage/connect/filamfix.cpp
  storage/connect/filamfix.h
  storage/connect/filamtxt.cpp
  storage/connect/filamtxt.h
  storage/connect/filamvct.cpp
  storage/connect/filamvct.h
  storage/connect/filamzip.cpp
  storage/connect/filamzip.h
  storage/connect/ha_connect.cc

- Add arguments abort to CloseTableFile and RenameTempFile
modified:
  storage/connect/filamap.cpp
  storage/connect/filamap.h
  storage/connect/filamdbf.cpp
  storage/connect/filamdbf.h
  storage/connect/filamfix.cpp
  storage/connect/filamfix.h
  storage/connect/filamtxt.cpp
  storage/connect/filamtxt.h
  storage/connect/filamvct.cpp
  storage/connect/filamvct.h
  storage/connect/filamzip.cpp
  storage/connect/filamzip.h
  storage/connect/tabdos.cpp
  storage/connect/tabdos.h
  storage/connect/tabvct.cpp
  storage/connect/xtable.h

- Fix info->records when file does not exists
modified:
  storage/connect/connect.cc

- Close XML table when opened for info
modified:
  storage/connect/connect.cc

- Add function VCTFAM::GetFileLength
modified:
  storage/connect/filamvct.cpp
  storage/connect/filamvct.h

- Column option DISTRIB -> ENUM
modified:
  storage/connect/ha_connect.cc

- Options connect, query_string and partname allways available
modified:
  storage/connect/ha_connect.cc

- Add function MYSQLC::GetTableSize
modified:
  storage/connect/myconn.cpp
  storage/connect/myconn.h

- Add new special columns (PARTNAME, FNAME, FPATH, FTYPE and FDISK)
modified:
  storage/connect/colblk.cpp
  storage/connect/colblk.h
  storage/connect/plgdbsem.h
  storage/connect/table.cpp

- Add function ExtractFromPath
modified:
  storage/connect/colblk.cpp
  storage/connect/plgdbsem.h
  storage/connect/plgdbutl.cpp

- Enhance Cardinality for some table types
modified:
  storage/connect/tabdos.cpp
  storage/connect/tabmysql.cpp
  storage/connect/tabmysql.h
  storage/connect/tabodbc.cpp
  storage/connect/tabodbc.h
  storage/connect/tabsys.cpp
  storage/connect/tabsys.h
  storage/connect/xindex.cpp
  storage/connect/xindex.h
  storage/connect/xtable.h

- Add test on special column
modified:
  storage/connect/tabfmt.cpp

- Add new files (added for block indexing)
modified:
  storage/connect/CMakeLists.txt
This commit is contained in:
Olivier Bertrand
2014-07-17 18:13:51 +02:00
parent 78292e17ae
commit 1904284361
50 changed files with 1704 additions and 409 deletions

View File

@@ -3195,13 +3195,26 @@ uint32 get_partition_id_cols_list_for_endpoint(partition_info *part_info,
(list_index - 1)*num_columns, (list_index - 1)*num_columns,
nparts, left_endpoint, nparts, left_endpoint,
include_endpoint))); include_endpoint)));
#if 0
if (!left_endpoint) if (!left_endpoint)
{ {
/* Set the end after this list tuple if not already after the last. */ /* Set the end after this list tuple if not already after the last. */
if (list_index < part_info->num_parts) if (list_index < part_info->num_parts)
list_index++; list_index++;
} }
#else
if (!left_endpoint && list_index < part_info->num_list_values)
{
/*
Set the end after this list tuple if it is not already after the last
and it matches.
*/
int cmp = cmp_rec_and_tuple_prune(list_col_array + list_index*num_columns,
nparts, left_endpoint, include_endpoint);
if (cmp >= 0)
list_index++;
}
#endif
DBUG_RETURN(list_index); DBUG_RETURN(list_index);
} }

View File

@@ -19,20 +19,20 @@ SET(CONNECT_PLUGIN_DYNAMIC "connect")
SET(CONNECT_SOURCES SET(CONNECT_SOURCES
ha_connect.cc connect.cc user_connect.cc mycat.cc ha_connect.cc connect.cc user_connect.cc mycat.cc
fmdlex.c osutil.c plugutil.c rcmsg.c rcmsg.h fmdlex.c osutil.c plugutil.c rcmsg.c rcmsg.h
csort.cpp maputil.cpp plgdbutl.cpp array.cpp blkfil.cpp colblk.cpp csort.cpp
colblk.cpp reldef.cpp tabcol.cpp table.cpp filamap.cpp filamdbf.cpp filamfix.cpp filamtxt.cpp filamvct.cpp filamzip.cpp
filamap.cpp filamdbf.cpp filamfix.cpp filamtxt.cpp filamvct.cpp filter.cpp maputil.cpp myutil.cpp plgdbutl.cpp reldef.cpp tabcol.cpp
tabdos.cpp tabfix.cpp tabfmt.cpp tabmul.cpp tabsys.cpp tabvct.cpp tabdos.cpp tabfix.cpp tabfmt.cpp table.cpp tabmul.cpp taboccur.cpp
tabpivot.cpp tabsys.cpp tabtbl.cpp tabutil.cpp tabvct.cpp tabxcl.cpp
valblk.cpp value.cpp xindex.cpp xobject.cpp valblk.cpp value.cpp xindex.cpp xobject.cpp
filamzip.cpp tabtbl.cpp myutil.cpp
tabutil.cpp tabxcl.cpp taboccur.cpp tabpivot.cpp array.h blkfil.h block.h catalog.h checklvl.h colblk.h connect.h csort.h
block.h catalog.h checklvl.h colblk.h connect.h csort.h engmsg.h engmsg.h filamap.h filamdbf.h filamfix.h filamtxt.h filamvct.h filamzip.h
filamap.h filamdbf.h filamfix.h filamtxt.h filamvct.h filamzip.h filter.h global.h ha_connect.h inihandl.h maputil.h msgid.h mycat.h myutil.h
global.h ha_connect.h inihandl.h maputil.h msgid.h mycat.h myutil.h os.h os.h osutil.h plgcnx.h plgdbsem.h preparse.h reldef.h resource.h tabcol.h
osutil.h plgcnx.h plgdbsem.h preparse.h reldef.h resource.h tabcol.h tabdos.h tabfix.h tabfmt.h tabmul.h taboccur.h tabpivot.h tabsys.h
tabdos.h tabfix.h tabfmt.h tabmul.h tabsys.h tabtbl.h tabvct.h tabtbl.h tabutil.h tabvct.h tabxcl.h user_connect.h valblk.h value.h
user_connect.h valblk.h value.h xindex.h xobject.h xtable.h xindex.h xobject.h xtable.h)
tabutil.h tabxcl.h taboccur.h tabpivot.h)
# #
# Definitions that are shared for all OSes # Definitions that are shared for all OSes

View File

@@ -292,7 +292,7 @@ void RIDBLK::ReadColumn(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
/* FIDBLK constructor for the FILEID special column. */ /* FIDBLK constructor for the FILEID special column. */
/***********************************************************************/ /***********************************************************************/
FIDBLK::FIDBLK(PCOLUMN cp) : SPCBLK(cp) FIDBLK::FIDBLK(PCOLUMN cp, OPVAL op) : SPCBLK(cp), Op(op)
{ {
//Is_Key = 2; for when the MUL table indexed reading will be implemented. //Is_Key = 2; for when the MUL table indexed reading will be implemented.
Precision = Long = _MAX_PATH; Precision = Long = _MAX_PATH;
@@ -319,7 +319,14 @@ void FIDBLK::ReadColumn(PGLOBAL g)
Fn = ((PTDBASE)To_Tdb)->GetFile(g); Fn = ((PTDBASE)To_Tdb)->GetFile(g);
PlugSetPath(filename, Fn, ((PTDBASE)To_Tdb)->GetPath()); PlugSetPath(filename, Fn, ((PTDBASE)To_Tdb)->GetPath());
if (Op != OP_XX) {
char buff[_MAX_PATH];
Value->SetValue_psz(ExtractFromPath(g, buff, filename, Op));
} else
Value->SetValue_psz(filename); Value->SetValue_psz(filename);
} // endif Fn } // endif Fn
} // end of ReadColumn } // end of ReadColumn
@@ -351,6 +358,38 @@ void TIDBLK::ReadColumn(PGLOBAL g)
} // end of ReadColumn } // end of ReadColumn
/***********************************************************************/
/* PRTBLK constructor for the PARTID special column. */
/***********************************************************************/
PRTBLK::PRTBLK(PCOLUMN cp) : SPCBLK(cp)
{
//Is_Key = 2; for when the MUL table indexed reading will be implemented.
Precision = Long = 64;
Buf_Type = TYPE_STRING;
*Format.Type = 'C';
Format.Length = Long;
Format.Prec = 1; // Case insensitive
Constant = true; // TODO: check whether this is true indeed
Pname = NULL;
} // end of PRTBLK constructor
/***********************************************************************/
/* ReadColumn: what this routine does is to return the partition ID. */
/***********************************************************************/
void PRTBLK::ReadColumn(PGLOBAL g)
{
if (Pname == NULL) {
char *p;
PTDBASE tdbp = (PTDBASE)To_Tdb;
Pname = tdbp->GetDef()->GetStringCatInfo(g, "partname", "?");
p = strrchr(Pname, '#');
Value->SetValue_psz((p) ? p + 1 : Pname);
} // endif Pname
} // end of ReadColumn
/***********************************************************************/ /***********************************************************************/
/* SIDBLK constructor for the SERVID special column. */ /* SIDBLK constructor for the SERVID special column. */
/***********************************************************************/ /***********************************************************************/

View File

@@ -144,7 +144,7 @@ class DllExport RIDBLK : public SPCBLK {
class DllExport FIDBLK : public SPCBLK { class DllExport FIDBLK : public SPCBLK {
public: public:
// Constructor // Constructor
FIDBLK(PCOLUMN cp); FIDBLK(PCOLUMN cp, OPVAL op);
// Implementation // Implementation
virtual int GetAmType(void) {return TYPE_AM_FILID;} virtual int GetAmType(void) {return TYPE_AM_FILID;}
@@ -155,6 +155,7 @@ class DllExport FIDBLK : public SPCBLK {
protected: protected:
PSZ Fn; // The current To_File of the table PSZ Fn; // The current To_File of the table
OPVAL Op; // The file part operator
}; // end of class FIDBLK }; // end of class FIDBLK
/***********************************************************************/ /***********************************************************************/
@@ -180,6 +181,29 @@ class DllExport TIDBLK : public SPCBLK {
PSZ Tname; // The current table name PSZ Tname; // The current table name
}; // end of class TIDBLK }; // end of class TIDBLK
/***********************************************************************/
/* Class PRTBLK: PARTID special column descriptor. */
/***********************************************************************/
class DllExport PRTBLK : public SPCBLK {
public:
// Constructor
PRTBLK(PCOLUMN cp);
// Implementation
virtual int GetAmType(void) {return TYPE_AM_PRTID;}
// Methods
virtual void Reset(void) {} // This is a pseudo constant column
virtual void ReadColumn(PGLOBAL g);
protected:
// Default constructor not to be used
PRTBLK(void) {}
// Members
PSZ Pname; // The current partition name
}; // end of class PRTBLK
/***********************************************************************/ /***********************************************************************/
/* Class SIDBLK: SERVID special column descriptor. */ /* Class SIDBLK: SERVID special column descriptor. */
/***********************************************************************/ /***********************************************************************/

View File

@@ -142,7 +142,7 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname)
return true; return true;
((MYCAT *)dbuserp->Catalog)->SetDataPath(g, pathname); ((MYCAT *)dbuserp->Catalog)->SetDataPath(g, pathname);
dbuserp->UseTemp= TMP_YES; // Must use temporary file dbuserp->UseTemp= TMP_AUTO;
/*********************************************************************/ /*********************************************************************/
/* All is correct. */ /* All is correct. */
@@ -167,7 +167,12 @@ bool CntInfo(PGLOBAL g, PTDB tp, PXF info)
if (tdbp) { if (tdbp) {
b= tdbp->GetFtype() != RECFM_NAF; b= tdbp->GetFtype() != RECFM_NAF;
info->data_file_length= (b) ? (ulonglong)tdbp->GetFileLength(g) : 0; info->data_file_length= (b) ? (ulonglong)tdbp->GetFileLength(g) : 0;
if (!b || info->data_file_length)
info->records= (unsigned)tdbp->GetMaxSize(g); info->records= (unsigned)tdbp->GetMaxSize(g);
else
info->records= 0;
// info->mean_rec_length= tdbp->GetLrecl(); // info->mean_rec_length= tdbp->GetLrecl();
info->mean_rec_length= 0; info->mean_rec_length= 0;
info->data_file_name= (b) ? tdbp->GetFile(g) : NULL; info->data_file_name= (b) ? tdbp->GetFile(g) : NULL;
@@ -343,12 +348,12 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
//tdbp->SetMode(mode); //tdbp->SetMode(mode);
if (del && ((PTDBASE)tdbp)->GetFtype() != RECFM_NAF) { if (del/* && ((PTDBASE)tdbp)->GetFtype() != RECFM_NAF*/) {
// To avoid erasing the table when doing a partial delete // To avoid erasing the table when doing a partial delete
// make a fake Next // make a fake Next
PDOSDEF ddp= new(g) DOSDEF; // PDOSDEF ddp= new(g) DOSDEF;
PTDB tp= new(g) TDBDOS(ddp, NULL); // PTDB tp= new(g) TDBDOS(ddp, NULL);
tdbp->SetNext(tp); tdbp->SetNext((PTDB)1);
dup->Check &= ~CHK_DELETE; dup->Check &= ~CHK_DELETE;
} // endif del } // endif del
@@ -544,16 +549,23 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all)
/***********************************************************************/ /***********************************************************************/
/* CLOSETAB: Close a table. */ /* CLOSETAB: Close a table. */
/***********************************************************************/ /***********************************************************************/
int CntCloseTable(PGLOBAL g, PTDB tdbp) int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
{ {
int rc= RC_OK; int rc= RC_OK;
TDBDOX *tbxp= NULL; TDBDOX *tbxp= NULL;
if (!tdbp || tdbp->GetUse() != USE_OPEN) if (!tdbp)
return rc; // Nothing to do return rc; // Nothing to do
else if (tdbp->GetUse() != USE_OPEN) {
if (tdbp->GetAmType() == TYPE_AM_XML)
tdbp->CloseDB(g); // Opened by GetMaxSize
return rc;
} // endif !USE_OPEN
if (trace) if (trace)
printf("CntCloseTable: tdbp=%p mode=%d\n", tdbp, tdbp->GetMode()); 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) if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN)
rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine
@@ -572,8 +584,9 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
// This will close the table file(s) and also finalize write // This will close the table file(s) and also finalize write
// operations such as Insert, Update, or Delete. // operations such as Insert, Update, or Delete.
tdbp->SetAbort(abort);
tdbp->CloseDB(g); tdbp->CloseDB(g);
tdbp->SetAbort(false);
g->jump_level--; g->jump_level--;
if (trace > 1) if (trace > 1)
@@ -582,7 +595,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
//if (!((PTDBDOX)tdbp)->GetModified()) //if (!((PTDBDOX)tdbp)->GetModified())
// return 0; // return 0;
if (tdbp->GetMode() == MODE_READ || tdbp->GetMode() == MODE_ANY) if (nox || tdbp->GetMode() == MODE_READ || tdbp->GetMode() == MODE_ANY)
return 0; return 0;
if (trace > 1) if (trace > 1)

View File

@@ -33,7 +33,7 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname);
PTDB CntGetTDB(PGLOBAL g, const char *name, MODE xmod, PHC); PTDB CntGetTDB(PGLOBAL g, const char *name, MODE xmod, PHC);
bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE, char *, char *, bool, PHC); bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE, char *, char *, bool, PHC);
bool CntRewindTable(PGLOBAL g, PTDB tdbp); bool CntRewindTable(PGLOBAL g, PTDB tdbp);
int CntCloseTable(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);
RCODE CntReadNext(PGLOBAL g, PTDB tdbp); RCODE CntReadNext(PGLOBAL g, PTDB tdbp);
RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const void *k, int n, bool mrr); RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const void *k, int n, bool mrr);
@@ -58,7 +58,7 @@ class DOXDEF: public DOSDEF {
/***********************************************************************/ /***********************************************************************/
class TDBDOX: public TDBDOS { class TDBDOX: public TDBDOS {
friend int MakeIndex(PGLOBAL, PTDB, PIXDEF); friend int MakeIndex(PGLOBAL, PTDB, PIXDEF);
friend int CntCloseTable(PGLOBAL, PTDB); friend int CntCloseTable(PGLOBAL, PTDB, bool, bool);
friend int CntIndexInit(PGLOBAL, PTDB, int); friend int CntIndexInit(PGLOBAL, PTDB, int);
friend RCODE CntIndexRead(PGLOBAL, PTDB, OPVAL, const void*, int, bool); friend RCODE CntIndexRead(PGLOBAL, PTDB, OPVAL, const void*, int, bool);
friend RCODE CntDeleteRow(PGLOBAL, PTDB, bool); friend RCODE CntDeleteRow(PGLOBAL, PTDB, bool);

View File

@@ -476,7 +476,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
/***********************************************************************/ /***********************************************************************/
/* Table file close routine for MAP access method. */ /* Table file close routine for MAP access method. */
/***********************************************************************/ /***********************************************************************/
void MAPFAM::CloseTableFile(PGLOBAL g) void MAPFAM::CloseTableFile(PGLOBAL g, bool abort)
{ {
PlugCloseFile(g, To_Fb); PlugCloseFile(g, To_Fb);
To_Fb = NULL; // To get correct file size in Cardinality To_Fb = NULL; // To get correct file size in Cardinality

View File

@@ -43,7 +43,7 @@ class DllExport MAPFAM : public TXTFAM {
virtual int ReadBuffer(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc); virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g); virtual void CloseTableFile(PGLOBAL g, bool abort);
virtual void Rewind(void); virtual void Rewind(void);
protected: protected:

View File

@@ -791,7 +791,7 @@ void DBFFAM::Rewind(void)
/***********************************************************************/ /***********************************************************************/
/* Table file close routine for DBF access method. */ /* Table file close routine for DBF access method. */
/***********************************************************************/ /***********************************************************************/
void DBFFAM::CloseTableFile(PGLOBAL g) void DBFFAM::CloseTableFile(PGLOBAL g, bool abort)
{ {
int rc = RC_OK, wrc = RC_OK; int rc = RC_OK, wrc = RC_OK;
MODE mode = Tdbp->GetMode(); MODE mode = Tdbp->GetMode();
@@ -810,17 +810,17 @@ void DBFFAM::CloseTableFile(PGLOBAL g)
} // endif Modif } // endif Modif
if (UseTemp && T_Stream && wrc == RC_OK) { if (UseTemp && T_Stream && wrc == RC_OK) {
if (!abort) {
// Copy any remaining lines // Copy any remaining lines
bool b; bool b;
Fpos = Tdbp->Cardinality(g); Fpos = Tdbp->Cardinality(g);
abort = MoveIntermediateLines(g, &b) != RC_OK;
} // endif abort
if ((rc = MoveIntermediateLines(g, &b)) == RC_OK) {
// Delete the old file and rename the new temp file. // Delete the old file and rename the new temp file.
RenameTempFile(g); RenameTempFile(g, abort);
goto fin; goto fin;
} // endif rc
} // endif UseTemp } // endif UseTemp
} // endif's mode } // endif's mode

View File

@@ -67,7 +67,7 @@ class DllExport DBFFAM : public FIXFAM, public DBFBASE {
virtual void ResetBuffer(PGLOBAL g); virtual void ResetBuffer(PGLOBAL g);
virtual int ReadBuffer(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc); virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g); virtual void CloseTableFile(PGLOBAL g, bool abort);
virtual void Rewind(void); virtual void Rewind(void);
protected: protected:

View File

@@ -315,8 +315,7 @@ int FIXFAM::WriteBuffer(PGLOBAL g)
} else { // Mode == MODE_UPDATE } else { // Mode == MODE_UPDATE
// T_Stream is the temporary stream or the table file stream itself // T_Stream is the temporary stream or the table file stream itself
if (!T_Stream) if (!T_Stream) {
{
if (UseTemp /*&& Tdbp->GetMode() == MODE_UPDATE*/) { if (UseTemp /*&& Tdbp->GetMode() == MODE_UPDATE*/) {
if (OpenTempFile(g)) if (OpenTempFile(g))
return RC_FX; return RC_FX;
@@ -326,7 +325,9 @@ int FIXFAM::WriteBuffer(PGLOBAL g)
} else } else
T_Stream = Stream; T_Stream = Stream;
}
} // endif T_Stream
Modif++; // Modified line in Update mode Modif++; // Modified line in Update mode
} // endif Mode } // endif Mode
@@ -420,7 +421,7 @@ int FIXFAM::DeleteRecords(PGLOBAL g, int irc)
/*****************************************************************/ /*****************************************************************/
/* Ok, now delete old file and rename new temp file. */ /* Ok, now delete old file and rename new temp file. */
/*****************************************************************/ /*****************************************************************/
if (RenameTempFile(g)) if (RenameTempFile(g, false))
return RC_FX; return RC_FX;
} else { } else {
@@ -527,7 +528,7 @@ bool FIXFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
/***********************************************************************/ /***********************************************************************/
/* Table file close routine for FIX access method. */ /* Table file close routine for FIX access method. */
/***********************************************************************/ /***********************************************************************/
void FIXFAM::CloseTableFile(PGLOBAL g) void FIXFAM::CloseTableFile(PGLOBAL g, bool abort)
{ {
int rc = RC_OK, wrc = RC_OK; int rc = RC_OK, wrc = RC_OK;
MODE mode = Tdbp->GetMode(); MODE mode = Tdbp->GetMode();
@@ -546,17 +547,17 @@ void FIXFAM::CloseTableFile(PGLOBAL g)
} // endif Modif } // endif Modif
if (UseTemp && T_Stream && wrc == RC_OK) { if (UseTemp && T_Stream && wrc == RC_OK) {
if (!abort) {
// Copy any remaining lines // Copy any remaining lines
bool b; bool b;
Fpos = Tdbp->Cardinality(g); Fpos = Tdbp->Cardinality(g);
abort = MoveIntermediateLines(g, &b) != RC_OK;
} // endif // abort
if ((rc = MoveIntermediateLines(g, &b)) == RC_OK) {
// Delete the old file and rename the new temp file. // Delete the old file and rename the new temp file.
RenameTempFile(g); RenameTempFile(g, abort);
goto fin; goto fin;
} // endif rc
} // endif UseTemp } // endif UseTemp
} // endif's mode } // endif's mode
@@ -1245,7 +1246,7 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc)
/*****************************************************************/ /*****************************************************************/
/* Ok, now delete old file and rename new temp file. */ /* Ok, now delete old file and rename new temp file. */
/*****************************************************************/ /*****************************************************************/
if (RenameTempFile(g)) if (RenameTempFile(g, false))
return RC_FX; return RC_FX;
} else { } else {
@@ -1375,7 +1376,7 @@ bool BGXFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
/***********************************************************************/ /***********************************************************************/
/* Data Base close routine for BIGFIX access method. */ /* Data Base close routine for BIGFIX access method. */
/***********************************************************************/ /***********************************************************************/
void BGXFAM::CloseTableFile(PGLOBAL g) void BGXFAM::CloseTableFile(PGLOBAL g, bool abort)
{ {
int rc = RC_OK, wrc = RC_OK; int rc = RC_OK, wrc = RC_OK;
MODE mode = Tdbp->GetMode(); MODE mode = Tdbp->GetMode();
@@ -1393,17 +1394,17 @@ void BGXFAM::CloseTableFile(PGLOBAL g)
} // endif Modif } // endif Modif
if (UseTemp && Tfile && wrc == RC_OK) { if (UseTemp && Tfile && wrc == RC_OK) {
if (!abort) {
// Copy any remaining lines // Copy any remaining lines
bool b; bool b;
Fpos = Tdbp->Cardinality(g); Fpos = Tdbp->Cardinality(g);
abort = MoveIntermediateLines(g, &b) != RC_OK;
} // endif abort
if ((rc = MoveIntermediateLines(g, &b)) == RC_OK) {
// Delete the old file and rename the new temp file. // Delete the old file and rename the new temp file.
RenameTempFile(g); RenameTempFile(g, abort);
goto fin; goto fin;
} // endif rc
} // endif UseTemp } // endif UseTemp
} // endif's mode } // endif's mode

View File

@@ -38,7 +38,7 @@ class DllExport FIXFAM : public BLKFAM {
virtual int ReadBuffer(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc); virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g); virtual void CloseTableFile(PGLOBAL g, bool abort);
protected: protected:
virtual bool CopyHeader(PGLOBAL g) {return false;} virtual bool CopyHeader(PGLOBAL g) {return false;}
@@ -69,7 +69,7 @@ class BGXFAM : public FIXFAM {
virtual int ReadBuffer(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc); virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g); virtual void CloseTableFile(PGLOBAL g, bool abort);
virtual void Rewind(void); virtual void Rewind(void);
protected: protected:

View File

@@ -922,13 +922,16 @@ bool DOSFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
/***********************************************************************/ /***********************************************************************/
/* Delete the old file and rename the new temp file. */ /* Delete the old file and rename the new temp file. */
/* If aborting just delete the new temp file. */
/***********************************************************************/ /***********************************************************************/
int DOSFAM::RenameTempFile(PGLOBAL g) int DOSFAM::RenameTempFile(PGLOBAL g, bool abort)
{ {
char *tempname, filetemp[_MAX_PATH], filename[_MAX_PATH]; char *tempname, filetemp[_MAX_PATH], filename[_MAX_PATH];
int rc; int rc = RC_OK;
if (!To_Fbt) if (To_Fbt)
tempname = (char*)To_Fbt->Fname;
else
return RC_INFO; // Nothing to do ??? return RC_INFO; // Nothing to do ???
// This loop is necessary because, in case of join, // This loop is necessary because, in case of join,
@@ -937,7 +940,7 @@ int DOSFAM::RenameTempFile(PGLOBAL g)
if (fb == To_Fb || fb == To_Fbt) if (fb == To_Fb || fb == To_Fbt)
rc = PlugCloseFile(g, fb); rc = PlugCloseFile(g, fb);
tempname = (char*)To_Fbt->Fname; if (!abort) {
PlugSetPath(filename, To_File, Tdbp->GetPath()); PlugSetPath(filename, To_File, Tdbp->GetPath());
strcat(PlugRemoveType(filetemp, filename), ".ttt"); strcat(PlugRemoveType(filetemp, filename), ".ttt");
remove(filetemp); // May still be there from previous error remove(filetemp); // May still be there from previous error
@@ -955,8 +958,10 @@ int DOSFAM::RenameTempFile(PGLOBAL g)
sprintf(g->Message, MSG(REMOVE_ERROR), sprintf(g->Message, MSG(REMOVE_ERROR),
filetemp, strerror(errno)); filetemp, strerror(errno));
rc = RC_INFO; // Acceptable rc = RC_INFO; // Acceptable
} // endif's
} else } else
rc = RC_OK; remove(tempname);
return rc; return rc;
} // end of RenameTempFile } // end of RenameTempFile
@@ -964,22 +969,22 @@ int DOSFAM::RenameTempFile(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
/* Table file close routine for DOS access method. */ /* Table file close routine for DOS access method. */
/***********************************************************************/ /***********************************************************************/
void DOSFAM::CloseTableFile(PGLOBAL g) void DOSFAM::CloseTableFile(PGLOBAL g, bool abort)
{ {
int rc; int rc;
if (UseTemp && T_Stream) { if (UseTemp && T_Stream) {
if (Tdbp->Mode == MODE_UPDATE) { if (Tdbp->Mode == MODE_UPDATE && !abort) {
// Copy eventually remaining lines // Copy eventually remaining lines
bool b; bool b;
fseek(Stream, 0, SEEK_END); fseek(Stream, 0, SEEK_END);
Fpos = ftell(Stream); Fpos = ftell(Stream);
rc = MoveIntermediateLines(g, &b); abort = MoveIntermediateLines(g, &b) != RC_OK;
} // endif Mode } // endif abort
// Delete the old file and rename the new temp file. // Delete the old file and rename the new temp file.
RenameTempFile(g); // Also close all files RenameTempFile(g, abort); // Also close all files
} else { } else {
rc = PlugCloseFile(g, To_Fb); rc = PlugCloseFile(g, To_Fb);
@@ -1045,9 +1050,7 @@ void BLKFAM::Reset(void)
/***********************************************************************/ /***********************************************************************/
int BLKFAM::Cardinality(PGLOBAL g) int BLKFAM::Cardinality(PGLOBAL g)
{ {
// Should not be called in this version return (g) ? (int)((Block - 1) * Nrec + Last) : 1;
return (g) ? -1 : 0;
//return (g) ? (int)((Block - 1) * Nrec + Last) : 1;
} // end of Cardinality } // end of Cardinality
/***********************************************************************/ /***********************************************************************/
@@ -1382,27 +1385,22 @@ int BLKFAM::WriteBuffer(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
/* Table file close routine for DOS access method. */ /* Table file close routine for DOS access method. */
/***********************************************************************/ /***********************************************************************/
void BLKFAM::CloseTableFile(PGLOBAL g) void BLKFAM::CloseTableFile(PGLOBAL g, bool abort)
{ {
int rc, wrc = RC_OK; int rc, wrc = RC_OK;
if (UseTemp && T_Stream) { if (UseTemp && T_Stream) {
if (Tdbp->GetMode() == MODE_UPDATE) { if (Tdbp->GetMode() == MODE_UPDATE && !abort) {
// Copy eventually remaining lines // Copy eventually remaining lines
bool b; bool b;
fseek(Stream, 0, SEEK_END); fseek(Stream, 0, SEEK_END);
Fpos = ftell(Stream); Fpos = ftell(Stream);
rc = MoveIntermediateLines(g, &b); abort = MoveIntermediateLines(g, &b) != RC_OK;
} else } // endif abort
rc = RC_OK;
if (rc == RC_OK)
// Delete the old file and rename the new temp file. // Delete the old file and rename the new temp file.
rc = RenameTempFile(g); // Also close all files rc = RenameTempFile(g, abort); // Also close all files
else
rc = PlugCloseFile(g, To_Fb);
} else { } else {
// Closing is True if last Write was in error // Closing is True if last Write was in error
if (Tdbp->GetMode() == MODE_INSERT && CurNum && !Closing) { if (Tdbp->GetMode() == MODE_INSERT && CurNum && !Closing) {

View File

@@ -66,7 +66,7 @@ class DllExport TXTFAM : public BLOCK {
virtual int ReadBuffer(PGLOBAL g) = 0; virtual int ReadBuffer(PGLOBAL g) = 0;
virtual int WriteBuffer(PGLOBAL g) = 0; virtual int WriteBuffer(PGLOBAL g) = 0;
virtual int DeleteRecords(PGLOBAL g, int irc) = 0; virtual int DeleteRecords(PGLOBAL g, int irc) = 0;
virtual void CloseTableFile(PGLOBAL g) = 0; virtual void CloseTableFile(PGLOBAL g, bool abort) = 0;
virtual void Rewind(void) = 0; virtual void Rewind(void) = 0;
protected: protected:
@@ -135,13 +135,13 @@ class DllExport DOSFAM : public TXTFAM {
virtual int ReadBuffer(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc); virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g); virtual void CloseTableFile(PGLOBAL g, bool abort);
virtual void Rewind(void); virtual void Rewind(void);
protected: protected:
virtual bool OpenTempFile(PGLOBAL g); virtual bool OpenTempFile(PGLOBAL g);
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b); virtual bool MoveIntermediateLines(PGLOBAL g, bool *b);
virtual int RenameTempFile(PGLOBAL g); virtual int RenameTempFile(PGLOBAL g, bool abort);
// Members // Members
FILE *Stream; // Points to Dos file structure FILE *Stream; // Points to Dos file structure
@@ -182,7 +182,7 @@ class DllExport BLKFAM : public DOSFAM {
virtual int SkipRecord(PGLOBAL g, bool header); virtual int SkipRecord(PGLOBAL g, bool header);
virtual int ReadBuffer(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g);
virtual void CloseTableFile(PGLOBAL g); virtual void CloseTableFile(PGLOBAL g, bool abort);
virtual void Rewind(void); virtual void Rewind(void);
protected: protected:

View File

@@ -136,6 +136,39 @@ VCTFAM::VCTFAM(PVCTFAM txfp) : FIXFAM(txfp)
Ncol = txfp->Ncol; Ncol = txfp->Ncol;
} // end of VCTFAM copy constructor } // end of VCTFAM copy constructor
/***********************************************************************/
/* VCT GetFileLength: returns file size in number of bytes. */
/* This function is here to be accessible by VECFAM and VMPFAM. */
/***********************************************************************/
int VCTFAM::GetFileLength(PGLOBAL g)
{
if (Split) {
// Get the total file length
char filename[_MAX_PATH];
char *savfile = To_File;
int i, len = 0;
// Initialize the array of file structures
if (!Colfn) {
// Prepare the column file name pattern and set Ncol
Colfn = (char*)PlugSubAlloc(g, NULL, _MAX_PATH);
Ncol = ((PVCTDEF)Tdbp->GetDef())->MakeFnPattern(Colfn);
} // endif Colfn
To_File = filename;
for (i = 0; i < Ncol; i++) {
sprintf(filename, Colfn, i+1);
len += TXTFAM::GetFileLength(g);
} // endfor i
To_File = savfile;
return len;
} else
return TXTFAM::GetFileLength(g);
} // end of GetFileLength
/***********************************************************************/ /***********************************************************************/
/* Reset read/write position values. */ /* Reset read/write position values. */
/***********************************************************************/ /***********************************************************************/
@@ -295,7 +328,7 @@ int VCTFAM::Cardinality(PGLOBAL g)
clen = cdp->GetClen(); clen = cdp->GetClen();
sprintf(filename, Colfn, 1); sprintf(filename, Colfn, 1);
To_File = filename; To_File = filename;
len = GetFileLength(g); len = TXTFAM::GetFileLength(g);
To_File = savfn; To_File = savfn;
if (len >= 0) { if (len >= 0) {
@@ -1042,7 +1075,7 @@ bool VCTFAM::CleanUnusedSpace(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
/* Data Base close routine for VCT access method. */ /* Data Base close routine for VCT access method. */
/***********************************************************************/ /***********************************************************************/
void VCTFAM::CloseTableFile(PGLOBAL g) void VCTFAM::CloseTableFile(PGLOBAL g, bool abort)
{ {
int rc = 0, wrc = RC_OK; int rc = 0, wrc = RC_OK;
MODE mode = Tdbp->GetMode(); MODE mode = Tdbp->GetMode();
@@ -1078,7 +1111,7 @@ void VCTFAM::CloseTableFile(PGLOBAL g)
colp->WriteBlock(g); colp->WriteBlock(g);
if (UseTemp && T_Stream) { if (UseTemp && T_Stream) {
rc = RenameTempFile(g); rc = RenameTempFile(g, abort);
if (Header) { if (Header) {
// Header must be set because it was not set in temp file // Header must be set because it was not set in temp file
@@ -1092,7 +1125,7 @@ void VCTFAM::CloseTableFile(PGLOBAL g)
if (MaxBlk) if (MaxBlk)
rc = CleanUnusedSpace(g); rc = CleanUnusedSpace(g);
if ((rc = RenameTempFile(g)) != RC_FX) { if ((rc = RenameTempFile(g, abort)) != RC_FX) {
Stream = T_Stream = NULL; // For SetBlockInfo Stream = T_Stream = NULL; // For SetBlockInfo
rc = ResetTableSize(g, Block, Last); rc = ResetTableSize(g, Block, Last);
} // endif rc } // endif rc
@@ -1715,7 +1748,7 @@ int VCMFAM::DeleteRecords(PGLOBAL g, int irc)
/***********************************************************************/ /***********************************************************************/
/* Data Base close routine for VMP access method. */ /* Data Base close routine for VMP access method. */
/***********************************************************************/ /***********************************************************************/
void VCMFAM::CloseTableFile(PGLOBAL g) void VCMFAM::CloseTableFile(PGLOBAL g, bool abort)
{ {
int wrc = RC_OK; int wrc = RC_OK;
MODE mode = Tdbp->GetMode(); MODE mode = Tdbp->GetMode();
@@ -2252,7 +2285,7 @@ int VECFAM::DeleteRecords(PGLOBAL g, int irc)
} else // UseTemp } else // UseTemp
// Ok, now delete old files and rename new temp files // Ok, now delete old files and rename new temp files
if (RenameTempFile(g) == RC_FX) if (RenameTempFile(g, false) == RC_FX)
return RC_FX; return RC_FX;
// Reset these values for TDBVCT::MakeBlockValues // Reset these values for TDBVCT::MakeBlockValues
@@ -2382,7 +2415,7 @@ bool VECFAM::MoveIntermediateLines(PGLOBAL g, bool *bn)
/***********************************************************************/ /***********************************************************************/
/* Delete the old files and rename the new temporary files. */ /* Delete the old files and rename the new temporary files. */
/***********************************************************************/ /***********************************************************************/
int VECFAM::RenameTempFile(PGLOBAL g) int VECFAM::RenameTempFile(PGLOBAL g, bool abort)
{ {
char *tempname, filetemp[_MAX_PATH], filename[_MAX_PATH]; char *tempname, filetemp[_MAX_PATH], filename[_MAX_PATH];
int rc = RC_OK; int rc = RC_OK;
@@ -2398,6 +2431,8 @@ int VECFAM::RenameTempFile(PGLOBAL g)
continue; continue;
tempname = (char*)T_Fbs[i]->Fname; tempname = (char*)T_Fbs[i]->Fname;
if (!abort) {
sprintf(filename, Colfn, i+1); sprintf(filename, Colfn, i+1);
PlugSetPath(filename, filename, Tdbp->GetPath()); PlugSetPath(filename, filename, Tdbp->GetPath());
strcat(PlugRemoveType(filetemp, filename), ".ttt"); strcat(PlugRemoveType(filetemp, filename), ".ttt");
@@ -2418,6 +2453,9 @@ int VECFAM::RenameTempFile(PGLOBAL g)
rc = RC_INFO; // Acceptable rc = RC_INFO; // Acceptable
} // endif's } // endif's
} else
remove(tempname);
} // endfor i } // endfor i
return rc; return rc;
@@ -2426,7 +2464,7 @@ int VECFAM::RenameTempFile(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
/* Data Base close routine for VEC access method. */ /* Data Base close routine for VEC access method. */
/***********************************************************************/ /***********************************************************************/
void VECFAM::CloseTableFile(PGLOBAL g) void VECFAM::CloseTableFile(PGLOBAL g, bool abort)
{ {
int rc = 0, wrc = RC_OK; int rc = 0, wrc = RC_OK;
MODE mode = Tdbp->GetMode(); MODE mode = Tdbp->GetMode();
@@ -2453,10 +2491,10 @@ void VECFAM::CloseTableFile(PGLOBAL g)
longjmp(g->jumper[g->jump_level], 44); longjmp(g->jumper[g->jump_level], 44);
} else if (mode == MODE_UPDATE) { } else if (mode == MODE_UPDATE) {
if (UseTemp && !InitUpdate) { if (UseTemp && !InitUpdate && !abort) {
// Write any intermediate lines to temp file // Write any intermediate lines to temp file
Fpos = OldBlk * Nrec; Fpos = OldBlk * Nrec;
wrc = MoveIntermediateLines(g); abort = MoveIntermediateLines(g) != RC_OK;
// Spos = Fpos + Nrec; // Spos = Fpos + Nrec;
} // endif UseTemp } // endif UseTemp
@@ -2466,20 +2504,17 @@ void VECFAM::CloseTableFile(PGLOBAL g)
colp; colp = (PVCTCOL)colp->Next) colp; colp = (PVCTCOL)colp->Next)
colp->WriteBlock(g); colp->WriteBlock(g);
if (wrc == RC_OK && UseTemp && !InitUpdate) { if (wrc == RC_OK && UseTemp && !InitUpdate && !abort) {
// Write any intermediate lines to temp file // Write any intermediate lines to temp file
Fpos = (Block - 1) * Nrec + Last; Fpos = (Block - 1) * Nrec + Last;
wrc = MoveIntermediateLines(g); abort = MoveIntermediateLines(g) != RC_OK;
} // endif UseTemp } // endif UseTemp
} // endif's mode } // endif's mode
if (UseTemp && !InitUpdate) { if (UseTemp && !InitUpdate) {
// If they are errors, leave files unchanged // If they are errors, leave files unchanged
if (wrc == RC_OK) rc = RenameTempFile(g, abort);
rc = RenameTempFile(g);
else
longjmp(g->jumper[g->jump_level], 44);
} else if (Streams) } else if (Streams)
for (int i = 0; i < Ncol; i++) for (int i = 0; i < Ncol; i++)
@@ -2950,7 +2985,7 @@ int VMPFAM::DeleteRecords(PGLOBAL g, int irc)
/***********************************************************************/ /***********************************************************************/
/* Data Base close routine for VMP access method. */ /* Data Base close routine for VMP access method. */
/***********************************************************************/ /***********************************************************************/
void VMPFAM::CloseTableFile(PGLOBAL g) void VMPFAM::CloseTableFile(PGLOBAL g, bool abort)
{ {
if (Tdbp->GetMode() == MODE_DELETE) { if (Tdbp->GetMode() == MODE_DELETE) {
// Set Block and Nrec values for TDBVCT::MakeBlockValues // Set Block and Nrec values for TDBVCT::MakeBlockValues
@@ -4072,7 +4107,7 @@ bool BGVFAM::CleanUnusedSpace(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
/* Data Base close routine for huge VEC access method. */ /* Data Base close routine for huge VEC access method. */
/***********************************************************************/ /***********************************************************************/
void BGVFAM::CloseTableFile(PGLOBAL g) void BGVFAM::CloseTableFile(PGLOBAL g, bool abort)
{ {
int rc = 0, wrc = RC_OK; int rc = 0, wrc = RC_OK;
MODE mode = Tdbp->GetMode(); MODE mode = Tdbp->GetMode();
@@ -4108,7 +4143,7 @@ void BGVFAM::CloseTableFile(PGLOBAL g)
colp->WriteBlock(g); colp->WriteBlock(g);
if (UseTemp && Tfile) { if (UseTemp && Tfile) {
rc = RenameTempFile(g); rc = RenameTempFile(g, abort);
Hfile = Tfile = INVALID_HANDLE_VALUE; Hfile = Tfile = INVALID_HANDLE_VALUE;
if (Header) if (Header)
@@ -4121,7 +4156,7 @@ void BGVFAM::CloseTableFile(PGLOBAL g)
if (MaxBlk) if (MaxBlk)
rc = CleanUnusedSpace(g); rc = CleanUnusedSpace(g);
if ((rc = RenameTempFile(g)) != RC_FX) { if ((rc = RenameTempFile(g, abort)) != RC_FX) {
Hfile = Tfile = INVALID_HANDLE_VALUE; // For SetBlockInfo Hfile = Tfile = INVALID_HANDLE_VALUE; // For SetBlockInfo
rc = ResetTableSize(g, Block, Last); rc = ResetTableSize(g, Block, Last);
} // endif rc } // endif rc

View File

@@ -37,6 +37,7 @@ class DllExport VCTFAM : public FIXFAM {
virtual AMT GetAmType(void) {return TYPE_AM_VCT;} virtual AMT GetAmType(void) {return TYPE_AM_VCT;}
virtual PTXF Duplicate(PGLOBAL g) virtual PTXF Duplicate(PGLOBAL g)
{return (PTXF)new(g) VCTFAM(this);} {return (PTXF)new(g) VCTFAM(this);}
virtual int GetFileLength(PGLOBAL g);
// Methods // Methods
virtual void Reset(void); virtual void Reset(void);
@@ -52,7 +53,7 @@ class DllExport VCTFAM : public FIXFAM {
virtual int ReadBuffer(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc); virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g); virtual void CloseTableFile(PGLOBAL g, bool abort);
virtual void Rewind(void); virtual void Rewind(void);
// Specific functions // Specific functions
@@ -71,8 +72,8 @@ class DllExport VCTFAM : public FIXFAM {
// Members // Members
char *NewBlock; // To block written on Insert char *NewBlock; // To block written on Insert
char *Colfn; // Pattern for column file names (VER) char *Colfn; // Pattern for column file names (VEC)
char *Tempat; // Pattern for temp file names (VER) char *Tempat; // Pattern for temp file names (VEC)
int *Clens; // Pointer to col size array int *Clens; // Pointer to col size array
int *Deplac; // Pointer to col start position array int *Deplac; // Pointer to col start position array
bool *Isnum; // Pointer to buffer type isnum result bool *Isnum; // Pointer to buffer type isnum result
@@ -109,7 +110,7 @@ class DllExport VCMFAM : public VCTFAM {
virtual bool OpenTableFile(PGLOBAL g); virtual bool OpenTableFile(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc); virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g); virtual void CloseTableFile(PGLOBAL g, bool abort);
// Specific functions // Specific functions
virtual bool ReadBlock(PGLOBAL g, PVCTCOL colp); virtual bool ReadBlock(PGLOBAL g, PVCTCOL colp);
@@ -146,7 +147,7 @@ class DllExport VECFAM : public VCTFAM {
virtual bool OpenTableFile(PGLOBAL g); virtual bool OpenTableFile(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc); virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g); virtual void CloseTableFile(PGLOBAL g, bool abort);
// Specific functions // Specific functions
virtual bool ReadBlock(PGLOBAL g, PVCTCOL colp); virtual bool ReadBlock(PGLOBAL g, PVCTCOL colp);
@@ -156,7 +157,7 @@ class DllExport VECFAM : public VCTFAM {
virtual bool OpenTempFile(PGLOBAL g); virtual bool OpenTempFile(PGLOBAL g);
virtual bool MoveLines(PGLOBAL g); virtual bool MoveLines(PGLOBAL g);
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL); virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL);
virtual int RenameTempFile(PGLOBAL g); virtual int RenameTempFile(PGLOBAL g, bool abort);
bool OpenColumnFile(PGLOBAL g, char *opmode, int i); bool OpenColumnFile(PGLOBAL g, char *opmode, int i);
// Members // Members
@@ -190,7 +191,7 @@ class DllExport VMPFAM : public VCMFAM {
// Database routines // Database routines
virtual bool OpenTableFile(PGLOBAL g); virtual bool OpenTableFile(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc); virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g); virtual void CloseTableFile(PGLOBAL g, bool abort);
protected: protected:
bool MapColumnFile(PGLOBAL g, MODE mode, int i); bool MapColumnFile(PGLOBAL g, MODE mode, int i);
@@ -221,7 +222,7 @@ class BGVFAM : public VCTFAM {
virtual bool OpenTableFile(PGLOBAL g); virtual bool OpenTableFile(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc); virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g); virtual void CloseTableFile(PGLOBAL g, bool abort);
virtual void Rewind(void); virtual void Rewind(void);
// Specific functions // Specific functions

View File

@@ -386,7 +386,7 @@ int ZIPFAM::DeleteRecords(PGLOBAL g, int irc)
/***********************************************************************/ /***********************************************************************/
/* Data Base close routine for DOS access method. */ /* Data Base close routine for DOS access method. */
/***********************************************************************/ /***********************************************************************/
void ZIPFAM::CloseTableFile(PGLOBAL g) void ZIPFAM::CloseTableFile(PGLOBAL g, bool abort)
{ {
int rc = gzclose(Zfile); int rc = gzclose(Zfile);
@@ -456,9 +456,7 @@ int ZBKFAM::MaxBlkSize(PGLOBAL g, int s)
/***********************************************************************/ /***********************************************************************/
int ZBKFAM::Cardinality(PGLOBAL g) int ZBKFAM::Cardinality(PGLOBAL g)
{ {
// Should not be called in this version return (g) ? (int)((Block - 1) * Nrec + Last) : 1;
return (g) ? -1 : 0;
//return (g) ? (int)((Block - 1) * Nrec + Last) : 1;
} // end of Cardinality } // end of Cardinality
/***********************************************************************/ /***********************************************************************/
@@ -671,7 +669,7 @@ int ZBKFAM::DeleteRecords(PGLOBAL g, int irc)
/***********************************************************************/ /***********************************************************************/
/* Data Base close routine for ZBK access method. */ /* Data Base close routine for ZBK access method. */
/***********************************************************************/ /***********************************************************************/
void ZBKFAM::CloseTableFile(PGLOBAL g) void ZBKFAM::CloseTableFile(PGLOBAL g, bool abort)
{ {
int rc = RC_OK; int rc = RC_OK;
@@ -1328,7 +1326,7 @@ bool ZLBFAM::WriteCompressedBuffer(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
/* Table file close routine for DOS access method. */ /* Table file close routine for DOS access method. */
/***********************************************************************/ /***********************************************************************/
void ZLBFAM::CloseTableFile(PGLOBAL g) void ZLBFAM::CloseTableFile(PGLOBAL g, bool abort)
{ {
int rc = RC_OK; int rc = RC_OK;

View File

@@ -48,7 +48,7 @@ class DllExport ZIPFAM : public TXTFAM {
virtual int ReadBuffer(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc); virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g); virtual void CloseTableFile(PGLOBAL g, bool abort);
virtual void Rewind(void); virtual void Rewind(void);
protected: protected:
@@ -86,7 +86,7 @@ class DllExport ZBKFAM : public ZIPFAM {
virtual int ReadBuffer(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc); virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g); virtual void CloseTableFile(PGLOBAL g, bool abort);
virtual void Rewind(void); virtual void Rewind(void);
protected: protected:
@@ -152,7 +152,7 @@ class DllExport ZLBFAM : public BLKFAM {
virtual bool AllocateBuffer(PGLOBAL g); virtual bool AllocateBuffer(PGLOBAL g);
virtual int ReadBuffer(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g);
virtual void CloseTableFile(PGLOBAL g); virtual void CloseTableFile(PGLOBAL g, bool abort);
virtual void Rewind(void); virtual void Rewind(void);
protected: protected:

View File

@@ -108,7 +108,6 @@
#define MYSQL_SERVER 1 #define MYSQL_SERVER 1
#define DONT_DEFINE_VOID #define DONT_DEFINE_VOID
//#include "sql_partition.h"
#include "sql_class.h" #include "sql_class.h"
#include "create_options.h" #include "create_options.h"
#include "mysql_com.h" #include "mysql_com.h"
@@ -316,11 +315,12 @@ ha_create_table_option connect_field_option_list[]=
{ {
HA_FOPTION_NUMBER("FLAG", offset, (ulonglong) -1, 0, INT_MAX32, 1), HA_FOPTION_NUMBER("FLAG", offset, (ulonglong) -1, 0, INT_MAX32, 1),
HA_FOPTION_NUMBER("MAX_DIST", freq, 0, 0, INT_MAX32, 1), // BLK_INDX HA_FOPTION_NUMBER("MAX_DIST", freq, 0, 0, INT_MAX32, 1), // BLK_INDX
HA_FOPTION_NUMBER("DISTRIB", opt, 0, 0, 2, 1), // used for BLK_INDX //HA_FOPTION_NUMBER("DISTRIB", opt, 0, 0, 2, 1), // used for BLK_INDX
HA_FOPTION_NUMBER("FIELD_LENGTH", fldlen, 0, 0, INT_MAX32, 1), HA_FOPTION_NUMBER("FIELD_LENGTH", fldlen, 0, 0, INT_MAX32, 1),
HA_FOPTION_STRING("DATE_FORMAT", dateformat), HA_FOPTION_STRING("DATE_FORMAT", dateformat),
HA_FOPTION_STRING("FIELD_FORMAT", fieldformat), HA_FOPTION_STRING("FIELD_FORMAT", fieldformat),
HA_FOPTION_STRING("SPECIAL", special), HA_FOPTION_STRING("SPECIAL", special),
HA_FOPTION_ENUM("DISTRIB", opt, "scattered,clustered,sorted", 0),
HA_FOPTION_END HA_FOPTION_END
}; };
@@ -332,7 +332,6 @@ ha_create_table_option connect_field_option_list[]=
*/ */
ha_create_table_option connect_index_option_list[]= ha_create_table_option connect_index_option_list[]=
{ {
HA_IOPTION_BOOL("DYNAMIC", dynamic, 0),
HA_IOPTION_BOOL("DYNAM", dynamic, 0), HA_IOPTION_BOOL("DYNAM", dynamic, 0),
HA_IOPTION_BOOL("MAPPED", mapped, 0), HA_IOPTION_BOOL("MAPPED", mapped, 0),
HA_IOPTION_END HA_IOPTION_END
@@ -553,8 +552,12 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg)
stop= false; stop= false;
alter= false; alter= false;
mrr= false; mrr= false;
nox= false;
abort= false;
indexing= -1; indexing= -1;
only= -1;
locked= 0; locked= 0;
part_id= NULL;
data_file_name= NULL; data_file_name= NULL;
index_file_name= NULL; index_file_name= NULL;
enable_activate_all_index= 0; enable_activate_all_index= 0;
@@ -819,7 +822,17 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
char *opval= NULL; char *opval= NULL;
PTOS options= GetTableOptionStruct(); PTOS options= GetTableOptionStruct();
if (!options) if (!stricmp(opname, "Connect")) {
LEX_STRING cnc= (tshp) ? tshp->connect_string : table->s->connect_string;
if (cnc.length)
opval= cnc.str;
} else if (!stricmp(opname, "Query_String"))
opval= thd_query_string(table->in_use)->str;
else if (!stricmp(opname, "Partname"))
opval= partname;
else if (!options)
; ;
else if (!stricmp(opname, "Type")) else if (!stricmp(opname, "Type"))
opval= (char*)options->type; opval= (char*)options->type;
@@ -836,8 +849,6 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
opval= (char*)options->dbname; opval= (char*)options->dbname;
else if (!stricmp(opname, "Separator")) else if (!stricmp(opname, "Separator"))
opval= (char*)options->separator; opval= (char*)options->separator;
else if (!stricmp(opname, "Connect"))
opval= (tshp) ? tshp->connect_string.str : table->s->connect_string.str;
else if (!stricmp(opname, "Qchar")) else if (!stricmp(opname, "Qchar"))
opval= (char*)options->qchar; opval= (char*)options->qchar;
else if (!stricmp(opname, "Module")) else if (!stricmp(opname, "Module"))
@@ -852,8 +863,6 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
opval= (char*)options->colist; opval= (char*)options->colist;
else if (!stricmp(opname, "Data_charset")) else if (!stricmp(opname, "Data_charset"))
opval= (char*)options->data_charset; opval= (char*)options->data_charset;
else if (!stricmp(opname, "Query_String"))
opval= thd_query_string(table->in_use)->str;
if (!opval && options && options->oplist) if (!opval && options && options->oplist)
opval= GetListOption(xp->g, opname, options->oplist); opval= GetListOption(xp->g, opname, options->oplist);
@@ -1196,6 +1205,17 @@ bool ha_connect::GetIndexOption(KEY *kp, char *opname)
return opval; return opval;
} // end of GetIndexOption } // end of GetIndexOption
/****************************************************************************/
/* Returns the index description structure used to make the index. */
/****************************************************************************/
bool ha_connect::IsUnique(uint n)
{
TABLE_SHARE *s= (table) ? table->s : NULL;
KEY kp= s->key_info[n];
return (kp.flags & 1) != 0;
} // end of IsUnique
/****************************************************************************/ /****************************************************************************/
/* Returns the index description structure used to make the index. */ /* Returns the index description structure used to make the index. */
/****************************************************************************/ /****************************************************************************/
@@ -1280,6 +1300,7 @@ bool ha_connect::IsPartitioned(void)
return true; return true;
else else
return false; return false;
} // end of IsPartitioned } // end of IsPartitioned
const char *ha_connect::GetDBName(const char* name) const char *ha_connect::GetDBName(const char* name)
@@ -1365,7 +1386,7 @@ PTDB ha_connect::GetTDB(PGLOBAL g)
tp->SetMode(xmod); tp->SetMode(xmod);
} else if ((tp= CntGetTDB(g, table_name, xmod, this))) { } else if ((tp= CntGetTDB(g, table_name, xmod, this))) {
valid_query_id= xp->last_query_id; valid_query_id= xp->last_query_id;
tp->SetMode(xmod); // tp->SetMode(xmod);
} else } else
htrc("GetTDB: %s\n", g->Message); htrc("GetTDB: %s\n", g->Message);
@@ -1444,6 +1465,17 @@ int ha_connect::OpenTable(PGLOBAL g, bool del)
for (field= table->field; fp= *field; field++) for (field= table->field; fp= *field; field++)
if (bitmap_is_set(ump, fp->field_index)) { if (bitmap_is_set(ump, fp->field_index)) {
strcpy(p, (char*)fp->field_name); strcpy(p, (char*)fp->field_name);
if (part_id && bitmap_is_set(part_id, fp->field_index)) {
// Trying to update a column used for partitioning
// This cannot be currently done because it may require
// a row to be moved in another partition.
sprintf(g->Message,
"Cannot update column %s because it is used for partitioning",
p);
return HA_ERR_INTERNAL_ERROR;
} // endif part_id
p+= (strlen(p) + 1); p+= (strlen(p) + 1);
} // endif used field } // endif used field
@@ -1475,6 +1507,50 @@ int ha_connect::OpenTable(PGLOBAL g, bool del)
} // end of OpenTable } // end of OpenTable
/****************************************************************************/
/* CheckColumnList: check that all bitmap columns do exist. */
/****************************************************************************/
bool ha_connect::CheckColumnList(PGLOBAL g)
{
// Check the list of used fields (columns)
int rc;
bool brc= false;
PCOL colp;
Field* *field;
Field* fp;
MY_BITMAP *map= table->read_set;
// Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
return true;
} // endif jump_level
if ((rc= setjmp(g->jumper[++g->jump_level])) == 0) {
for (field= table->field; fp= *field; field++)
if (bitmap_is_set(map, fp->field_index)) {
if (!(colp= tdbp->ColDB(g, (PSZ)fp->field_name, 0))) {
sprintf(g->Message, "Column %s not found in %s",
fp->field_name, tdbp->GetName());
brc= true;
goto fin;
} // endif colp
if ((brc= colp->InitValue(g)))
goto fin;
colp->AddColUse(U_P); // For PLG tables
} // endif
} else
brc= true;
fin:
g->jump_level--;
return brc;
} // end of CheckColumnList
/****************************************************************************/ /****************************************************************************/
/* IsOpened: returns true if the table is already opened. */ /* IsOpened: returns true if the table is already opened. */
/****************************************************************************/ /****************************************************************************/
@@ -1490,12 +1566,15 @@ bool ha_connect::IsOpened(void)
/****************************************************************************/ /****************************************************************************/
int ha_connect::CloseTable(PGLOBAL g) int ha_connect::CloseTable(PGLOBAL g)
{ {
int rc= CntCloseTable(g, tdbp); int rc= CntCloseTable(g, tdbp, nox, abort);
tdbp= NULL; tdbp= NULL;
sdvalin=NULL; sdvalin=NULL;
sdvalout=NULL; sdvalout=NULL;
valid_info= false; valid_info= false;
indexing= -1; indexing= -1;
nox= false;
abort= false;
only= -1;
return rc; return rc;
} // end of CloseTable } // end of CloseTable
@@ -1623,6 +1702,11 @@ int ha_connect::MakeRecord(char *buf)
} // endfor field } // endfor field
// This is sometimes required for partition tables because the buf
// can be different from the table->record[0] buffer
if (buf != (char*)table->record[0])
memcpy(buf, table->record[0], table->s->stored_rec_length);
// This is copied from ha_tina and is necessary to avoid asserts // This is copied from ha_tina and is necessary to avoid asserts
dbug_tmp_restore_column_map(table->write_set, org_bitmap); dbug_tmp_restore_column_map(table->write_set, org_bitmap);
DBUG_RETURN(rc); DBUG_RETURN(rc);
@@ -1773,7 +1857,11 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, char *qry, OPVAL op, char *q,
KEY_PART_INFO *kpart; KEY_PART_INFO *kpart;
if (active_index == MAX_KEY) if (active_index == MAX_KEY)
return 0; return false;
else if (!key) {
strcpy(g->Message, "MakeKeyWhere: No key");
return true;
} // endif key
strcat(qry, " WHERE ("); strcat(qry, " WHERE (");
kfp= &table->key_info[active_index]; kfp= &table->key_info[active_index];
@@ -2448,6 +2536,21 @@ bool ha_connect::get_error_message(int error, String* buf)
DBUG_RETURN(false); DBUG_RETURN(false);
} // end of get_error_message } // end of get_error_message
/**
Convert a filename partition name to system
*/
static char *decode(PGLOBAL g, const char *pn)
{
char *buf= (char*)PlugSubAlloc(g, NULL, strlen(pn) + 1);
uint dummy_errors;
uint32 len= copy_and_convert(buf, strlen(pn) + 1,
system_charset_info,
pn, strlen(pn),
&my_charset_filename,
&dummy_errors);
buf[len]= '\0';
return buf;
} // end of decode
/** /**
@brief @brief
@@ -2499,11 +2602,14 @@ int ha_connect::open(const char *name, int mode, uint test_if_locked)
#if defined(WITH_PARTITION_STORAGE_ENGINE) #if defined(WITH_PARTITION_STORAGE_ENGINE)
if (table->part_info) { if (table->part_info) {
if (GetStringOption("Filename") || GetStringOption("Tabname")) if (GetStringOption("Filename") || GetStringOption("Tabname")
strcpy(partname, strrchr(name, '#') + 1); || GetStringOption("Connect")) {
else // Inward table strcpy(partname, decode(g, strrchr(name, '#') + 1));
// strcpy(partname, table->part_info->curr_part_elem->partition_name);
part_id= &table->part_info->full_part_field_set;
} else // Inward table
strcpy(partname, strrchr(name, slash) + 1); strcpy(partname, strrchr(name, slash) + 1);
part_id= &table->part_info->full_part_field_set; // Temporary
} // endif part_info } // endif part_info
#endif // WITH_PARTITION_STORAGE_ENGINE #endif // WITH_PARTITION_STORAGE_ENGINE
} else } else
@@ -2610,8 +2716,13 @@ int ha_connect::write_row(uchar *buf)
DBUG_ENTER("ha_connect::write_row"); DBUG_ENTER("ha_connect::write_row");
// This is not tested yet // This is not tested yet
if (xmod == MODE_ALTER) if (xmod == MODE_ALTER) {
if (IsPartitioned() && GetStringOption("Filename", NULL))
// Why does this happen now that check_if_supported_inplace_alter is called?
DBUG_RETURN(0); // Alter table on an outward partition table
xmod= MODE_INSERT; xmod= MODE_INSERT;
} // endif xmod
// Open the table if it was not opened yet (locked) // Open the table if it was not opened yet (locked)
if (!IsOpened() || xmod != tdbp->GetMode()) { if (!IsOpened() || xmod != tdbp->GetMode()) {
@@ -2684,7 +2795,7 @@ int ha_connect::update_row(const uchar *old_data, uchar *new_data)
// Check values for possible change in indexed column // Check values for possible change in indexed column
if ((rc= CheckRecord(g, old_data, new_data))) if ((rc= CheckRecord(g, old_data, new_data)))
return rc; DBUG_RETURN(rc);
if (CntUpdateRow(g, tdbp)) { if (CntUpdateRow(g, tdbp)) {
DBUG_PRINT("update_row", ("%s", g->Message)); DBUG_PRINT("update_row", ("%s", g->Message));
@@ -2742,12 +2853,19 @@ int ha_connect::index_init(uint idx, bool sorted)
htrc("index_init: this=%p idx=%u sorted=%d\n", this, idx, sorted); htrc("index_init: this=%p idx=%u sorted=%d\n", this, idx, sorted);
if (GetIndexType(GetRealType()) == 2) { if (GetIndexType(GetRealType()) == 2) {
if (xmod == MODE_READ)
// This is a remote index // This is a remote index
xmod= MODE_READX; xmod= MODE_READX;
if (!(rc= rnd_init(0))) { if (!(rc= rnd_init(0))) {
if (xmod == MODE_READX) {
active_index= idx; active_index= idx;
indexing= 2; // TO DO: mul? indexing= IsUnique(idx) ? 1 : 2;
} else {
active_index= MAX_KEY;
indexing= 0;
} // endif xmod
} //endif rc } //endif rc
DBUG_RETURN(rc); DBUG_RETURN(rc);
@@ -2756,11 +2874,17 @@ int ha_connect::index_init(uint idx, bool sorted)
if ((rc= rnd_init(0))) if ((rc= rnd_init(0)))
DBUG_RETURN(rc); DBUG_RETURN(rc);
if (locked == 2) { if ((xmod == MODE_UPDATE && ((TDBASE*)tdbp)->IsUsingTemp(g)) ||
xmod == MODE_DELETE || locked == 2) {
// Indexes are not updated in lock write mode // Indexes are not updated in lock write mode
// and cannot be used for DELETE or UPDATE using temp file.
if (locked == 2 || xmod == MODE_DELETE || !IsUnique(idx)) {
active_index= MAX_KEY; active_index= MAX_KEY;
indexing= 0; indexing= 0;
DBUG_RETURN(0); DBUG_RETURN(0);
} else
only= 1; // Indexing acceptable for only one value
} // endif locked } // endif locked
indexing= CntIndexInit(g, tdbp, (signed)idx); indexing= CntIndexInit(g, tdbp, (signed)idx);
@@ -2874,10 +2998,16 @@ int ha_connect::index_read(uchar * buf, const uchar * key, uint key_len,
if (xtrace > 1) if (xtrace > 1)
htrc("%p index_read: op=%d\n", this, op); htrc("%p index_read: op=%d\n", this, op);
if (indexing > 0) if ((indexing > 0 && (only < 0 || (only == 1 && op == OP_EQ)))
|| GetIndexType(GetRealType()) == 2) {
rc= ReadIndexed(buf, op, key, key_len); rc= ReadIndexed(buf, op, key, key_len);
else only= (only == 1) ? 0 : -1;
rc= HA_ERR_INTERNAL_ERROR; } else {
nox= true; // To block making indexes
abort= true; // Don't rename temp file
strcpy(xp->g->Message, "Cannot use indexing for this command");
rc= HA_ERR_INTERNAL_ERROR; // HA_ERR_KEY_NOT_FOUND ?
} // endelse
DBUG_RETURN(rc); DBUG_RETURN(rc);
} // end of index_read } // end of index_read
@@ -3032,6 +3162,10 @@ int ha_connect::rnd_init(bool scan)
// Do not close the table if it was opened yet (locked?) // Do not close the table if it was opened yet (locked?)
if (IsOpened()) { if (IsOpened()) {
if (IsPartitioned() && xmod != MODE_INSERT)
if (CheckColumnList(g)) // map can have been changed
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
if (tdbp->OpenDB(g)) // Rewind table if (tdbp->OpenDB(g)) // Rewind table
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
else else
@@ -3260,7 +3394,6 @@ int ha_connect::info(uint flag)
if (xtrace) if (xtrace)
htrc("%p In info: flag=%u valid_info=%d\n", this, flag, valid_info); htrc("%p In info: flag=%u valid_info=%d\n", this, flag, valid_info);
if (!valid_info) {
// tdbp must be available to get updated info // tdbp must be available to get updated info
if (xp->CheckQuery(valid_query_id) || !tdbp) { if (xp->CheckQuery(valid_query_id) || !tdbp) {
PDBUSER dup= PlgGetUser(g); PDBUSER dup= PlgGetUser(g);
@@ -3278,9 +3411,13 @@ int ha_connect::info(uint flag)
else else
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen
tdbp= GetTDB(g); if (!(tdbp= GetTDB(g)))
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen
valid_info = false;
} // endif tdbp } // endif tdbp
if (!valid_info) {
valid_info= CntInfo(g, tdbp, &xinfo); valid_info= CntInfo(g, tdbp, &xinfo);
if (((signed)xinfo.records) < 0) if (((signed)xinfo.records) < 0)
@@ -3532,11 +3669,6 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
case SQLCOM_RENAME_TABLE: case SQLCOM_RENAME_TABLE:
newmode= MODE_ANY; newmode= MODE_ANY;
break; break;
case SQLCOM_DROP_INDEX:
case SQLCOM_CREATE_INDEX:
newmode= MODE_ANY;
// stop= true;
break;
case SQLCOM_CREATE_VIEW: case SQLCOM_CREATE_VIEW:
case SQLCOM_DROP_VIEW: case SQLCOM_DROP_VIEW:
newmode= MODE_ANY; newmode= MODE_ANY;
@@ -3544,6 +3676,13 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
case SQLCOM_ALTER_TABLE: case SQLCOM_ALTER_TABLE:
newmode= MODE_ALTER; newmode= MODE_ALTER;
break; break;
case SQLCOM_DROP_INDEX:
case SQLCOM_CREATE_INDEX:
// if (!IsPartitioned()) {
newmode= MODE_ANY;
break;
// } // endif partitioned
default: default:
htrc("Unsupported sql_command=%d\n", thd_sql_command(thd)); htrc("Unsupported sql_command=%d\n", thd_sql_command(thd));
strcpy(g->Message, "CONNECT Unsupported command"); strcpy(g->Message, "CONNECT Unsupported command");
@@ -3573,10 +3712,6 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
case SQLCOM_LOCK_TABLES: case SQLCOM_LOCK_TABLES:
locked= 1; locked= 1;
break; break;
case SQLCOM_DROP_INDEX:
case SQLCOM_CREATE_INDEX:
*chk= true;
// stop= true;
case SQLCOM_DROP_TABLE: case SQLCOM_DROP_TABLE:
case SQLCOM_RENAME_TABLE: case SQLCOM_RENAME_TABLE:
newmode= MODE_ANY; newmode= MODE_ANY;
@@ -3589,6 +3724,14 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
*chk= true; *chk= true;
newmode= MODE_ALTER; newmode= MODE_ALTER;
break; break;
case SQLCOM_DROP_INDEX:
case SQLCOM_CREATE_INDEX:
// if (!IsPartitioned()) {
*chk= true;
newmode= MODE_ANY;
break;
// } // endif partitioned
default: default:
htrc("Unsupported sql_command=%d\n", thd_sql_command(thd)); htrc("Unsupported sql_command=%d\n", thd_sql_command(thd));
strcpy(g->Message, "CONNECT Unsupported command"); strcpy(g->Message, "CONNECT Unsupported command");
@@ -3809,6 +3952,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
} // endif Close } // endif Close
locked= 0; locked= 0;
xmod= MODE_ANY; // For info commands
DBUG_RETURN(rc); DBUG_RETURN(rc);
} // endif MODE_ANY } // endif MODE_ANY
@@ -4128,7 +4272,7 @@ ha_rows ha_connect::records_in_range(uint inx, key_range *min_key,
if (xtrace) if (xtrace)
htrc("records_in_range: inx=%d indexing=%d\n", inx, indexing); htrc("records_in_range: inx=%d indexing=%d\n", inx, indexing);
if (indexing > 0) { if (indexing > 0 && only < 0) {
int nval; int nval;
uint len[2]; uint len[2];
const uchar *key[2]; const uchar *key[2];
@@ -4149,10 +4293,11 @@ ha_rows ha_connect::records_in_range(uint inx, key_range *min_key,
else else
rows= (ha_rows)nval; rows= (ha_rows)nval;
} else if (indexing < 0) } else if (indexing == 0) {
rows= HA_POS_ERROR;
else
rows= 100000000; // Don't use missing index rows= 100000000; // Don't use missing index
only= -1;
} else
rows= HA_POS_ERROR;
DBUG_RETURN(rows); DBUG_RETURN(rows);
} // end of records_in_range } // end of records_in_range
@@ -4160,7 +4305,7 @@ ha_rows ha_connect::records_in_range(uint inx, key_range *min_key,
/** /**
Convert an ISO-8859-1 column name to UTF-8 Convert an ISO-8859-1 column name to UTF-8
*/ */
static char *encode(PGLOBAL g, char *cnm) static char *encode(PGLOBAL g, const char *cnm)
{ {
char *buf= (char*)PlugSubAlloc(g, NULL, strlen(cnm) * 3); char *buf= (char*)PlugSubAlloc(g, NULL, strlen(cnm) * 3);
uint dummy_errors; uint dummy_errors;
@@ -4171,7 +4316,7 @@ static char *encode(PGLOBAL g, char *cnm)
&dummy_errors); &dummy_errors);
buf[len]= '\0'; buf[len]= '\0';
return buf; return buf;
} // end of Encode } // end of encode
/** /**
Store field definition for create. Store field definition for create.
@@ -4547,7 +4692,7 @@ static void add_option(THD* thd, HA_CREATE_INFO *create_info,
} // end of add_option } // end of add_option
// Used to check whether a MYSQL table is created on itself // Used to check whether a MYSQL table is created on itself
static bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host, bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host,
const char *db, char *tab, const char *src, int port) const char *db, char *tab, const char *src, int port)
{ {
if (src) if (src)
@@ -5129,7 +5274,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
HA_CREATE_INFO *create_info) HA_CREATE_INFO *create_info)
{ {
int rc= RC_OK; int rc= RC_OK;
bool dbf; bool dbf, inward;
Field* *field; Field* *field;
Field *fp; Field *fp;
TABTYPE type; TABTYPE type;
@@ -5144,7 +5289,6 @@ int ha_connect::create(const char *name, TABLE *table_arg,
DBUG_ENTER("ha_connect::create"); DBUG_ENTER("ha_connect::create");
int sqlcom= thd_sql_command(table_arg->in_use); int sqlcom= thd_sql_command(table_arg->in_use);
PTOS options= GetTableOptionStruct(table_arg->s); PTOS options= GetTableOptionStruct(table_arg->s);
bool inward= !options->filename;
table= table_arg; // Used by called functions table= table_arg; // Used by called functions
@@ -5175,6 +5319,8 @@ int ha_connect::create(const char *name, TABLE *table_arg,
if (check_privileges(thd, options, GetDBfromName(name))) if (check_privileges(thd, options, GetDBfromName(name)))
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
inward= IsFileType(type) && !options->filename;
if (options->data_charset) { if (options->data_charset) {
const CHARSET_INFO *data_charset; const CHARSET_INFO *data_charset;
@@ -5226,6 +5372,9 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endif tabname } // endif tabname
case TAB_MYSQL: case TAB_MYSQL:
#if defined(WITH_PARTITION_STORAGE_ENGINE)
if (!part_info)
#endif // WITH_PARTITION_STORAGE_ENGINE
{const char *src= options->srcdef; {const char *src= options->srcdef;
char *host, *db, *tab= (char*)options->tabname; char *host, *db, *tab= (char*)options->tabname;
int port; int port;
@@ -5419,8 +5568,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
} // endfor field } // endfor field
if ((sqlcom == SQLCOM_CREATE_TABLE || *GetTableName() == '#') if ((sqlcom == SQLCOM_CREATE_TABLE || *GetTableName() == '#') && inward) {
&& IsFileType(type) && inward) {
// The file name is not specified, create a default file in // The file name is not specified, create a default file in
// the database directory named table_name.table_type. // the database directory named table_name.table_type.
// (temporarily not done for XML because a void file causes // (temporarily not done for XML because a void file causes
@@ -5504,19 +5652,32 @@ int ha_connect::create(const char *name, TABLE *table_arg,
// We should be in CREATE TABLE, ALTER_TABLE or CREATE INDEX // We should be in CREATE TABLE, ALTER_TABLE or CREATE INDEX
if (!(sqlcom == SQLCOM_CREATE_TABLE || sqlcom == SQLCOM_ALTER_TABLE || if (!(sqlcom == SQLCOM_CREATE_TABLE || sqlcom == SQLCOM_ALTER_TABLE ||
(sqlcom == SQLCOM_CREATE_INDEX && part_info) || sqlcom == SQLCOM_CREATE_INDEX || sqlcom == SQLCOM_DROP_INDEX))
(sqlcom == SQLCOM_DROP_INDEX && part_info))) // (sqlcom == SQLCOM_CREATE_INDEX && part_info) ||
// (sqlcom == SQLCOM_DROP_INDEX && part_info)))
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0,
"Unexpected command in create, please contact CONNECT team"); "Unexpected command in create, please contact CONNECT team");
if (sqlcom == SQLCOM_ALTER_TABLE && g->Alchecked == 0 && #if defined(WITH_PARTITION_STORAGE_ENGINE)
if (part_info && !inward)
strcpy(partname, decode(g, strrchr(name, '#') + 1));
// strcpy(partname, part_info->curr_part_elem->partition_name);
#endif // WITH_PARTITION_STORAGE_ENGINE
if (g->Alchecked == 0 &&
(!IsFileType(type) || FileExists(options->filename))) { (!IsFileType(type) || FileExists(options->filename))) {
if (part_info) {
sprintf(g->Message, "Data repartition in %s is unchecked", partname);
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
} else if (sqlcom == SQLCOM_ALTER_TABLE) {
// This is an ALTER to CONNECT from another engine. // This is an ALTER to CONNECT from another engine.
// It cannot be accepted because the table data would be lost // It cannot be accepted because the table data would be modified
// except when the target file does not exist. // except when the target file does not exist.
strcpy(g->Message, "Operation denied. Table data would be lost."); strcpy(g->Message, "Operation denied. Table data would be modified.");
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
} // endif part_info
} // endif outward } // endif outward
// Get the index definitions // Get the index definitions
@@ -5581,7 +5742,8 @@ bool ha_connect::FileExists(const char *fn)
return false; return false;
if (table) { if (table) {
char *s, filename[_MAX_PATH], path[128]; char *s, tfn[_MAX_PATH], filename[_MAX_PATH], path[128];
bool b= false;
int n; int n;
struct stat info; struct stat info;
@@ -5594,9 +5756,18 @@ bool ha_connect::FileExists(const char *fn)
#else // !WIN32 #else // !WIN32
s= "/"; s= "/";
#endif // !WIN32 #endif // !WIN32
if (IsPartitioned()) {
sprintf(tfn, fn, GetPartName());
// This is to avoid an initialization error raised by the
// test on check_table_flags made in ha_partition::open
// that can fail if some partition files are empty.
b= true;
} else
strcpy(tfn, fn);
strcat(strcat(strcat(strcpy(path, "."), s), table->s->db.str), s); strcat(strcat(strcat(strcpy(path, "."), s), table->s->db.str), s);
PlugSetPath(filename, fn, path); PlugSetPath(filename, tfn, path);
n= stat(filename, &info); n= stat(filename, &info);
if (n < 0) { if (n < 0) {
@@ -5610,7 +5781,7 @@ bool ha_connect::FileExists(const char *fn)
return false; return false;
} else } else
return (info.st_size) ? true : false; return (info.st_size || b) ? true : false;
} // endif table } // endif table

View File

@@ -124,8 +124,8 @@ struct ha_field_option_struct
{ {
ulonglong offset; ulonglong offset;
ulonglong freq; ulonglong freq;
ulonglong opt;
ulonglong fldlen; ulonglong fldlen;
uint opt;
const char *dateformat; const char *dateformat;
const char *fieldformat; const char *fieldformat;
char *special; char *special;
@@ -208,9 +208,11 @@ public:
TABLE *GetTable(void) {return table;} TABLE *GetTable(void) {return table;}
bool IsSameIndex(PIXDEF xp1, PIXDEF xp2); bool IsSameIndex(PIXDEF xp1, PIXDEF xp2);
bool IsPartitioned(void); bool IsPartitioned(void);
bool IsUnique(uint n);
PTDB GetTDB(PGLOBAL g); PTDB GetTDB(PGLOBAL g);
int OpenTable(PGLOBAL g, bool del= false); int OpenTable(PGLOBAL g, bool del= false);
bool CheckColumnList(PGLOBAL g);
bool IsOpened(void); bool IsOpened(void);
int CloseTable(PGLOBAL g); int CloseTable(PGLOBAL g);
int MakeRecord(char *buf); int MakeRecord(char *buf);
@@ -529,8 +531,12 @@ protected:
bool stop; // Used when creating index bool stop; // Used when creating index
bool alter; // True when converting to other engine bool alter; // True when converting to other engine
bool mrr; // True when getting index positions bool mrr; // True when getting index positions
bool nox; // True when index should not be made
bool abort; // True after error in UPDATE/DELETE
int indexing; // Type of indexing for CONNECT int indexing; // Type of indexing for CONNECT
int only; // If only one action is accepted
int locked; // Table lock int locked; // Table lock
MY_BITMAP *part_id; // Columns used for partition func
THR_LOCK_DATA lock_data; THR_LOCK_DATA lock_data;
public: public:

View File

@@ -571,6 +571,7 @@ PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type)
tdbp->GetAmType()); tdbp->GetAmType());
tablep->SetTo_Tdb(tdbp); tablep->SetTo_Tdb(tdbp);
tdbp->SetTable(tablep); tdbp->SetTable(tablep);
tdbp->SetMode(mode);
} // endif tdbp } // endif tdbp
return (tdbp); return (tdbp);

View File

@@ -693,6 +693,35 @@ if (w)
return rc; return rc;
} // end of ExecSQL } // end of ExecSQL
/***********************************************************************/
/* Get table size by executing "select count(*) from table_name". */
/***********************************************************************/
int MYSQLC::GetTableSize(PGLOBAL g, PSZ query)
{
if (mysql_real_query(m_DB, query, strlen(query))) {
#if defined(_DEBUG)
char *msg = (char*)PlugSubAlloc(g, NULL, 512 + strlen(query));
sprintf(msg, "(%d) %s [%s]", mysql_errno(m_DB),
mysql_error(m_DB), query);
strncpy(g->Message, msg, sizeof(g->Message) - 1);
g->Message[sizeof(g->Message) - 1] = 0;
#endif // _DEBUG
return -2;
} // endif mysql_real_query
if (!(m_Res = mysql_store_result(m_DB)))
return -3;
// Get the resulting count value
m_Rows = (int)mysql_num_rows(m_Res); // Should be 1
if (m_Rows && (m_Row = mysql_fetch_row(m_Res)))
return atoi(*m_Row);
return -4;
} // end of GetTableSize
/***********************************************************************/ /***********************************************************************/
/* Move to a specific row and column */ /* Move to a specific row and column */
/***********************************************************************/ /***********************************************************************/

View File

@@ -64,6 +64,7 @@ class DllItem MYSQLC {
// Methods // Methods
int GetResultSize(PGLOBAL g, PSZ sql); int GetResultSize(PGLOBAL g, PSZ sql);
int GetTableSize(PGLOBAL g, PSZ query);
int Open(PGLOBAL g, const char *host, const char *db, int Open(PGLOBAL g, const char *host, const char *db,
const char *user= "root", const char *pwd= "*", const char *user= "root", const char *pwd= "*",
int pt= 0); int pt= 0);

View File

@@ -0,0 +1,355 @@
# This will be used to see what data files are created
CREATE TABLE dr1 (
FNAME VARCHAR(256) NOT NULL FLAG=2,
FTYPE CHAR(8) NOT NULL FLAG=3
# ,FSIZE INT(6) NOT NULL FLAG=5 removed because Unix size != Windows size
) engine=CONNECT table_type=DIR file_name='t1#P#*.*';
#
# Testing partitioning on inward table
#
CREATE TABLE t1 (
id INT NOT NULL,
msg VARCHAR(32)
) ENGINE=CONNECT TABLE_TYPE=CSV
PARTITION BY RANGE(id) (
PARTITION first VALUES LESS THAN(10),
PARTITION middle VALUES LESS THAN(50),
PARTITION last VALUES LESS THAN(MAXVALUE));
INSERT INTO t1 VALUES(4, 'four'),(24, 'twenty four');
INSERT INTO t1 VALUES(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one');
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
partition_name table_rows
first 2
middle 3
last 2
SELECT * FROM t1;
id msg
4 four
7 seven
24 twenty four
10 ten
40 forty
60 sixty
81 eighty one
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id > 50;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 last ALL NULL NULL NULL NULL 13 Using where
SELECT * FROM t1 WHERE id > 50;
id msg
60 sixty
81 eighty one
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 CONNECT 10 Dynamic 7 10 76 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned `TABLE_TYPE`=CSV
UPDATE t1 set id = 41 WHERE msg = 'four';
ERROR HY000: Got error 174 'Cannot update column id because it is used for partitioning' from CONNECT
UPDATE t1 set msg = 'quatre' WHERE id = 4;
SELECT * FROM dr1;
FNAME FTYPE
t1#P#first .csv
t1#P#last .csv
t1#P#middle .csv
#
# Altering partitioning on inward table
#
ALTER TABLE t1
PARTITION by range(id) (
PARTITION first VALUES LESS THAN(11),
PARTITION middle VALUES LESS THAN(50),
PARTITION last VALUES LESS THAN(MAXVALUE));
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
partition_name table_rows
first 3
middle 2
last 2
SELECT * FROM dr1;
FNAME FTYPE
t1#P#first .csv
t1#P#last .csv
t1#P#middle .csv
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id=10;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 first ALL NULL NULL NULL NULL 14 Using where
SELECT * FROM t1 WHERE id=10;
id msg
10 ten
DELETE FROM t1 WHERE id in (4,60);
SELECT * FROM t1;
id msg
7 seven
10 ten
24 twenty four
40 forty
81 eighty one
DROP TABLE t1;
SELECT * FROM dr1;
FNAME FTYPE
#
# Testing partitioning on a void outward table
#
ALTER TABLE dr1 file_name='part*.*';
Warnings:
Warning 1105 This is an outward table, table data were not modified.
CREATE TABLE t1 (
rwid INT(6) DEFAULT 0 SPECIAL=ROWID,
rnum INT(6) DEFAULT 0 SPECIAL=ROWNUM,
prtn VARCHAR(64) DEFAULT '' SPECIAL=PARTID,
tbn VARCHAR(64) DEFAULT '' SPECIAL=TABID,
fid VARCHAR(256) DEFAULT '' SPECIAL=FNAME,
id INT KEY NOT NULL,
msg VARCHAR(32)
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='part%s.txt';
ALTER TABLE t1
PARTITION by range columns(id) (
PARTITION `1` VALUES LESS THAN(10),
PARTITION `2` VALUES LESS THAN(50),
PARTITION `3` VALUES LESS THAN(MAXVALUE));
Warnings:
Warning 1105 Open(rb) error 2 on DATADIR/test/part%s.txt: No such file or directory
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 0 PRIMARY 1 id A NULL NULL NULL XINDEX
SELECT * FROM dr1;
FNAME FTYPE
INSERT INTO t1(id,msg) VALUES(4, 'four');
SELECT * FROM dr1;
FNAME FTYPE
part1 .fnx
part1 .txt
INSERT INTO t1(id,msg) VALUES(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one');
INSERT INTO t1(id,msg) VALUES(72,'seventy two'),(20,'twenty'),(1,'one'),(35,'thirty five'),(8,'eight');
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
partition_name table_rows
1 4
2 4
3 3
SELECT * FROM t1;
rwid rnum prtn tbn fid id msg
1 1 1 t1 part1 4 four
2 2 1 t1 part1 7 seven
3 3 1 t1 part1 1 one
4 4 1 t1 part1 8 eight
1 1 2 t1 part2 10 ten
2 2 2 t1 part2 40 forty
3 3 2 t1 part2 20 twenty
4 4 2 t1 part2 35 thirty five
1 1 3 t1 part3 60 sixty
2 2 3 t1 part3 81 eighty one
3 3 3 t1 part3 72 seventy two
SELECT * FROM t1 order by id;
rwid rnum prtn tbn fid id msg
3 3 1 t1 part1 1 one
1 1 1 t1 part1 4 four
2 2 1 t1 part1 7 seven
4 4 1 t1 part1 8 eight
1 1 2 t1 part2 10 ten
3 3 2 t1 part2 20 twenty
4 4 2 t1 part2 35 thirty five
2 2 2 t1 part2 40 forty
1 1 3 t1 part3 60 sixty
3 3 3 t1 part3 72 seventy two
2 2 3 t1 part3 81 eighty one
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id = 10;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 2 const PRIMARY PRIMARY 4 const 1
SELECT * FROM t1 WHERE id = 10;
rwid rnum prtn tbn fid id msg
1 1 2 t1 part2 10 ten
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id >= 10;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 2,3 range PRIMARY PRIMARY 4 NULL 7 Using where
SELECT * FROM t1 WHERE id >= 10;
rwid rnum prtn tbn fid id msg
1 1 2 t1 part2 10 ten
3 3 2 t1 part2 20 twenty
4 4 2 t1 part2 35 thirty five
2 2 2 t1 part2 40 forty
1 1 3 t1 part3 60 sixty
3 3 3 t1 part3 72 seventy two
2 2 3 t1 part3 81 eighty one
SELECT count(*) FROM t1 WHERE id < 10;
count(*)
4
SELECT case when id < 10 then 1 when id < 50 then 2 else 3 end as pn, count(*) FROM t1 group by pn;
pn count(*)
1 4
2 4
3 3
SELECT prtn, count(*) FROM t1 group by prtn;
prtn count(*)
1 4
2 4
3 3
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id > 50;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 3 range PRIMARY PRIMARY 4 NULL 3 Using where
SELECT * FROM t1 WHERE id = 35;
rwid rnum prtn tbn fid id msg
4 4 2 t1 part2 35 thirty five
SELECT * FROM dr1;
FNAME FTYPE
part1 .fnx
part1 .txt
part2 .fnx
part2 .txt
part3 .fnx
part3 .txt
# This does not change the partition file data and is WRONG
ALTER TABLE t1
PARTITION by range columns(id) (
PARTITION `1` VALUES LESS THAN(11),
PARTITION `2` VALUES LESS THAN(70),
PARTITION `3` VALUES LESS THAN(MAXVALUE));
Warnings:
Warning 1105 Data repartition in 1 is unchecked
Warning 1105 Data repartition in 2 is unchecked
Warning 1105 Data repartition in 3 is unchecked
SELECT CASE WHEN id < 11 THEN 1 WHEN id < 70 THEN 2 ELSE 3 END AS pn, COUNT(*) FROM t1 GROUP BY pn;
pn COUNT(*)
1 5
2 4
3 2
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
partition_name table_rows
1 4
2 4
3 3
SELECT * FROM dr1;
FNAME FTYPE
part1 .fnx
part1 .txt
part2 .fnx
part2 .txt
part3 .fnx
part3 .txt
#
# This is the correct way to change partitioning:
# Save table values, erase the table, then re-insert saved values in modified table
#
CREATE TABLE t2 (
id INT NOT NULL,
msg VARCHAR(32)
) ENGINE=CONNECT TABLE_TYPE=FIX;
Warnings:
Warning 1105 No file name. Table will use t2.fix
INSERT INTO t2 SELECT id, msg FROM t1;
DELETE FROM t1;
INSERT INTO t1(id,msg) SELECT * FROM t2;
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
partition_name table_rows
1 5
2 4
3 2
SELECT * FROM t1;
rwid rnum prtn tbn fid id msg
1 1 1 t1 part1 4 four
2 2 1 t1 part1 7 seven
3 3 1 t1 part1 1 one
4 4 1 t1 part1 8 eight
5 5 1 t1 part1 10 ten
1 1 2 t1 part2 40 forty
2 2 2 t1 part2 20 twenty
3 3 2 t1 part2 35 thirty five
4 4 2 t1 part2 60 sixty
1 1 3 t1 part3 81 eighty one
2 2 3 t1 part3 72 seventy two
SELECT * FROM dr1;
FNAME FTYPE
part1 .fnx
part1 .txt
part2 .fnx
part2 .txt
part3 .fnx
part3 .txt
DROP TABLE t2;
DROP TABLE t1;
#
# Testing partitioning on a populated outward table
#
CREATE TABLE t1 (
id INT NOT NULL,
msg VARCHAR(32)
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='part%s.txt'
PARTITION by range columns(id) (
PARTITION `1` VALUES LESS THAN(11),
PARTITION `2` VALUES LESS THAN(70),
PARTITION `3` VALUES LESS THAN(MAXVALUE));
Warnings:
Warning 1105 Data repartition in 1 is unchecked
Warning 1105 Data repartition in 2 is unchecked
Warning 1105 Data repartition in 3 is unchecked
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
partition_name table_rows
1 5
2 4
3 2
SELECT * FROM t1 WHERE id < 11;
id msg
4 four
7 seven
1 one
8 eight
10 ten
SELECT * FROM t1 WHERE id >= 70;
id msg
81 eighty one
72 seventy two
SELECT * FROM dr1;
FNAME FTYPE
part1 .fnx
part1 .txt
part2 .fnx
part2 .txt
part3 .fnx
part3 .txt
#
# Testing indexing on a partitioned table
#
CREATE INDEX XID ON t1(id);
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 1 XID 1 id A NULL NULL NULL XINDEX
SELECT * FROM dr1;
FNAME FTYPE
part1 .fnx
part1 .txt
part2 .fnx
part2 .txt
part3 .fnx
part3 .txt
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id = 10;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 1 ref XID XID 4 const 1
DROP INDEX XID ON t1;
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
SELECT * FROM dr1;
FNAME FTYPE
part1 .txt
part2 .txt
part3 .txt
ALTER TABLE t1 ADD PRIMARY KEY (id);
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 0 PRIMARY 1 id A NULL NULL NULL XINDEX
SELECT * FROM dr1;
FNAME FTYPE
part1 .fnx
part1 .txt
part2 .fnx
part2 .txt
part3 .fnx
part3 .txt
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id = 10;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 1 const PRIMARY PRIMARY 4 const 1
ALTER TABLE t1 DROP PRIMARY KEY;
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
SELECT * FROM dr1;
FNAME FTYPE
part1 .txt
part2 .txt
part3 .txt
DROP TABLE t1;
DROP TABLE dr1;

View File

@@ -0,0 +1,180 @@
CREATE TABLE xt1 (
id INT KEY NOT NULL,
msg VARCHAR(32))
ENGINE=MyISAM;
INSERT INTO xt1 VALUES(4, 'four'),(7,'seven'),(1,'one'),(8,'eight');
SELECT * FROM xt1;
id msg
4 four
7 seven
1 one
8 eight
CREATE TABLE xt2 (
id INT KEY NOT NULL,
msg VARCHAR(32));
INSERT INTO xt2 VALUES(10,'ten'),(40,'forty'),(11,'eleven'),(35,'thirty five');
SELECT * FROM xt2;
id msg
10 ten
40 forty
11 eleven
35 thirty five
CREATE TABLE xt3 (
id INT KEY NOT NULL,
msg VARCHAR(32))
ENGINE=CONNECT TABLE_TYPE=CSV;
Warnings:
Warning 1105 No file name. Table will use xt3.csv
INSERT INTO xt3 VALUES(60,'sixty'),(81,'eighty one'),(72,'seventy two');
SELECT * FROM xt3;
id msg
60 sixty
81 eighty one
72 seventy two
CREATE TABLE t1 (
id INT NOT NULL,
msg VARCHAR(32))
ENGINE=CONNECT TABLE_TYPE=PROXY TABNAME='xt%s'
PARTITION BY RANGE COLUMNS(id) (
PARTITION `1` VALUES LESS THAN(10),
PARTITION `2` VALUES LESS THAN(50),
PARTITION `3` VALUES LESS THAN(MAXVALUE));
Warnings:
Warning 1105 Data repartition in 1 is unchecked
Warning 1105 Data repartition in 2 is unchecked
Warning 1105 Data repartition in 3 is unchecked
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
partition_name table_rows
1 4
2 4
3 3
SELECT * FROM t1;
id msg
4 four
7 seven
1 one
8 eight
10 ten
40 forty
11 eleven
35 thirty five
60 sixty
81 eighty one
72 seventy two
DELETE FROM t1;
Warnings:
Note 1105 xt1: 4 affected rows
Note 1105 xt2: 4 affected rows
ALTER TABLE t1 ADD INDEX XID(id);
ERROR HY000: Table type PROXY is not indexable
INSERT INTO t1 VALUES(4, 'four');
INSERT INTO t1 VALUES(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one');
INSERT INTO t1 VALUES(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight');
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
partition_name table_rows
1 4
2 4
3 3
SELECT * FROM t1;
id msg
4 four
7 seven
1 one
8 eight
10 ten
40 forty
11 eleven
35 thirty five
60 sixty
81 eighty one
72 seventy two
EXPLAIN PARTITIONS
SELECT * FROM t1 WHERE id = 81;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 3 ALL NULL NULL NULL NULL 21 Using where
DELETE FROM t1;
Warnings:
Note 1105 xt1: 4 affected rows
Note 1105 xt2: 4 affected rows
DROP TABLE t1;
CREATE TABLE t1 (
id INT KEY NOT NULL,
msg VARCHAR(32))
ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='xt%s'
PARTITION BY RANGE COLUMNS(id) (
PARTITION `1` VALUES LESS THAN(10),
PARTITION `2` VALUES LESS THAN(50),
PARTITION `3` VALUES LESS THAN(MAXVALUE));
Warnings:
Warning 1105 Data repartition in 1 is unchecked
Warning 1105 Data repartition in 2 is unchecked
Warning 1105 Data repartition in 3 is unchecked
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 0 PRIMARY 1 id NULL NULL NULL NULL REMOTE
INSERT INTO t1 VALUES(4, 'four');
INSERT INTO t1 VALUES(40, 'forty');
INSERT INTO t1 VALUES(72,'seventy two');
INSERT INTO t1 VALUES(7,'seven'),(10,'ten'),(60,'sixty'),(81,'eighty one'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight');
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
partition_name table_rows
1 4
2 4
3 3
SELECT * FROM t1;
id msg
4 four
7 seven
1 one
8 eight
40 forty
10 ten
11 eleven
35 thirty five
72 seventy two
60 sixty
81 eighty one
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id = 81;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 3 const PRIMARY PRIMARY 4 const 1
SELECT * FROM t1 WHERE id = 7;
id msg
7 seven
SELECT * FROM t1 WHERE id = 35;
id msg
35 thirty five
UPDATE t1 SET msg = 'number' WHERE id in (60,72);
ERROR HY000: Got error 122 'Remote: Got error 122 'Cannot use indexing for this command' from CONNECT' from CONNECT
UPDATE t1 SET msg = 'soixante' WHERE id = 60;
Warnings:
Note 1105 xt3: 1 affected rows
SELECT * FROM t1 WHERE id > 50;
id msg
60 soixante
72 seventy two
81 eighty one
UPDATE t1 SET msg = 'big' WHERE id > 50;
Warnings:
Note 1105 xt3: 3 affected rows
UPDATE t1 SET msg = 'sept' WHERE id = 7;
Warnings:
Note 1105 xt1: 1 affected rows
SELECT * FROM t1;
id msg
4 four
7 sept
1 one
8 eight
40 forty
10 ten
11 eleven
35 thirty five
72 big
60 big
81 big
DELETE FROM t1 WHERE id in (60,72);
ERROR HY000: Got error 122 'Remote: Got error 122 'Cannot use indexing for this command' from CONNECT' from CONNECT
DROP TABLE t1;
DROP TABLE xt1;
DROP TABLE xt2;
DROP TABLE xt3;

View File

@@ -0,0 +1,159 @@
--source include/have_partition.inc
let $MYSQLD_DATADIR= `select @@datadir`;
--echo # This will be used to see what data files are created
CREATE TABLE dr1 (
FNAME VARCHAR(256) NOT NULL FLAG=2,
FTYPE CHAR(8) NOT NULL FLAG=3
# ,FSIZE INT(6) NOT NULL FLAG=5 removed because Unix size != Windows size
) engine=CONNECT table_type=DIR file_name='t1#P#*.*';
--echo #
--echo # Testing partitioning on inward table
--echo #
CREATE TABLE t1 (
id INT NOT NULL,
msg VARCHAR(32)
) ENGINE=CONNECT TABLE_TYPE=CSV
PARTITION BY RANGE(id) (
PARTITION first VALUES LESS THAN(10),
PARTITION middle VALUES LESS THAN(50),
PARTITION last VALUES LESS THAN(MAXVALUE));
INSERT INTO t1 VALUES(4, 'four'),(24, 'twenty four');
INSERT INTO t1 VALUES(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one');
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
SELECT * FROM t1;
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id > 50;
SELECT * FROM t1 WHERE id > 50;
SHOW TABLE STATUS LIKE 't1';
--error ER_GET_ERRMSG
UPDATE t1 set id = 41 WHERE msg = 'four';
UPDATE t1 set msg = 'quatre' WHERE id = 4;
SELECT * FROM dr1;
--echo #
--echo # Altering partitioning on inward table
--echo #
ALTER TABLE t1
PARTITION by range(id) (
PARTITION first VALUES LESS THAN(11),
PARTITION middle VALUES LESS THAN(50),
PARTITION last VALUES LESS THAN(MAXVALUE));
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
SELECT * FROM dr1;
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id=10;
SELECT * FROM t1 WHERE id=10;
DELETE FROM t1 WHERE id in (4,60);
SELECT * FROM t1;
DROP TABLE t1;
SELECT * FROM dr1;
--echo #
--echo # Testing partitioning on a void outward table
--echo #
ALTER TABLE dr1 file_name='part*.*';
CREATE TABLE t1 (
rwid INT(6) DEFAULT 0 SPECIAL=ROWID,
rnum INT(6) DEFAULT 0 SPECIAL=ROWNUM,
prtn VARCHAR(64) DEFAULT '' SPECIAL=PARTID,
tbn VARCHAR(64) DEFAULT '' SPECIAL=TABID,
fid VARCHAR(256) DEFAULT '' SPECIAL=FNAME,
id INT KEY NOT NULL,
msg VARCHAR(32)
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='part%s.txt';
--replace_result $MYSQLD_DATADIR "DATADIR/"
ALTER TABLE t1
PARTITION by range columns(id) (
PARTITION `1` VALUES LESS THAN(10),
PARTITION `2` VALUES LESS THAN(50),
PARTITION `3` VALUES LESS THAN(MAXVALUE));
SHOW INDEX FROM t1;
SELECT * FROM dr1;
INSERT INTO t1(id,msg) VALUES(4, 'four');
SELECT * FROM dr1;
INSERT INTO t1(id,msg) VALUES(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one');
INSERT INTO t1(id,msg) VALUES(72,'seventy two'),(20,'twenty'),(1,'one'),(35,'thirty five'),(8,'eight');
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
SELECT * FROM t1;
SELECT * FROM t1 order by id;
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id = 10;
SELECT * FROM t1 WHERE id = 10;
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id >= 10;
SELECT * FROM t1 WHERE id >= 10;
SELECT count(*) FROM t1 WHERE id < 10;
SELECT case when id < 10 then 1 when id < 50 then 2 else 3 end as pn, count(*) FROM t1 group by pn;
SELECT prtn, count(*) FROM t1 group by prtn;
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id > 50;
SELECT * FROM t1 WHERE id = 35;
SELECT * FROM dr1;
--echo # This does not change the partition file data and is WRONG
ALTER TABLE t1
PARTITION by range columns(id) (
PARTITION `1` VALUES LESS THAN(11),
PARTITION `2` VALUES LESS THAN(70),
PARTITION `3` VALUES LESS THAN(MAXVALUE));
SELECT CASE WHEN id < 11 THEN 1 WHEN id < 70 THEN 2 ELSE 3 END AS pn, COUNT(*) FROM t1 GROUP BY pn;
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
SELECT * FROM dr1;
--echo #
--echo # This is the correct way to change partitioning:
--echo # Save table values, erase the table, then re-insert saved values in modified table
--echo #
CREATE TABLE t2 (
id INT NOT NULL,
msg VARCHAR(32)
) ENGINE=CONNECT TABLE_TYPE=FIX;
INSERT INTO t2 SELECT id, msg FROM t1;
DELETE FROM t1;
INSERT INTO t1(id,msg) SELECT * FROM t2;
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
SELECT * FROM t1;
SELECT * FROM dr1;
DROP TABLE t2;
DROP TABLE t1;
--echo #
--echo # Testing partitioning on a populated outward table
--echo #
CREATE TABLE t1 (
id INT NOT NULL,
msg VARCHAR(32)
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='part%s.txt'
PARTITION by range columns(id) (
PARTITION `1` VALUES LESS THAN(11),
PARTITION `2` VALUES LESS THAN(70),
PARTITION `3` VALUES LESS THAN(MAXVALUE));
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
SELECT * FROM t1 WHERE id < 11;
SELECT * FROM t1 WHERE id >= 70;
SELECT * FROM dr1;
--echo #
--echo # Testing indexing on a partitioned table
--echo #
CREATE INDEX XID ON t1(id);
SHOW INDEX FROM t1;
SELECT * FROM dr1;
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id = 10;
DROP INDEX XID ON t1;
SHOW INDEX FROM t1;
SELECT * FROM dr1;
ALTER TABLE t1 ADD PRIMARY KEY (id);
SHOW INDEX FROM t1;
SELECT * FROM dr1;
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id = 10;
ALTER TABLE t1 DROP PRIMARY KEY;
SHOW INDEX FROM t1;
SELECT * FROM dr1;
DROP TABLE t1;
DROP TABLE dr1;
#
# Clean up
#
--remove_file $MYSQLD_DATADIR/test/part1.txt
--remove_file $MYSQLD_DATADIR/test/part2.txt
--remove_file $MYSQLD_DATADIR/test/part3.txt
#--remove_file $MYSQLD_DATADIR/test/part%s.fnx
#--remove_file $MYSQLD_DATADIR/test/part1.fnx
#--remove_file $MYSQLD_DATADIR/test/part2.fnx
#--remove_file $MYSQLD_DATADIR/test/part3.fnx

View File

@@ -0,0 +1,85 @@
--source include/have_partition.inc
#
# These will be used by the t1 table partition table
#
CREATE TABLE xt1 (
id INT KEY NOT NULL,
msg VARCHAR(32))
ENGINE=MyISAM;
INSERT INTO xt1 VALUES(4, 'four'),(7,'seven'),(1,'one'),(8,'eight');
SELECT * FROM xt1;
CREATE TABLE xt2 (
id INT KEY NOT NULL,
msg VARCHAR(32));
INSERT INTO xt2 VALUES(10,'ten'),(40,'forty'),(11,'eleven'),(35,'thirty five');
SELECT * FROM xt2;
CREATE TABLE xt3 (
id INT KEY NOT NULL,
msg VARCHAR(32))
ENGINE=CONNECT TABLE_TYPE=CSV;
INSERT INTO xt3 VALUES(60,'sixty'),(81,'eighty one'),(72,'seventy two');
SELECT * FROM xt3;
#
# Based on PROXY the table is not indexable
#
CREATE TABLE t1 (
id INT NOT NULL,
msg VARCHAR(32))
ENGINE=CONNECT TABLE_TYPE=PROXY TABNAME='xt%s'
PARTITION BY RANGE COLUMNS(id) (
PARTITION `1` VALUES LESS THAN(10),
PARTITION `2` VALUES LESS THAN(50),
PARTITION `3` VALUES LESS THAN(MAXVALUE));
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
SELECT * FROM t1;
DELETE FROM t1;
--error ER_UNKNOWN_ERROR
ALTER TABLE t1 ADD INDEX XID(id);
INSERT INTO t1 VALUES(4, 'four');
INSERT INTO t1 VALUES(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one');
INSERT INTO t1 VALUES(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight');
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
SELECT * FROM t1;
EXPLAIN PARTITIONS
SELECT * FROM t1 WHERE id = 81;
DELETE FROM t1;
DROP TABLE t1;
#
# Based on MYSQL the table is indexable
#
CREATE TABLE t1 (
id INT KEY NOT NULL,
msg VARCHAR(32))
ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='xt%s'
PARTITION BY RANGE COLUMNS(id) (
PARTITION `1` VALUES LESS THAN(10),
PARTITION `2` VALUES LESS THAN(50),
PARTITION `3` VALUES LESS THAN(MAXVALUE));
SHOW INDEX FROM t1;
INSERT INTO t1 VALUES(4, 'four');
INSERT INTO t1 VALUES(40, 'forty');
INSERT INTO t1 VALUES(72,'seventy two');
INSERT INTO t1 VALUES(7,'seven'),(10,'ten'),(60,'sixty'),(81,'eighty one'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight');
SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1';
SELECT * FROM t1;
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id = 81;
SELECT * FROM t1 WHERE id = 7;
SELECT * FROM t1 WHERE id = 35;
--error ER_GET_ERRMSG
UPDATE t1 SET msg = 'number' WHERE id in (60,72);
UPDATE t1 SET msg = 'soixante' WHERE id = 60;
SELECT * FROM t1 WHERE id > 50;
UPDATE t1 SET msg = 'big' WHERE id > 50;
UPDATE t1 SET msg = 'sept' WHERE id = 7;
SELECT * FROM t1;
--error ER_GET_ERRMSG
DELETE FROM t1 WHERE id in (60,72);
DROP TABLE t1;
DROP TABLE xt1;
DROP TABLE xt2;
DROP TABLE xt3;

View File

@@ -85,6 +85,7 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
TYPE_AM_SRVID = 5, /* SERVID type (special column) */ TYPE_AM_SRVID = 5, /* SERVID type (special column) */
TYPE_AM_TABID = 6, /* TABID type (special column) */ TYPE_AM_TABID = 6, /* TABID type (special column) */
TYPE_AM_CNSID = 7, /* CONSTID type (special column) */ TYPE_AM_CNSID = 7, /* CONSTID type (special column) */
TYPE_AM_PRTID = 8, /* PARTID type (special column) */
TYPE_AM_COUNT = 10, /* CPT AM type no (count table) */ TYPE_AM_COUNT = 10, /* CPT AM type no (count table) */
TYPE_AM_DCD = 20, /* Decode access method type no */ TYPE_AM_DCD = 20, /* Decode access method type no */
TYPE_AM_CMS = 30, /* CMS access method type no */ TYPE_AM_CMS = 30, /* CMS access method type no */
@@ -549,6 +550,7 @@ PPARM Vcolist(PGLOBAL, PTDB, PSZ, bool);
void PlugPutOut(PGLOBAL, FILE *, short, void *, uint); void PlugPutOut(PGLOBAL, FILE *, short, void *, uint);
void PlugLineDB(PGLOBAL, PSZ, short, void *, uint); void PlugLineDB(PGLOBAL, PSZ, short, void *, uint);
char *PlgGetDataPath(PGLOBAL g); char *PlgGetDataPath(PGLOBAL g);
char *ExtractFromPath(PGLOBAL, char *, char *, OPVAL);
void AddPointer(PTABS, void *); void AddPointer(PTABS, void *);
PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int); PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int);
int ExtractDate(char *, PDTP, int, int val[6]); int ExtractDate(char *, PDTP, int, int val[6]);

View File

@@ -383,6 +383,31 @@ char *PlgGetDataPath(PGLOBAL g)
return (cat) ? cat->GetDataPath() : NULL; return (cat) ? cat->GetDataPath() : NULL;
} // end of PlgGetDataPath } // end of PlgGetDataPath
/***********************************************************************/
/* Extract from a path name the required component. */
/* This function assumes there is enough space in the buffer. */
/***********************************************************************/
char *ExtractFromPath(PGLOBAL g, char *pBuff, char *FileName, OPVAL op)
{
char *drive = NULL, *direc = NULL, *fname = NULL, *ftype = NULL;
switch (op) { // Determine which part to extract
#if !defined(UNIX)
case OP_FDISK: drive = pBuff; break;
#endif // !UNIX
case OP_FPATH: direc = pBuff; break;
case OP_FNAME: fname = pBuff; break;
case OP_FTYPE: ftype = pBuff; break;
default:
sprintf(g->Message, MSG(INVALID_OPER), op, "ExtractFromPath");
return NULL;
} // endswitch op
// Now do the extraction
_splitpath(FileName, drive, direc, fname, ftype);
return pBuff;
} // end of PlgExtractFromPath
/***********************************************************************/ /***********************************************************************/
/* Check the occurence and matching of a pattern against a string. */ /* Check the occurence and matching of a pattern against a string. */
/* Because this function is only used for catalog name checking, */ /* Because this function is only used for catalog name checking, */

View File

@@ -126,6 +126,14 @@ int RELDEF::GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size)
return size; return size;
} // end of GetCharCatInfo } // end of GetCharCatInfo
/***********************************************************************/
/* To be used by any TDB's. */
/***********************************************************************/
bool RELDEF::Partitioned(void)
{
return Hc->IsPartitioned();
} // end of Partitioned
/***********************************************************************/ /***********************************************************************/
/* This function returns string table information. */ /* This function returns string table information. */
/* Default parameter is "*" to get the handler default. */ /* Default parameter is "*" to get the handler default. */
@@ -136,7 +144,8 @@ char *RELDEF::GetStringCatInfo(PGLOBAL g, PSZ what, PSZ sdef)
if (s) { if (s) {
if (Hc->IsPartitioned() && if (Hc->IsPartitioned() &&
(!stricmp(what, "filename") || !stricmp(what, "tabname"))) { (!stricmp(what, "filename") || !stricmp(what, "tabname")
|| !stricmp(what, "connect"))) {
name= Hc->GetPartName(); name= Hc->GetPartName();
sval= (char*)PlugSubAlloc(g, NULL, strlen(s) + strlen(name)); sval= (char*)PlugSubAlloc(g, NULL, strlen(s) + strlen(name));
sprintf(sval, s, name); sprintf(sval, s, name);

View File

@@ -42,6 +42,7 @@ class DllExport RELDEF : public BLOCK { // Relation definition block
// Methods // Methods
bool GetBoolCatInfo(PSZ what, bool bdef); bool GetBoolCatInfo(PSZ what, bool bdef);
bool SetIntCatInfo(PSZ what, int ival); bool SetIntCatInfo(PSZ what, int ival);
bool Partitioned(void);
int GetIntCatInfo(PSZ what, int idef); int GetIntCatInfo(PSZ what, int idef);
int GetSizeCatInfo(PSZ what, PSZ sdef); int GetSizeCatInfo(PSZ what, PSZ sdef);
int GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size); int GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size);

View File

@@ -97,7 +97,7 @@ class DllExport COLUMN: public XOBJECT { // Column Name/Qualifier block.
/***********************************************************************/ /***********************************************************************/
/* Definition of class SPCCOL with all its method functions. */ /* Definition of class SPCCOL with all its method functions. */
/* Note: Currently the special columns are ROWID, ROWNUM, FILEID, */ /* Note: Currently the special columns are ROWID, ROWNUM, FILEID, */
/* SERVID, TABID, and CONID. */ /* SERVID, TABID, PARTID, and CONID. */
/***********************************************************************/ /***********************************************************************/
class SPCCOL: public COLUMN { // Special Column Name/Qualifier block. class SPCCOL: public COLUMN { // Special Column Name/Qualifier block.
public: public:

View File

@@ -414,12 +414,12 @@ TDBDOS::TDBDOS(PDOSDEF tdp, PTXF txfp) : TDBASE(tdp)
AvgLen = tdp->AvgLen; AvgLen = tdp->AvgLen;
Ftype = tdp->Recfm; Ftype = tdp->Recfm;
To_Line = NULL; To_Line = NULL;
Cardinal = -1;
//To_BlkIdx = NULL; //To_BlkIdx = NULL;
To_BlkFil = NULL; To_BlkFil = NULL;
SavFil = NULL; SavFil = NULL;
//Xeval = 0; //Xeval = 0;
Beval = 0; Beval = 0;
Abort = false;
} // end of TDBDOS standard constructor } // end of TDBDOS standard constructor
TDBDOS::TDBDOS(PGLOBAL g, PTDBDOS tdbp) : TDBASE(tdbp) TDBDOS::TDBDOS(PGLOBAL g, PTDBDOS tdbp) : TDBASE(tdbp)
@@ -429,7 +429,6 @@ TDBDOS::TDBDOS(PGLOBAL g, PTDBDOS tdbp) : TDBASE(tdbp)
AvgLen = tdbp->AvgLen; AvgLen = tdbp->AvgLen;
Ftype = tdbp->Ftype; Ftype = tdbp->Ftype;
To_Line = tdbp->To_Line; To_Line = tdbp->To_Line;
Cardinal = tdbp->Cardinal;
//To_BlkIdx = tdbp->To_BlkIdx; //To_BlkIdx = tdbp->To_BlkIdx;
To_BlkFil = tdbp->To_BlkFil; To_BlkFil = tdbp->To_BlkFil;
SavFil = tdbp->SavFil; SavFil = tdbp->SavFil;
@@ -561,8 +560,13 @@ int TDBDOS::MakeBlockValues(PGLOBAL g)
//void *memp = cat->GetDescp(); //void *memp = cat->GetDescp();
if ((nrec = defp->GetElemt()) < 2) { if ((nrec = defp->GetElemt()) < 2) {
if (!To_Def->Partitioned()) {
// This may be wrong to do in some cases
strcpy(g->Message, MSG(TABLE_NOT_OPT)); strcpy(g->Message, MSG(TABLE_NOT_OPT));
return RC_INFO; // Not to be optimized return RC_INFO; // Not to be optimized
} else
return RC_OK;
} else if (GetMaxSize(g) == 0 || !(dup->Check & CHK_OPT)) { } else if (GetMaxSize(g) == 0 || !(dup->Check & CHK_OPT)) {
// Suppress the opt file firstly if the table is void, // Suppress the opt file firstly if the table is void,
// secondly when it was modified with OPTIMIZATION unchecked // secondly when it was modified with OPTIMIZATION unchecked
@@ -1565,6 +1569,12 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
Mode = MODE_READ; Mode = MODE_READ;
Use = USE_READY; Use = USE_READY;
dfp = (PDOSDEF)To_Def; dfp = (PDOSDEF)To_Def;
if (!Cardinality(g)) {
// Void table erase eventual index file(s)
(void)dfp->DeleteIndexFile(g, NULL);
return RC_OK;
} else
fixed = Cardinality(g) >= 0; fixed = Cardinality(g) >= 0;
// Are we are called from CreateTable or CreateIndex? // Are we are called from CreateTable or CreateIndex?
@@ -1823,12 +1833,51 @@ int TDBDOS::RowNumber(PGLOBAL g, bool b)
/***********************************************************************/ /***********************************************************************/
int TDBDOS::Cardinality(PGLOBAL g) int TDBDOS::Cardinality(PGLOBAL g)
{ {
if (!g) int n = Txfp->Cardinality(NULL);
return Txfp->Cardinality(g);
if (Cardinal < 0) if (!g)
return (Mode == MODE_ANY) ? 1 : n;
if (Cardinal < 0) {
if (Mode == MODE_ANY && n == 0) {
// Info command, we must return exact row number
PDOSDEF dfp = (PDOSDEF)To_Def;
PIXDEF xdp = dfp->To_Indx;
if (xdp) {
// Cardinality can be retreived from one index
PXLOAD pxp;
if (dfp->Huge)
pxp = new(g) XHUGE;
else
pxp = new(g) XFILE;
PXINDEX kxp = new(g) XINDEX(this, xdp, pxp, NULL, NULL);
if (!(kxp->GetAllSizes(g, Cardinal)))
return Cardinal;
} // endif Mode
// Using index impossible or failed, do it the hard way
Mode = MODE_READ;
To_Line = (char*)PlugSubAlloc(g, NULL, Lrecl + 1);
if (Txfp->OpenTableFile(g))
return (Cardinal = Txfp->Cardinality(g));
for (Cardinal = 0; n != RC_EF;)
if (!(n = Txfp->ReadBuffer(g)))
Cardinal++;
Txfp->CloseTableFile(g, false);
Mode = MODE_ANY;
} else
Cardinal = Txfp->Cardinality(g); Cardinal = Txfp->Cardinality(g);
} // endif Cardinal
return Cardinal; return Cardinal;
} // end of Cardinality } // end of Cardinality
@@ -2104,7 +2153,7 @@ void TDBDOS::CloseDB(PGLOBAL g)
To_Kindex = NULL; To_Kindex = NULL;
} // endif } // endif
Txfp->CloseTableFile(g); Txfp->CloseTableFile(g, Abort);
} // end of CloseDB } // end of CloseDB
// ------------------------ DOSCOL functions ---------------------------- // ------------------------ DOSCOL functions ----------------------------

View File

@@ -125,6 +125,7 @@ class DllExport TDBDOS : public TDBASE {
virtual AMT GetAmType(void) {return Txfp->GetAmType();} virtual AMT GetAmType(void) {return Txfp->GetAmType();}
virtual PSZ GetFile(PGLOBAL g) {return Txfp->To_File;} virtual PSZ GetFile(PGLOBAL g) {return Txfp->To_File;}
virtual void SetFile(PGLOBAL g, PSZ fn) {Txfp->To_File = fn;} virtual void SetFile(PGLOBAL g, PSZ fn) {Txfp->To_File = fn;}
virtual void SetAbort(bool b) {Abort = b;}
virtual RECFM GetFtype(void) {return Ftype;} virtual RECFM GetFtype(void) {return Ftype;}
virtual bool SkipHeader(PGLOBAL g) {return false;} virtual bool SkipHeader(PGLOBAL g) {return false;}
virtual void RestoreNrec(void) {Txfp->SetNrec(1);} virtual void RestoreNrec(void) {Txfp->SetNrec(1);}
@@ -183,8 +184,8 @@ class DllExport TDBDOS : public TDBASE {
PBF To_BlkFil; // To evaluation block filter PBF To_BlkFil; // To evaluation block filter
PFIL SavFil; // Saved hidden filter PFIL SavFil; // Saved hidden filter
char *To_Line; // Points to current processed line char *To_Line; // Points to current processed line
int Cardinal; // Table Cardinality
RECFM Ftype; // File type: 0-var 1-fixed 2-binary (VCT) RECFM Ftype; // File type: 0-var 1-fixed 2-binary (VCT)
bool Abort; // TRUE when aborting UPDATE/DELETE
int Lrecl; // Logical Record Length int Lrecl; // Logical Record Length
int AvgLen; // Logical Record Average Length int AvgLen; // Logical Record Average Length
//int Xeval; // BlockTest return value //int Xeval; // BlockTest return value

View File

@@ -63,12 +63,10 @@ static const longlong M4G = (longlong)2 * M2G;
/***********************************************************************/ /***********************************************************************/
TDBFIX::TDBFIX(PDOSDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp) TDBFIX::TDBFIX(PDOSDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp)
{ {
//Cardinal = -1;
} // end of TDBFIX standard constructor } // end of TDBFIX standard constructor
TDBFIX::TDBFIX(PGLOBAL g, PTDBFIX tdbp) : TDBDOS(g, tdbp) TDBFIX::TDBFIX(PGLOBAL g, PTDBFIX tdbp) : TDBDOS(g, tdbp)
{ {
//Cardinal = tdbp->Cardinal;
} // end of TDBFIX copy constructor } // end of TDBFIX copy constructor
// Method // Method

View File

@@ -648,7 +648,7 @@ bool TDBCSV::OpenDB(PGLOBAL g)
} else } else
for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
if (!cdp->IsVirtual()) if (!cdp->IsSpecial() && !cdp->IsVirtual())
Fields++; Fields++;
Offset = (int*)PlugSubAlloc(g, NULL, sizeof(int) * Fields); Offset = (int*)PlugSubAlloc(g, NULL, sizeof(int) * Fields);
@@ -685,7 +685,7 @@ bool TDBCSV::OpenDB(PGLOBAL g)
} else // MODE_UPDATE } else // MODE_UPDATE
for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
if (!cdp->IsVirtual()) { if (!cdp->IsSpecial() && !cdp->IsVirtual()) {
i = cdp->GetOffset() - 1; i = cdp->GetOffset() - 1;
len = cdp->GetLength(); len = cdp->GetLength();
Field[i] = (PSZ)PlugSubAlloc(g, NULL, len + 1); Field[i] = (PSZ)PlugSubAlloc(g, NULL, len + 1);
@@ -1117,7 +1117,8 @@ bool TDBFMT::OpenDB(PGLOBAL g)
// Get the column formats // Get the column formats
for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
if (!cdp->IsVirtual() && (i = cdp->GetOffset() - 1) < Fields) { if (!cdp->IsSpecial() && !cdp->IsVirtual()
&& (i = cdp->GetOffset() - 1) < Fields) {
if (!(pfm = cdp->GetFmt())) { if (!(pfm = cdp->GetFmt())) {
sprintf(g->Message, MSG(NO_FLD_FORMAT), i + 1, Name); sprintf(g->Message, MSG(NO_FLD_FORMAT), i + 1, Name);
return true; return true;

View File

@@ -52,7 +52,8 @@ TDB::TDB(PTABDEF tdp) : Tdb_No(++Tnum)
To_Table = NULL; To_Table = NULL;
Columns = NULL; Columns = NULL;
Degree = (tdp) ? tdp->GetDegree() : 0; Degree = (tdp) ? tdp->GetDegree() : 0;
Mode = MODE_READ; Mode = MODE_ANY;
Cardinal = -1;
} // end of TDB standard constructor } // end of TDB standard constructor
TDB::TDB(PTDB tdbp) : Tdb_No(++Tnum) TDB::TDB(PTDB tdbp) : Tdb_No(++Tnum)
@@ -67,6 +68,7 @@ TDB::TDB(PTDB tdbp) : Tdb_No(++Tnum)
Columns = NULL; Columns = NULL;
Degree = tdbp->Degree; Degree = tdbp->Degree;
Mode = tdbp->Mode; Mode = tdbp->Mode;
Cardinal = tdbp->Cardinal;
} // end of TDB copy constructor } // end of TDB copy constructor
// Methods // Methods
@@ -227,7 +229,7 @@ PCOL TDBASE::ColDB(PGLOBAL g, PSZ name, int num)
colp = cp; colp = cp;
else if (!(cdp->Flags & U_SPECIAL)) else if (!(cdp->Flags & U_SPECIAL))
colp = MakeCol(g, cdp, cprec, i); colp = MakeCol(g, cdp, cprec, i);
else if (Mode == MODE_READ) else if (Mode != MODE_INSERT)
colp = InsertSpcBlk(g, cdp); colp = InsertSpcBlk(g, cdp);
if (trace) if (trace)
@@ -267,22 +269,38 @@ PCOL TDBASE::InsertSpcBlk(PGLOBAL g, PCOLDEF cdp)
PCOL colp; PCOL colp;
cp= new(g) COLUMN(cdp->GetName()); cp= new(g) COLUMN(cdp->GetName());
if (! To_Table) {
strcpy(g->Message, "Cannot make special column: To_Table is NULL");
return NULL;
} else
cp->SetTo_Table(To_Table); cp->SetTo_Table(To_Table);
if (!stricmp(name, "FILEID") || if (!stricmp(name, "FILEID") || !stricmp(name, "FDISK") ||
!stricmp(name, "SERVID")) { !stricmp(name, "FPATH") || !stricmp(name, "FNAME") ||
!stricmp(name, "FTYPE") || !stricmp(name, "SERVID")) {
if (!To_Def || !(To_Def->GetPseudo() & 2)) { if (!To_Def || !(To_Def->GetPseudo() & 2)) {
sprintf(g->Message, MSG(BAD_SPEC_COLUMN)); sprintf(g->Message, MSG(BAD_SPEC_COLUMN));
return NULL; return NULL;
} // endif Pseudo } // endif Pseudo
if (!stricmp(name, "FILEID")) if (!stricmp(name, "FILEID"))
colp = new(g) FIDBLK(cp); colp = new(g) FIDBLK(cp, OP_XX);
else if (!stricmp(name, "FDISK"))
colp = new(g) FIDBLK(cp, OP_FDISK);
else if (!stricmp(name, "FPATH"))
colp = new(g) FIDBLK(cp, OP_FPATH);
else if (!stricmp(name, "FNAME"))
colp = new(g) FIDBLK(cp, OP_FNAME);
else if (!stricmp(name, "FTYPE"))
colp = new(g) FIDBLK(cp, OP_FTYPE);
else else
colp = new(g) SIDBLK(cp); colp = new(g) SIDBLK(cp);
} else if (!stricmp(name, "TABID")) { } else if (!stricmp(name, "TABID")) {
colp = new(g) TIDBLK(cp); colp = new(g) TIDBLK(cp);
} else if (!stricmp(name, "PARTID")) {
colp = new(g) PRTBLK(cp);
//} else if (!stricmp(name, "CONID")) { //} else if (!stricmp(name, "CONID")) {
// colp = new(g) CIDBLK(cp); // colp = new(g) CIDBLK(cp);
} else if (!stricmp(name, "ROWID")) { } else if (!stricmp(name, "ROWID")) {

View File

@@ -1,7 +1,7 @@
/************* TabMySQL C++ Program Source Code File (.CPP) *************/ /************* TabMySQL C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABMYSQL */ /* PROGRAM NAME: TABMYSQL */
/* ------------- */ /* ------------- */
/* Version 1.8 */ /* Version 1.9 */
/* */ /* */
/* AUTHOR: */ /* AUTHOR: */
/* ------- */ /* ------- */
@@ -69,6 +69,10 @@ void PrintResult(PGLOBAL, PSEM, PQRYRES);
extern "C" int trace; extern "C" int trace;
// Used to check whether a MYSQL table is created on itself
bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host,
const char *db, char *tab, const char *src, int port);
/* -------------- Implementation of the MYSQLDEF class --------------- */ /* -------------- Implementation of the MYSQLDEF class --------------- */
/***********************************************************************/ /***********************************************************************/
@@ -353,8 +357,12 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Tabname = Name; Tabname = Name;
} // endif am } // endif am
if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) {
Read_Only = true;
Isview = true; Isview = true;
} else if (CheckSelf(g, Hc->GetTable()->s, Hostname, Database,
Tabname, Srcdef, Portnumber))
return true;
// Used for Update and Delete // Used for Update and Delete
Qrystr = GetStringCatInfo(g, "Query_String", "?"); Qrystr = GetStringCatInfo(g, "Query_String", "?");
@@ -603,9 +611,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
else else
qlen += colp->GetLength(); qlen += colp->GetLength();
} // endif Prep } else // Prep
if (Prep)
strcat(valist, "?"); strcat(valist, "?");
} // endfor colp } // endfor colp
@@ -740,33 +746,49 @@ int TDBMYSQL::MakeDelete(PGLOBAL g)
#endif // 0 #endif // 0
/***********************************************************************/ /***********************************************************************/
/* XCV GetMaxSize: returns the maximum number of rows in the table. */ /* MYSQL Cardinality: returns the number of rows in the table. */
/***********************************************************************/
int TDBMYSQL::Cardinality(PGLOBAL g)
{
if (!g)
return (Mode == MODE_ANY && !Srcdef) ? 1 : 0;
if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef) {
// Info command, we must return the exact table row number
char query[96];
MYSQLC myc;
if (myc.Open(g, Host, Database, User, Pwd, Port))
return -1;
strcpy(query, "SELECT COUNT(*) FROM ");
if (Quoted > 0)
strcat(strcat(strcat(query, "`"), Tabname), "`");
else
strcat(query, Tabname);
Cardinal = myc.GetTableSize(g, query);
myc.Close();
} // endif Cardinal
return Cardinal;
} // end of Cardinality
/***********************************************************************/
/* MYSQL GetMaxSize: returns the maximum number of rows in the table. */
/***********************************************************************/ /***********************************************************************/
int TDBMYSQL::GetMaxSize(PGLOBAL g) int TDBMYSQL::GetMaxSize(PGLOBAL g)
{ {
if (MaxSize < 0) { if (MaxSize < 0) {
#if 0 if (Mode == MODE_DELETE)
if (MakeSelect(g))
return -2;
if (!Myc.Connected()) {
if (Myc.Open(g, Host, Database, User, Pwd, Port))
return -1;
} // endif connected
if ((MaxSize = Myc.GetResultSize(g, Query)) < 0) {
Myc.Close();
return -3;
} // endif MaxSize
// FIXME: Columns should be known when Info calls GetMaxSize
if (!Columns)
Query = NULL; // Must be remade when columns are known
#endif // 0
// Return 0 in mode DELETE in case of delete all. // Return 0 in mode DELETE in case of delete all.
MaxSize = (Mode == MODE_DELETE) ? 0 : 10; // To make MySQL happy MaxSize = 0;
else if (!Cardinality(NULL))
MaxSize = 10; // To make MySQL happy
else if ((MaxSize = Cardinality(g)) < 0)
MaxSize = 12; // So we can see an error occured
} // endif MaxSize } // endif MaxSize
return MaxSize; return MaxSize;
@@ -881,11 +903,12 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
} // endif MakeInsert } // endif MakeInsert
if (m_Rc != RC_FX) { if (m_Rc != RC_FX) {
int rc;
char cmd[64]; char cmd[64];
int w; int w;
sprintf(cmd, "ALTER TABLE `%s` DISABLE KEYS", Tabname); sprintf(cmd, "ALTER TABLE `%s` DISABLE KEYS", Tabname);
m_Rc = Myc.ExecSQL(g, cmd, &w); rc = Myc.ExecSQL(g, cmd, &w); // may fail for some engines
} // endif m_Rc } // endif m_Rc
} else } else
@@ -1012,7 +1035,7 @@ bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
{ {
int oldlen = strlen(Query); int oldlen = strlen(Query);
if (op == OP_NEXT) if (!key || op == OP_NEXT)
return false; return false;
else if (op == OP_FIRST) { else if (op == OP_FIRST) {
if (To_CondFil) if (To_CondFil)
@@ -1129,7 +1152,7 @@ void TDBMYSQL::CloseDB(PGLOBAL g)
dup->Step = "Enabling indexes"; dup->Step = "Enabling indexes";
sprintf(cmd, "ALTER TABLE `%s` ENABLE KEYS", Tabname); sprintf(cmd, "ALTER TABLE `%s` ENABLE KEYS", Tabname);
Myc.m_Rows = -1; // To execute the query Myc.m_Rows = -1; // To execute the query
m_Rc = Myc.ExecSQL(g, cmd, &w); m_Rc = Myc.ExecSQL(g, cmd, &w); // May fail for some engines
} // endif m_Rc } // endif m_Rc
Myc.Close(); Myc.Close();

View File

@@ -1,4 +1,4 @@
// TDBMYSQL.H Olivier Bertrand 2007-2013 // TDBMYSQL.H Olivier Bertrand 2007-2014
#include "myconn.h" // MySQL connection declares #include "myconn.h" // MySQL connection declares
typedef class MYSQLDEF *PMYDEF; typedef class MYSQLDEF *PMYDEF;
@@ -92,6 +92,7 @@ class TDBMYSQL : public TDBASE {
// Database routines // Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual int Cardinality(PGLOBAL g);
virtual int GetMaxSize(PGLOBAL g); virtual int GetMaxSize(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g); virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g); virtual int ReadDB(PGLOBAL g);

View File

@@ -100,7 +100,13 @@ ODBCDEF::ODBCDEF(void)
/***********************************************************************/ /***********************************************************************/
bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{ {
Desc = Connect = GetStringCatInfo(g, "Connect", ""); Desc = Connect = GetStringCatInfo(g, "Connect", NULL);
if (!Connect && !Catfunc) {
sprintf(g->Message, "Missing connection for ODBC table %s", Name);
return true;
} // endif Connect
Tabname = GetStringCatInfo(g, "Name", Tabname = GetStringCatInfo(g, "Name",
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
Tabname = GetStringCatInfo(g, "Tabname", Tabname); Tabname = GetStringCatInfo(g, "Tabname", Tabname);
@@ -108,7 +114,10 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Tabschema = GetStringCatInfo(g, "Schema", Tabschema); Tabschema = GetStringCatInfo(g, "Schema", Tabschema);
Tabcat = GetStringCatInfo(g, "Qualifier", NULL); Tabcat = GetStringCatInfo(g, "Qualifier", NULL);
Tabcat = GetStringCatInfo(g, "Catalog", Tabcat); Tabcat = GetStringCatInfo(g, "Catalog", Tabcat);
Srcdef = GetStringCatInfo(g, "Srcdef", NULL);
if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL)))
Read_Only = true;
Qrystr = GetStringCatInfo(g, "Query_String", "?"); Qrystr = GetStringCatInfo(g, "Query_String", "?");
Sep = GetStringCatInfo(g, "Separator", NULL); Sep = GetStringCatInfo(g, "Separator", NULL);
Catver = GetIntCatInfo("Catver", 2); Catver = GetIntCatInfo("Catver", 2);
@@ -654,41 +663,58 @@ void TDBODBC::ResetSize(void)
} // end of ResetSize } // end of ResetSize
/***********************************************************************/
/* ODBC Cardinality: returns table size in number of rows. */
/***********************************************************************/
int TDBODBC::Cardinality(PGLOBAL g)
{
if (!g)
return (Mode == MODE_ANY && !Srcdef) ? 1 : 0;
if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef) {
// Info command, we must return the exact table row number
char qry[96], tbn[64];
ODBConn *ocp = new(g) ODBConn(g, this);
if (ocp->Open(Connect, Options) < 1)
return -1;
// Table name can be encoded in UTF-8
Decode(TableName, tbn, sizeof(tbn));
strcpy(qry, "SELECT COUNT(*) FROM ");
if (Quote)
strcat(strcat(strcat(qry, Quote), tbn), Quote);
else
strcat(qry, tbn);
// Allocate a Count(*) column (must not use the default constructor)
Cnp = new(g) ODBCCOL;
Cnp->InitValue(g);
if ((Cardinal = ocp->GetResultSize(qry, Cnp)) < 0)
return -3;
ocp->Close();
} // endif Cardinal
return Cardinal;
} // end of Cardinality
/***********************************************************************/ /***********************************************************************/
/* ODBC GetMaxSize: returns table size estimate in number of lines. */ /* ODBC GetMaxSize: returns table size estimate in number of lines. */
/***********************************************************************/ /***********************************************************************/
int TDBODBC::GetMaxSize(PGLOBAL g) int TDBODBC::GetMaxSize(PGLOBAL g)
{ {
if (MaxSize < 0) { if (MaxSize < 0) {
// Make MariaDB happy if (Mode == MODE_DELETE)
MaxSize = (Mode == MODE_DELETE) ? 0 : 10; // Return 0 in mode DELETE in case of delete all.
#if 0 MaxSize = 0;
// This is unuseful and takes time else if (!Cardinality(NULL))
if (Srcdef) { MaxSize = 10; // To make MySQL happy
// Return a reasonable guess else if ((MaxSize = Cardinality(g)) < 0)
MaxSize = 100; MaxSize = 12; // So we can see an error occured
return MaxSize;
} // endif Srcdef
if (!Ocp)
Ocp = new(g) ODBConn(g, this);
if (!Ocp->IsOpen())
if (Ocp->Open(Connect, Options) < 1)
return -1;
if (!Count && !(Count = MakeSQL(g, true)))
return -2;
if (!Cnp) {
// Allocate a Count(*) column (must not use the default constructor)
Cnp = new(g) ODBCCOL;
Cnp->InitValue(g);
} // endif Cnp
if ((MaxSize = Ocp->GetResultSize(Count, Cnp)) < 0)
return -3;
#endif // 0
} // endif MaxSize } // endif MaxSize
return MaxSize; return MaxSize;

View File

@@ -94,8 +94,9 @@ class TDBODBC : public TDBASE {
// Database routines // Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual int GetProgMax(PGLOBAL g); virtual int Cardinality(PGLOBAL g);
virtual int GetMaxSize(PGLOBAL g); virtual int GetMaxSize(PGLOBAL g);
virtual int GetProgMax(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g); virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g); virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g); virtual int WriteDB(PGLOBAL g);

View File

@@ -1,9 +1,9 @@
/************* TabSys C++ Program Source Code File (.CPP) **************/ /************* TabSys C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABSYS */ /* PROGRAM NAME: TABSYS */
/* ------------- */ /* ------------- */
/* Version 2.2 */ /* Version 2.3 */
/* */ /* */
/* Author Olivier BERTRAND 2004-2013 */ /* Author Olivier BERTRAND 2004-2014 */
/* */ /* */
/* This program are the INI/CFG tables classes. */ /* This program are the INI/CFG tables classes. */
/***********************************************************************/ /***********************************************************************/
@@ -203,18 +203,35 @@ PCOL TDBINI::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
} // end of MakeCol } // end of MakeCol
/***********************************************************************/ /***********************************************************************/
/* INI GetMaxSize: returns the number of sections in the INI file. */ /* INI Cardinality: returns the number of sections in the INI file. */
/***********************************************************************/
int TDBINI::Cardinality(PGLOBAL g)
{
if (!g)
return 1;
if (Cardinal < 0) {
// Count the number of sections from the section list
char *p = GetSeclist(g);
Cardinal = 0;
if (p)
for (; *p; p += (strlen(p) + 1))
Cardinal++;
} // endif Cardinal
return Cardinal;
} // end of Cardinality
/***********************************************************************/
/* INI GetMaxSize: returns the table cardinality. */
/***********************************************************************/ /***********************************************************************/
int TDBINI::GetMaxSize(PGLOBAL g) int TDBINI::GetMaxSize(PGLOBAL g)
{ {
if (MaxSize < 0 && GetSeclist(g)) { if (MaxSize < 0)
// Count the number of sections from the section list MaxSize = Cardinality(g);
char *p;
for (MaxSize = 0, p = Seclist; *p; p += (strlen(p) + 1))
MaxSize++;
} // endif MaxSize
return MaxSize; return MaxSize;
} // end of GetMaxSize } // end of GetMaxSize
@@ -609,22 +626,28 @@ PCOL TDBXIN::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
} // end of MakeCol } // end of MakeCol
/***********************************************************************/ /***********************************************************************/
/* XIN GetMaxSize: returns the number of sections in the XIN file. */ /* XIN Cardinality: returns the number of keys in the XIN file. */
/***********************************************************************/ /***********************************************************************/
int TDBXIN::GetMaxSize(PGLOBAL g) int TDBXIN::Cardinality(PGLOBAL g)
{ {
if (MaxSize < 0 && GetSeclist(g)) { if (!g)
return 1;
if (Cardinal < 0) {
// Count the number of keys from the section list // Count the number of keys from the section list
char *p, *k; char *k, *p = GetSeclist(g);
for (MaxSize = 0, p = Seclist; *p; p += (strlen(p) + 1)) Cardinal = 0;
if (p)
for (; *p; p += (strlen(p) + 1))
for (k = GetKeylist(g, p); *k; k += (strlen(k) + 1)) for (k = GetKeylist(g, p); *k; k += (strlen(k) + 1))
MaxSize++; Cardinal++;
} // endif MaxSize } // endif Cardinal
return MaxSize; return Cardinal;
} // end of GetMaxSize } // end of Cardinality
/***********************************************************************/ /***********************************************************************/
/* Record position is Section+Key. */ /* Record position is Section+Key. */

View File

@@ -1,7 +1,7 @@
/*************** TabSys H Declares Source Code File (.H) ***************/ /*************** TabSys H Declares Source Code File (.H) ***************/
/* Name: TABSYS.H Version 2.2 */ /* Name: TABSYS.H Version 2.3 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 2004-2013 */ /* (C) Copyright to the author Olivier BERTRAND 2004-2014 */
/* */ /* */
/* This file contains the XDB system tables classes declares. */ /* This file contains the XDB system tables classes declares. */
/***********************************************************************/ /***********************************************************************/
@@ -70,6 +70,7 @@ class TDBINI : public TDBASE {
// Database routines // Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual int Cardinality(PGLOBAL g);
virtual int GetMaxSize(PGLOBAL g); virtual int GetMaxSize(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g); virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g); virtual int ReadDB(PGLOBAL g);
@@ -144,7 +145,7 @@ class TDBXIN : public TDBINI {
// Database routines // Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual int GetMaxSize(PGLOBAL g); virtual int Cardinality(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g); virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g); virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g); virtual int WriteDB(PGLOBAL g);

View File

@@ -435,7 +435,7 @@ bool TDBTBL::OpenDB(PGLOBAL g)
if ((CurTable = Tablist)) { if ((CurTable = Tablist)) {
Tdbp = (PTDBASE)CurTable->GetTo_Tdb(); Tdbp = (PTDBASE)CurTable->GetTo_Tdb();
Tdbp->SetMode(Mode); // Tdbp->SetMode(Mode);
// Tdbp->ResetDB(); // Tdbp->ResetDB();
// Tdbp->ResetSize(); // Tdbp->ResetSize();
@@ -685,7 +685,7 @@ bool TDBTBM::OpenDB(PGLOBAL g)
/*********************************************************************/ /*********************************************************************/
if ((CurTable = Tablist)) { if ((CurTable = Tablist)) {
Tdbp = (PTDBASE)CurTable->GetTo_Tdb(); Tdbp = (PTDBASE)CurTable->GetTo_Tdb();
Tdbp->SetMode(Mode); // Tdbp->SetMode(Mode);
// Check and initialize the subtable columns // Check and initialize the subtable columns
for (PCOL cp = Columns; cp; cp = cp->GetNext()) for (PCOL cp = Columns; cp; cp = cp->GetNext())

View File

@@ -425,7 +425,7 @@ PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b)
if (mysql) { if (mysql) {
#if defined(MYSQL_SUPPORT) #if defined(MYSQL_SUPPORT)
// Access sub-table via MySQL API // Access sub-table via MySQL API
if (!(tdbp= cat->GetTable(g, tabp, MODE_READ, "MYPRX"))) { if (!(tdbp= cat->GetTable(g, tabp, Mode, "MYPRX"))) {
char buf[MAX_STR]; char buf[MAX_STR];
strcpy(buf, g->Message); strcpy(buf, g->Message);
@@ -437,6 +437,9 @@ PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b)
if (db) if (db)
((PTDBMY)tdbp)->SetDatabase(tabp->GetQualifier()); ((PTDBMY)tdbp)->SetDatabase(tabp->GetQualifier());
if (Mode == MODE_UPDATE || Mode == MODE_DELETE)
tdbp->SetName(Name); // For Make_Command
#else // !MYSQL_SUPPORT #else // !MYSQL_SUPPORT
sprintf(g->Message, "%s.%s is not a CONNECT table", sprintf(g->Message, "%s.%s is not a CONNECT table",
db, tblp->Name); db, tblp->Name);
@@ -480,7 +483,7 @@ bool TDBPRX::InitTable(PGLOBAL g)
if (!(Tdbp = GetSubTable(g, ((PPRXDEF)To_Def)->Tablep))) if (!(Tdbp = GetSubTable(g, ((PPRXDEF)To_Def)->Tablep)))
return true; return true;
Tdbp->SetMode(Mode); // Tdbp->SetMode(Mode);
} // endif Tdbp } // endif Tdbp
return false; return false;
@@ -530,16 +533,12 @@ bool TDBPRX::OpenDB(PGLOBAL g)
return Tdbp->OpenDB(g); return Tdbp->OpenDB(g);
} // endif use } // endif use
if (Mode == MODE_DELETE) {
/*******************************************************************/
/* Currently XCOL tables cannot be modified. */
/*******************************************************************/
strcpy(g->Message, "No DELETE for PROXY tables");
return true;
} // endif Mode
if (InitTable(g)) if (InitTable(g))
return true; return true;
else if (Mode != MODE_READ && (Read_Only || Tdbp->IsReadOnly())) {
strcpy(g->Message, "Cannot modify a read only table");
return true;
} // endif tp
/*********************************************************************/ /*********************************************************************/
/* Check and initialize the subtable columns. */ /* Check and initialize the subtable columns. */
@@ -565,7 +564,8 @@ bool TDBPRX::OpenDB(PGLOBAL g)
if (((PPRXCOL)cp)->Init(g, utp)) if (((PPRXCOL)cp)->Init(g, utp))
return true; return true;
} // endif MODE_UPDATE } else if (Mode == MODE_DELETE)
Tdbp->SetNext(Next);
/*********************************************************************/ /*********************************************************************/
/* Physically open the object table. */ /* Physically open the object table. */
@@ -573,6 +573,7 @@ bool TDBPRX::OpenDB(PGLOBAL g)
if (Tdbp->OpenDB(g)) if (Tdbp->OpenDB(g))
return true; return true;
Tdbp->SetNext(NULL);
Use = USE_OPEN; Use = USE_OPEN;
return false; return false;
} // end of OpenDB } // end of OpenDB
@@ -593,8 +594,6 @@ int TDBPRX::ReadDB(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
int TDBPRX::WriteDB(PGLOBAL g) int TDBPRX::WriteDB(PGLOBAL g)
{ {
//sprintf(g->Message, "%s tables are read only", To_Def->GetType());
//return RC_FX;
return Tdbp->WriteDB(g); return Tdbp->WriteDB(g);
} // end of WriteDB } // end of WriteDB
@@ -603,9 +602,7 @@ int TDBPRX::WriteDB(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
int TDBPRX::DeleteDB(PGLOBAL g, int irc) int TDBPRX::DeleteDB(PGLOBAL g, int irc)
{ {
sprintf(g->Message, "Delete not enabled for %s tables", return Tdbp->DeleteDB(g, irc);
To_Def->GetType());
return RC_FX;
} // end of DeleteDB } // end of DeleteDB
/***********************************************************************/ /***********************************************************************/

View File

@@ -388,7 +388,7 @@ void TDBVCT::CloseDB(PGLOBAL g)
To_Kindex = NULL; To_Kindex = NULL;
} // endif } // endif
Txfp->CloseTableFile(g); Txfp->CloseTableFile(g, false);
} // end of CloseDB } // end of CloseDB
// ------------------------ VCTCOL functions ---------------------------- // ------------------------ VCTCOL functions ----------------------------

View File

@@ -366,7 +366,7 @@ int TDBXML::LoadTableFile(PGLOBAL g, char *filename)
/*********************************************************************/ /*********************************************************************/
/* Firstly we check whether this file have been already loaded. */ /* Firstly we check whether this file have been already loaded. */
/*********************************************************************/ /*********************************************************************/
if (Mode == MODE_READ) if (Mode == MODE_READ || Mode == MODE_ANY)
for (fp = dup->Openlist; fp; fp = fp->Next) for (fp = dup->Openlist; fp; fp = fp->Next)
if (fp->Type == type && fp->Length && fp->Count) if (fp->Type == type && fp->Length && fp->Count)
if (!stricmp(fp->Fname, filename)) if (!stricmp(fp->Fname, filename))

View File

@@ -1380,16 +1380,19 @@ err:
/***********************************************************************/ /***********************************************************************/
/* Get Ndif and Num_K from the index file. */ /* Get Ndif and Num_K from the index file. */
/***********************************************************************/ /***********************************************************************/
bool XINDEX::GetAllSizes(PGLOBAL g, int &ndif, int &numk) bool XINDEX::GetAllSizes(PGLOBAL g,/* int &ndif,*/ int &numk)
{ {
char *ftype; char *ftype;
char fn[_MAX_PATH]; char fn[_MAX_PATH];
int n, nv[NZ], id = -1; int nv[NZ], id = -1; // n
bool estim = false; //bool estim = false;
bool rc = true;
PDOSDEF defp = (PDOSDEF)Tdbp->To_Def; PDOSDEF defp = (PDOSDEF)Tdbp->To_Def;
ndif = numk = 0; // ndif = numk = 0;
numk = 0;
#if 0
/*********************************************************************/ /*********************************************************************/
/* Get the estimated table size. */ /* Get the estimated table size. */
/* Note: for fixed tables we must use cardinality to avoid the call */ /* Note: for fixed tables we must use cardinality to avoid the call */
@@ -1417,6 +1420,7 @@ bool XINDEX::GetAllSizes(PGLOBAL g, int &ndif, int &numk)
strcpy(g->Message, MSG(NO_KEY_COL)); strcpy(g->Message, MSG(NO_KEY_COL));
return true; // Error return true; // Error
} // endif Nk } // endif Nk
#endif // 0
switch (Tdbp->Ftype) { switch (Tdbp->Ftype) {
case RECFM_VAR: ftype = ".dnx"; break; case RECFM_VAR: ftype = ".dnx"; break;
@@ -1480,6 +1484,7 @@ bool XINDEX::GetAllSizes(PGLOBAL g, int &ndif, int &numk)
goto err; goto err;
} // endif } // endif
#if 0
if (nv[2]) { if (nv[2]) {
Mul = true; Mul = true;
Ndif = nv[2] - 1; // nv[2] is offset size, equal to Ndif + 1 Ndif = nv[2] - 1; // nv[2] is offset size, equal to Ndif + 1
@@ -1495,9 +1500,11 @@ bool XINDEX::GetAllSizes(PGLOBAL g, int &ndif, int &numk)
sprintf(g->Message, MSG(OPT_NOT_MATCH), fn); sprintf(g->Message, MSG(OPT_NOT_MATCH), fn);
goto err; goto err;
} // endif } // endif
#endif // 0
Num_K = nv[3]; Num_K = nv[3];
#if 0
if (Nk > 1) { if (Nk > 1) {
if (nv[2] && X->Seek(g, nv[2] * sizeof(int), 0, SEEK_CUR)) if (nv[2] && X->Seek(g, nv[2] * sizeof(int), 0, SEEK_CUR))
goto err; goto err;
@@ -1518,17 +1525,18 @@ bool XINDEX::GetAllSizes(PGLOBAL g, int &ndif, int &numk)
Ndif = nv[0]; Ndif = nv[0];
} // endif Nk } // endif Nk
#endif // 0
/*********************************************************************/ /*********************************************************************/
/* Set size values. */ /* Set size values. */
/*********************************************************************/ /*********************************************************************/
ndif = Ndif; //ndif = Ndif;
numk = Num_K; numk = Num_K;
return false; rc = false;
err: err:
X->Close(); X->Close();
return true; return rc;
} // end of GetAllSizes } // end of GetAllSizes
/***********************************************************************/ /***********************************************************************/

View File

@@ -275,7 +275,7 @@ class DllExport XINDEX : public XXBASE {
virtual bool Make(PGLOBAL g, PIXDEF sxp); virtual bool Make(PGLOBAL g, PIXDEF sxp);
virtual bool SaveIndex(PGLOBAL g, PIXDEF sxp); virtual bool SaveIndex(PGLOBAL g, PIXDEF sxp);
virtual bool Reorder(PGLOBAL g); virtual bool Reorder(PGLOBAL g);
bool GetAllSizes(PGLOBAL g, int &ndif, int &numk); bool GetAllSizes(PGLOBAL g,/* int &ndif,*/ int &numk);
protected: protected:
bool AddColumns(PIXDEF xdp); bool AddColumns(PIXDEF xdp);

View File

@@ -79,6 +79,7 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
virtual int GetTdb_No(void) {return Tdb_No;} virtual int GetTdb_No(void) {return Tdb_No;}
virtual PTDB GetNext(void) {return Next;} virtual PTDB GetNext(void) {return Next;}
virtual PCATLG GetCat(void) {return NULL;} virtual PCATLG GetCat(void) {return NULL;}
virtual void SetAbort(bool b) {;}
// Methods // Methods
virtual bool IsSame(PTDB tp) {return tp == this;} virtual bool IsSame(PTDB tp) {return tp == this;}
@@ -125,6 +126,7 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
PCOL Columns; // Points to the first column of the table PCOL Columns; // Points to the first column of the table
MODE Mode; // 10 Read, 30 Update, 40 Insert, 50 Delete MODE Mode; // 10 Read, 30 Update, 40 Insert, 50 Delete
int Degree; // Number of columns int Degree; // Number of columns
int Cardinal; // Table number of rows
}; // end of class TDB }; // end of class TDB
/***********************************************************************/ /***********************************************************************/