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:
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -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. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -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)
|
||||||
|
@@ -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);
|
||||||
|
@@ -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
|
||||||
|
@@ -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:
|
||||||
|
@@ -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
|
||||||
|
@@ -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:
|
||||||
|
@@ -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
|
||||||
|
@@ -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:
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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:
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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:
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
@@ -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:
|
||||||
|
@@ -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);
|
||||||
|
@@ -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 */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -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);
|
||||||
|
355
storage/connect/mysql-test/connect/r/part_file.result
Normal file
355
storage/connect/mysql-test/connect/r/part_file.result
Normal 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;
|
180
storage/connect/mysql-test/connect/r/part_table.result
Normal file
180
storage/connect/mysql-test/connect/r/part_table.result
Normal 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;
|
159
storage/connect/mysql-test/connect/t/part_file.test
Normal file
159
storage/connect/mysql-test/connect/t/part_file.test
Normal 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
|
85
storage/connect/mysql-test/connect/t/part_table.test
Normal file
85
storage/connect/mysql-test/connect/t/part_table.test
Normal 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;
|
@@ -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]);
|
||||||
|
@@ -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, */
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
@@ -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:
|
||||||
|
@@ -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 ----------------------------
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
@@ -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")) {
|
||||||
|
@@ -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();
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
@@ -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. */
|
||||||
|
@@ -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);
|
||||||
|
@@ -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())
|
||||||
|
@@ -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
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -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 ----------------------------
|
||||||
|
@@ -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))
|
||||||
|
@@ -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
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -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);
|
||||||
|
@@ -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
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
Reference in New Issue
Block a user