mariadb/storage/connect/filamvct.cpp

4300 lines
140 KiB
C++
Raw Normal View History

/*********** File AM Vct C++ Program Source Code File (.CPP) ***********/
/* PROGRAM NAME: FILAMVCT */
/* ------------- */
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
/* Version 2.6 */
/* */
/* COPYRIGHT: */
/* ---------- */
2015-03-19 12:21:08 +01:00
/* (C) Copyright to the author Olivier BERTRAND 2005-2015 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
/* This program are the VCT file access method classes. */
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
/* Added in version 2: */
/* - Split Vec format. */
/* - Partial delete. */
/* - Use of tempfile for update. */
/* */
/***********************************************************************/
/***********************************************************************/
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include "my_global.h"
#if defined(WIN32)
#include <io.h>
#include <fcntl.h>
#if defined(__BORLANDC__)
#define __MFC_COMPAT__ // To define min/max as macro
#endif // __BORLAND__
//#include <windows.h>
#include <sys/stat.h>
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
#else // !WIN32
#if defined(UNIX)
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#define NO_ERROR 0
#else // !UNIX
#include <io.h>
#endif // !UNIX
#include <fcntl.h>
#endif // !WIN32
/***********************************************************************/
/* Include application header files: */
/* global.h is header containing all global declarations. */
/* plgdbsem.h is header containing the DB application declarations. */
/* tabdos.h is header containing the TABDOS class declarations. */
/***********************************************************************/
#include "global.h"
#include "osutil.h" // Unuseful for WIN32
#include "plgdbsem.h"
#include "valblk.h"
#include "filamfix.h"
#include "tabdos.h"
#include "tabvct.h"
#include "maputil.h"
#include "filamvct.h"
#ifndef INVALID_SET_FILE_POINTER
#define INVALID_SET_FILE_POINTER ((DWORD)-1)
#endif
extern int num_read, num_there; // Statistics
static int num_write;
#if defined(UNIX)
// Add dummy strerror (NGC)
char *strerror(int num);
#endif // UNIX
/***********************************************************************/
/* Header containing block info for not split VEC tables. */
/* Block and last values can be calculated from NumRec and Nrec. */
/* This is better than directly storing Block and Last because it */
/* make possible to use the same file with tables having a different */
/* block size value (Element -> Nrec) */
/* Note: can be in a separate file if header=1 or a true header (2) */
/***********************************************************************/
typedef struct _vecheader {
//int Block; /* The number of used blocks */
//int Last; /* The number of used records in last block */
int MaxRec; /* Max number of records (True vector format)*/
int NumRec; /* Number of valid records in the table */
} VECHEADER;
/***********************************************************************/
/* Char VCT column blocks are right filled with blanks (blank = true) */
/* Conversion of block values allowed conditionally for insert only. */
/***********************************************************************/
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int, int,
bool check = true, bool blank = true, bool un = false);
/* -------------------------- Class VCTFAM --------------------------- */
/***********************************************************************/
/* Implementation of the VCTFAM class. */
/***********************************************************************/
VCTFAM::VCTFAM(PVCTDEF tdp) : FIXFAM((PDOSDEF)tdp)
{
Last = tdp->GetLast();
MaxBlk = (tdp->GetEstimate() > 0) ?
((tdp->GetEstimate() - 1) / Nrec + 1) : 0;
NewBlock = NULL;
AddBlock = false;
Split = false;
if ((Header = (MaxBlk) ? tdp->Header : 0))
Block = Last = -1;
Bsize = Nrec;
CurNum = Nrec - 1;
Colfn = NULL;
Tempat = NULL;
Clens = NULL;
Deplac = NULL;
Isnum = NULL;
Ncol = 0;
} // end of VCTFAM standard constructor
VCTFAM::VCTFAM(PVCTFAM txfp) : FIXFAM(txfp)
{
MaxBlk = txfp->MaxBlk;
NewBlock = NULL;
AddBlock = false;
Split = txfp->Split;
Header = txfp->Header;
Bsize = txfp->Bsize;
Colfn = txfp->Colfn;
Tempat = txfp->Tempat;
Clens = txfp->Clens;
Deplac = txfp->Deplac;
Isnum = txfp->Isnum;
Ncol = txfp->Ncol;
} // end of VCTFAM copy constructor
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
2014-07-17 18:13:51 +02:00
/***********************************************************************/
/* 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. */
/***********************************************************************/
void VCTFAM::Reset(void)
{
FIXFAM::Reset();
NewBlock = NULL;
AddBlock = false;
CurNum = Nrec - 1;
} // end of Reset
/***********************************************************************/
/* Get the Headlen, Block and Last info from the file header. */
/***********************************************************************/
int VCTFAM::GetBlockInfo(PGLOBAL g)
{
char filename[_MAX_PATH];
int h, k, n;
VECHEADER vh;
if (Header < 1 || Header > 3 || !MaxBlk) {
sprintf(g->Message, "Invalid header value %d", Header);
return -1;
} else
n = (Header == 1) ? (int)sizeof(VECHEADER) : 0;
PlugSetPath(filename, To_File, Tdbp->GetPath());
if (Header == 2)
strcat(PlugRemoveType(filename, filename), ".blk");
if ((h = global_open(g, MSGID_CANNOT_OPEN, filename, O_RDONLY)) == -1
|| !_filelength(h)) {
// Consider this is a void table
Last = Nrec;
Block = 0;
if (h != -1)
close(h);
return n;
} else if (Header == 3)
k = lseek(h, -(int)sizeof(VECHEADER), SEEK_END);
if ((k = read(h, &vh, sizeof(vh))) != sizeof(vh)) {
sprintf(g->Message, "Error reading header file %s", filename);
n = -1;
} else if (MaxBlk * Nrec != vh.MaxRec) {
sprintf(g->Message, "MaxRec=%d doesn't match MaxBlk=%d Nrec=%d",
vh.MaxRec, MaxBlk, Nrec);
n = -1;
} else {
Block = (vh.NumRec > 0) ? (vh.NumRec + Nrec - 1) / Nrec : 0;
Last = (vh.NumRec + Nrec - 1) % Nrec + 1;
} // endif s
close(h);
return n;
} // end of GetBlockInfo
/***********************************************************************/
/* Get the Headlen, Block and Last info from the file header. */
/***********************************************************************/
bool VCTFAM::SetBlockInfo(PGLOBAL g)
{
char filename[_MAX_PATH];
bool rc = false;
size_t n;
VECHEADER vh;
FILE *s;
PlugSetPath(filename, To_File, Tdbp->GetPath());
if (Header != 2) {
if (Stream) {
s = Stream;
if (Header == 1)
/*k =*/ fseek(s, 0, SEEK_SET);
} else
s= global_fopen(g, MSGID_CANNOT_OPEN, filename, "r+b");
} else { // Header == 2
strcat(PlugRemoveType(filename, filename), ".blk");
s= global_fopen(g, MSGID_CANNOT_OPEN, filename, "wb");
} // endif Header
if (!s) {
sprintf(g->Message, "Error opening header file %s", filename);
return true;
} else if (Header == 3)
/*k =*/ fseek(s, -(int)sizeof(VECHEADER), SEEK_END);
vh.MaxRec = MaxBlk * Bsize;
vh.NumRec = (Block - 1) * Nrec + Last;
if ((n = fwrite(&vh, sizeof(vh), 1, s)) != 1) {
sprintf(g->Message, "Error writing header file %s", filename);
rc = true;
} // endif fread
if (Header == 2 || !Stream)
fclose(s);
return rc;
} // end of SetBlockInfo
/***********************************************************************/
/* Use BlockTest to reduce the table estimated size. */
/***********************************************************************/
2015-05-10 12:52:28 +02:00
int VCTFAM::MaxBlkSize(PGLOBAL g, int)
{
int rc = RC_OK, savcur = CurBlk;
int size;
// Roughly estimate the table size as the sum of blocks
// that can contain good rows
for (size = 0, CurBlk = 0; CurBlk < Block; CurBlk++)
if ((rc = Tdbp->TestBlock(g)) == RC_OK)
size += (CurBlk == Block - 1) ? Last : Nrec;
else if (rc == RC_EF)
break;
CurBlk = savcur;
return size;
} // end of MaxBlkSize
/***********************************************************************/
/* VCT Cardinality: returns table cardinality in number of rows. */
/* This function can be called with a null argument to test the */
/* availability of Cardinality implementation (1 yes, 0 no). */
/***********************************************************************/
int VCTFAM::Cardinality(PGLOBAL g)
{
if (!g)
return 1;
if (Block < 0)
if (Split) {
// Separate column files and no pre setting of Block and Last
// This allows to see a table modified externally, but Block
// and Last must be set from the file cardinality.
// Only happens when called by sub classes.
char filename[_MAX_PATH];
PSZ savfn = To_File;
int len, clen, card = -1;
PCOLDEF cdp = Tdbp->GetDef()->GetCols();
if (!Colfn) {
// Prepare the column file name pattern
Colfn = (char*)PlugSubAlloc(g, NULL, _MAX_PATH);
Ncol = ((VCTDEF*)Tdbp->GetDef())->MakeFnPattern(Colfn);
} // endif Colfn
// Use the first column file to calculate the cardinality
clen = cdp->GetClen();
sprintf(filename, Colfn, 1);
To_File = filename;
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
2014-07-17 18:13:51 +02:00
len = TXTFAM::GetFileLength(g);
To_File = savfn;
if (len >= 0) {
if (!(len % clen))
card = len / clen; // Fixed length file
else
sprintf(g->Message, MSG(NOT_FIXED_LEN), To_File, len, clen);
if (trace)
htrc(" Computed max_K=%d Filen=%d Clen=%d\n", card, len, clen);
} else
card = 0;
// Set number of blocks for later use
Block = (card > 0) ? (card + Nrec - 1) / Nrec : 0;
Last = (card + Nrec - 1) % Nrec + 1;
return card;
} else {
// Vector table having Block and Last info in a Header (file)
if ((Headlen = GetBlockInfo(g)) < 0)
return -1; // Error
} // endif split
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
return (Block) ? ((Block - 1) * Nrec + Last) : 0;
} // end of Cardinality
/***********************************************************************/
/* GetRowID: return the RowID of last read record. */
/***********************************************************************/
int VCTFAM::GetRowID(void)
{
return 1 + ((CurBlk < Block) ? CurNum + Nrec * CurBlk
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
: (Block - 1) * Nrec + Last);
} // end of GetRowID
/***********************************************************************/
/* VCT Create an empty file for Vector formatted tables. */
/***********************************************************************/
bool VCTFAM::MakeEmptyFile(PGLOBAL g, char *fn)
{
// Vector formatted file: this will create an empty file of the
// required length if it does not exists yet.
char filename[_MAX_PATH], c = 0;
int h, n;
PlugSetPath(filename, fn, Tdbp->GetPath());
#if defined(WIN32)
h= global_open(g, MSGID_OPEN_EMPTY_FILE, filename, _O_CREAT | _O_WRONLY, S_IREAD | S_IWRITE);
#else // !WIN32
h= global_open(g, MSGID_OPEN_EMPTY_FILE, filename, O_CREAT | O_WRONLY, S_IREAD | S_IWRITE);
#endif // !WIN32
if (h == -1)
return true;
n = (Header == 1 || Header == 3) ? sizeof(VECHEADER) : 0;
if (lseek(h, n + MaxBlk * Nrec * Lrecl - 1, SEEK_SET) < 0)
goto err;
// This actually fills the empty file
if (write(h, &c, 1) < 0)
goto err;
close(h);
return false;
err:
sprintf(g->Message, MSG(MAKE_EMPTY_FILE), To_File, strerror(errno));
close(h);
return true;
} // end of MakeEmptyFile
/***********************************************************************/
/* VCT Access Method opening routine. */
/* New method now that this routine is called recursively (last table */
/* first in reverse order): index blocks are immediately linked to */
/* join block of next table if it exists or else are discarted. */
/***********************************************************************/
bool VCTFAM::OpenTableFile(PGLOBAL g)
{
char opmode[4], filename[_MAX_PATH];
MODE mode = Tdbp->GetMode();
PDBUSER dbuserp = PlgGetUser(g);
/*********************************************************************/
/* Update block info if necessary. */
/*********************************************************************/
if (Block < 0)
if ((Headlen = GetBlockInfo(g)) < 0)
return true;
/*********************************************************************/
/* Open according to input/output mode required. */
/*********************************************************************/
switch (mode) {
case MODE_READ:
strcpy(opmode, "rb");
break;
case MODE_DELETE:
if (!Tdbp->GetNext()) {
// Store the number of deleted lines
DelRows = Cardinality(g);
// This will delete the whole file
strcpy(opmode, "wb");
break;
} // endif
// Selective delete, pass thru
case MODE_UPDATE:
UseTemp = Tdbp->IsUsingTemp(g);
strcpy(opmode, (UseTemp) ? "rb" : "r+b");
break;
case MODE_INSERT:
if (MaxBlk) {
if (!Block)
if (MakeEmptyFile(g, To_File))
return true;
strcpy(opmode, "r+b"); // Required to update empty blocks
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
} else if (!Block || Last == Nrec)
strcpy(opmode, "ab");
else
strcpy(opmode, "r+b"); // Required to update the last block
break;
default:
sprintf(g->Message, MSG(BAD_OPEN_MODE), mode);
return true;
} // endswitch Mode
/*********************************************************************/
/* Use conventionnal input/output functions. */
/*********************************************************************/
PlugSetPath(filename, To_File, Tdbp->GetPath());
if (!(Stream = PlugOpenFile(g, filename, opmode))) {
if (trace)
htrc("%s\n", g->Message);
return (mode == MODE_READ && errno == ENOENT)
? PushWarning(g, Tdbp) : true;
} // endif Stream
if (trace)
htrc("File %s is open in mode %s\n", filename, opmode);
To_Fb = dbuserp->Openlist; // Keep track of File block
if (!strcmp(opmode, "wb"))
// This will stop the process by
// causing GetProgMax to return 0.
return ResetTableSize(g, 0, Nrec);
num_read = num_there = num_write = 0;
// Allocate the table and column block buffer
return AllocateBuffer(g);
} // end of OpenTableFile
/***********************************************************************/
/* Allocate the block buffers for columns used in the query. */
/***********************************************************************/
bool VCTFAM::AllocateBuffer(PGLOBAL g)
{
MODE mode = Tdbp->GetMode();
PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
PCOLDEF cdp;
PVCTCOL cp = (PVCTCOL)Tdbp->GetColumns();
if (mode == MODE_INSERT) {
bool chk = PlgGetUser(g)->Check & CHK_TYPE;
NewBlock = (char*)PlugSubAlloc(g, NULL, Blksize);
for (cdp = defp->GetCols(); cdp; cdp = cdp->GetNext())
memset(NewBlock + Nrec * cdp->GetPoff(),
(IsTypeNum(cdp->GetType()) ? 0 : ' '),
Nrec * cdp->GetClen());
for (; cp; cp = (PVCTCOL)cp->Next)
cp->Blk = AllocValBlock(g, NewBlock + Nrec * cp->Deplac,
cp->Buf_Type, Nrec, cp->Format.Length,
cp->Format.Prec, chk);
return InitInsert(g); // Initialize inserting
} else {
if (UseTemp || mode == MODE_DELETE) {
// Allocate all that is needed to move lines
int i = 0, n = (MaxBlk) ? MaxBlk : 1;
if (!Ncol)
for (cdp = defp->GetCols(); cdp; cdp = cdp->GetNext())
Ncol++;
Clens = (int*)PlugSubAlloc(g, NULL, Ncol * sizeof(int));
Deplac = (int*)PlugSubAlloc(g, NULL, Ncol * sizeof(int));
Isnum = (bool*)PlugSubAlloc(g, NULL, Ncol * sizeof(bool));
for (cdp = defp->GetCols(); cdp; i++, cdp = cdp->GetNext()) {
Clens[i] = cdp->GetClen();
Deplac[i] = Headlen + cdp->GetPoff() * n * Nrec;
Isnum[i] = IsTypeNum(cdp->GetType());
2014-04-21 12:57:10 +02:00
Buflen = MY_MAX(Buflen, cdp->GetClen());
} // endfor cdp
if (!UseTemp || MaxBlk) {
Buflen *= Nrec;
To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
} else
NewBlock = (char*)PlugSubAlloc(g, NULL, Blksize);
} // endif mode
for (; cp; cp = (PVCTCOL)cp->Next)
if (!cp->IsSpecial()) // Not a pseudo column
cp->Blk = AllocValBlock(g, NULL, cp->Buf_Type, Nrec,
cp->Format.Length, cp->Format.Prec);
} //endif mode
return false;
} // end of AllocateBuffer
/***********************************************************************/
/* Do initial action when inserting. */
/***********************************************************************/
bool VCTFAM::InitInsert(PGLOBAL g)
{
// We come here in MODE_INSERT only
if (Last == Nrec) {
CurBlk = Block;
CurNum = 0;
AddBlock = !MaxBlk;
} else {
int rc;
PVCTCOL cp = (PVCTCOL)Tdbp->GetColumns();
// The starting point must be at the end of file as for append.
CurBlk = Block - 1;
CurNum = Last;
// Prepare error return
if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
return true;
} // endif
if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) {
g->jump_level--;
return true;
} // endif
// Last block must be updated by new values
for (; cp; cp = (PVCTCOL)cp->Next)
cp->ReadBlock(g);
g->jump_level--;
} // endif Last
// We are not currently using a temporary file for Insert
T_Stream = Stream;
return false;
} // end of InitInsert
/***********************************************************************/
/* ReadBuffer: Read one line for a VCT file. */
/***********************************************************************/
int VCTFAM::ReadBuffer(PGLOBAL g)
{
int rc = RC_OK;
MODE mode = Tdbp->GetMode();
if (Placed)
Placed = false;
else if ((++CurNum) >= ((CurBlk < Block - 1) ? Nrec : Last)) {
/*******************************************************************/
/* New block. */
/*******************************************************************/
CurNum = 0;
next:
if (++CurBlk == Block)
return RC_EF; // End of file
/*******************************************************************/
/* Before reading a new block, check whether block optimizing */
/* can be done, as well as for join as for local filtering. */
/*******************************************************************/
switch (Tdbp->TestBlock(g)) {
case RC_EF:
return RC_EF;
case RC_NF:
goto next;
} // endswitch rc
num_there++;
} // endif CurNum
if (OldBlk != CurBlk) {
if (mode == MODE_UPDATE) {
/*****************************************************************/
/* Flush the eventually modified column buffers in old blocks */
/* and read the blocks to modify attached to Set columns. */
/*****************************************************************/
if (MoveLines(g)) // For VECFAM
return RC_FX;
for (PVCTCOL colp = (PVCTCOL)Tdbp->GetSetCols();
colp; colp = (PVCTCOL)colp->Next) {
colp->WriteBlock(g);
colp->ReadBlock(g);
} // endfor colp
} // endif mode
OldBlk = CurBlk; // Last block actually read
} // endif oldblk
if (trace)
htrc(" Read: CurNum=%d CurBlk=%d rc=%d\n", CurNum, CurBlk, RC_OK);
return rc;
} // end of ReadBuffer
/***********************************************************************/
/* Data Base write routine for VCT access method. */
/***********************************************************************/
int VCTFAM::WriteBuffer(PGLOBAL g)
{
if (trace)
htrc("VCT WriteBuffer: R%d Mode=%d CurNum=%d CurBlk=%d\n",
Tdbp->GetTdb_No(), Tdbp->GetMode(), CurNum, CurBlk);
if (Tdbp->GetMode() == MODE_UPDATE) {
// Mode Update is done in ReadDB, we just initialize it here
if (!T_Stream) {
if (UseTemp) {
if (OpenTempFile(g))
return RC_FX;
// Most of the time, not all table columns are updated.
// This why we must completely pre-fill the temporary file.
Fpos = (MaxBlk) ? (Block - 1) * Nrec + Last
: Block * Nrec; // To write last lock
if (MoveIntermediateLines(g))
return RC_FX;
} else
T_Stream = Stream;
} // endif T_Stream
} else {
// Mode Insert
if (MaxBlk && CurBlk == MaxBlk) {
strcpy(g->Message, MSG(TRUNC_BY_ESTIM));
return RC_EF; // Too many lines for vector formatted table
} // endif MaxBlk
if (Closing || ++CurNum == Nrec) {
PVCTCOL cp = (PVCTCOL)Tdbp->GetColumns();
if (!AddBlock) {
// Write back the updated last block values
for (; cp; cp = (PVCTCOL)cp->Next)
cp->WriteBlock(g);
if (!Closing && !MaxBlk) {
// For VCT tables, future blocks must be added
char filename[_MAX_PATH];
// Close the file and reopen it in mode Insert
fclose(Stream);
PlugSetPath(filename, To_File, Tdbp->GetPath());
if (!(Stream= global_fopen(g, MSGID_OPEN_MODE_STRERROR, filename, "ab"))) {
Closing = true; // Tell CloseDB of error
return RC_FX;
} // endif Stream
AddBlock = true;
} // endif Closing
} else {
// Here we must add a new block to the file
if (Closing)
// Reset the overwritten columns for last block extra records
for (; cp; cp = (PVCTCOL)cp->Next)
memset(NewBlock + Nrec * cp->Deplac + Last * cp->Clen,
(cp->Buf_Type == TYPE_STRING) ? ' ' : '\0',
(Nrec - Last) * cp->Clen);
if ((size_t)Nrec !=
fwrite(NewBlock, (size_t)Lrecl, (size_t)Nrec, Stream)) {
sprintf(g->Message, MSG(WRITE_STRERROR), To_File, strerror(errno));
return RC_FX;
} // endif
} // endif AddBlock
if (!Closing) {
CurBlk++;
CurNum = 0;
} // endif Closing
} // endif Closing || CurNum
} // endif Mode
return RC_OK;
} // end of WriteBuffer
/***********************************************************************/
/* Data Base delete line routine for VCT access method. */
/* Note: lines are moved directly in the files (ooops...) */
/* Using temp file depends on the Check setting, false by default. */
/***********************************************************************/
int VCTFAM::DeleteRecords(PGLOBAL g, int irc)
{
bool eof = false;
if (trace)
htrc("VCT DeleteDB: rc=%d UseTemp=%d Fpos=%d Tpos=%d Spos=%d\n",
irc, UseTemp, Fpos, Tpos, Spos);
if (irc != RC_OK) {
/*******************************************************************/
/* EOF: position Fpos at the end-of-file position. */
/*******************************************************************/
Fpos = (Block - 1) * Nrec + Last;
if (trace)
htrc("Fpos placed at file end=%d\n", Fpos);
eof = UseTemp && !MaxBlk;
} else // Fpos is the Deleted line position
Fpos = CurBlk * Nrec + CurNum;
if (Tpos == Spos) {
if (UseTemp) {
/*****************************************************************/
/* Open the temporary file, Spos is at the beginning of file. */
/*****************************************************************/
if (OpenTempFile(g))
return RC_FX;
} else {
/*****************************************************************/
/* First line to delete. Move of eventual preceding lines is */
/* not required here, just the setting of future Spos and Tpos. */
/*****************************************************************/
T_Stream = Stream;
Spos = Tpos = Fpos;
} // endif UseTemp
} // endif Tpos == Spos
/*********************************************************************/
/* Move any intermediate lines. */
/*********************************************************************/
if (MoveIntermediateLines(g, &eof))
return RC_FX;
if (irc == RC_OK) {
/*******************************************************************/
/* Reposition the file pointer and set Spos. */
/*******************************************************************/
#ifdef _DEBUG
assert(Spos == Fpos);
#endif
Spos++; // New start position is on next line
if (trace)
htrc("after: Tpos=%d Spos=%d\n", Tpos, Spos);
} else {
/*******************************************************************/
/* Last call after EOF has been reached. */
/* Update the Block and Last values. */
/*******************************************************************/
Block = (Tpos > 0) ? (Tpos + Nrec - 1) / Nrec : 0;
Last = (Tpos + Nrec - 1) % Nrec + 1;
if (!UseTemp) { // The UseTemp case is treated in CloseTableFile
if (!MaxBlk) {
/***************************************************************/
/* Because the chsize functionality is only accessible with a */
/* system call we must close the file and reopen it with the */
/* open function (_fopen for MS ??) this is still to be */
/* checked for compatibility with Text files and other OS's. */
/***************************************************************/
char filename[_MAX_PATH];
int h;
/*rc =*/ CleanUnusedSpace(g); // Clean last block
/*rc =*/ PlugCloseFile(g, To_Fb);
Stream = NULL; // For SetBlockInfo
PlugSetPath(filename, To_File, Tdbp->GetPath());
if ((h= global_open(g, MSGID_OPEN_STRERROR, filename, O_WRONLY)) <= 0)
return RC_FX;
/***************************************************************/
/* Remove extra blocks. */
/***************************************************************/
#if defined(UNIX)
if (ftruncate(h, (off_t)(Headlen + Block * Blksize))) {
sprintf(g->Message, MSG(TRUNCATE_ERROR), strerror(errno));
close(h);
return RC_FX;
} // endif
#else
if (chsize(h, Headlen + Block * Blksize)) {
sprintf(g->Message, MSG(CHSIZE_ERROR), strerror(errno));
close(h);
return RC_FX;
} // endif
#endif
close(h);
if (trace)
htrc("done, h=%d irc=%d\n", h, irc);
} else
// Clean the unused space in the file, this is required when
// inserting again with a partial column list.
if (CleanUnusedSpace(g))
return RC_FX;
if (ResetTableSize(g, Block, Last))
return RC_FX;
} // endif UseTemp
} // endif irc
return RC_OK; // All is correct
} // end of DeleteRecords
/***********************************************************************/
/* Open a temporary file used while updating or deleting. */
/***********************************************************************/
bool VCTFAM::OpenTempFile(PGLOBAL g)
{
char *opmode, tempname[_MAX_PATH];
bool rc = false;
/*********************************************************************/
/* Open the temporary file, Spos is at the beginning of file. */
/*********************************************************************/
PlugSetPath(tempname, To_File, Tdbp->GetPath());
strcat(PlugRemoveType(tempname, tempname), ".t");
if (MaxBlk) {
if (MakeEmptyFile(g, tempname))
return true;
opmode = "r+b";
} else
opmode = "wb";
if (!(T_Stream = PlugOpenFile(g, tempname, opmode))) {
if (trace)
htrc("%s\n", g->Message);
rc = true;
} else
To_Fbt = PlgGetUser(g)->Openlist;
return rc;
} // end of OpenTempFile
/***********************************************************************/
/* Move intermediate deleted or updated lines. */
/***********************************************************************/
bool VCTFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
{
int i, dep, off;
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
int n;
bool eof = (b) ? *b : false;
size_t req, len;
for (n = Fpos - Spos; n > 0 || eof; n -= req) {
/*******************************************************************/
/* Non consecutive line to delete. Move intermediate lines. */
/*******************************************************************/
if (!MaxBlk)
2014-04-21 12:57:10 +02:00
req = (size_t)MY_MIN(n, Nrec - MY_MAX(Spos % Nrec, Tpos % Nrec));
else
2014-04-21 12:57:10 +02:00
req = (size_t)MY_MIN(n, Nrec);
if (req) for (i = 0; i < Ncol; i++) {
if (MaxBlk) {
dep = Deplac[i];
off = Spos * Clens[i];
} else {
if (UseTemp)
To_Buf = NewBlock + Deplac[i] + (Tpos % Nrec) * Clens[i];
dep = Deplac[i] + (Spos / Nrec) * Blksize;
off = (Spos % Nrec) * Clens[i];
} // endif MaxBlk
if (fseek(Stream, dep + off, SEEK_SET)) {
sprintf(g->Message, MSG(READ_SEEK_ERROR), strerror(errno));
return true;
} // endif
len = fread(To_Buf, Clens[i], req, Stream);
if (trace)
htrc("after read req=%d len=%d\n", req, len);
if (len != req) {
sprintf(g->Message, MSG(DEL_READ_ERROR), (int) req, (int) len);
return true;
} // endif len
if (!UseTemp || MaxBlk) {
if (MaxBlk) {
dep = Deplac[i];
off = Tpos * Clens[i];
} else {
dep = Deplac[i] + (Tpos / Nrec) * Blksize;
off = (Tpos % Nrec) * Clens[i];
} // endif MaxBlk
if (fseek(T_Stream, dep + off, SEEK_SET)) {
sprintf(g->Message, MSG(WRITE_SEEK_ERR), strerror(errno));
return true;
} // endif
if ((len = fwrite(To_Buf, Clens[i], req, T_Stream)) != req) {
sprintf(g->Message, MSG(DEL_WRITE_ERROR), strerror(errno));
return true;
} // endif
} // endif UseTemp
if (trace)
htrc("after write pos=%d\n", ftell(Stream));
} // endfor i
Tpos += (int)req;
Spos += (int)req;
if (UseTemp && !MaxBlk && (Tpos % Nrec == 0 || (eof && Spos == Fpos))) {
// Write the full or last block to the temporary file
if ((dep = Nrec - (Tpos % Nrec)) < Nrec)
// Clean the last block in case of future insert,
// must be done here because T_Stream was open in write only.
for (i = 0; i < Ncol; i++) {
To_Buf = NewBlock + Deplac[i] + (Tpos % Nrec) * Clens[i];
memset(To_Buf, (Isnum[i]) ? 0 : ' ', dep * Clens[i]);
} // endfor i
// Write a new block in the temporary file
len = (size_t)Blksize;
if (fwrite(NewBlock, 1, len, T_Stream) != len) {
sprintf(g->Message, MSG(DEL_WRITE_ERROR), strerror(errno));
return true;
} // endif
if (Spos == Fpos)
eof = false;
} // endif UseTemp
if (trace)
htrc("loop: Tpos=%d Spos=%d\n", Tpos, Spos);
} // endfor n
return false;
} // end of MoveIntermediateLines
/***********************************************************************/
/* Clean deleted space in a VCT or Vec table file. */
/***********************************************************************/
bool VCTFAM::CleanUnusedSpace(PGLOBAL g)
{
int i, dep;
int n;
size_t req, len;
if (!MaxBlk) {
/*******************************************************************/
/* Clean last block of the VCT table file. */
/*******************************************************************/
assert(!UseTemp);
if (!(n = Nrec - Last))
return false;
dep = (Block - 1) * Blksize;
req = (size_t)n;
for (i = 0; i < Ncol; i++) {
memset(To_Buf, (Isnum[i]) ? 0 : ' ', n * Clens[i]);
if (fseek(Stream, dep + Deplac[i] + Last * Clens[i], SEEK_SET)) {
sprintf(g->Message, MSG(WRITE_SEEK_ERR), strerror(errno));
return true;
} // endif
if ((len = fwrite(To_Buf, Clens[i], req, Stream)) != req) {
sprintf(g->Message, MSG(DEL_WRITE_ERROR), strerror(errno));
return true;
} // endif
} // endfor i
} else for (n = Fpos - Tpos; n > 0; n -= req) {
/*******************************************************************/
/* Fill VEC file remaining lines with 0's. */
/* Note: this seems to work even column blocks have been made */
/* with Blanks = true. Perhaps should it be set to false for VEC. */
/*******************************************************************/
2014-04-21 12:57:10 +02:00
req = (size_t)MY_MIN(n, Nrec);
memset(To_Buf, 0, Buflen);
for (i = 0; i < Ncol; i++) {
if (fseek(T_Stream, Deplac[i] + Tpos * Clens[i], SEEK_SET)) {
sprintf(g->Message, MSG(WRITE_SEEK_ERR), strerror(errno));
return true;
} // endif
if ((len = fwrite(To_Buf, Clens[i], req, T_Stream)) != req) {
sprintf(g->Message, MSG(DEL_WRITE_ERROR), strerror(errno));
return true;
} // endif
} // endfor i
Tpos += (int)req;
} // endfor n
return false;
} // end of CleanUnusedSpace
/***********************************************************************/
/* Data Base close routine for VCT access method. */
/***********************************************************************/
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
2014-07-17 18:13:51 +02:00
void VCTFAM::CloseTableFile(PGLOBAL g, bool abort)
{
int rc = 0, wrc = RC_OK;
MODE mode = Tdbp->GetMode();
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
Abort = abort;
if (mode == MODE_INSERT) {
if (Closing)
wrc = RC_FX; // Last write was in error
else
if (CurNum) {
// Some more inserted lines remain to be written
Last = CurNum;
Block = CurBlk + 1;
Closing = true;
wrc = WriteBuffer(g);
} else {
Last = Nrec;
Block = CurBlk;
wrc = RC_OK;
} // endif CurNum
if (wrc != RC_FX) {
rc = ResetTableSize(g, Block, Last);
} else if (AddBlock) {
// Last block was not written
rc = ResetTableSize(g, CurBlk, Nrec);
longjmp(g->jumper[g->jump_level], 44);
} // endif
} else if (mode == MODE_UPDATE) {
// Write back to file any pending modifications
for (PVCTCOL colp = (PVCTCOL)((PTDBVCT)Tdbp)->To_SetCols;
colp; colp = (PVCTCOL)colp->Next)
colp->WriteBlock(g);
if (UseTemp && T_Stream) {
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
rc = RenameTempFile(g);
if (Header) {
// Header must be set because it was not set in temp file
Stream = T_Stream = NULL; // For SetBlockInfo
rc = SetBlockInfo(g);
} // endif Header
} // endif UseTemp
} else if (mode == MODE_DELETE && UseTemp && T_Stream) {
if (MaxBlk)
rc = CleanUnusedSpace(g);
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
if ((rc = RenameTempFile(g)) != RC_FX) {
Stream = T_Stream = NULL; // For SetBlockInfo
rc = ResetTableSize(g, Block, Last);
} // endif rc
} // endif's mode
if (!(UseTemp && T_Stream))
rc = PlugCloseFile(g, To_Fb);
if (trace)
htrc("VCT CloseTableFile: closing %s wrc=%d rc=%d\n",
To_File, wrc, rc);
Stream = NULL;
} // end of CloseTableFile
/***********************************************************************/
/* Data Base close routine for VCT access method. */
/***********************************************************************/
bool VCTFAM::ResetTableSize(PGLOBAL g, int block, int last)
{
bool rc = false;
// Set Block and Last values for TDBVCT::MakeBlockValues
Block = block;
Last = last;
if (!Split) {
if (!Header) {
// Update catalog values for Block and Last
PVCTDEF defp = (PVCTDEF)Tdbp->GetDef();
LPCSTR name = Tdbp->GetName();
defp->SetBlock(Block);
defp->SetLast(Last);
if (!defp->SetIntCatInfo("Blocks", Block) ||
!defp->SetIntCatInfo("Last", Last)) {
sprintf(g->Message, MSG(UPDATE_ERROR), "Header");
rc = true;
} // endif
} else
rc = SetBlockInfo(g);
} // endif Split
Tdbp->ResetSize();
return rc;
} // end of ResetTableSize
/***********************************************************************/
/* Rewind routine for VCT access method. */
/***********************************************************************/
void VCTFAM::Rewind(void)
{
// In mode update we need to read Set Column blocks
if (Tdbp->GetMode() == MODE_UPDATE)
OldBlk = -1;
// Initialize so block optimization is called for 1st block
CurBlk = -1;
CurNum = Nrec - 1;
//rewind(Stream); will be placed by fseek
} // end of Rewind
/***********************************************************************/
/* ReadBlock: Read column values from current block. */
/***********************************************************************/
bool VCTFAM::ReadBlock(PGLOBAL g, PVCTCOL colp)
{
int len;
size_t n;
/*********************************************************************/
/* Calculate the offset and size of the block to read. */
/*********************************************************************/
if (MaxBlk) // True vector format
len = Headlen + Nrec * (colp->Deplac * MaxBlk + colp->Clen * CurBlk);
else // Blocked vector format
len = Nrec * (colp->Deplac + Lrecl * CurBlk);
if (trace)
htrc("len=%d Nrec=%d Deplac=%d Lrecl=%d CurBlk=%d maxblk=%d\n",
len, Nrec, colp->Deplac, Lrecl, CurBlk, MaxBlk);
if (fseek(Stream, len, SEEK_SET)) {
sprintf(g->Message, MSG(FSEEK_ERROR), strerror(errno));
return true;
} // endif
n = fread(colp->Blk->GetValPointer(), (size_t)colp->Clen,
(size_t)Nrec, Stream);
if (n != (size_t)Nrec) {
if (errno == NO_ERROR)
sprintf(g->Message, MSG(BAD_READ_NUMBER), (int) n, To_File);
else
sprintf(g->Message, MSG(READ_ERROR),
To_File, strerror(errno));
if (trace)
htrc(" Read error: %s\n", g->Message);
return true;
} // endif
if (trace)
num_read++;
return false;
} // end of ReadBlock
/***********************************************************************/
/* WriteBlock: Write back current column values for one block. */
/* Note: the test of Status is meant to prevent physical writing of */
/* the block during the checking loop in mode Update. It is set to */
/* BUF_EMPTY when reopening the table between the two loops. */
/***********************************************************************/
bool VCTFAM::WriteBlock(PGLOBAL g, PVCTCOL colp)
{
int len;
size_t n;
/*********************************************************************/
/* Calculate the offset and size of the block to write. */
/*********************************************************************/
if (MaxBlk) // File has Vector format
len = Headlen
+ Nrec * (colp->Deplac * MaxBlk + colp->Clen * colp->ColBlk);
else // Old VCT format
len = Nrec * (colp->Deplac + Lrecl * colp->ColBlk);
if (trace)
htrc("modif=%d len=%d Nrec=%d Deplac=%d Lrecl=%d colblk=%d\n",
Modif, len, Nrec, colp->Deplac, Lrecl, colp->ColBlk);
if (fseek(T_Stream, len, SEEK_SET)) {
sprintf(g->Message, MSG(FSEEK_ERROR), strerror(errno));
return true;
} // endif
// Here Nrec was changed to CurNum in mode Insert,
// this is the true number of records to write,
// this also avoid writing garbage in the file for true vector tables.
n = (Tdbp->GetMode() == MODE_INSERT) ? CurNum : Nrec;
if (n != fwrite(colp->Blk->GetValPointer(),
(size_t)colp->Clen, n, T_Stream)) {
sprintf(g->Message, MSG(WRITE_STRERROR),
(UseTemp) ? To_Fbt->Fname : To_File, strerror(errno));
if (trace)
htrc("Write error: %s\n", strerror(errno));
return true;
} // endif
#if defined(UNIX)
fflush(T_Stream); //NGC
#endif
#ifdef _DEBUG
num_write++;
#endif
return false;
} // end of WriteBlock
/* -------------------------- Class VCMFAM --------------------------- */
/***********************************************************************/
/* Implementation of the VCMFAM class. */
/***********************************************************************/
VCMFAM::VCMFAM(PVCTDEF tdp) : VCTFAM((PVCTDEF)tdp)
{
Memory = NULL;
Memcol = NULL;
} // end of VCMFAM standard constructor
VCMFAM::VCMFAM(PVCMFAM txfp) : VCTFAM(txfp)
{
Memory = txfp->Memory;
Memcol = txfp->Memcol;
} // end of VCMFAM copy constructor
/***********************************************************************/
/* Mapped VCT Access Method opening routine. */
/* New method now that this routine is called recursively (last table */
/* first in reverse order): index blocks are immediately linked to */
/* join block of next table if it exists or else are discarted. */
/***********************************************************************/
bool VCMFAM::OpenTableFile(PGLOBAL g)
{
char filename[_MAX_PATH];
int len;
MODE mode = Tdbp->GetMode();
PFBLOCK fp = NULL;
PDBUSER dbuserp = (PDBUSER)g->Activityp->Aptr;
/*********************************************************************/
/* Update block info if necessary. */
/*********************************************************************/
if (Block < 0)
if ((Headlen = GetBlockInfo(g)) < 0)
return true;
/*********************************************************************/
/* We used the file name relative to recorded datapath. */
/*********************************************************************/
PlugSetPath(filename, To_File, Tdbp->GetPath());
/*********************************************************************/
/* The whole file will be mapped so we can use it as if it were */
/* entirely read into virtual memory. */
/* Firstly we check whether this file have been already mapped. */
/*********************************************************************/
if (mode == MODE_READ) {
for (fp = dbuserp->Openlist; fp; fp = fp->Next)
if (fp->Type == TYPE_FB_MAP && !stricmp(fp->Fname, filename)
&& fp->Count && fp->Mode == mode)
break;
if (trace)
htrc("Mapping VCM file, fp=%p cnt=%d\n", fp, fp->Count);
} else
fp = NULL;
if (fp) {
/*******************************************************************/
/* File already mapped. Just increment use count and get pointer. */
/*******************************************************************/
fp->Count++;
Memory = fp->Memory;
len = fp->Length;
} else {
/*******************************************************************/
/* If required, delete the whole file if no filtering is implied. */
/*******************************************************************/
bool del;
HANDLE hFile;
MEMMAP mm;
MODE mapmode = mode;
if (mode == MODE_INSERT) {
if (MaxBlk) {
if (!Block)
if (MakeEmptyFile(g, To_File))
return true;
// Inserting will be like updating the file
mapmode = MODE_UPDATE;
} else {
strcpy(g->Message, "MAP Insert is for VEC Estimate tables only");
return true;
} // endif MaxBlk
} // endif mode
del = mode == MODE_DELETE && !Tdbp->GetNext();
if (del) {
DelRows = Cardinality(g);
// This will stop the process by causing GetProgMax to return 0.
// ResetTableSize(g, 0, Nrec); must be done later
} // endif del
/*******************************************************************/
/* Create the mapping file object. */
/*******************************************************************/
hFile = CreateFileMap(g, filename, &mm, mapmode, del);
if (hFile == INVALID_HANDLE_VALUE) {
DWORD rc = GetLastError();
if (!(*g->Message))
sprintf(g->Message, MSG(OPEN_MODE_ERROR),
"map", (int) rc, filename);
if (trace)
htrc("%s\n", g->Message);
return (mode == MODE_READ && rc == ENOENT)
? PushWarning(g, Tdbp) : true;
} // endif hFile
/*******************************************************************/
/* Get the file size (assuming file is smaller than 4 GB) */
/*******************************************************************/
len = mm.lenL;
Memory = (char *)mm.memory;
if (!len) { // Empty or deleted file
CloseFileHandle(hFile);
bool rc = ResetTableSize(g, 0, Nrec);
return (mapmode == MODE_UPDATE) ? true : rc;
} // endif len
if (!Memory) {
CloseFileHandle(hFile);
sprintf(g->Message, MSG(MAP_VIEW_ERROR),
filename, GetLastError());
return true;
} // endif Memory
if (mode != MODE_DELETE) {
CloseFileHandle(hFile); // Not used anymore
hFile = INVALID_HANDLE_VALUE; // For Fblock
} // endif Mode
/*******************************************************************/
/* Link a Fblock. This make possible to reuse already opened maps */
/* and also to automatically unmap them in case of error g->jump. */
/* Note: block can already exist for previously closed file. */
/*******************************************************************/
fp = (PFBLOCK)PlugSubAlloc(g, NULL, sizeof(FBLOCK));
fp->Type = TYPE_FB_MAP;
2015-03-19 12:21:08 +01:00
fp->Fname = PlugDup(g, filename);
fp->Next = dbuserp->Openlist;
dbuserp->Openlist = fp;
fp->Count = 1;
fp->Length = len;
fp->Memory = Memory;
fp->Mode = mode;
fp->File = NULL;
fp->Handle = hFile; // Used for Delete
} // endif fp
To_Fb = fp; // Useful when closing
if (trace)
htrc("fp=%p count=%d MapView=%p len=%d Top=%p\n",
fp, fp->Count, Memory, len);
return AllocateBuffer(g);
} // end of OpenTableFile
/***********************************************************************/
/* Allocate the block buffers for columns used in the query. */
/* Give a dummy value (1) to prevent allocating the value block. */
/* It will be set pointing into the memory map of the file. */
/* Note: Memcol must be set for all columns because it can be used */
/* for set columns in Update. Clens values are used only in Delete. */
/***********************************************************************/
bool VCMFAM::AllocateBuffer(PGLOBAL g)
{
int m, i = 0;
bool b = Tdbp->GetMode() == MODE_DELETE;
PVCTCOL cp;
PCOLDEF cdp;
PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
// Calculate the number of columns
if (!Ncol)
for (cdp = defp->GetCols(); cdp; cdp = cdp->GetNext())
Ncol++;
// To store the start position of each column
Memcol = (char**)PlugSubAlloc(g, NULL, Ncol * sizeof(char*));
m = (MaxBlk) ? MaxBlk : 1;
// We will need all column sizes and type for Delete
if (b) {
Clens = (int*)PlugSubAlloc(g, NULL, Ncol * sizeof(int));
Isnum = (bool*)PlugSubAlloc(g, NULL, Ncol * sizeof(bool));
} // endif b
for (cdp = defp->GetCols(); i < Ncol; i++, cdp = cdp->GetNext()) {
if (b) {
Clens[i] = cdp->GetClen();
Isnum[i] = IsTypeNum(cdp->GetType());
} // endif b
Memcol[i] = Memory + Headlen + cdp->GetPoff() * m * Nrec;
} // endfor cdp
for (cp = (PVCTCOL)Tdbp->GetColumns(); cp; cp = (PVCTCOL)cp->Next)
if (!cp->IsSpecial()) { // Not a pseudo column
cp->Blk = AllocValBlock(g, (void*)1, cp->Buf_Type, Nrec,
cp->Format.Length, cp->Format.Prec);
cp->AddStatus(BUF_MAPPED);
} // endif IsSpecial
if (Tdbp->GetMode() == MODE_INSERT)
return InitInsert(g);
return false;
} // end of AllocateBuffer
/***********************************************************************/
/* Do initial action when inserting. */
/***********************************************************************/
bool VCMFAM::InitInsert(PGLOBAL g)
{
int rc;
volatile PVCTCOL cp = (PVCTCOL)Tdbp->GetColumns();
// We come here in MODE_INSERT only
if (Last == Nrec) {
CurBlk = Block;
CurNum = 0;
AddBlock = !MaxBlk;
} else {
// The starting point must be at the end of file as for append.
CurBlk = Block - 1;
CurNum = Last;
} // endif Last
// Prepare error return
if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
return true;
} // endif
if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) {
g->jump_level--;
return true;
} // endif
// Initialize the column block pointer
for (; cp; cp = (PVCTCOL)cp->Next)
cp->ReadBlock(g);
g->jump_level--;
return false;
} // end of InitInsert
/***********************************************************************/
/* Data Base write routine for VMP access method. */
/***********************************************************************/
int VCMFAM::WriteBuffer(PGLOBAL g)
{
if (trace)
htrc("VCM WriteBuffer: R%d Mode=%d CurNum=%d CurBlk=%d\n",
Tdbp->GetTdb_No(), Tdbp->GetMode(), CurNum, CurBlk);
// Mode Update being done in ReadDB we process here Insert mode only.
if (Tdbp->GetMode() == MODE_INSERT) {
if (CurBlk == MaxBlk) {
strcpy(g->Message, MSG(TRUNC_BY_ESTIM));
return RC_EF; // Too many lines for vector formatted table
} // endif MaxBlk
if (Closing || ++CurNum == Nrec) {
PVCTCOL cp = (PVCTCOL)Tdbp->GetColumns();
// Write back the updated last block values
for (; cp; cp = (PVCTCOL)cp->Next)
cp->WriteBlock(g);
if (!Closing) {
CurBlk++;
CurNum = 0;
// Re-initialize the column block pointer
for (cp = (PVCTCOL)Tdbp->GetColumns(); cp; cp = (PVCTCOL)cp->Next)
cp->ReadBlock(g);
} // endif Closing
} // endif Closing || CurNum
} // endif Mode
return RC_OK;
} // end of WriteBuffer
/***********************************************************************/
/* Data Base delete line routine for VMP access method. */
/* Lines between deleted lines are moved in the mapfile view. */
/***********************************************************************/
int VCMFAM::DeleteRecords(PGLOBAL g, int irc)
{
if (trace)
htrc("VCM DeleteDB: irc=%d tobuf=%p Tpos=%p Spos=%p\n",
irc, To_Buf, Tpos, Spos);
if (irc != RC_OK) {
/*******************************************************************/
/* EOF: position Fpos at the top of map position. */
/*******************************************************************/
Fpos = (Block - 1) * Nrec + Last;
if (trace)
htrc("Fpos placed at file top=%p\n", Fpos);
} else // Fpos is the Deleted line position
Fpos = CurBlk * Nrec + CurNum;
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
if (Tpos == Spos) {
/*******************************************************************/
/* First line to delete. Move of eventual preceding lines is */
/* not required here, just setting of future Spos and Tpos. */
/*******************************************************************/
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
Tpos = Spos = Fpos;
} else
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
(void)MoveIntermediateLines(g);
if (irc == RC_OK) {
Spos = Fpos + 1; // New start position
if (trace)
htrc("after: Tpos=%p Spos=%p\n", Tpos, Spos);
} else {
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
/*******************************************************************/
/* Last call after EOF has been reached. */
/*******************************************************************/
int i, m, n;
/*******************************************************************/
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
/* Reset the Block and Last values for TDBVCT::MakeBlockValues. */
/*******************************************************************/
Block = (Tpos > 0) ? (Tpos + Nrec - 1) / Nrec : 0;
Last = (Tpos + Nrec - 1) % Nrec + 1;
if (!MaxBlk) {
PFBLOCK fp = To_Fb;
// Clean the unused part of the last block
m = (Block - 1) * Blksize;
n = Nrec - Last;
for (i = 0; i < Ncol; i++)
memset(Memcol[i] + m + Last * Clens[i],
(Isnum[i]) ? 0 : ' ', n * Clens[i]);
// We must Unmap the view and use the saved file handle
// to put an EOF at the end of the last block of the file.
CloseMemMap(fp->Memory, (size_t)fp->Length);
fp->Count = 0; // Avoid doing it twice
// Remove extra blocks
n = Block * Blksize;
#if defined(WIN32)
DWORD drc = SetFilePointer(fp->Handle, n, NULL, FILE_BEGIN);
if (drc == 0xFFFFFFFF) {
sprintf(g->Message, MSG(FUNCTION_ERROR),
"SetFilePointer", GetLastError());
CloseHandle(fp->Handle);
return RC_FX;
} // endif
if (trace)
htrc("done, Tpos=%p newsize=%d drc=%d\n", Tpos, n, drc);
if (!SetEndOfFile(fp->Handle)) {
sprintf(g->Message, MSG(FUNCTION_ERROR),
"SetEndOfFile", GetLastError());
CloseHandle(fp->Handle);
return RC_FX;
} // endif
CloseHandle(fp->Handle);
#else // UNIX
if (ftruncate(fp->Handle, (off_t)n)) {
sprintf(g->Message, MSG(TRUNCATE_ERROR), strerror(errno));
close(fp->Handle);
return RC_FX;
} // endif
close(fp->Handle);
#endif // UNIX
} else
// True vector table, Table file size does not change.
// Just clean the unused part of the file.
for (n = Fpos - Tpos, i = 0; i < Ncol; i++)
memset(Memcol[i] + Tpos * Clens[i], 0, n * Clens[i]);
// Reset Last and Block values in the catalog
PlugCloseFile(g, To_Fb); // in case of Header
ResetTableSize(g, Block, Last);
} // endif irc
return RC_OK; // All is correct
} // end of DeleteRecords
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
/***********************************************************************/
/* Move intermediate deleted or updated lines. */
/***********************************************************************/
2015-05-10 12:52:28 +02:00
bool VCMFAM::MoveIntermediateLines(PGLOBAL, bool *)
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
{
int i, m, n;
if ((n = Fpos - Spos) > 0) {
/*******************************************************************/
/* Non consecutive line to delete. Move intermediate lines. */
/*******************************************************************/
if (!MaxBlk) {
// Old VCT format, moving must respect block limits
char *ps, *pt;
int req, soff, toff;
for (; n > 0; n -= req) {
soff = Spos % Nrec;
toff = Tpos % Nrec;
req = (size_t)MY_MIN(n, Nrec - MY_MAX(soff, toff));
for (i = 0; i < Ncol; i++) {
ps = Memcol[i] + (Spos / Nrec) * Blksize + soff * Clens[i];
pt = Memcol[i] + (Tpos / Nrec) * Blksize + toff * Clens[i];
memmove(pt, ps, req * Clens[i]);
} // endfor i
Tpos += req;
Spos += req;
} // endfor n
} else {
// True vector format, all is simple...
for (i = 0; i < Ncol; i++) {
m = Clens[i];
memmove(Memcol[i] + Tpos * m, Memcol[i] + Spos * m, n * m);
} // endfor i
Tpos += n;
} // endif MaxBlk
if (trace)
htrc("move %d bytes\n", n);
} // endif n
return false;
} // end of MoveIntermediate Lines
/***********************************************************************/
/* Data Base close routine for VMP access method. */
/***********************************************************************/
2015-05-10 12:52:28 +02:00
void VCMFAM::CloseTableFile(PGLOBAL g, bool)
{
int wrc = RC_OK;
MODE mode = Tdbp->GetMode();
if (mode == MODE_INSERT) {
if (!Closing) {
if (CurNum) {
// Some more inserted lines remain to be written
Last = CurNum;
Block = CurBlk + 1;
Closing = true;
wrc = WriteBuffer(g);
} else {
Last = Nrec;
Block = CurBlk;
wrc = RC_OK;
} // endif CurNum
} else
wrc = RC_FX; // Last write was in error
PlugCloseFile(g, To_Fb);
if (wrc != RC_FX)
/*rc =*/ ResetTableSize(g, Block, Last);
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
} else if (mode != MODE_DELETE || Abort)
PlugCloseFile(g, To_Fb);
} // end of CloseTableFile
/***********************************************************************/
/* ReadBlock: Read column values from current block. */
/***********************************************************************/
2015-05-10 12:52:28 +02:00
bool VCMFAM::ReadBlock(PGLOBAL, PVCTCOL colp)
{
char *mempos;
int i = colp->Index - 1;
int n = Nrec * ((MaxBlk || Split) ? colp->Clen : Lrecl);
/*********************************************************************/
/* Calculate the start position of the column block to read. */
/*********************************************************************/
mempos = Memcol[i] + n * CurBlk;
if (trace)
htrc("mempos=%p i=%d Nrec=%d Clen=%d CurBlk=%d\n",
mempos, i, Nrec, colp->Clen, CurBlk);
if (colp->GetStatus(BUF_MAPPED))
colp->Blk->SetValPointer(mempos);
if (trace)
num_read++;
return false;
} // end of ReadBlock
/***********************************************************************/
/* WriteBlock: Write back current column values for one block. */
/* Note: there is nothing to do because we are working directly into */
/* the mapped file, except when checking for Update but in this case */
/* we do not want to write back the modifications either. */
/***********************************************************************/
2015-05-10 12:52:28 +02:00
bool VCMFAM::WriteBlock(PGLOBAL, PVCTCOL colp __attribute__((unused)))
{
#if defined(_DEBUG)
char *mempos;
int i = colp->Index - 1;
int n = Nrec * colp->Clen;
/*********************************************************************/
/* Calculate the offset and size of the block to write. */
/*********************************************************************/
mempos = Memcol[i] + n * CurBlk;
if (trace)
htrc("modif=%d mempos=%p i=%d Nrec=%d Clen=%d colblk=%d\n",
Modif, mempos, i, Nrec, colp->Clen, colp->ColBlk);
#endif // _DEBUG
return false;
} // end of WriteBlock
/* -------------------------- Class VECFAM --------------------------- */
/***********************************************************************/
/* Implementation of the VECFAM class. */
/***********************************************************************/
VECFAM::VECFAM(PVCTDEF tdp) : VCTFAM((PVCTDEF)tdp)
{
Streams = NULL;
To_Fbs = NULL;
To_Bufs = NULL;
Split = true;
Block = Last = -1;
InitUpdate = false;
} // end of VECFAM standard constructor
VECFAM::VECFAM(PVECFAM txfp) : VCTFAM(txfp)
{
Streams = txfp->Streams;
To_Fbs = txfp->To_Fbs;
Clens = txfp->Clens;
To_Bufs = txfp->To_Bufs;
InitUpdate = txfp->InitUpdate;
} // end of VECFAM copy constructor
/***********************************************************************/
/* VEC Access Method opening routine. */
/* New method now that this routine is called recursively (last table */
/* first in reverse order): index blocks are immediately linked to */
/* join block of next table if it exists or else are discarted. */
/***********************************************************************/
bool VECFAM::OpenTableFile(PGLOBAL g)
{
char opmode[4];
int i;
bool b= false;
PCOLDEF cdp;
PVCTCOL cp;
MODE mode = Tdbp->GetMode();
PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
/*********************************************************************/
/* Call Cardinality to set Block and Last values in case it was not */
/* already called (this happens indeed in test xmode) */
/*********************************************************************/
Cardinality(g);
/*********************************************************************/
/* Open according to input/output mode required. */
/*********************************************************************/
switch (mode) {
case MODE_READ:
strcpy(opmode, "rb");
break;
case MODE_DELETE:
if (!Tdbp->GetNext()) {
// Store the number of deleted lines
DelRows = Cardinality(g);
// This will delete the whole file
strcpy(opmode, "wb");
// This will stop the process by causing GetProgMax to return 0.
ResetTableSize(g, 0, Nrec);
break;
} // endif filter
// Selective delete, pass thru
case MODE_UPDATE:
UseTemp = Tdbp->IsUsingTemp(g);
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
strcpy(opmode, (UseTemp) ? "rb": "r+b");
break;
case MODE_INSERT:
strcpy(opmode, "ab");
break;
default:
sprintf(g->Message, MSG(BAD_OPEN_MODE), mode);
return true;
} // endswitch Mode
/*********************************************************************/
/* 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 = ((VCTDEF*)Tdbp->GetDef())->MakeFnPattern(Colfn);
} // endif Colfn
Streams = (FILE* *)PlugSubAlloc(g, NULL, Ncol * sizeof(FILE*));
To_Fbs = (PFBLOCK *)PlugSubAlloc(g, NULL, Ncol * sizeof(PFBLOCK));
for (i = 0; i < Ncol; i++) {
Streams[i] = NULL;
To_Fbs[i] = NULL;
} // endif i
/*********************************************************************/
/* Open the files corresponding to columns used in the query. */
/*********************************************************************/
if (mode == MODE_INSERT || mode == MODE_DELETE) {
// All columns must be written or deleted
for (i = 0, cdp = defp->GetCols(); cdp; i++, cdp = cdp->GetNext())
if (OpenColumnFile(g, opmode, i))
return true;
// Check for void table or missing columns
for (b = !Streams[0], i = 1; i < Ncol; i++)
if (b != !Streams[i])
return true;
} else {
/*******************************************************************/
/* Open the files corresponding to updated columns of the query. */
/*******************************************************************/
for (cp = (PVCTCOL)((PTDBVCT)Tdbp)->To_SetCols; cp;
cp = (PVCTCOL)cp->Next)
if (OpenColumnFile(g, opmode, cp->Index - 1))
return true;
// Open in read only mode the used columns not already open
for (cp = (PVCTCOL)Tdbp->GetColumns(); cp; cp = (PVCTCOL)cp->Next)
if (!cp->IsSpecial() && !Streams[cp->Index - 1])
if (OpenColumnFile(g, "rb", cp->Index - 1))
return true;
// Check for void table or missing columns
for (i = 0, cp = (PVCTCOL)Tdbp->GetColumns(); cp;
cp = (PVCTCOL)cp->Next)
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
if (!cp->IsSpecial()) {
if (!i++)
b = !Streams[cp->Index - 1];
else if (b != !Streams[cp->Index - 1])
return true;
} // endif Special
} // endif mode
/*********************************************************************/
/* Allocate the table and column block buffer. */
/*********************************************************************/
return (b) ? false : AllocateBuffer(g);
} // end of OpenTableFile
/***********************************************************************/
/* Open the file corresponding to one column. */
/***********************************************************************/
bool VECFAM::OpenColumnFile(PGLOBAL g, char *opmode, int i)
{
char filename[_MAX_PATH];
PDBUSER dup = PlgGetUser(g);
sprintf(filename, Colfn, i+1);
if (!(Streams[i] = PlugOpenFile(g, filename, opmode))) {
if (trace)
htrc("%s\n", g->Message);
return (Tdbp->GetMode() == MODE_READ && errno == ENOENT)
? PushWarning(g, Tdbp) : true;
} // endif Streams
if (trace)
htrc("File %s is open in mode %s\n", filename, opmode);
To_Fbs[i] = dup->Openlist; // Keep track of File blocks
return false;
} // end of OpenColumnFile
/***********************************************************************/
/* Allocate the block buffers for columns used in the query. */
/***********************************************************************/
bool VECFAM::AllocateBuffer(PGLOBAL g)
{
int i;
PVCTCOL cp;
PCOLDEF cdp;
PTDBVCT tdbp = (PTDBVCT)Tdbp;
MODE mode = tdbp->GetMode();
PDOSDEF defp = (PDOSDEF)tdbp->GetDef();
if (mode != MODE_READ) {
// Allocate what is needed by all modes except Read
T_Streams = (FILE* *)PlugSubAlloc(g, NULL, Ncol * sizeof(FILE*));
Clens = (int*)PlugSubAlloc(g, NULL, Ncol * sizeof(int));
// Give default values
for (i = 0; i < Ncol; i++) {
T_Streams[i] = Streams[i];
Clens[i] = 0;
} // endfor i
} // endif mode
if (mode == MODE_INSERT) {
bool chk = PlgGetUser(g)->Check & CHK_TYPE;
To_Bufs = (void**)PlugSubAlloc(g, NULL, Ncol * sizeof(void*));
cdp = defp->GetCols();
for (i = 0; cdp && i < Ncol; i++, cdp = cdp->GetNext()) {
Clens[i] = cdp->GetClen();
To_Bufs[i] = PlugSubAlloc(g, NULL, Nrec * Clens[i]);
if (cdp->GetType() == TYPE_STRING)
memset(To_Bufs[i], ' ', Nrec * Clens[i]);
else
memset(To_Bufs[i], 0, Nrec * Clens[i]);
} // endfor cdp
for (cp = (PVCTCOL)tdbp->Columns; cp; cp = (PVCTCOL)cp->Next)
cp->Blk = AllocValBlock(g, To_Bufs[cp->Index - 1],
cp->Buf_Type, Nrec, cp->Format.Length,
cp->Format.Prec, chk);
return InitInsert(g);
} else {
if (UseTemp || mode == MODE_DELETE) {
// Allocate all that is needed to move lines and make Temp
if (UseTemp) {
Tempat = (char*)PlugSubAlloc(g, NULL, _MAX_PATH);
strcpy(Tempat, Colfn);
PlugSetPath(Tempat, Tempat, Tdbp->GetPath());
strcat(PlugRemoveType(Tempat, Tempat), ".t");
T_Fbs = (PFBLOCK *)PlugSubAlloc(g, NULL, Ncol * sizeof(PFBLOCK));
} // endif UseTemp
if (UseTemp)
for (i = 0; i < Ncol; i++) {
T_Streams[i] = (mode == MODE_UPDATE) ? (FILE*)1 : NULL;
T_Fbs[i] = NULL;
} // endfor i
if (mode == MODE_DELETE) { // All columns are moved
cdp = defp->GetCols();
for (i = 0; cdp && i < Ncol; i++, cdp = cdp->GetNext()) {
Clens[i] = cdp->GetClen();
2014-04-21 12:57:10 +02:00
Buflen = MY_MAX(Buflen, cdp->GetClen());
} // endfor cdp
} else { // Mode Update, only some columns are updated
for (cp = (PVCTCOL)tdbp->To_SetCols; cp; cp = (PVCTCOL)cp->Next) {
i = cp->Index -1;
if (UseTemp)
T_Streams[i] = NULL; // Mark the streams to open
Clens[i] = cp->Clen;
2014-04-21 12:57:10 +02:00
Buflen = MY_MAX(Buflen, cp->Clen);
} // endfor cp
InitUpdate = true; // To be initialized
} // endif mode
To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen * Nrec);
} // endif mode
// Finally allocate column buffers for all modes
for (cp = (PVCTCOL)tdbp->Columns; cp; cp = (PVCTCOL)cp->Next)
if (!cp->IsSpecial()) // Not a pseudo column
cp->Blk = AllocValBlock(g, NULL, cp->Buf_Type, Nrec,
cp->Format.Length, cp->Format.Prec);
} // endif mode
return false;
} // end of AllocateBuffer
/***********************************************************************/
/* Do initial action when inserting. */
/***********************************************************************/
2015-05-10 12:52:28 +02:00
bool VECFAM::InitInsert(PGLOBAL)
{
// We come here in MODE_INSERT only
CurBlk = 0;
CurNum = 0;
AddBlock = true;
return false;
} // end of InitInsert
/***********************************************************************/
/* Reset buffer access according to indexing and to mode. */
/* >>>>>>>>>>>>>> TO BE RE-VISITED AND CHECKED <<<<<<<<<<<<<<<<<<<<<< */
/***********************************************************************/
void VECFAM::ResetBuffer(PGLOBAL g)
{
/*********************************************************************/
/* If access is random, performances can be much better when the */
/* reads are done on only one row, except for small tables that can */
/* be entirely read in one block. If the index is just used as a */
/* bitmap filter, as for Update or Delete, reading will be */
/* sequential and we better keep block reading. */
/*********************************************************************/
if (Tdbp->GetKindex() && Block > 1 && Tdbp->GetMode() == MODE_READ) {
Nrec = 1; // Better for random access
Rbuf = 0;
OldBlk = -2; // Has no meaning anymore
Block = Tdbp->Cardinality(g); // Blocks are one line now
Last = 1; // Probably unuseful
} // endif Mode
} // end of ResetBuffer
/***********************************************************************/
/* Data Base write routine for VCT access method. */
/***********************************************************************/
int VECFAM::WriteBuffer(PGLOBAL g)
{
if (trace)
htrc("VCT WriteBuffer: R%d Mode=%d CurNum=%d CurBlk=%d\n",
Tdbp->GetTdb_No(), Tdbp->GetMode(), CurNum, CurBlk);
if (Tdbp->GetMode() == MODE_INSERT) {
if (Closing || ++CurNum == Nrec) {
// Here we must add a new blocks to the files
int i;
size_t n = (size_t)CurNum;
for (i = 0; i < Ncol; i++)
if (n != fwrite(To_Bufs[i], (size_t)Clens[i], n, Streams[i])) {
sprintf(g->Message, MSG(WRITE_STRERROR), To_File, strerror(errno));
return RC_FX;
} // endif
if (!Closing) {
CurBlk++;
CurNum = 0;
} // endif Closing
} // endif Closing || CurNum
} else // Mode Update
// Writing updates being done in ReadDB we do initialization only.
if (InitUpdate) {
if (OpenTempFile(g))
return RC_FX;
InitUpdate = false; // Done
} // endif InitUpdate
return RC_OK;
} // end of WriteBuffer
/***********************************************************************/
/* Data Base delete line routine for split vertical access methods. */
/* Note: lines are moved directly in the files (ooops...) */
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
/* Using temp file depends on the Check setting, false by default. */
/***********************************************************************/
int VECFAM::DeleteRecords(PGLOBAL g, int irc)
{
if (trace)
htrc("VEC DeleteDB: rc=%d UseTemp=%d Fpos=%d Tpos=%d Spos=%d\n",
irc, UseTemp, Fpos, Tpos, Spos);
if (irc != RC_OK) {
/*******************************************************************/
/* EOF: position Fpos at the end-of-file position. */
/*******************************************************************/
Fpos = Cardinality(g);
if (trace)
htrc("Fpos placed at file end=%d\n", Fpos);
} else // Fpos is the Deleted line position
Fpos = CurBlk * Nrec + CurNum;
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
if (Tpos == Spos) {
// First line to delete
if (UseTemp) {
/*****************************************************************/
/* Open the temporary files, Spos is at the beginning of file. */
/*****************************************************************/
if (OpenTempFile(g))
return RC_FX;
} else
/*****************************************************************/
/* Move of eventual preceding lines is not required here. */
/* Set the future Tpos, and give Spos a value to block copying. */
/*****************************************************************/
Spos = Tpos = Fpos;
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
} // endif Tpos == Spos
/*********************************************************************/
/* Move any intermediate lines. */
/*********************************************************************/
if (MoveIntermediateLines(g))
return RC_FX;
if (irc == RC_OK) {
#ifdef _DEBUG
assert(Spos == Fpos);
#endif
Spos++; // New start position is on next line
if (trace)
htrc("after: Tpos=%d Spos=%d\n", Tpos, Spos);
} else {
/*******************************************************************/
/* Last call after EOF has been reached. */
/*******************************************************************/
if (!UseTemp) {
/*****************************************************************/
/* Because the chsize functionality is only accessible with a */
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
/* system call we must close the files and reopen them with the */
/* open function (_fopen for MS??) this is still to be checked */
/* for compatibility with other OS's. */
/*****************************************************************/
char filename[_MAX_PATH];
int h; // File handle, return code
for (int i = 0; i < Ncol; i++) {
sprintf(filename, Colfn, i + 1);
/*rc =*/ PlugCloseFile(g, To_Fbs[i]);
if ((h= global_open(g, MSGID_OPEN_STRERROR, filename, O_WRONLY)) <= 0)
return RC_FX;
/***************************************************************/
/* Remove extra records. */
/***************************************************************/
#if defined(UNIX)
if (ftruncate(h, (off_t)(Tpos * Clens[i]))) {
sprintf(g->Message, MSG(TRUNCATE_ERROR), strerror(errno));
close(h);
return RC_FX;
} // endif
#else
if (chsize(h, Tpos * Clens[i])) {
sprintf(g->Message, MSG(CHSIZE_ERROR), strerror(errno));
close(h);
return RC_FX;
} // endif
#endif
close(h);
if (trace)
htrc("done, h=%d irc=%d\n", h, irc);
} // endfor i
} else // UseTemp
// Ok, now delete old files and rename new temp files
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
if (RenameTempFile(g) == RC_FX)
return RC_FX;
// Reset these values for TDBVCT::MakeBlockValues
Block = (Tpos > 0) ? (Tpos + Nrec - 1) / Nrec : 0;
Last = (Tpos + Nrec - 1) % Nrec + 1;
if (ResetTableSize(g, Block, Last))
return RC_FX;
} // endif irc
return RC_OK; // All is correct
} // end of DeleteRecords
/***********************************************************************/
/* Open temporary files used while updating or deleting. */
/* Note: the files not updated have been given a T_Stream value of 1. */
/***********************************************************************/
bool VECFAM::OpenTempFile(PGLOBAL g)
{
char tempname[_MAX_PATH];
for (int i = 0; i < Ncol; i++)
if (!T_Streams[i]) {
/*****************************************************************/
/* Open the temporary file, Spos is at the beginning of file. */
/*****************************************************************/
sprintf(tempname, Tempat, i+1);
if (!(T_Streams[i] = PlugOpenFile(g, tempname, "wb"))) {
if (trace)
htrc("%s\n", g->Message);
return true;
} else
T_Fbs[i] = PlgGetUser(g)->Openlist;
} else // This is a column that is not updated
T_Streams[i] = NULL; // For RenameTempFile
return false;
} // end of OpenTempFile
/***********************************************************************/
/* Move intermediate updated lines before writing blocks. */
/***********************************************************************/
bool VECFAM::MoveLines(PGLOBAL g)
{
if (UseTemp && !InitUpdate) { // Don't do it in check pass
Fpos = OldBlk * Nrec;
if (MoveIntermediateLines(g)) {
Closing = true; // ???
return true;
} // endif UseTemp
// Spos = Fpos + Nrec;
} // endif UseTemp
return false;
} // end of MoveLines
/***********************************************************************/
/* Move intermediate deleted or updated lines. */
/***********************************************************************/
2015-05-10 12:52:28 +02:00
bool VECFAM::MoveIntermediateLines(PGLOBAL g, bool *)
{
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
int i, n;
bool b = false;
size_t req, len;
for (n = Fpos - Spos; n > 0; n -= Nrec) {
/*******************************************************************/
/* Non consecutive line to delete. Move intermediate lines. */
/*******************************************************************/
2014-04-21 12:57:10 +02:00
req = (size_t)MY_MIN(n, Nrec);
for (i = 0; i < Ncol; i++) {
if (!T_Streams[i])
continue; // Non updated column
if (!UseTemp || !b)
if (fseek(Streams[i], Spos * Clens[i], SEEK_SET)) {
sprintf(g->Message, MSG(READ_SEEK_ERROR), strerror(errno));
return true;
} // endif
len = fread(To_Buf, Clens[i], req, Streams[i]);
if (trace)
htrc("after read req=%d len=%d\n", req, len);
if (len != req) {
sprintf(g->Message, MSG(DEL_READ_ERROR), (int) req, (int) len);
return true;
} // endif len
if (!UseTemp)
if (fseek(T_Streams[i], Tpos * Clens[i], SEEK_SET)) {
sprintf(g->Message, MSG(WRITE_SEEK_ERR), strerror(errno));
return true;
} // endif
if ((len = fwrite(To_Buf, Clens[i], req, T_Streams[i])) != req) {
sprintf(g->Message, MSG(DEL_WRITE_ERROR), strerror(errno));
return true;
} // endif
if (trace)
htrc("after write pos=%d\n", ftell(Streams[i]));
} // endfor i
Tpos += (int)req;
Spos += (int)req;
if (trace)
htrc("loop: Tpos=%d Spos=%d\n", Tpos, Spos);
b = true;
} // endfor n
return false;
} // end of MoveIntermediate Lines
/***********************************************************************/
/* Delete the old files and rename the new temporary files. */
/***********************************************************************/
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
int VECFAM::RenameTempFile(PGLOBAL g)
{
char *tempname, filetemp[_MAX_PATH], filename[_MAX_PATH];
int rc = RC_OK;
// Close all files.
// This loop is necessary because, in case of join,
// the table files can have been open several times.
for (PFBLOCK fb = PlgGetUser(g)->Openlist; fb; fb = fb->Next)
rc = PlugCloseFile(g, fb);
for (int i = 0; i < Ncol && rc == RC_OK; i++) {
if (!T_Fbs[i])
continue;
tempname = (char*)T_Fbs[i]->Fname;
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
2014-07-17 18:13:51 +02:00
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
if (!Abort) {
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
2014-07-17 18:13:51 +02:00
sprintf(filename, Colfn, i+1);
PlugSetPath(filename, filename, Tdbp->GetPath());
strcat(PlugRemoveType(filetemp, filename), ".ttt");
remove(filetemp); // May still be there from previous error
if (rename(filename, filetemp)) { // Save file for security
sprintf(g->Message, MSG(RENAME_ERROR),
filename, filetemp, strerror(errno));
rc = RC_FX;
} else if (rename(tempname, filename)) {
sprintf(g->Message, MSG(RENAME_ERROR),
tempname, filename, strerror(errno));
rc = rename(filetemp, filename); // Restore saved file
rc = RC_FX;
} else if (remove(filetemp)) {
sprintf(g->Message, MSG(REMOVE_ERROR),
filetemp, strerror(errno));
rc = RC_INFO; // Acceptable
} // endif's
} else
remove(tempname);
} // endfor i
return rc;
} // end of RenameTempFile
/***********************************************************************/
/* Data Base close routine for VEC access method. */
/***********************************************************************/
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
2014-07-17 18:13:51 +02:00
void VECFAM::CloseTableFile(PGLOBAL g, bool abort)
{
int rc = 0, wrc = RC_OK;
MODE mode = Tdbp->GetMode();
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
Abort = abort;
if (mode == MODE_INSERT) {
if (Closing)
wrc = RC_FX; // Last write was in error
else
if (CurNum) {
// Some more inserted lines remain to be written
Last += (CurBlk * Nrec + CurNum -1);
Block += (Last / Nrec);
Last = Last % Nrec + 1;
Closing = true;
wrc = WriteBuffer(g);
} else {
Block += CurBlk;
wrc = RC_OK;
} // endif CurNum
if (wrc != RC_FX)
rc = ResetTableSize(g, Block, Last);
else
longjmp(g->jumper[g->jump_level], 44);
} else if (mode == MODE_UPDATE) {
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
if (UseTemp && !InitUpdate && !Abort) {
// Write any intermediate lines to temp file
Fpos = OldBlk * Nrec;
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
Abort = MoveIntermediateLines(g) != RC_OK;
// Spos = Fpos + Nrec;
} // endif UseTemp
// Write back to file any pending modifications
if (wrc == RC_OK)
for (PVCTCOL colp = (PVCTCOL)((PTDBVCT)Tdbp)->To_SetCols;
colp; colp = (PVCTCOL)colp->Next)
colp->WriteBlock(g);
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
if (wrc == RC_OK && UseTemp && !InitUpdate && !Abort) {
// Write any intermediate lines to temp file
Fpos = (Block - 1) * Nrec + Last;
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
Abort = MoveIntermediateLines(g) != RC_OK;
} // endif UseTemp
} // endif's mode
if (UseTemp && !InitUpdate) {
// If they are errors, leave files unchanged
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
rc = RenameTempFile(g);
} else if (Streams)
for (int i = 0; i < Ncol; i++)
if (Streams[i]) {
rc = PlugCloseFile(g, To_Fbs[i]);
Streams[i] = NULL;
To_Fbs[i] = NULL;
} // endif Streams
if (trace)
htrc("VCT CloseTableFile: closing %s wrc=%d rc=%d\n", To_File, wrc, rc);
} // end of CloseTableFile
/***********************************************************************/
/* ReadBlock: Read column values from current block. */
/***********************************************************************/
bool VECFAM::ReadBlock(PGLOBAL g, PVCTCOL colp)
{
int i, len;
size_t n;
/*********************************************************************/
/* Calculate the offset and size of the block to read. */
/*********************************************************************/
len = Nrec * colp->Clen * CurBlk;
i = colp->Index - 1;
if (trace)
htrc("len=%d i=%d Nrec=%d Deplac=%d Lrecl=%d CurBlk=%d\n",
len, i, Nrec, colp->Deplac, Lrecl, CurBlk);
if (fseek(Streams[i], len, SEEK_SET)) {
sprintf(g->Message, MSG(FSEEK_ERROR), strerror(errno));
return true;
} // endif
n = fread(colp->Blk->GetValPointer(), (size_t)colp->Clen,
(size_t)Nrec, Streams[i]);
if (n != (size_t)Nrec && (CurBlk+1 != Block || n != (size_t)Last)) {
char fn[_MAX_PATH];
sprintf(fn, Colfn, colp->Index);
#if defined(WIN32)
if (feof(Streams[i]))
#else // !WIN32
if (errno == NO_ERROR)
#endif // !WIN32
sprintf(g->Message, MSG(BAD_READ_NUMBER), (int) n, fn);
else
sprintf(g->Message, MSG(READ_ERROR),
fn, strerror(errno));
if (trace)
htrc(" Read error: %s\n", g->Message);
return true;
} // endif
if (trace)
num_read++;
return false;
} // end of ReadBlock
/***********************************************************************/
/* WriteBlock: Write back current column values for one block. */
/* Note: the test of Status is meant to prevent physical writing of */
/* the block during the checking loop in mode Update. It is set to */
/* BUF_EMPTY when reopening the table between the two loops. */
/***********************************************************************/
bool VECFAM::WriteBlock(PGLOBAL g, PVCTCOL colp)
{
int i, len;
size_t n;
/*********************************************************************/
/* Calculate the offset and size of the block to write. */
/*********************************************************************/
len = Nrec * colp->Clen * colp->ColBlk;
i = colp->Index - 1;
if (trace)
htrc("modif=%d len=%d i=%d Nrec=%d Deplac=%d Lrecl=%d colblk=%d\n",
Modif, len, i, Nrec, colp->Deplac, Lrecl, colp->ColBlk);
if (Tdbp->GetMode() == MODE_UPDATE && !UseTemp)
if (fseek(T_Streams[i], len, SEEK_SET)) {
sprintf(g->Message, MSG(FSEEK_ERROR), strerror(errno));
return true;
} // endif
// Here Nrec was changed to CurNum in mode Insert,
// this is the true number of records to write,
// this also avoid writing garbage in the file for true vector tables.
n = (Tdbp->GetMode() == MODE_INSERT) ? CurNum
: (colp->ColBlk == Block - 1) ? Last : Nrec;
if (n != fwrite(colp->Blk->GetValPointer(),
(size_t)colp->Clen, n, T_Streams[i])) {
char fn[_MAX_PATH];
sprintf(fn, (UseTemp) ? Tempat : Colfn, colp->Index);
sprintf(g->Message, MSG(WRITE_STRERROR), fn, strerror(errno));
if (trace)
htrc("Write error: %s\n", strerror(errno));
return true;
} else
Spos = Fpos + n;
#if defined(UNIX)
fflush(Streams[i]); //NGC
#endif
return false;
} // end of WriteBlock
/* -------------------------- Class VMPFAM --------------------------- */
/***********************************************************************/
/* Implementation of the VMPFAM class. */
/***********************************************************************/
VMPFAM::VMPFAM(PVCTDEF tdp) : VCMFAM((PVCTDEF)tdp)
{
To_Fbs = NULL;
Split = true;
Block = Last = -1;
} // end of VMPFAM standard constructor
VMPFAM::VMPFAM(PVMPFAM txfp) : VCMFAM(txfp)
{
To_Fbs = txfp->To_Fbs;
} // end of VMPFAM copy constructor
/***********************************************************************/
/* VCT Access Method opening routine. */
/* New method now that this routine is called recursively (last table */
/* first in reverse order): index blocks are immediately linked to */
/* join block of next table if it exists or else are discarted. */
/***********************************************************************/
bool VMPFAM::OpenTableFile(PGLOBAL g)
{
int i;
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
bool b = false;
MODE mode = Tdbp->GetMode();
PCOLDEF cdp;
PVCTCOL cp;
PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
if (mode == MODE_DELETE && !Tdbp->GetNext()) {
DelRows = Cardinality(g);
// This will stop the process by causing GetProgMax to return 0.
ResetTableSize(g, 0, Nrec);
} else
Cardinality(g); // See comment in VECFAM::OpenTbleFile
/*********************************************************************/
/* Prepare the filename pattern for column files and set Ncol. */
/*********************************************************************/
if (!Colfn) {
// Prepare the column file name pattern
Colfn = (char*)PlugSubAlloc(g, NULL, _MAX_PATH);
Ncol = ((VCTDEF*)Tdbp->GetDef())->MakeFnPattern(Colfn);
} // endif Colfn
/*********************************************************************/
/* Initialize the array of file structures. */
/*********************************************************************/
Memcol = (char* *)PlugSubAlloc(g, NULL, Ncol * sizeof(char *));
To_Fbs = (PFBLOCK *)PlugSubAlloc(g, NULL, Ncol * sizeof(PFBLOCK));
for (i = 0; i < Ncol; i++) {
Memcol[i] = NULL;
To_Fbs[i] = NULL;
} // endif i
/*********************************************************************/
/* Open the files corresponding to columns used in the query. */
/*********************************************************************/
if (mode == MODE_DELETE) {
// All columns are used in Delete mode
for (i = 0, cdp = defp->GetCols(); cdp; i++, cdp = cdp->GetNext())
if (MapColumnFile(g, mode, i))
return true;
} else {
/*******************************************************************/
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
/* Open the files corresponding to updated columns of the query. */
/*******************************************************************/
for (cp = (PVCTCOL)((PTDBVCT)Tdbp)->To_SetCols; cp;
cp = (PVCTCOL)cp->Next)
if (MapColumnFile(g, MODE_UPDATE, cp->Index - 1))
return true;
/*******************************************************************/
/* Open other non already open used columns (except pseudos) */
/*******************************************************************/
for (cp = (PVCTCOL)Tdbp->GetColumns(); cp; cp = (PVCTCOL)cp->Next)
if (!cp->IsSpecial() && !Memcol[cp->Index - 1])
if (MapColumnFile(g, MODE_READ, cp->Index - 1))
return true;
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
// Check for void table or missing columns
for (i = 0, cp = (PVCTCOL)Tdbp->GetColumns(); cp;
cp = (PVCTCOL)cp->Next)
if (!cp->IsSpecial()) {
if (!i++)
b = !Memcol[cp->Index - 1];
else if (b != !Memcol[cp->Index - 1])
return true;
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
} // endif Special
} // endif mode
/*********************************************************************/
/* Allocate the table and column block buffer. */
/*********************************************************************/
return (b) ? false : AllocateBuffer(g);
} // end of OpenTableFile
/***********************************************************************/
/* Open the file corresponding to one column. */
/***********************************************************************/
bool VMPFAM::MapColumnFile(PGLOBAL g, MODE mode, int i)
{
char filename[_MAX_PATH];
int len;
HANDLE hFile;
MEMMAP mm;
PFBLOCK fp;
PDBUSER dup = PlgGetUser(g);
sprintf(filename, Colfn, i+1);
/*********************************************************************/
/* The whole file will be mapped so we can use it as */
/* if it were entirely read into virtual memory. */
/* Firstly we check whether this file have been already mapped. */
/*********************************************************************/
if (mode == MODE_READ) {
for (fp = dup->Openlist; fp; fp = fp->Next)
if (fp->Type == TYPE_FB_MAP && !stricmp(fp->Fname, filename)
&& fp->Count && fp->Mode == mode)
break;
if (trace)
htrc("Mapping file, fp=%p\n", fp);
} else
fp = NULL;
if (fp) {
/*******************************************************************/
/* File already mapped. Just increment use count and get pointer. */
/*******************************************************************/
fp->Count++;
Memcol[i] = fp->Memory;
len = fp->Length;
} else {
/*******************************************************************/
/* Create the mapping file object. */
/*******************************************************************/
hFile = CreateFileMap(g, filename, &mm, mode, DelRows);
if (hFile == INVALID_HANDLE_VALUE) {
DWORD rc = GetLastError();
if (!(*g->Message))
sprintf(g->Message, MSG(OPEN_MODE_ERROR),
"map", (int) rc, filename);
if (trace)
htrc("%s\n", g->Message);
return (mode == MODE_READ && rc == ENOENT)
? PushWarning(g, Tdbp) : true;
} // endif hFile
/*****************************************************************/
/* Get the file size (assuming file is smaller than 4 GB) */
/*****************************************************************/
len = mm.lenL;
Memcol[i] = (char *)mm.memory;
if (!len) { // Empty or deleted file
CloseFileHandle(hFile);
ResetTableSize(g, 0, Nrec);
return false;
} // endif len
if (!Memcol[i]) {
CloseFileHandle(hFile);
sprintf(g->Message, MSG(MAP_VIEW_ERROR),
filename, GetLastError());
return true;
} // endif Memory
if (mode != MODE_DELETE) {
CloseFileHandle(hFile); // Not used anymore
hFile = INVALID_HANDLE_VALUE; // For Fblock
} // endif Mode
/*******************************************************************/
/* Link a Fblock. This make possible to reuse already opened maps */
/* and also to automatically unmap them in case of error g->jump. */
/* Note: block can already exist for previously closed file. */
/*******************************************************************/
fp = (PFBLOCK)PlugSubAlloc(g, NULL, sizeof(FBLOCK));
fp->Type = TYPE_FB_MAP;
2015-03-19 12:21:08 +01:00
fp->Fname = PlugDup(g, filename);
fp->Next = dup->Openlist;
dup->Openlist = fp;
fp->Count = 1;
fp->Length = len;
fp->Memory = Memcol[i];
fp->Mode = mode;
fp->File = NULL;
fp->Handle = hFile; // Used for Delete
} // endif fp
To_Fbs[i] = fp; // Useful when closing
if (trace)
htrc("fp=%p count=%d MapView=%p len=%d\n",
fp, fp->Count, Memcol[i], len);
return false;
} // end of MapColumnFile
/***********************************************************************/
/* Allocate the block buffers for columns used in the query. */
/* Give a dummy value (1) to prevent allocating the value block. */
/* It will be set pointing into the memory map of the file. */
/***********************************************************************/
bool VMPFAM::AllocateBuffer(PGLOBAL g)
{
PVCTCOL cp;
if (Tdbp->GetMode() == MODE_DELETE) {
PCOLDEF cdp = Tdbp->GetDef()->GetCols();
Clens = (int*)PlugSubAlloc(g, NULL, Ncol * sizeof(int));
for (int i = 0; cdp && i < Ncol; i++, cdp = cdp->GetNext())
Clens[i] = cdp->GetClen();
} // endif mode
for (cp = (PVCTCOL)Tdbp->GetColumns(); cp; cp = (PVCTCOL)cp->Next)
if (!cp->IsSpecial()) { // Not a pseudo column
cp->Blk = AllocValBlock(g, (void*)1, cp->Buf_Type, Nrec,
cp->Format.Length, cp->Format.Prec);
cp->AddStatus(BUF_MAPPED);
} // endif IsSpecial
return false;
} // end of AllocateBuffer
/***********************************************************************/
/* Data Base delete line routine for VMP access method. */
/* Lines between deleted lines are moved in the mapfile view. */
/***********************************************************************/
int VMPFAM::DeleteRecords(PGLOBAL g, int irc)
{
int i;
int m, n;
if (trace)
htrc("VMP DeleteDB: irc=%d tobuf=%p Tpos=%p Spos=%p\n",
irc, To_Buf, Tpos, Spos);
if (irc != RC_OK) {
/*******************************************************************/
/* EOF: position Fpos at the top of map position. */
/*******************************************************************/
Fpos = (Block - 1) * Nrec + Last;
if (trace)
htrc("Fpos placed at file top=%p\n", Fpos);
} else // Fpos is the Deleted line position
Fpos = CurBlk * Nrec + CurNum;
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
if (Tpos == Spos) {
/*******************************************************************/
/* First line to delete. Move of eventual preceding lines is */
/* not required here, just setting of future Spos and Tpos. */
/*******************************************************************/
Tpos = Fpos; // Spos is set below
} else if ((n = Fpos - Spos) > 0) {
/*******************************************************************/
/* Non consecutive line to delete. Move intermediate lines. */
/*******************************************************************/
for (i = 0; i < Ncol; i++) {
m = Clens[i];
memmove(Memcol[i] + Tpos * m, Memcol[i] + Spos * m, m * n);
} // endif i
Tpos += n;
if (trace)
htrc("move %d bytes\n", n);
} // endif n
if (irc == RC_OK) {
Spos = Fpos + 1; // New start position
if (trace)
htrc("after: Tpos=%p Spos=%p\n", Tpos, Spos);
} else {
/*******************************************************************/
/* Last call after EOF has been reached. */
/* We must firstly Unmap the view and use the saved file handle */
/* to put an EOF at the end of the copied part of the file. */
/*******************************************************************/
PFBLOCK fp;
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
/*******************************************************************/
/* Reset the Block and Last values for TDBVCT::MakeBlockValues. */
/*******************************************************************/
// Block = (Tpos > 0) ? (Tpos + Nrec - 1) / Nrec : 0;
// Last = (Tpos + Nrec - 1) % Nrec + 1;
for (i = 0; i < Ncol; i++) {
fp = To_Fbs[i];
CloseMemMap(fp->Memory, (size_t)fp->Length);
fp->Count = 0; // Avoid doing it twice
/*****************************************************************/
/* Remove extra records. */
/*****************************************************************/
n = Tpos * Clens[i];
#if defined(WIN32)
DWORD drc = SetFilePointer(fp->Handle, n, NULL, FILE_BEGIN);
if (drc == 0xFFFFFFFF) {
sprintf(g->Message, MSG(FUNCTION_ERROR),
"SetFilePointer", GetLastError());
CloseHandle(fp->Handle);
return RC_FX;
} // endif
if (trace)
htrc("done, Tpos=%p newsize=%d drc=%d\n", Tpos, n, drc);
if (!SetEndOfFile(fp->Handle)) {
sprintf(g->Message, MSG(FUNCTION_ERROR),
"SetEndOfFile", GetLastError());
CloseHandle(fp->Handle);
return RC_FX;
} // endif
CloseHandle(fp->Handle);
#else // UNIX
if (ftruncate(fp->Handle, (off_t)n)) {
sprintf(g->Message, MSG(TRUNCATE_ERROR), strerror(errno));
close(fp->Handle);
return RC_FX;
} // endif
close(fp->Handle);
#endif // UNIX
} // endfor i
} // endif irc
return RC_OK; // All is correct
} // end of DeleteRecords
/***********************************************************************/
/* Data Base close routine for VMP access method. */
/***********************************************************************/
2015-05-10 12:52:28 +02:00
void VMPFAM::CloseTableFile(PGLOBAL g, bool)
{
if (Tdbp->GetMode() == MODE_DELETE) {
// Set Block and Nrec values for TDBVCT::MakeBlockValues
Block = (Tpos > 0) ? (Tpos + Nrec - 1) / Nrec : 0;
Last = (Tpos + Nrec - 1) % Nrec + 1;
ResetTableSize(g, Block, Last);
} else if (Tdbp->GetMode() == MODE_INSERT)
assert(false);
for (int i = 0; i < Ncol; i++)
PlugCloseFile(g, To_Fbs[i]);
} // end of CloseTableFile
/* -------------------------- Class BGVFAM --------------------------- */
/***********************************************************************/
/* Implementation of the BGVFAM class. */
/***********************************************************************/
// Constructors
BGVFAM::BGVFAM(PVCTDEF tdp) : VCTFAM(tdp)
{
Hfile = INVALID_HANDLE_VALUE;
Tfile = INVALID_HANDLE_VALUE;
BigDep = NULL;
} // end of BGVFAM constructor
BGVFAM::BGVFAM(PBGVFAM txfp) : VCTFAM(txfp)
{
Hfile = txfp->Hfile;
Tfile = txfp->Tfile;
BigDep= txfp->BigDep;
} // end of BGVFAM copy constructor
/***********************************************************************/
/* Set current position in a big file. */
/***********************************************************************/
bool BGVFAM::BigSeek(PGLOBAL g, HANDLE h, BIGINT pos, bool b)
{
#if defined(WIN32)
char buf[256];
DWORD drc, m = (b) ? FILE_END : FILE_BEGIN;
LARGE_INTEGER of;
of.QuadPart = pos;
of.LowPart = SetFilePointer(h, of.LowPart, &of.HighPart, m);
if (of.LowPart == INVALID_SET_FILE_POINTER &&
(drc = GetLastError()) != NO_ERROR) {
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, drc, 0,
(LPTSTR)buf, sizeof(buf), NULL);
sprintf(g->Message, MSG(SFP_ERROR), buf);
return true;
} // endif
#else // !WIN32
if (lseek64(h, pos, (b) ? SEEK_END : SEEK_SET) < 0) {
sprintf(g->Message, MSG(ERROR_IN_LSK), errno);
return true;
} // endif
#endif // !WIN32
return false;
} // end of BigSeek
/***********************************************************************/
/* Read from a big file. */
/***********************************************************************/
bool BGVFAM::BigRead(PGLOBAL g, HANDLE h, void *inbuf, int req)
{
bool rc = false;
#if defined(WIN32)
DWORD nbr, drc, len = (DWORD)req;
bool brc = ReadFile(h, inbuf, len, &nbr, NULL);
if (trace)
htrc("after read req=%d brc=%d nbr=%d\n", req, brc, nbr);
if (!brc || nbr != len) {
char buf[256]; // , *fn = (h == Hfile) ? To_File : "Tempfile";
if (brc)
strcpy(buf, MSG(BAD_BYTE_READ));
else {
drc = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, drc, 0,
(LPTSTR)buf, sizeof(buf), NULL);
} // endelse brc
sprintf(g->Message, MSG(READ_ERROR), To_File, buf);
if (trace)
htrc("BIGREAD: %s\n", g->Message);
rc = true;
} // endif brc || nbr
#else // !WIN32
size_t len = (size_t)req;
ssize_t nbr = read(h, inbuf, len);
if (nbr != (ssize_t)len) {
const char *fn = (h == Hfile) ? To_File : "Tempfile";
sprintf(g->Message, MSG(READ_ERROR), fn, strerror(errno));
if (trace)
htrc("BIGREAD: nbr=%d len=%d errno=%d %s\n",
nbr, len, errno, g->Message);
rc = true;
} // endif nbr
#endif // !WIN32
return rc;
} // end of BigRead
/***********************************************************************/
/* Write into a big file. */
/***********************************************************************/
bool BGVFAM::BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req)
{
bool rc = false;
#if defined(WIN32)
DWORD nbw, drc, len = (DWORD)req;
bool brc = WriteFile(h, inbuf, len, &nbw, NULL);
if (trace)
htrc("after write req=%d brc=%d nbw=%d\n", req, brc, nbw);
if (!brc || nbw != len) {
char buf[256], *fn = (h == Hfile) ? To_File : "Tempfile";
if (brc)
strcpy(buf, MSG(BAD_BYTE_NUM));
else {
drc = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, drc, 0,
(LPTSTR)buf, sizeof(buf), NULL);
} // endelse brc
sprintf(g->Message, MSG(WRITE_STRERROR), fn, buf);
if (trace)
htrc("BIGWRITE: nbw=%d len=%d errno=%d %s\n",
nbw, len, drc, g->Message);
rc = true;
} // endif brc || nbw
#else // !WIN32
size_t len = (size_t)req;
ssize_t nbw = write(h, inbuf, len);
if (nbw != (ssize_t)len) {
const char *fn = (h == Hfile) ? To_File : "Tempfile";
sprintf(g->Message, MSG(WRITE_STRERROR), fn, strerror(errno));
if (trace)
htrc("BIGWRITE: nbw=%d len=%d errno=%d %s\n",
nbw, len, errno, g->Message);
rc = true;
} // endif nbr
#endif // !WIN32
return rc;
} // end of BigWrite
/***********************************************************************/
/* Get the Headlen, Block and Last info from the file header. */
/***********************************************************************/
int BGVFAM::GetBlockInfo(PGLOBAL g)
{
char filename[_MAX_PATH];
int n;
VECHEADER vh;
HANDLE h;
if (Header < 1 || Header > 3 || !MaxBlk) {
sprintf(g->Message, "Invalid header value %d", Header);
return -1;
} else
n = (Header == 1) ? (int)sizeof(VECHEADER) : 0;
PlugSetPath(filename, To_File, Tdbp->GetPath());
if (Header == 2)
strcat(PlugRemoveType(filename, filename), ".blk");
#if defined(WIN32)
LARGE_INTEGER len;
h = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h != INVALID_HANDLE_VALUE) {
// Get the size of the file (can be greater than 4 GB)
len.LowPart = GetFileSize(h, (LPDWORD)&len.HighPart);
} // endif h
if (h == INVALID_HANDLE_VALUE || !len.QuadPart) {
#else // !WIN32
h = open64(filename, O_RDONLY, 0);
if (h == INVALID_HANDLE_VALUE || !_filelength(h)) {
#endif // !WIN32
// Consider this is a void table
if (trace)
htrc("Void table h=%d\n", h);
Last = Nrec;
Block = 0;
if (h != INVALID_HANDLE_VALUE)
CloseFileHandle(h);
return n;
} else if (Header == 3)
/*b = */ BigSeek(g, h, -(BIGINT)sizeof(vh), true);
if (BigRead(g, h, &vh, sizeof(vh))) {
sprintf(g->Message, "Error reading header file %s", filename);
n = -1;
} else if (MaxBlk * Nrec != vh.MaxRec) {
sprintf(g->Message, "MaxRec=%d doesn't match MaxBlk=%d Nrec=%d",
vh.MaxRec, MaxBlk, Nrec);
n = -1;
} else {
Block = (vh.NumRec > 0) ? (vh.NumRec + Nrec - 1) / Nrec : 0;
Last = (vh.NumRec + Nrec - 1) % Nrec + 1;
if (trace)
htrc("Block=%d Last=%d\n", Block, Last);
} // endif's
CloseFileHandle(h);
return n;
} // end of GetBlockInfo
/***********************************************************************/
/* Set the MaxRec and NumRec info in the file header. */
/***********************************************************************/
bool BGVFAM::SetBlockInfo(PGLOBAL g)
{
char filename[_MAX_PATH];
bool b = false, rc = false;
VECHEADER vh;
HANDLE h = INVALID_HANDLE_VALUE;
PlugSetPath(filename, To_File, Tdbp->GetPath());
if (Header != 2) {
if (Hfile != INVALID_HANDLE_VALUE) {
h = Hfile;
if (Header == 1)
/*bk =*/ BigSeek(g, h, (BIGINT)0);
} else
b = true;
} else // Header == 2
strcat(PlugRemoveType(filename, filename), ".blk");
if (h == INVALID_HANDLE_VALUE) {
#if defined(WIN32)
DWORD creation = (b) ? OPEN_EXISTING : TRUNCATE_EXISTING;
h = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, 0,
NULL, creation, FILE_ATTRIBUTE_NORMAL, NULL);
#else // !WIN32
int oflag = (b) ? O_RDWR : O_RDWR | O_TRUNC;
h = open64(filename, oflag, 0);
#endif // !WIN32
if (h == INVALID_HANDLE_VALUE) {
sprintf(g->Message, "Error opening header file %s", filename);
return true;
} // endif h
} // endif h
if (Header == 3)
/*bk =*/ BigSeek(g, h, -(BIGINT)sizeof(vh), true);
vh.MaxRec = MaxBlk * Bsize;
vh.NumRec = (Block - 1) * Nrec + Last;
if (BigWrite(g, h, &vh, sizeof(vh))) {
sprintf(g->Message, "Error writing header file %s", filename);
rc = true;
} // endif fread
if (Header == 2 || Hfile == INVALID_HANDLE_VALUE)
CloseFileHandle(h);
return rc;
} // end of SetBlockInfo
/***********************************************************************/
/* VEC Create an empty file for new Vector formatted tables. */
/***********************************************************************/
bool BGVFAM::MakeEmptyFile(PGLOBAL g, char *fn)
{
// Vector formatted file this will create an empty file of the
// required length if it does not exists yet.
char filename[_MAX_PATH], c = 0;
int n = (Header == 1 || Header == 3) ? sizeof(VECHEADER) : 0;
PlugSetPath(filename, fn, Tdbp->GetPath());
#if defined(WIN32)
char *p;
DWORD rc;
bool brc;
LARGE_INTEGER of;
HANDLE h;
h = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE) {
p = MSG(OPENING);
goto err;
} // endif h
of.QuadPart = (BIGINT)n + (BIGINT)MaxBlk * (BIGINT)Blksize - (BIGINT)1;
if (trace)
htrc("MEF: of=%lld n=%d maxblk=%d blksize=%d\n",
of.QuadPart, n, MaxBlk, Blksize);
of.LowPart = SetFilePointer(h, of.LowPart,
&of.HighPart, FILE_BEGIN);
if (of.LowPart == INVALID_SET_FILE_POINTER &&
GetLastError() != NO_ERROR) {
p = MSG(MAKING);
goto err;
} // endif
brc = WriteFile(h, &c, 1, &rc, NULL);
if (!brc || rc != 1) {
p = MSG(WRITING);
goto err;
} // endif
CloseHandle(h);
return false;
err:
rc = GetLastError();
sprintf(g->Message, MSG(EMPTY_FILE), p, filename);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)filename, sizeof(filename), NULL);
strcat(g->Message, filename);
if (h != INVALID_HANDLE_VALUE)
CloseHandle(h);
return true;
#else // !WIN32
int h;
BIGINT pos;
h= open64(filename, O_CREAT | O_WRONLY, S_IREAD | S_IWRITE);
if (h == -1)
return true;
pos = (BIGINT)n + (BIGINT)MaxBlk * (BIGINT)Blksize - (BIGINT)1;
if (trace)
htrc("MEF: pos=%lld n=%d maxblk=%d blksize=%d\n",
pos, n, MaxBlk, Blksize);
if (lseek64(h, pos, SEEK_SET) < 0)
goto err;
// This actually fills the empty file
if (write(h, &c, 1) < 0)
goto err;
close(h);
return false;
err:
sprintf(g->Message, MSG(MAKE_EMPTY_FILE), To_File, strerror(errno));
close(h);
return true;
#endif // !WIN32
} // end of MakeEmptyFile
/***********************************************************************/
/* Vopen function: opens a file using Windows or Unix API's. */
/***********************************************************************/
bool BGVFAM::OpenTableFile(PGLOBAL g)
{
char filename[_MAX_PATH];
bool del = false;
MODE mode = Tdbp->GetMode();
PDBUSER dbuserp = PlgGetUser(g);
if ((To_Fb && To_Fb->Count) || Hfile != INVALID_HANDLE_VALUE) {
sprintf(g->Message, MSG(FILE_OPEN_YET), To_File);
return true;
} // endif
/*********************************************************************/
/* Update block info if necessary. */
/*********************************************************************/
if (Block < 0)
if ((Headlen = GetBlockInfo(g)) < 0)
return true;
PlugSetPath(filename, To_File, Tdbp->GetPath());
if (trace)
htrc("OpenTableFile: filename=%s mode=%d Last=%d\n",
filename, mode, Last);
#if defined(WIN32)
DWORD access, creation, share = 0, rc = 0;
/*********************************************************************/
/* Create the file object according to access mode */
/*********************************************************************/
switch (mode) {
case MODE_READ:
access = GENERIC_READ;
share = FILE_SHARE_READ;
creation = OPEN_EXISTING;
break;
case MODE_INSERT:
if (MaxBlk) {
if (!Block)
if (MakeEmptyFile(g, To_File))
return true;
// Required to update empty blocks
access = GENERIC_READ | GENERIC_WRITE;
} else if (Last == Nrec)
access = GENERIC_WRITE;
else
// Required to update the last block
access = GENERIC_READ | GENERIC_WRITE;
creation = OPEN_ALWAYS;
break;
case MODE_DELETE:
if (!Tdbp->GetNext()) {
// Store the number of deleted lines
DelRows = Cardinality(g);
// This will stop the process by
// causing GetProgMax to return 0.
// ResetTableSize(g, 0, Nrec); must be done later
del = true;
// This will delete the whole file
access = GENERIC_READ | GENERIC_WRITE;
creation = TRUNCATE_EXISTING;
break;
} // endif
// Selective delete, pass thru
case MODE_UPDATE:
if ((UseTemp = Tdbp->IsUsingTemp(g)))
access = GENERIC_READ;
else
access = GENERIC_READ | GENERIC_WRITE;
creation = OPEN_EXISTING;
break;
default:
sprintf(g->Message, MSG(BAD_OPEN_MODE), mode);
return true;
} // endswitch
/*********************************************************************/
/* Use specific Windows API functions. */
/*********************************************************************/
Hfile = CreateFile(filename, access, share, NULL, creation,
FILE_ATTRIBUTE_NORMAL, NULL);
if (Hfile == INVALID_HANDLE_VALUE) {
rc = GetLastError();
sprintf(g->Message, MSG(OPEN_ERROR), rc, mode, filename);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)filename, sizeof(filename), NULL);
strcat(g->Message, filename);
} // endif Hfile
if (trace)
htrc(" rc=%d access=%p share=%p creation=%d handle=%p fn=%s\n",
rc, access, share, creation, Hfile, filename);
if (mode == MODE_INSERT) {
/*******************************************************************/
/* In Insert mode we must position the cursor at end of file. */
/*******************************************************************/
LARGE_INTEGER of;
of.QuadPart = (BIGINT)0;
of.LowPart = SetFilePointer(Hfile, of.LowPart,
&of.HighPart, FILE_END);
if (of.LowPart == INVALID_SET_FILE_POINTER &&
(rc = GetLastError()) != NO_ERROR) {
sprintf(g->Message, MSG(ERROR_IN_SFP), rc);
CloseHandle(Hfile);
Hfile = INVALID_HANDLE_VALUE;
} // endif
} // endif Mode
#else // UNIX
/*********************************************************************/
/* The open() function has a transitional interface for 64-bit */
/* file offsets. Note that using open64() is equivalent to using */
/* open() with O_LARGEFILE set in oflag (see Xopen in tabfix.cpp). */
/*********************************************************************/
int rc = 0;
int oflag;
mode_t pmd = 0;
/*********************************************************************/
/* Create the file object according to access mode */
/*********************************************************************/
switch (mode) {
case MODE_READ:
oflag = O_RDONLY;
break;
case MODE_INSERT:
if (MaxBlk) {
if (!Block)
if (MakeEmptyFile(g, To_File))
return true;
// Required to update empty blocks
oflag = O_RDWR;
} else if (Last == Nrec)
oflag = O_WRONLY | O_CREAT | O_APPEND;
else
// Required to update the last block
oflag = O_RDWR | O_CREAT | O_APPEND;
pmd = S_IREAD | S_IWRITE;
break;
case MODE_DELETE:
// This is temporary until a partial delete is implemented
if (!Tdbp->GetNext()) {
// Store the number of deleted lines
DelRows = Cardinality(g);
del = true;
// This will delete the whole file and provoque ReadDB to
// return immediately.
oflag = O_RDWR | O_TRUNC;
strcpy(g->Message, MSG(NO_VCT_DELETE));
break;
} // endif
// Selective delete, pass thru
case MODE_UPDATE:
UseTemp = Tdbp->IsUsingTemp(g);
oflag = (UseTemp) ? O_RDONLY : O_RDWR;
break;
default:
sprintf(g->Message, MSG(BAD_OPEN_MODE), mode);
return true;
} // endswitch
Hfile = open64(filename, oflag, pmd); // Enable file size > 2G
if (Hfile == INVALID_HANDLE_VALUE) {
rc = errno;
sprintf(g->Message, MSG(OPEN_ERROR), rc, mode, filename);
strcat(g->Message, strerror(errno));
} // endif Hfile
if (trace)
htrc(" rc=%d oflag=%p mode=%p handle=%d fn=%s\n",
rc, oflag, mode, Hfile, filename);
#endif // UNIX
if (!rc) {
if (!To_Fb) {
To_Fb = (PFBLOCK)PlugSubAlloc(g, NULL, sizeof(FBLOCK));
To_Fb->Fname = To_File;
To_Fb->Type = TYPE_FB_HANDLE;
To_Fb->Memory = NULL;
To_Fb->Length = 0;
To_Fb->File = NULL;
To_Fb->Next = dbuserp->Openlist;
dbuserp->Openlist = To_Fb;
} // endif To_Fb
To_Fb->Count = 1;
To_Fb->Mode = mode;
To_Fb->Handle = Hfile;
if (trace)
htrc("File %s is open in mode %d\n", filename, mode);
if (del)
// This will stop the process by
// causing GetProgMax to return 0.
return ResetTableSize(g, 0, Nrec);
/*********************************************************************/
/* Allocate the table and column block buffers. */
/*********************************************************************/
return AllocateBuffer(g);
} else
return (mode == MODE_READ && rc == ENOENT)
? PushWarning(g, Tdbp) : true;
} // end of OpenTableFile
/***********************************************************************/
/* Allocate the block buffers for columns used in the query. */
/***********************************************************************/
bool BGVFAM::AllocateBuffer(PGLOBAL g)
{
MODE mode = Tdbp->GetMode();
PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
PCOLDEF cdp;
PVCTCOL cp = (PVCTCOL)Tdbp->GetColumns();
if (mode == MODE_INSERT) {
if (!NewBlock) {
// Not reopening after inserting the last block
bool chk = PlgGetUser(g)->Check & CHK_TYPE;
NewBlock = (char*)PlugSubAlloc(g, NULL, Blksize);
for (cdp = defp->GetCols(); cdp; cdp = cdp->GetNext())
memset(NewBlock + Nrec * cdp->GetPoff(),
(IsTypeNum(cdp->GetType()) ? 0 : ' '),
Nrec * cdp->GetClen());
for (; cp; cp = (PVCTCOL)cp->Next)
cp->Blk = AllocValBlock(g, NewBlock + Nrec * cp->Deplac,
cp->Buf_Type, Nrec, cp->Format.Length,
cp->Format.Prec, chk);
InitInsert(g); // Initialize inserting
// Currently we don't use a temporary file for inserting
Tfile = Hfile;
} // endif NewBlock
} else {
if (UseTemp || mode == MODE_DELETE) {
// Allocate all that is needed to move lines
int i = 0;
if (!Ncol)
for (cdp = defp->GetCols(); cdp; cdp = cdp->GetNext())
Ncol++;
if (MaxBlk)
BigDep = (BIGINT*)PlugSubAlloc(g, NULL, Ncol * sizeof(BIGINT));
else
Deplac = (int*)PlugSubAlloc(g, NULL, Ncol * sizeof(int));
Clens = (int*)PlugSubAlloc(g, NULL, Ncol * sizeof(int));
Isnum = (bool*)PlugSubAlloc(g, NULL, Ncol * sizeof(bool));
for (cdp = defp->GetCols(); cdp; i++, cdp = cdp->GetNext()) {
if (MaxBlk)
BigDep[i] = (BIGINT)Headlen
+ (BIGINT)(cdp->GetPoff() * Nrec) * (BIGINT)MaxBlk;
else
Deplac[i] = cdp->GetPoff() * Nrec;
Clens[i] = cdp->GetClen();
Isnum[i] = IsTypeNum(cdp->GetType());
2014-04-21 12:57:10 +02:00
Buflen = MY_MAX(Buflen, cdp->GetClen());
} // endfor cdp
if (!UseTemp || MaxBlk) {
Buflen *= Nrec;
To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
} else
NewBlock = (char*)PlugSubAlloc(g, NULL, Blksize);
} // endif mode
for (; cp; cp = (PVCTCOL)cp->Next)
if (!cp->IsSpecial()) // Not a pseudo column
cp->Blk = AllocValBlock(g, NULL, cp->Buf_Type, Nrec,
cp->Format.Length, cp->Format.Prec);
} //endif mode
return false;
} // end of AllocateBuffer
/***********************************************************************/
/* Data Base write routine for huge VCT access method. */
/***********************************************************************/
int BGVFAM::WriteBuffer(PGLOBAL g)
{
if (trace)
htrc("BGV WriteDB: R%d Mode=%d CurNum=%d CurBlk=%d\n",
Tdbp->GetTdb_No(), Tdbp->GetMode(), CurNum, CurBlk);
if (Tdbp->GetMode() == MODE_UPDATE) {
// Mode Update is done in ReadDB, we just initialize it here
if (Tfile == INVALID_HANDLE_VALUE) {
if (UseTemp) {
if (OpenTempFile(g))
return RC_FX;
// Most of the time, not all table columns are updated.
// This why we must completely pre-fill the temporary file.
Fpos = (MaxBlk) ? (Block - 1) * Nrec + Last
: Block * Nrec; // To write last lock
if (MoveIntermediateLines(g))
return RC_FX;
} else
Tfile = Hfile;
} // endif Tfile
} else {
// Mode Insert
if (MaxBlk && CurBlk == MaxBlk) {
strcpy(g->Message, MSG(TRUNC_BY_ESTIM));
return RC_EF; // Too many lines for a Vector formatted table
} // endif MaxBlk
if (Closing || ++CurNum == Nrec) {
PVCTCOL cp = (PVCTCOL)Tdbp->GetColumns();
if (!AddBlock) {
// Write back the updated last block values
for (; cp; cp = (PVCTCOL)cp->Next)
cp->WriteBlock(g);
if (!Closing && !MaxBlk) {
// Close the VCT file and reopen it in mode Insert
//#if defined(WIN32) //OB
// CloseHandle(Hfile);
//#else // UNIX
// close(Hfile);
//#endif // UNIX
CloseFileHandle(Hfile);
Hfile = INVALID_HANDLE_VALUE;
To_Fb->Count = 0;
Last = Nrec; // Tested in OpenTableFile
if (OpenTableFile(g)) {
Closing = true; // Tell CloseDB of error
return RC_FX;
} // endif Vopen
AddBlock = true;
} // endif Closing
} else {
// Here we must add a new block to the VCT file
if (Closing)
// Reset the overwritten columns for last block extra records
for (; cp; cp = (PVCTCOL)cp->Next)
memset(NewBlock + Nrec * cp->Deplac + Last * cp->Clen,
(cp->Buf_Type == TYPE_STRING) ? ' ' : '\0',
(Nrec - Last) * cp->Clen);
if (BigWrite(g, Hfile, NewBlock, Blksize))
return RC_FX;
} // endif AddBlock
if (!Closing) {
CurBlk++;
CurNum = 0;
} // endif Closing
} // endif
} // endif Mode
return RC_OK;
} // end of WriteBuffer
/***********************************************************************/
/* Data Base delete line routine for BGVFAM access method. */
/***********************************************************************/
int BGVFAM::DeleteRecords(PGLOBAL g, int irc)
{
bool eof = false;
/*********************************************************************/
/* There is an alternative here depending on UseTemp: */
/* 1 - use a temporary file in which are copied all not deleted */
/* lines, at the end the original file will be deleted and */
/* the temporary file renamed to the original file name. */
/* 2 - directly move the not deleted lines inside the original */
/* file, and at the end erase all trailing records. */
/*********************************************************************/
if (trace)
htrc("BGV DeleteDB: irc=%d UseTemp=%d Fpos=%d Tpos=%d Spos=%d\n",
irc, UseTemp, Fpos, Tpos, Spos);
if (irc != RC_OK) {
/*******************************************************************/
/* EOF: position Fpos at the end-of-file position. */
/*******************************************************************/
Fpos = (Block - 1) * Nrec + Last;
if (trace)
htrc("Fpos placed at file end=%d\n", Fpos);
eof = UseTemp && !MaxBlk;
} else // Fpos is the deleted line position
Fpos = CurBlk * Nrec + CurNum;
if (Tpos == Spos) {
if (UseTemp) {
/*****************************************************************/
/* Open the temporary file, Spos is at the beginning of file. */
/*****************************************************************/
if (OpenTempFile(g))
return RC_FX;
} else {
/*****************************************************************/
/* Move of eventual preceding lines is not required here. */
/* Set the target file as being the source file itself. */
/* Set the future Tpos, and give Spos a value to block copying. */
/*****************************************************************/
Tfile = Hfile;
Spos = Tpos = Fpos;
} // endif UseTemp
} // endif Tpos == Spos
/*********************************************************************/
/* Move any intermediate lines. */
/*********************************************************************/
if (MoveIntermediateLines(g, &eof))
return RC_FX;
if (irc == RC_OK) {
#ifdef _DEBUG
assert(Spos == Fpos);
#endif
Spos++; // New start position is on next line
if (trace)
htrc("after: Tpos=%d Spos=%d\n", Tpos, Spos);
} else {
/*******************************************************************/
/* Last call after EOF has been reached. */
/*******************************************************************/
Block = (Tpos > 0) ? (Tpos + Nrec - 1) / Nrec : 0;
Last = (Tpos + Nrec - 1) % Nrec + 1;
if (!UseTemp) { // The UseTemp case is treated in CloseTableFile
if (!MaxBlk) {
if (Last < Nrec) // Clean last block
if (CleanUnusedSpace(g))
return RC_FX;
/***************************************************************/
/* Remove extra records. */
/***************************************************************/
#if defined(WIN32)
BIGINT pos = (BIGINT)Block * (BIGINT)Blksize;
if (BigSeek(g, Hfile, pos))
return RC_FX;
if (!SetEndOfFile(Hfile)) {
DWORD drc = GetLastError();
sprintf(g->Message, MSG(SETEOF_ERROR), drc);
return RC_FX;
} // endif error
#else // !WIN32
if (ftruncate64(Hfile, (BIGINT)(Tpos * Lrecl))) {
sprintf(g->Message, MSG(TRUNCATE_ERROR), strerror(errno));
return RC_FX;
} // endif
#endif // !WIN32
} else // MaxBlk
// Clean the unused space in the file, this is required when
// inserting again with a partial column list.
if (CleanUnusedSpace(g))
return RC_FX;
if (ResetTableSize(g, Block, Last))
return RC_FX;
} // endif UseTemp
} // endif irc
return RC_OK; // All is correct
} // end of DeleteRecords
/***********************************************************************/
/* Open a temporary file used while updating or deleting. */
/***********************************************************************/
bool BGVFAM::OpenTempFile(PGLOBAL g)
{
char *tempname;
PDBUSER dup = PlgGetUser(g);
/*********************************************************************/
/* Open the temporary file, Spos is at the beginning of file. */
/*********************************************************************/
tempname = (char*)PlugSubAlloc(g, NULL, _MAX_PATH);
PlugSetPath(tempname, To_File, Tdbp->GetPath());
strcat(PlugRemoveType(tempname, tempname), ".t");
if (!MaxBlk)
remove(tempname); // Be sure it does not exist yet
else if (MakeEmptyFile(g, tempname))
return true;
#if defined(WIN32)
DWORD access = (MaxBlk) ? OPEN_EXISTING : CREATE_NEW;
Tfile = CreateFile(tempname, GENERIC_WRITE, 0, NULL,
access, FILE_ATTRIBUTE_NORMAL, NULL);
if (Tfile == INVALID_HANDLE_VALUE) {
DWORD rc = GetLastError();
sprintf(g->Message, MSG(OPEN_ERROR), rc, MODE_DELETE, tempname);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)tempname, _MAX_PATH, NULL);
strcat(g->Message, tempname);
return true;
} // endif Tfile
#else // UNIX
int oflag = (MaxBlk) ? O_WRONLY : O_WRONLY | O_TRUNC;
Tfile = open64(tempname, oflag, S_IWRITE);
if (Tfile == INVALID_HANDLE_VALUE) {
int rc = errno;
sprintf(g->Message, MSG(OPEN_ERROR), rc, MODE_INSERT, tempname);
strcat(g->Message, strerror(errno));
return true;
} //endif Tfile
#endif // UNIX
To_Fbt = (PFBLOCK)PlugSubAlloc(g, NULL, sizeof(FBLOCK));
To_Fbt->Fname = tempname;
To_Fbt->Type = TYPE_FB_HANDLE;
To_Fbt->Memory = NULL;
To_Fbt->Length = 0;
To_Fbt->File = NULL;
To_Fbt->Next = dup->Openlist;
To_Fbt->Count = 1;
To_Fbt->Mode = MODE_INSERT;
To_Fbt->Handle = Tfile;
dup->Openlist = To_Fbt;
return false;
} // end of OpenTempFile
/***********************************************************************/
/* Move intermediate deleted or updated lines. */
/***********************************************************************/
bool BGVFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
{
int i, n, req, dep;
bool eof = (b) ? *b : false;
BIGINT pos;
for (n = Fpos - Spos; n > 0 || eof; n -= req) {
/*******************************************************************/
/* Non consecutive line to delete. Move intermediate lines. */
/*******************************************************************/
if (!MaxBlk)
2014-04-21 12:57:10 +02:00
req = (DWORD)MY_MIN(n, Nrec - MY_MAX(Spos % Nrec, Tpos % Nrec));
else
2014-04-21 12:57:10 +02:00
req = (DWORD)MY_MIN(n, Nrec);
if (req) for (i = 0; i < Ncol; i++) {
if (!MaxBlk) {
if (UseTemp)
To_Buf = NewBlock + Deplac[i] + (Tpos % Nrec) * Clens[i];
pos = (BIGINT)Deplac[i] + (BIGINT)((Spos % Nrec) * Clens[i])
+ (BIGINT)(Spos / Nrec) * (BIGINT)Blksize;
} else
pos = BigDep[i] + (BIGINT)Spos * (BIGINT)Clens[i];
if (BigSeek(g, Hfile, pos))
return true;
if (BigRead(g, Hfile, To_Buf, req * Clens[i]))
return true;
if (!UseTemp || MaxBlk) {
if (!MaxBlk)
pos = (BIGINT)Deplac[i] + (BIGINT)((Tpos % Nrec) * Clens[i])
+ (BIGINT)(Tpos / Nrec) * (BIGINT)Blksize;
else
pos = BigDep[i] + (BIGINT)Tpos * (BIGINT)Clens[i];
if (BigSeek(g, Tfile, pos))
return true;
if (BigWrite(g, Tfile, To_Buf, req * Clens[i]))
return true;
} // endif UseTemp
} // endfor i
Tpos += (int)req;
Spos += (int)req;
if (UseTemp && !MaxBlk && (!(Tpos % Nrec) || (eof && Spos == Fpos))) {
// Write the full or last block to the temporary file
if ((dep = Nrec - (Tpos % Nrec)) < Nrec)
// Clean the last block in case of future insert, must be
// done here because Tfile was open in write only.
for (i = 0; i < Ncol; i++) {
To_Buf = NewBlock + Deplac[i] + (Tpos % Nrec) * Clens[i];
memset(To_Buf, (Isnum[i]) ? 0 : ' ', dep * Clens[i]);
} // endfor i
if (BigWrite(g, Tfile, NewBlock, Blksize))
return true;
if (Spos == Fpos)
eof = false;
} // endif Usetemp...
if (trace)
htrc("loop: Tpos=%d Spos=%d\n", Tpos, Spos);
} // endfor n
return false;
} // end of MoveIntermediateLines
/***********************************************************************/
/* Clean deleted space in a huge VCT or Vec table file. */
/***********************************************************************/
bool BGVFAM::CleanUnusedSpace(PGLOBAL g)
{
int i;
int n;
BIGINT pos, dep;
if (!MaxBlk) {
/*******************************************************************/
/* Clean last block of the VCT table file. */
/*******************************************************************/
assert(!UseTemp); // This case is handled in MoveIntermediateLines
if (!(n = Nrec - Last))
return false;
dep = (BIGINT)((Block - 1) * Blksize);
for (i = 0; i < Ncol; i++) {
memset(To_Buf, (Isnum[i]) ? 0 : ' ', n * Clens[i]);
pos = dep + (BIGINT)(Deplac[i] + Last * Clens[i]);
if (BigSeek(g, Hfile, pos))
return true;
if (BigWrite(g, Hfile, To_Buf, n * Clens[i]))
return true;
} // endfor i
} else {
int req;
memset(To_Buf, 0, Buflen);
for (n = Fpos - Tpos; n > 0; n -= req) {
/*****************************************************************/
/* Fill VEC file remaining lines with 0's. */
/* This seems to work even column blocks have been made with */
/* Blanks = true. Perhaps should it be set to false for VEC. */
/*****************************************************************/
2014-04-21 12:57:10 +02:00
req = MY_MIN(n, Nrec);
for (i = 0; i < Ncol; i++) {
pos = BigDep[i] + (BIGINT)Tpos * (BIGINT)Clens[i];
if (BigSeek(g, Tfile, pos))
return true;
if (BigWrite(g, Tfile, To_Buf, req * Clens[i]))
return true;
} // endfor i
Tpos += req;
} // endfor n
} // endif MaxBlk
return false;
} // end of CleanUnusedSpace
/***********************************************************************/
/* Data Base close routine for huge VEC access method. */
/***********************************************************************/
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
2014-07-17 18:13:51 +02:00
void BGVFAM::CloseTableFile(PGLOBAL g, bool abort)
{
int rc = 0, wrc = RC_OK;
MODE mode = Tdbp->GetMode();
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
Abort = abort;
if (mode == MODE_INSERT) {
if (Closing)
wrc = RC_FX; // Last write was in error
else
if (CurNum) {
// Some more inserted lines remain to be written
Last = CurNum;
Block = CurBlk + 1;
Closing = true;
wrc = WriteBuffer(g);
} else {
Last = Nrec;
Block = CurBlk;
wrc = RC_OK;
} // endif CurNum
if (wrc != RC_FX) {
rc = ResetTableSize(g, Block, Last);
} else if (AddBlock) {
// Last block was not written
rc = ResetTableSize(g, CurBlk, Nrec);
longjmp(g->jumper[g->jump_level], 44);
} // endif
} else if (mode == MODE_UPDATE) {
// Write back to file any pending modifications
for (PVCTCOL colp = (PVCTCOL)((PTDBVCT)Tdbp)->GetSetCols();
colp; colp = (PVCTCOL)colp->Next)
colp->WriteBlock(g);
if (UseTemp && Tfile) {
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
rc = RenameTempFile(g);
Hfile = Tfile = INVALID_HANDLE_VALUE;
if (Header)
// Header must be set because it was not set in temp file
rc = SetBlockInfo(g);
} // endif UseTemp
} else if (mode == MODE_DELETE && UseTemp && Tfile) {
if (MaxBlk)
rc = CleanUnusedSpace(g);
This is a major update that fixes most of the issues and bugs that have been created by the last addition of new CONNECT features. The version previous to this one is a preliminary test version and should not be distributed. - Handle indexed UPDATE/DELETE. Previously this was just tested and an error message send when it could not be done. Now CONNECT can do it in all the cases. It is done by a MRR like tchnique by making a list of all update or delete to do, sort them, then execute them. modified: storage/connect/array.cpp storage/connect/array.h storage/connect/filamap.cpp storage/connect/filamap.h storage/connect/filamdbf.cpp 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/global.h storage/connect/ha_connect.cc storage/connect/ha_connect.h - Differenciate Cardinality that returns a true or estimated table size and GetMaxSize that return a value equal or greater than the table row number. This fixes the errors of non matching opt files. modified: storage/connect/connect.cc storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/table.cpp storage/connect/tabmac.h storage/connect/tabmysql.cpp storage/connect/tabmysql.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabpivot.h storage/connect/tabtbl.cpp storage/connect/tabtbl.h storage/connect/tabutil.cpp storage/connect/tabutil.h storage/connect/tabwmi.h storage/connect/xtable.h - Fix some errors and issues when making index and opt files. Erase opt and index files for void tables. Fix wrong calculation of Block and Last in MakeBlockValues. Invalidate indexes before making opt file. Fully handle blocked variable tables. Make opt file for blocked variable tables even when they have no optimised colums. modified: storage/connect/tabdos.cpp storage/connect/xindex.h - Fix some errors making index Return an error when the allocation is too small (should not really occur now that GetMaxSize is sure) Don't use XXROW index for DBF tables because of soft deleted lines. modified: storage/connect/xindex.cpp - Typo modified: storage/connect/macutil.cpp storage/connect/tabdos.h storage/connect/tabsys.cpp storage/connect/tabsys.h
2014-08-07 17:59:21 +02:00
if ((rc = RenameTempFile(g)) != RC_FX) {
Hfile = Tfile = INVALID_HANDLE_VALUE; // For SetBlockInfo
rc = ResetTableSize(g, Block, Last);
} // endif rc
} // endif's mode
if (Hfile != INVALID_HANDLE_VALUE)
rc = PlugCloseFile(g, To_Fb);
if (trace)
htrc("BGV CloseTableFile: closing %s wrc=%d rc=%d\n",
To_File, wrc, rc);
Hfile = INVALID_HANDLE_VALUE;
} // end of CloseDB
/***********************************************************************/
/* Rewind routine for huge VCT access method. */
/***********************************************************************/
void BGVFAM::Rewind(void)
{
// In mode update we need to read Set Column blocks
if (Tdbp->GetMode() == MODE_UPDATE)
OldBlk = -1;
// Initialize so block optimization is called for 1st block
CurBlk = -1;
CurNum = Nrec - 1;
#if 0 // This is probably unuseful as the file is directly accessed
#if defined(WIN32) //OB
SetFilePointer(Hfile, 0, NULL, FILE_BEGIN);
#else // UNIX
lseek64(Hfile, 0, SEEK_SET);
#endif // UNIX
#endif // 0
} // end of Rewind
/***********************************************************************/
/* ReadBlock: Read column values from current block. */
/***********************************************************************/
bool BGVFAM::ReadBlock(PGLOBAL g, PVCTCOL colp)
{
BIGINT pos;
/*********************************************************************/
/* Calculate the offset and size of the block to read. */
/*********************************************************************/
if (MaxBlk) // File has Vector format
pos = (BIGINT)Nrec * ((BIGINT)colp->Deplac * (BIGINT)MaxBlk
+ (BIGINT)colp->Clen * (BIGINT)CurBlk) + (BIGINT)Headlen;
else // Old VCT format
pos = (BIGINT)Nrec * ((BIGINT)colp->Deplac
+ (BIGINT)Lrecl * (BIGINT)CurBlk);
if (trace)
htrc("RB: offset=%lld Nrec=%d Deplac=%d Lrecl=%d CurBlk=%d MaxBlk=%d\n",
pos, Nrec, colp->Deplac, Lrecl, CurBlk, MaxBlk);
if (BigSeek(g, Hfile, pos))
return true;
if (BigRead(g, Hfile, colp->Blk->GetValPointer(), colp->Clen * Nrec))
return true;
if (trace)
num_read++;
return false;
} // end of ReadBlock
/***********************************************************************/
/* WriteBlock: Write back current column values for one block. */
/* Note: the test of Status is meant to prevent physical writing of */
/* the block during the checking loop in mode Update. It is set to */
/* BUF_EMPTY when reopening the table between the two loops. */
/***********************************************************************/
bool BGVFAM::WriteBlock(PGLOBAL g, PVCTCOL colp)
{
int len;
BIGINT pos;
/*********************************************************************/
/* Calculate the offset and size of the block to write. */
/*********************************************************************/
if (MaxBlk) // File has Vector format
pos = (BIGINT)Nrec * ((BIGINT)colp->Deplac * (BIGINT)MaxBlk
+ (BIGINT)colp->Clen * (BIGINT)colp->ColBlk) + (BIGINT)Headlen;
else // Old VCT format
pos = (BIGINT)Nrec * ((BIGINT)colp->Deplac
+ (BIGINT)Lrecl * (BIGINT)colp->ColBlk);
if (trace)
htrc("WB: offset=%lld Nrec=%d Deplac=%d Lrecl=%d ColBlk=%d\n",
pos, Nrec, colp->Deplac, Lrecl, colp->ColBlk);
if (BigSeek(g, Tfile, pos))
return true;
//len = colp->Clen * Nrec; see comment in VCTFAM
len = colp->Clen * ((Tdbp->GetMode() == MODE_INSERT) ? CurNum : Nrec);
if (BigWrite(g, Tfile, colp->Blk->GetValPointer(), len))
return true;
return false;
} // end of WriteBlock
/* ----------------------- End of FilAMVct --------------------------- */