From 61c2e7b27d11e77bab053028e9bde7aa88dba69e Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Fri, 8 Aug 2014 19:46:02 +0200 Subject: [PATCH 01/15] - Fix MDEV-6502 modified: storage/connect/ha_connect.cc - Apply Sergei's fixes modified: storage/connect/filamtxt.cpp storage/connect/mysql-test/connect/t/part_file.test --- storage/connect/filamtxt.cpp | 2 +- storage/connect/ha_connect.cc | 8 +++----- storage/connect/mysql-test/connect/t/part_file.test | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp index 28059d4f28a..7c2b93afbb1 100644 --- a/storage/connect/filamtxt.cpp +++ b/storage/connect/filamtxt.cpp @@ -475,7 +475,7 @@ bool DOSFAM::AllocateBuffer(PGLOBAL g) MODE mode = Tdbp->Mode; // Lrecl does not include line ending - Buflen = Lrecl + Ending + ((Bin) ? 1 : 0); + Buflen = Lrecl + Ending + ((Bin) ? 1 : 0) + 1; // Sergei if (trace) htrc("SubAllocating a buffer of %d bytes\n", Buflen); diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 6f9334bb604..639d0020d67 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -2739,7 +2739,8 @@ int ha_connect::write_row(uchar *buf) DBUG_RETURN(0); // Alter table on an outward partition table xmod= MODE_INSERT; - } // endif xmod + } else if (xmod == MODE_ANY) + DBUG_RETURN(0); // Probably never met // Open the table if it was not opened yet (locked) if (!IsOpened() || xmod != tdbp->GetMode()) { @@ -2751,9 +2752,6 @@ int ha_connect::write_row(uchar *buf) } // endif isopened - if (tdbp->GetMode() == MODE_ANY) - DBUG_RETURN(0); - #if 0 // AUTO_INCREMENT NIY if (table->next_number_field && buf == table->record[0]) { int error; @@ -4935,7 +4933,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, } else if (!user) user= "root"; - if (CheckSelf(g, table_s, host, db, tab, src, port)) + if (ok && CheckSelf(g, table_s, host, db, tab, src, port)) ok= false; break; diff --git a/storage/connect/mysql-test/connect/t/part_file.test b/storage/connect/mysql-test/connect/t/part_file.test index 04f07b83ec7..159908b6d9b 100644 --- a/storage/connect/mysql-test/connect/t/part_file.test +++ b/storage/connect/mysql-test/connect/t/part_file.test @@ -72,7 +72,7 @@ SHOW INDEX FROM t1; # TODO: this fails on Linux #SELECT * FROM dr1 ORDER BY fname, ftype; INSERT INTO t1(id,msg) VALUES(4, 'four'); -SELECT * FROM dr1; +SELECT * FROM dr1 ORDER BY fname, ftype; INSERT INTO t1(id,msg) VALUES(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'); INSERT INTO t1(id,msg) VALUES(72,'seventy two'),(20,'twenty'),(1,'one'),(35,'thirty five'),(8,'eight'); SELECT partition_name, table_rows FROM information_schema.partitions WHERE table_name = 't1'; From 78b1bdd2baec17eb02457214ebbc7602d0f455c3 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Fri, 8 Aug 2014 19:53:44 +0200 Subject: [PATCH 02/15] - Update part_file.result to match the test change modified: storage/connect/mysql-test/connect/r/part_file.result --- storage/connect/mysql-test/connect/r/part_file.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/connect/mysql-test/connect/r/part_file.result b/storage/connect/mysql-test/connect/r/part_file.result index 4eed61c71c7..bd5c258a4e2 100644 --- a/storage/connect/mysql-test/connect/r/part_file.result +++ b/storage/connect/mysql-test/connect/r/part_file.result @@ -101,7 +101,7 @@ SHOW INDEX FROM t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t1 0 PRIMARY 1 id A NULL NULL NULL XINDEX INSERT INTO t1(id,msg) VALUES(4, 'four'); -SELECT * FROM dr1; +SELECT * FROM dr1 ORDER BY fname, ftype; fname ftype part1 .fnx part1 .txt From 3a69c854c55025acc687e5852d7be5e38a38934e Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sat, 16 Aug 2014 16:46:35 +0200 Subject: [PATCH 03/15] - Modifies the way indexed UPDATE/DELETE are sorted in order to execute them sorted by file position. Firstly a new value is stored in indexes to know if they are sorted, preventing to do the sorting when it is not needed. Secondly, almost all in now done in connect instead of being done by the different file access method classes. This pepares the future use of temporary files for all table types and also fix the bug that was occuring when partially using a multi-column index because of false MRR like call of position followed by unsorted rnd_pos no more using indexing. modified: storage/connect/connect.cc 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/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.h storage/connect/tabfmt.cpp storage/connect/tabfmt.h storage/connect/xindex.cpp storage/connect/xindex.h storage/connect/xtable.h --- storage/connect/connect.cc | 71 +++++-- storage/connect/filamap.cpp | 85 ++------ storage/connect/filamap.h | 5 +- storage/connect/filamdbf.cpp | 36 +++- storage/connect/filamdbf.h | 5 +- storage/connect/filamfix.cpp | 155 ++------------ storage/connect/filamfix.h | 4 +- storage/connect/filamtxt.cpp | 364 ++++++++++++++++----------------- storage/connect/filamtxt.h | 17 +- storage/connect/filamvct.cpp | 278 +------------------------ storage/connect/filamvct.h | 4 - storage/connect/tabdos.cpp | 30 ++- storage/connect/tabdos.h | 3 + storage/connect/tabfix.h | 2 + storage/connect/tabfmt.cpp | 18 +- storage/connect/tabfmt.h | 381 ++++++++++++++++++----------------- storage/connect/xindex.cpp | 40 +++- storage/connect/xindex.h | 1 + storage/connect/xtable.h | 5 + 19 files changed, 591 insertions(+), 913 deletions(-) diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc index e495a0f62b9..a458c0e0c5a 100644 --- a/storage/connect/connect.cc +++ b/storage/connect/connect.cc @@ -479,7 +479,7 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp) /***********************************************************************/ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp) { - RCODE rc; + RCODE rc; PCOL colp; PTDBASE tp= (PTDBASE)tdbp; @@ -503,11 +503,14 @@ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp) if (!colp->GetColUse(U_VIRTUAL)) colp->WriteColumn(g); -// if (tdbp->GetMode() == MODE_INSERT) -// tbxp->SetModified(true); - - // Return result code from write operation - rc= (RCODE)tdbp->WriteDB(g); +//if (tp->GetMode() == MODE_UPDATE && tp->IsUsingTemp(g) && +// tp->GetKindex() && !tp->GetKindex()->IsSorted()) + if (tp->IsIndexed()) + // Index values must be sorted before updating + rc= (RCODE)((PTDBDOS)tp)->GetTxfp()->StoreValues(g, true); + else + // Return result code from write operation + rc= (RCODE)tdbp->WriteDB(g); err: g->jump_level--; @@ -517,7 +520,7 @@ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp) /***********************************************************************/ /* UpdateRow: Update a row into a table. */ /***********************************************************************/ -RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp) +RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp) { if (!tdbp || tdbp->GetMode() != MODE_UPDATE) return RC_FX; @@ -531,19 +534,28 @@ RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp) /***********************************************************************/ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all) { - RCODE rc; + RCODE rc; + PTDBASE tp= (PTDBASE)tdbp; if (!tdbp || tdbp->GetMode() != MODE_DELETE) return RC_FX; else if (tdbp->IsReadOnly()) return RC_NF; - if (((PTDBASE)tdbp)->GetDef()->Indexable() && all) - ((PTDBDOS)tdbp)->Cardinal= 0; + if (all) { + if (((PTDBASE)tdbp)->GetDef()->Indexable()) + ((PTDBDOS)tdbp)->Cardinal= 0; + + // Note: if all, this call will be done when closing the table + rc= (RCODE)tdbp->DeleteDB(g, RC_FX); +//} else if (tp->GetKindex() && !tp->GetKindex()->IsSorted() && +// tp->Txfp->GetAmType() != TYPE_AM_DBF) { + } else if(tp->IsIndexed()) { + // Index values must be sorted before updating + rc= (RCODE)((PTDBDOS)tp)->GetTxfp()->StoreValues(g, false); + } else // Return result code from delete operation + rc= (RCODE)tdbp->DeleteDB(g, RC_OK); - // Return result code from delete operation - // Note: if all, this call will be done when closing the table - rc= (RCODE)tdbp->DeleteDB(g, (all) ? RC_FX : RC_OK); return rc; } // end of CntDeleteRow @@ -553,7 +565,7 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all) int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort) { int rc= RC_OK; - TDBDOX *tbxp= NULL; + TDBASE *tbxp= (PTDBASE)tdbp; if (!tdbp) return rc; // Nothing to do @@ -568,8 +580,30 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort) printf("CntCloseTable: tdbp=%p mode=%d nox=%d abort=%d\n", tdbp, tdbp->GetMode(), nox, abort); - if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN) - rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine +#if 0 + if (tbxp->GetMode() == MODE_UPDATE && + tbxp->GetKindex() && !tbxp->GetKindex()->IsSorted()) { + rc= tbxp->Txfp->UpdateSortedRows(g); + } else + if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN) { + if (tbxp->GetKindex() && !tbxp->GetKindex()->IsSorted()) + rc= tbxp->Txfp->DeleteSortedRows(g); + + if (!rc) + rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine + + } // endif Mode +#endif // 0 + + if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN) { + if (tbxp->IsIndexed()) + rc= ((PTDBDOS)tdbp)->GetTxfp()->DeleteSortedRows(g); + + if (!rc) + rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine + + } else if (tbxp->GetMode() == MODE_UPDATE && tbxp->IsIndexed()) + rc= ((PTDBDOX)tdbp)->Txfp->UpdateSortedRows(g); // Prepare error return if (g->jump_level == MAX_JUMP) { @@ -606,9 +640,8 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort) // Make all the eventual indexes tbxp= (TDBDOX*)tdbp; tbxp->ResetKindex(g, NULL); - tbxp->To_Key_Col= NULL; - rc= tbxp->ResetTableOpt(g, true, - ((PTDBASE)tdbp)->GetDef()->Indexable() == 1); + tbxp->SetKey_Col(NULL); + rc= tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1); err: if (trace > 1) diff --git a/storage/connect/filamap.cpp b/storage/connect/filamap.cpp index b5958c1a854..3523c688788 100644 --- a/storage/connect/filamap.cpp +++ b/storage/connect/filamap.cpp @@ -48,11 +48,6 @@ extern "C" int trace; -/***********************************************************************/ -/* Routine called externally by MAPFAM MakeDeletedFile function. */ -/***********************************************************************/ -PARRAY MakeValueArray(PGLOBAL g, PPARM pp); - /* --------------------------- Class MAPFAM -------------------------- */ /***********************************************************************/ @@ -290,6 +285,16 @@ bool MAPFAM::RecordPos(PGLOBAL g) return false; } // end of RecordPos +/***********************************************************************/ +/* Initialize Fpos and Mempos for indexed DELETE. */ +/***********************************************************************/ +int MAPFAM::InitDelete(PGLOBAL g, int fpos, int spos) + { + Fpos = Memory + fpos; + Mempos = Memory + spos; + return RC_OK; + } // end of InitDelete + /***********************************************************************/ /* Skip one record in file. */ /***********************************************************************/ @@ -409,13 +414,6 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc) /* not required here, just setting of future Spos and Tpos. */ /*******************************************************************/ Tpos = Spos = Fpos; - Indxd = Tdbp->GetKindex() != NULL; - } // endif Tpos - - if (Indxd) { - // Moving will be done later, must be done in sequential order - (void)AddListValue(g, TYPE_PCHAR, Fpos, &To_Pos); - (void)AddListValue(g, TYPE_PCHAR, Mempos, &To_Sos); } else if ((n = Fpos - Spos) > 0) { /*****************************************************************/ /* Non consecutive line to delete. Move intermediate lines. */ @@ -437,10 +435,6 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc) } else if (To_Fb) { // Can be NULL for deleted files /*******************************************************************/ /* Last call after EOF has been reached. */ - /*******************************************************************/ - Abort = (Indxd && MakeDeletedFile(g)); - - /*******************************************************************/ /* We must firstly Unmap the view and use the saved file handle */ /* to put an EOF at the end of the copied part of the file. */ /*******************************************************************/ @@ -495,55 +489,6 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc) return RC_OK; // All is correct } // end of DeleteRecords -/***********************************************************************/ -/* MakeDeletedFile. When deleting using indexing, the issue is that */ -/* record are not necessarily deleted in sequential order. Moving */ -/* intermediate lines cannot be done while deleting them. */ -/* What we do here is to reorder the deleted records and move the */ -/* intermediate files from the ordered deleted record positions. */ -/***********************************************************************/ -bool MAPFAM::MakeDeletedFile(PGLOBAL g) - { - int *ix, i, n; - - /*********************************************************************/ - /* Make and order the arrays from the saved values. */ - /*********************************************************************/ - if (!(Posar = MakeValueArray(g, To_Pos))) { - strcpy(g->Message, "Position array is null"); - goto err; - } else if (!(Sosar = MakeValueArray(g, To_Sos))) { - strcpy(g->Message, "Start position array is null"); - goto err; - } else if (!(ix = (int*)Posar->GetSortIndex(g))) { - strcpy(g->Message, "Error getting array sort index"); - goto err; - } // endif's - - for (i = 0; i < Posar->GetNval(); i++) { - Fpos = Posar->GetStringValue(ix[i]); - - if (!i) { - Tpos = Fpos; - } else if ((n = Fpos - Spos) >= 0) { - // Move all not deleted lines preceding this one - memmove(Tpos, Spos, n); - Tpos += n; - } // endif n - - // New start position - Spos = Sosar->GetStringValue(ix[i]); - } // endfor i - - return false; - -err: - if (trace) - htrc("%s\n", g->Message); - - return true; - } // end of MakeDeletedFile - /***********************************************************************/ /* Table file close routine for MAP access method. */ /***********************************************************************/ @@ -734,6 +679,16 @@ bool MPXFAM::SetPos(PGLOBAL g, int pos) return false; } // end of SetPos +/***********************************************************************/ +/* Initialize CurBlk, CurNum, Mempos and Fpos for indexed DELETE. */ +/***********************************************************************/ +int MPXFAM::InitDelete(PGLOBAL g, int fpos, int spos) + { + Fpos = Memory + Headlen + fpos * Lrecl; + Mempos = Fpos + Lrecl; + return RC_OK; + } // end of InitDelete + /***********************************************************************/ /* ReadBuffer: Read one line for a mapped Fix file. */ /***********************************************************************/ diff --git a/storage/connect/filamap.h b/storage/connect/filamap.h index 7d3203d7ff2..1d85fa36155 100644 --- a/storage/connect/filamap.h +++ b/storage/connect/filamap.h @@ -47,7 +47,7 @@ class DllExport MAPFAM : public TXTFAM { virtual void Rewind(void); protected: - bool MakeDeletedFile(PGLOBAL g); + virtual int InitDelete(PGLOBAL g, int fpos, int spos); // Members char *Memory; // Pointer on file mapping view. @@ -104,11 +104,14 @@ class DllExport MPXFAM : public MBKFAM { virtual int MaxBlkSize(PGLOBAL g, int s) {return TXTFAM::MaxBlkSize(g, s);} virtual bool SetPos(PGLOBAL g, int recpos); + virtual int GetNextPos(void) {return (int)Fpos + Nrec;} virtual bool DeferReading(void) {return false;} virtual int ReadBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g); protected: + virtual int InitDelete(PGLOBAL g, int fpos, int spos); + // No additional members }; // end of class MPXFAM diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp index 5d01ee06df0..50a97739002 100644 --- a/storage/connect/filamdbf.cpp +++ b/storage/connect/filamdbf.cpp @@ -750,6 +750,36 @@ bool DBFFAM::CopyHeader(PGLOBAL g) return rc; } // end of CopyHeader +#if 0 // Not useful when UseTemp is false. +/***********************************************************************/ +/* Mark the line to delete with '*' (soft delete). */ +/* NOTE: this is not ready for UseTemp. */ +/***********************************************************************/ +int DBFFAM::InitDelete(PGLOBAL g, int fpos, int spos) + { + int rc = RC_FX; + size_t lrecl = (size_t)Lrecl; + + if (Nrec != 1) + strcpy(g->Message, "Cannot delete in block mode"); + else if (fseek(Stream, Headlen + fpos * Lrecl, SEEK_SET)) + sprintf(g->Message, MSG(FSETPOS_ERROR), 0); + else if (fread(To_Buf, 1, lrecl, Stream) != lrecl) + sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno)); + else + *To_Buf = '*'; + + if (fseek(Stream, Headlen + fpos * Lrecl, SEEK_SET)) + sprintf(g->Message, MSG(FSETPOS_ERROR), 0); + else if (fwrite(To_Buf, 1, lrecl, Stream) != lrecl) + sprintf(g->Message, MSG(FWRITE_ERROR), strerror(errno)); + else + rc = RC_NF; // Ok, Nothing else to do + + return rc; + } // end of InitDelete +#endif // 0 + /***********************************************************************/ /* Data Base delete line routine for DBF access methods. */ /* Deleted lines are just flagged in the first buffer character. */ @@ -760,16 +790,12 @@ int DBFFAM::DeleteRecords(PGLOBAL g, int irc) // T_Stream is the temporary stream or the table file stream itself if (!T_Stream) if (UseTemp) { - if ((Indxd = Tdbp->GetKindex() != NULL)) { - strcpy(g->Message, "DBF indexed udate using temp file NIY"); - return RC_FX; - } else if (OpenTempFile(g)) + if (OpenTempFile(g)) return RC_FX; if (CopyHeader(g)) // For DBF tables return RC_FX; -// Indxd = Tdbp->GetKindex() != NULL; } else T_Stream = Stream; diff --git a/storage/connect/filamdbf.h b/storage/connect/filamdbf.h index 0345c0338e8..9be8bfd980d 100644 --- a/storage/connect/filamdbf.h +++ b/storage/connect/filamdbf.h @@ -40,8 +40,8 @@ class DllExport DBFBASE { // Members int Records; /* records in the file */ bool Accept; /* true if bad lines are accepted */ - int Nerr; /* Number of bad records */ - int Maxerr; /* Maximum number of bad records */ + int Nerr; /* Number of bad records */ + int Maxerr; /* Maximum number of bad records */ int ReadMode; /* 1: ALL 2: DEL 0: NOT DEL */ }; // end of class DBFBASE @@ -72,6 +72,7 @@ class DllExport DBFFAM : public FIXFAM, public DBFBASE { protected: virtual bool CopyHeader(PGLOBAL g); +//virtual int InitDelete(PGLOBAL g, int fpos, int spos); // Members }; // end of class DBFFAM diff --git a/storage/connect/filamfix.cpp b/storage/connect/filamfix.cpp index 78b6ee58b24..1c9451bb982 100644 --- a/storage/connect/filamfix.cpp +++ b/storage/connect/filamfix.cpp @@ -55,11 +55,6 @@ extern "C" int trace; extern int num_read, num_there, num_eq[2]; // Statistics -/***********************************************************************/ -/* Routine called externally by BGXFAM MakeDeletedFile function. */ -/***********************************************************************/ -PARRAY MakeValueArray(PGLOBAL g, PPARM pp); - /* --------------------------- Class FIXFAM -------------------------- */ /***********************************************************************/ @@ -105,6 +100,16 @@ bool FIXFAM::SetPos(PGLOBAL g, int pos) return false; } // end of SetPos +/***********************************************************************/ +/* Initialize CurBlk and CurNum for indexed DELETE. */ +/***********************************************************************/ +int FIXFAM::InitDelete(PGLOBAL g, int fpos, int spos) + { + CurBlk = fpos / Nrec; + CurNum = fpos % Nrec; + return RC_OK; + } // end of InitDelete + /***********************************************************************/ /* Allocate the block buffer for the table. */ /***********************************************************************/ @@ -340,15 +345,11 @@ int FIXFAM::WriteBuffer(PGLOBAL g) // T_Stream is the temporary stream or the table file stream itself if (!T_Stream) { if (UseTemp) { - if ((Indxd = Tdbp->GetKindex() != NULL)) { - strcpy(g->Message, "FIX indexed udate using temp file NIY"); - return RC_FX; - } else if (OpenTempFile(g)) + if (OpenTempFile(g)) return RC_FX; else if (CopyHeader(g)) // For DBF tables return RC_FX; -// Indxd = Tdbp->GetKindex() != NULL; } else T_Stream = Stream; @@ -413,17 +414,12 @@ int FIXFAM::DeleteRecords(PGLOBAL g, int irc) Spos = Tpos = Fpos; } // endif UseTemp - Indxd = Tdbp->GetKindex() != NULL; } // endif Tpos == Spos /*********************************************************************/ /* Move any intermediate lines. */ /*********************************************************************/ - if (Indxd) { - // Moving will be done later, must be done in sequential order - (void)AddListValue(g, TYPE_INT, &Fpos, &To_Pos); - moved = false; - } else if (MoveIntermediateLines(g, &moved)) + if (MoveIntermediateLines(g, &moved)) return RC_FX; if (irc == RC_OK) { @@ -456,9 +452,6 @@ int FIXFAM::DeleteRecords(PGLOBAL g, int irc) return RC_FX; } else { - if (Indxd && (Abort = MakeDeletedFile(g))) - return RC_FX; - /*****************************************************************/ /* Because the chsize functionality is only accessible with a */ /* system call we must close the file and reopen it with the */ @@ -559,59 +552,6 @@ bool FIXFAM::MoveIntermediateLines(PGLOBAL g, bool *b) return false; } // end of MoveIntermediate Lines -/***********************************************************************/ -/* MakeDeletedFile. When deleting using indexing, the issue is that */ -/* record are not necessarily deleted in sequential order. Moving */ -/* intermediate lines cannot be done while deleing them because */ -/* this can cause extra wrong records to be included in the new file. */ -/* What we do here is to reorder the deleted record and make the new */ -/* deleted file from the ordered deleted records. */ -/***********************************************************************/ -bool FIXFAM::MakeDeletedFile(PGLOBAL g) - { - char *crlf = "\n", *mode = UseTemp ? "rb" : "r+b"; - int *ix, i; - bool moved; - - /*********************************************************************/ - /* Open the temporary file, Spos is at the beginning of file. */ - /*********************************************************************/ - if (!(Posar = MakeValueArray(g, To_Pos))) { - strcpy(g->Message, "Position array is null"); - goto err; - } else if (!(ix = (int*)Posar->GetSortIndex(g))) { - strcpy(g->Message, "Error getting array sort index"); - goto err; - } // endif's - - Spos = 0; - - for (i = 0; i < Posar->GetNval(); i++) { - Fpos = Posar->GetIntValue(ix[i]); - - if (i || UseTemp) { - // Copy all not updated lines preceding this one - if (MoveIntermediateLines(g, &moved)) - goto err; - - } else - Tpos = Fpos; - - // New start position - Spos = Fpos + 1; - } // endfor i - - if (!PlugCloseFile(g, To_Fbt) && !PlugCloseFile(g, To_Fb)) - return false; - -err: - if (trace) - htrc("%s\n", g->Message); - - PlugCloseFile(g, To_Fbt); - return true; - } // end of MakeDeletedFile - /***********************************************************************/ /* Table file close routine for FIX access method. */ /***********************************************************************/ @@ -640,7 +580,6 @@ void FIXFAM::CloseTableFile(PGLOBAL g, bool abort) // Copy any remaining lines bool b; - // Note: Indxd is not implemented yet Fpos = Tdbp->Cardinality(g); Abort = MoveIntermediateLines(g, &b) != RC_OK; } // endif Abort @@ -1233,10 +1172,7 @@ int BGXFAM::WriteBuffer(PGLOBAL g) if (Tfile == INVALID_HANDLE_VALUE) { if (UseTemp /*&& Tdbp->GetMode() == MODE_UPDATE*/) { - if ((Indxd = Tdbp->GetKindex() != NULL)) { - strcpy(g->Message, "FIX indexed udate using temp file NIY"); - return RC_FX; - } else if (OpenTempFile(g)) + if (OpenTempFile(g)) return RC_FX; } else @@ -1303,19 +1239,15 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc) Spos = Tpos = Fpos; } // endif UseTemp - Indxd = Tdbp->GetKindex() != NULL; } // endif Tpos == Spos /*********************************************************************/ /* Move any intermediate lines. */ /*********************************************************************/ - if (Indxd) - // Moving will be done later, must be done in sequential order - (void)AddListValue(g, TYPE_INT, &Fpos, &To_Pos); - else if (MoveIntermediateLines(g, &moved)) + if (MoveIntermediateLines(g, &moved)) return RC_FX; - if (irc == RC_OK && !Indxd) { + if (irc == RC_OK) { if (trace) assert(Spos == Fpos); @@ -1343,9 +1275,6 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc) return RC_FX; } else { - if (Indxd && (Abort = MakeDeletedFile(g))) - return RC_FX; - /*****************************************************************/ /* Remove extra records. */ /*****************************************************************/ @@ -1469,59 +1398,6 @@ bool BGXFAM::MoveIntermediateLines(PGLOBAL g, bool *b) return false; } // end of MoveIntermediateLines -/***********************************************************************/ -/* MakeDeletedFile. When deleting using indexing, the issue is that */ -/* record are not necessarily deleted in sequential order. Moving */ -/* intermediate lines cannot be done while deleing them because */ -/* this can cause extra wrong records to be included in the new file. */ -/* What we do here is to reorder the deleted record and make the new */ -/* deleted file from the ordered deleted records. */ -/***********************************************************************/ -bool BGXFAM::MakeDeletedFile(PGLOBAL g) - { - char *crlf = "\n", *mode = UseTemp ? "rb" : "r+b"; - int *ix, i; - bool moved; - - /*********************************************************************/ - /* Open the temporary file, Spos is at the beginning of file. */ - /*********************************************************************/ - if (!(Posar = MakeValueArray(g, To_Pos))) { - strcpy(g->Message, "Position array is null"); - goto err; - } else if (!(ix = (int*)Posar->GetSortIndex(g))) { - strcpy(g->Message, "Error getting array sort index"); - goto err; - } // endif's - - Spos = 0; - - for (i = 0; i < Posar->GetNval(); i++) { - Fpos = Posar->GetIntValue(ix[i]); - - if (i || UseTemp) { - // Copy all not updated lines preceding this one - if (MoveIntermediateLines(g, &moved)) - goto err; - - } else - Tpos = Fpos; - - // New start position - Spos = Fpos + 1; - } // endfor i - - if (!PlugCloseFile(g, To_Fbt)) - return false; - -err: - if (trace) - htrc("%s\n", g->Message); - - PlugCloseFile(g, To_Fbt); - return true; - } // end of MakeDeletedFile - /***********************************************************************/ /* Data Base close routine for BIGFIX access method. */ /***********************************************************************/ @@ -1549,7 +1425,6 @@ void BGXFAM::CloseTableFile(PGLOBAL g, bool abort) // Copy any remaining lines bool b; - // Indxd is not implemented yet Fpos = Tdbp->Cardinality(g); Abort = MoveIntermediateLines(g, &b) != RC_OK; } // endif Abort diff --git a/storage/connect/filamfix.h b/storage/connect/filamfix.h index a29bfbbeb48..694e653898a 100644 --- a/storage/connect/filamfix.h +++ b/storage/connect/filamfix.h @@ -34,6 +34,7 @@ class DllExport FIXFAM : public BLKFAM { virtual int MaxBlkSize(PGLOBAL g, int s) {return TXTFAM::MaxBlkSize(g, s);} virtual bool SetPos(PGLOBAL g, int recpos); + virtual int GetNextPos(void) {return Fpos + 1;} virtual bool AllocateBuffer(PGLOBAL g); virtual void ResetBuffer(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g); @@ -44,7 +45,7 @@ class DllExport FIXFAM : public BLKFAM { protected: virtual bool CopyHeader(PGLOBAL g) {return false;} virtual bool MoveIntermediateLines(PGLOBAL g, bool *b); - virtual bool MakeDeletedFile(PGLOBAL g); + virtual int InitDelete(PGLOBAL g, int fpos, int spos); // No additional members }; // end of class FIXFAM @@ -77,7 +78,6 @@ class BGXFAM : public FIXFAM { protected: virtual bool OpenTempFile(PGLOBAL g); virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL); - virtual bool MakeDeletedFile(PGLOBAL g); int BigRead(PGLOBAL g, HANDLE h, void *inbuf, int req); bool BigWrite(PGLOBAL g, HANDLE h, void *inbuf, int req); bool BigSeek(PGLOBAL g, HANDLE h, BIGINT pos diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp index 7c2b93afbb1..3e4c5adc319 100644 --- a/storage/connect/filamtxt.cpp +++ b/storage/connect/filamtxt.cpp @@ -59,7 +59,7 @@ extern int num_read, num_there, num_eq[2]; // Statistics extern "C" int trace; /***********************************************************************/ -/* Routine called externally by DOSFAM MakeUpdatedFile function. */ +/* Routine called externally by TXTFAM SortedRows functions. */ /***********************************************************************/ PARRAY MakeValueArray(PGLOBAL g, PPARM pp); @@ -102,10 +102,10 @@ TXTFAM::TXTFAM(PDOSDEF tdp) Rbuf = 0; Modif = 0; Blksize = 0; + Fpos = Spos = Tpos = 0; Padded = false; Eof = tdp->Eof; Ending = tdp->Ending; - Indxd = false; Abort = false; CrLf = (char*)(Ending == 1 ? "\n" : "\r\n"); } // end of TXTFAM standard constructor @@ -144,10 +144,12 @@ TXTFAM::TXTFAM(PTXF txfp) Rbuf = txfp->Rbuf; Modif = txfp->Modif; Blksize = txfp->Blksize; + Fpos = txfp->Fpos; + Spos = txfp->Spos; + Tpos = txfp->Tpos; Padded = txfp->Padded; Eof = txfp->Eof; Ending = txfp->Ending; - Indxd = txfp->Indxd; Abort = txfp->Abort; CrLf = txfp->CrLf; } // end of TXTFAM copy constructor @@ -302,6 +304,134 @@ bool TXTFAM::AddListValue(PGLOBAL g, int type, void *val, PPARM *top) return false; } // end of AddListValue +/***********************************************************************/ +/* Store needed values for indexed UPDATE or DELETE. */ +/***********************************************************************/ +int TXTFAM::StoreValues(PGLOBAL g, bool upd) +{ + int pos = GetPos(); + bool rc = AddListValue(g, TYPE_INT, &pos, &To_Pos); + + if (!rc) { + pos = GetNextPos(); + rc = AddListValue(g, TYPE_INT, &pos, &To_Sos); + } // endif rc + + if (upd && !rc) { + if (Tdbp->PrepareWriting(g)) + return RC_FX; + + rc = AddListValue(g, TYPE_STRING, Tdbp->GetLine(), &To_Upd); + } // endif upd + + return rc ? RC_FX : RC_OK; +} // end of StoreValues + +/***********************************************************************/ +/* UpdateSortedRows. When updating using indexing, the issue is that */ +/* record are not necessarily updated in sequential order. */ +/* Moving intermediate lines cannot be done while making them because */ +/* this can cause extra wrong records to be included in the new file. */ +/* What we do here is to reorder the updated records and do all the */ +/* updates ordered by record position. */ +/***********************************************************************/ +int TXTFAM::UpdateSortedRows(PGLOBAL g) + { + int *ix, i, rc = RC_OK; + + /*********************************************************************/ + /* Get the stored update values and sort them. */ + /*********************************************************************/ + if (!(Posar = MakeValueArray(g, To_Pos))) { + strcpy(g->Message, "Position array is null"); + goto err; + } else if (!(Sosar = MakeValueArray(g, To_Sos))) { + strcpy(g->Message, "Start position array is null"); + goto err; + } else if (!(Updar = MakeValueArray(g, To_Upd))) { + strcpy(g->Message, "Updated line array is null"); + goto err; + } else if (!(ix = (int*)Posar->GetSortIndex(g))) { + strcpy(g->Message, "Error getting array sort index"); + goto err; + } // endif's + + Rewind(); + + for (i = 0; i < Posar->GetNval(); i++) { + SetPos(g, Sosar->GetIntValue(ix[i])); + Fpos = Posar->GetIntValue(ix[i]); + strcpy(Tdbp->To_Line, Updar->GetStringValue(ix[i])); + + // Now write the updated line. + if ((rc = WriteBuffer(g))) + goto err; + + } // endfor i + +err: + if (trace && rc) + htrc("%s\n", g->Message); + + return rc; + } // end of UpdateSortedRows + +/***********************************************************************/ +/* DeleteSortedRows. When deleting using indexing, the issue is that */ +/* record are not necessarily deleted in sequential order. Moving */ +/* intermediate lines cannot be done while deleing them because */ +/* this can cause extra wrong records to be included in the new file. */ +/* What we do here is to reorder the deleted record and delete from */ +/* the file from the ordered deleted records. */ +/***********************************************************************/ +int TXTFAM::DeleteSortedRows(PGLOBAL g) + { + int *ix, i, irc, rc = RC_OK; + + /*********************************************************************/ + /* Get the stored delete values and sort them. */ + /*********************************************************************/ + if (!(Posar = MakeValueArray(g, To_Pos))) { + strcpy(g->Message, "Position array is null"); + goto err; + } else if (!(Sosar = MakeValueArray(g, To_Sos))) { + strcpy(g->Message, "Start position array is null"); + goto err; + } else if (!(ix = (int*)Posar->GetSortIndex(g))) { + strcpy(g->Message, "Error getting array sort index"); + goto err; + } // endif's + + Tpos = Spos = 0; + + for (i = 0; i < Posar->GetNval(); i++) { + if ((irc = InitDelete(g, Posar->GetIntValue(ix[i]), + Sosar->GetIntValue(ix[i])) == RC_FX)) + goto err; + + // Now delete the sorted rows + if ((rc = DeleteRecords(g, irc))) + goto err; + + } // endfor i + +err: + if (trace && rc) + htrc("%s\n", g->Message); + + return rc; + } // end of DeleteSortedRows + +/***********************************************************************/ +/* The purpose of this function is to deal with access methods that */ +/* are not coherent regarding the use of SetPos and GetPos. */ +/***********************************************************************/ +int TXTFAM::InitDelete(PGLOBAL g, int fpos, int spos) + { + strcpy(g->Message, "InitDelete should not be used by this table type"); + return RC_FX; + } // end of InitDelete + /* --------------------------- Class DOSFAM -------------------------- */ /***********************************************************************/ @@ -312,7 +442,6 @@ DOSFAM::DOSFAM(PDOSDEF tdp) : TXTFAM(tdp) To_Fbt = NULL; Stream = NULL; T_Stream = NULL; - Fpos = Spos = Tpos = 0; UseTemp = false; Bin = false; } // end of DOSFAM standard constructor @@ -322,9 +451,6 @@ DOSFAM::DOSFAM(PDOSFAM tdfp) : TXTFAM(tdfp) To_Fbt = tdfp->To_Fbt; Stream = tdfp->Stream; T_Stream = tdfp->T_Stream; - Fpos = tdfp->Fpos; - Spos = tdfp->Spos; - Tpos = tdfp->Tpos; UseTemp = tdfp->UseTemp; Bin = tdfp->Bin; } // end of DOSFAM copy constructor @@ -551,6 +677,21 @@ bool DOSFAM::RecordPos(PGLOBAL g) return false; } // end of RecordPos +/***********************************************************************/ +/* Initialize Fpos and the current position for indexed DELETE. */ +/***********************************************************************/ +int DOSFAM::InitDelete(PGLOBAL g, int fpos, int spos) + { + Fpos = fpos; + + if (fseek(Stream, spos, SEEK_SET)) { + sprintf(g->Message, MSG(FSETPOS_ERROR), Fpos); + return RC_FX; + } // endif + + return RC_OK; + } // end of InitDelete + /***********************************************************************/ /* Skip one record in file. */ /***********************************************************************/ @@ -713,7 +854,6 @@ int DOSFAM::WriteBuffer(PGLOBAL g) if (OpenTempFile(g)) return RC_FX; - Indxd = Tdbp->To_Kindex != NULL; } else T_Stream = Stream; @@ -735,20 +875,13 @@ int DOSFAM::WriteBuffer(PGLOBAL g) if (UseTemp) { /*****************************************************************/ /* We are using a temporary file. */ + /* Before writing the updated record, we must eventually copy */ + /* all the intermediate records that have not been updated. */ /*****************************************************************/ - if (Indxd) { - // Copying will be done later, must be done in sequential order - (void)AddListValue(g, TYPE_INT, &Fpos, &To_Pos); - (void)AddListValue(g, TYPE_INT, &curpos, &To_Sos); - } else { - // Before writing the updated record, we must eventually copy - // all the intermediate records that have not been updated. - if (MoveIntermediateLines(g, &moved)) - return RC_FX; - - Spos = curpos; // New start position - } // endif Indxd + if (MoveIntermediateLines(g, &moved)) + return RC_FX; + Spos = curpos; // New start position } else // Update is directly written back into the file, // with this (fast) method, record size cannot change. @@ -762,28 +895,24 @@ int DOSFAM::WriteBuffer(PGLOBAL g) /*********************************************************************/ /* Prepare the write the updated line. */ /*********************************************************************/ - if (!Indxd) { - strcat(strcpy(To_Buf, Tdbp->To_Line), (Bin) ? CrLf : "\n"); + strcat(strcpy(To_Buf, Tdbp->To_Line), (Bin) ? CrLf : "\n"); - /*******************************************************************/ - /* Now start the writing process. */ - /*******************************************************************/ - if ((fputs(To_Buf, T_Stream)) == EOF) { - sprintf(g->Message, MSG(FPUTS_ERROR), strerror(errno)); + /*********************************************************************/ + /* Now start the writing process. */ + /*********************************************************************/ + if ((fputs(To_Buf, T_Stream)) == EOF) { + sprintf(g->Message, MSG(FPUTS_ERROR), strerror(errno)); + return RC_FX; + } // endif EOF + + if (Tdbp->Mode == MODE_UPDATE && moved) + if (fseek(Stream, curpos, SEEK_SET)) { + sprintf(g->Message, MSG(FSEEK_ERROR), strerror(errno)); return RC_FX; - } // endif EOF + } // endif - if (Tdbp->Mode == MODE_UPDATE && moved) - if (fseek(Stream, curpos, SEEK_SET)) { - sprintf(g->Message, MSG(FSEEK_ERROR), strerror(errno)); - return RC_FX; - } // endif - - if (trace) - htrc("write done\n"); - - } else // Add this updated line to the updated line list - (void)AddListValue(g, TYPE_STRING, Tdbp->To_Line, &To_Upd); + if (trace) + htrc("write done\n"); return RC_OK; } // end of WriteBuffer @@ -840,18 +969,12 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc) Spos = Tpos = Fpos; } // endif UseTemp - Indxd = Tdbp->To_Kindex != NULL; } // endif Tpos == Spos /*********************************************************************/ /* Move any intermediate lines. */ /*********************************************************************/ - if (Indxd) { - // Moving will be done later, must be done in sequential order - (void)AddListValue(g, TYPE_INT, &Fpos, &To_Pos); - (void)AddListValue(g, TYPE_INT, &curpos, &To_Sos); - moved = false; - } else if (MoveIntermediateLines(g, &moved)) + if (MoveIntermediateLines(g, &moved)) return RC_FX; if (irc == RC_OK) { @@ -874,9 +997,6 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc) /* Last call after EOF has been reached. */ /* The UseTemp case is treated in CloseTableFile. */ /*******************************************************************/ - if (Indxd) - Abort = MakeDeletedFile(g); - if (!UseTemp & !Abort) { /*****************************************************************/ /* Because the chsize functionality is only accessible with a */ @@ -1000,136 +1120,6 @@ bool DOSFAM::MoveIntermediateLines(PGLOBAL g, bool *b) return false; } // end of MoveIntermediate Lines -/***********************************************************************/ -/* MakeUpdatedFile. When updating using indexing, the issue is that */ -/* record are not necessarily updated in sequential order. */ -/* Moving intermediate lines cannot be done while making them because */ -/* this can cause extra wrong records to be included in the new file. */ -/* What we do here is to reorder the updated record and make the new */ -/* updated file from the ordered updated records. */ -/***********************************************************************/ -bool DOSFAM::MakeUpdatedFile(PGLOBAL g) - { - char *crlf = "\n", *mode = UseTemp ? "rb" : "r+b"; - int *ix, i; - bool moved, b = false; - - /*********************************************************************/ - /* Open the temporary file, Spos is at the beginning of file. */ - /*********************************************************************/ - if (!(Stream = PlugReopenFile(g, To_Fb, mode))) { - goto err; - } else if (!(Posar = MakeValueArray(g, To_Pos))) { - strcpy(g->Message, "Position array is null"); - goto err; - } else if (!(Sosar = MakeValueArray(g, To_Sos))) { - strcpy(g->Message, "Start position array is null"); - goto err; - } else if (!(Updar = MakeValueArray(g, To_Upd))) { - strcpy(g->Message, "Updated line array is null"); - goto err; - } else if (!(ix = (int*)Posar->GetSortIndex(g))) { - strcpy(g->Message, "Error getting array sort index"); - goto err; - } // endif's - - Spos = 0; - - for (i = 0; i < Posar->GetNval(); i++) { - Fpos = Posar->GetIntValue(ix[i]); - - if (i || UseTemp) { - // Copy all not updated lines preceding this one - if (MoveIntermediateLines(g, &moved)) - goto err; - - } else - Tpos = Fpos; - - // Now write the updated line. - strcat(strcpy(To_Buf, Updar->GetStringValue(ix[i])), CrLf); - - if ((fputs(To_Buf, T_Stream)) == EOF) { - sprintf(g->Message, MSG(FPUTS_ERROR), strerror(errno)); - goto err; - } // endif EOF - - // New start position - Spos = Sosar->GetIntValue(ix[i]); - } // endfor i - - // Copy eventually remaining lines - fseek(Stream, 0, SEEK_END); - Fpos = ftell(Stream); - b = MoveIntermediateLines(g, &moved) != RC_OK; - - if (!PlugCloseFile(g, To_Fbt) && !PlugCloseFile(g, To_Fb) && !b) - return false; - -err: - if (trace) - htrc("%s\n", g->Message); - - PlugCloseFile(g, To_Fbt); - return true; - } // end of MakeUpdatedFile - -/***********************************************************************/ -/* MakeDeletedFile. When deleting using indexing, the issue is that */ -/* record are not necessarily deleted in sequential order. Moving */ -/* intermediate lines cannot be done while deleing them because */ -/* this can cause extra wrong records to be included in the new file. */ -/* What we do here is to reorder the deleted record and make the new */ -/* deleted file from the ordered deleted records. */ -/***********************************************************************/ -bool DOSFAM::MakeDeletedFile(PGLOBAL g) - { - char *crlf = "\n", *mode = UseTemp ? "rb" : "r+b"; - int *ix, i; - bool moved; - - /*********************************************************************/ - /* Open the temporary file, Spos is at the beginning of file. */ - /*********************************************************************/ - if (!(Posar = MakeValueArray(g, To_Pos))) { - strcpy(g->Message, "Position array is null"); - goto err; - } else if (!(Sosar = MakeValueArray(g, To_Sos))) { - strcpy(g->Message, "Start position array is null"); - goto err; - } else if (!(ix = (int*)Posar->GetSortIndex(g))) { - strcpy(g->Message, "Error getting array sort index"); - goto err; - } // endif's - - Spos = 0; - - for (i = 0; i < Posar->GetNval(); i++) { - Fpos = Posar->GetIntValue(ix[i]); - - if (i || UseTemp) { - // Copy all not updated lines preceding this one - if (MoveIntermediateLines(g, &moved)) - goto err; - - } else - Tpos = Fpos; - - // New start position - Spos = Sosar->GetIntValue(ix[i]); - } // endfor i - - if (!PlugCloseFile(g, To_Fbt) && !PlugCloseFile(g, To_Fb)) - return false; - -err: - if (trace) - htrc("%s\n", g->Message); - - PlugCloseFile(g, To_Fbt); - return true; - } // end of MakeDeletedFile - /***********************************************************************/ /* Delete the old file and rename the new temp file. */ /* If aborting just delete the new temp file. */ @@ -1148,22 +1138,10 @@ int DOSFAM::RenameTempFile(PGLOBAL g) // This loop is necessary because, in case of join, // To_File can have been open several times. for (PFBLOCK fb = PlgGetUser(g)->Openlist; fb; fb = fb->Next) - if (fb == To_Fb || (fb == To_Fbt && !Indxd)) + if (fb == To_Fb || (fb == To_Fbt)) rc = PlugCloseFile(g, fb); if (!Abort) { - // If indexed the temp file must be made - if (Indxd) { - Abort = (Tdbp->Mode == MODE_UPDATE) ? MakeUpdatedFile(g) - : MakeDeletedFile(g); - - if (Abort) { - remove(tempname); - return RC_FX; - } // endif Abort - - } // endif Indxd - PlugSetPath(filename, To_File, Tdbp->GetPath()); strcat(PlugRemoveType(filetemp, filename), ".ttt"); remove(filetemp); // May still be there from previous error @@ -1199,7 +1177,7 @@ void DOSFAM::CloseTableFile(PGLOBAL g, bool abort) Abort = abort; if (UseTemp && T_Stream) { - if (Tdbp->Mode == MODE_UPDATE && !Indxd && !Abort) { + if (Tdbp->Mode == MODE_UPDATE && !Abort) { // Copy eventually remaining lines bool b; diff --git a/storage/connect/filamtxt.h b/storage/connect/filamtxt.h index 83c93ecc6f2..b89d58965f9 100644 --- a/storage/connect/filamtxt.h +++ b/storage/connect/filamtxt.h @@ -69,10 +69,13 @@ class DllExport TXTFAM : public BLOCK { virtual int DeleteRecords(PGLOBAL g, int irc) = 0; virtual void CloseTableFile(PGLOBAL g, bool abort) = 0; virtual void Rewind(void) = 0; + virtual int InitDelete(PGLOBAL g, int fpos, int spos); + bool AddListValue(PGLOBAL g, int type, void *val, PPARM *top); + int StoreValues(PGLOBAL g, bool upd); + int UpdateSortedRows(PGLOBAL g); + int DeleteSortedRows(PGLOBAL g); protected: - bool AddListValue(PGLOBAL g, int type, void *val, PPARM *top); - // Members PTDBDOS Tdbp; // To table class PSZ To_File; // Points to table file name @@ -107,9 +110,11 @@ class DllExport TXTFAM : public BLOCK { int Modif; // Number of modified lines in block int Blksize; // Size of padded blocks int Ending; // Length of line end + int Fpos; // Position of last read record + int Spos; // Start position for update/delete move + int Tpos; // Target Position for delete move bool Padded; // true if fixed size blocks are padded bool Eof; // true if an EOF (0xA) character exists - bool Indxd; // True for indexed UPDATE/DELETE bool Abort; // To abort on error char *CrLf; // End of line character(s) }; // end of class TXTFAM @@ -154,16 +159,12 @@ class DllExport DOSFAM : public TXTFAM { virtual bool OpenTempFile(PGLOBAL g); virtual bool MoveIntermediateLines(PGLOBAL g, bool *b); virtual int RenameTempFile(PGLOBAL g); - virtual bool MakeUpdatedFile(PGLOBAL g); - virtual bool MakeDeletedFile(PGLOBAL g); + virtual int InitDelete(PGLOBAL g, int fpos, int spos); // Members FILE *Stream; // Points to Dos file structure FILE *T_Stream; // Points to temporary file structure PFBLOCK To_Fbt; // Pointer to temp file block - int Fpos; // Position of last read record - int Tpos; // Target Position for delete move - int Spos; // Start position for update/delete move bool UseTemp; // True to use a temporary file in Upd/Del bool Bin; // True to force binary mode }; // end of class DOSFAM diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp index 34f55cf831b..b93adbd13dd 100755 --- a/storage/connect/filamvct.cpp +++ b/storage/connect/filamvct.cpp @@ -93,11 +93,6 @@ typedef struct _vecheader { PVBLK AllocValBlock(PGLOBAL, void *, int, int, int, int, bool check = true, bool blank = true, bool un = false); -/***********************************************************************/ -/* Routine called externally by VCTFAM MakeUpdatedFile function. */ -/***********************************************************************/ -PARRAY MakeValueArray(PGLOBAL g, PPARM pp); - /* -------------------------- Class VCTFAM --------------------------- */ /***********************************************************************/ @@ -670,10 +665,7 @@ int VCTFAM::WriteBuffer(PGLOBAL g) // Mode Update is done in ReadDB, we just initialize it here if (!T_Stream) { if (UseTemp) { - if ((Indxd = Tdbp->GetKindex() != NULL)) { - strcpy(g->Message, "VCT indexed udate using temp file NIY"); - return RC_FX; - } else if (OpenTempFile(g)) + if (OpenTempFile(g)) return RC_FX; // Most of the time, not all table columns are updated. @@ -792,17 +784,12 @@ int VCTFAM::DeleteRecords(PGLOBAL g, int irc) Spos = Tpos = Fpos; } // endif UseTemp - Indxd = Tdbp->GetKindex() != NULL; } // endif Tpos == Spos /*********************************************************************/ /* Move any intermediate lines. */ /*********************************************************************/ - if (Indxd) { - // Moving will be done later, must be done in sequential order - (void)AddListValue(g, TYPE_INT, &Fpos, &To_Pos); - Spos = Fpos; - } else if (MoveIntermediateLines(g, &eof)) + if (MoveIntermediateLines(g, &eof)) return RC_FX; if (irc == RC_OK) { @@ -822,11 +809,6 @@ int VCTFAM::DeleteRecords(PGLOBAL g, int irc) /* Last call after EOF has been reached. */ /* Update the Block and Last values. */ /*******************************************************************/ - if (Indxd && (Abort = MakeDeletedFile(g))) - return RC_FX; - else - Indxd = false; // Not to be redone by RenameTempFile - Block = (Tpos > 0) ? (Tpos + Nrec - 1) / Nrec : 0; Last = (Tpos + Nrec - 1) % Nrec + 1; @@ -1026,63 +1008,6 @@ bool VCTFAM::MoveIntermediateLines(PGLOBAL g, bool *b) return false; } // end of MoveIntermediateLines -/***********************************************************************/ -/* MakeDeletedFile. When deleting using indexing, the issue is that */ -/* record are not necessarily deleted in sequential order. Moving */ -/* intermediate lines cannot be done while deleing them because */ -/* this can cause extra wrong records to be included in the new file. */ -/* What we do here is to reorder the deleted record and make the new */ -/* deleted file from the ordered deleted records. */ -/***********************************************************************/ -bool VCTFAM::MakeDeletedFile(PGLOBAL g) - { -//char *crlf = "\n", *mode = UseTemp ? "rb" : "r+b"; - int *ix, i, n; - bool eof = false; - - /*********************************************************************/ - /* Open the temporary file, Spos is at the beginning of file. */ - /*********************************************************************/ - if (!(Posar = MakeValueArray(g, To_Pos))) { - strcpy(g->Message, "Position array is null"); - goto err; - } else if (!(ix = (int*)Posar->GetSortIndex(g))) { - strcpy(g->Message, "Error getting array sort index"); - goto err; - } // endif's - - n = Posar->GetNval(); - Spos = 0; - - for (i = 0; i < n; i++) { - if (i == n - 1 && !MaxBlk && UseTemp) - eof = true; - - Fpos = Posar->GetIntValue(ix[i]); - - if (i || UseTemp) { - // Copy all not updated lines preceding this one - if (MoveIntermediateLines(g, &eof)) - goto err; - - } else - Tpos = Fpos; - - // New start position - Spos = Fpos + 1; - } // endfor i - - if (!PlugCloseFile(g, To_Fbt)) - return false; - -err: - if (trace) - htrc("%s\n", g->Message); - - PlugCloseFile(g, To_Fbt); - return true; - } // end of MakeDeletedFile - /***********************************************************************/ /* Clean deleted space in a VCT or Vec table file. */ /***********************************************************************/ @@ -1701,13 +1626,7 @@ int VCMFAM::DeleteRecords(PGLOBAL g, int irc) /* not required here, just setting of future Spos and Tpos. */ /*******************************************************************/ Tpos = Spos = Fpos; - Indxd = Tdbp->GetKindex() != NULL; - } // endif Tpos - - if (Indxd) - // Moving will be done later, must be done in sequential order - (void)AddListValue(g, TYPE_INT, &Fpos, &To_Pos); - else + } else (void)MoveIntermediateLines(g); if (irc == RC_OK) { @@ -1716,7 +1635,7 @@ int VCMFAM::DeleteRecords(PGLOBAL g, int irc) if (trace) htrc("after: Tpos=%p Spos=%p\n", Tpos, Spos); - } else if (!(Abort = (Indxd && MakeDeletedFile(g)))) { + } else { /*******************************************************************/ /* Last call after EOF has been reached. */ /*******************************************************************/ @@ -1786,8 +1705,7 @@ int VCMFAM::DeleteRecords(PGLOBAL g, int irc) // Reset Last and Block values in the catalog PlugCloseFile(g, To_Fb); // in case of Header ResetTableSize(g, Block, Last); - } else - return RC_FX; + } // endif irc return RC_OK; // All is correct } // end of DeleteRecords @@ -1841,49 +1759,6 @@ bool VCMFAM::MoveIntermediateLines(PGLOBAL g, bool *b) return false; } // end of MoveIntermediate Lines -/***********************************************************************/ -/* MakeDeletedFile. When deleting using indexing, the issue is that */ -/* record are not necessarily deleted in sequential order. Moving */ -/* intermediate lines cannot be done while deleting them. */ -/* What we do here is to reorder the deleted records and move the */ -/* intermediate files from the ordered deleted record positions. */ -/***********************************************************************/ -bool VCMFAM::MakeDeletedFile(PGLOBAL g) - { - int *ix, i; - - /*********************************************************************/ - /* Make and order the arrays from the saved values. */ - /*********************************************************************/ - if (!(Posar = MakeValueArray(g, To_Pos))) { - strcpy(g->Message, "Position array is null"); - goto err; - } else if (!(ix = (int*)Posar->GetSortIndex(g))) { - strcpy(g->Message, "Error getting array sort index"); - goto err; - } // endif's - - for (i = 0; i < Posar->GetNval(); i++) { - Fpos = Posar->GetIntValue(ix[i]); - - if (!i) { - Tpos = Fpos; - } else - (void)MoveIntermediateLines(g); - - // New start position - Spos = Fpos + 1; - } // endfor i - - return false; - -err: - if (trace) - htrc("%s\n", g->Message); - - return true; - } // end of MakeDeletedFile - /***********************************************************************/ /* Data Base close routine for VMP access method. */ /***********************************************************************/ @@ -2309,10 +2184,7 @@ int VECFAM::WriteBuffer(PGLOBAL g) } else // Mode Update // Writing updates being done in ReadDB we do initialization only. if (InitUpdate) { - if ((Indxd = Tdbp->GetKindex() != NULL)) { - strcpy(g->Message, "VEC indexed udate using temp file NIY"); - return RC_FX; - } else if (OpenTempFile(g)) + if (OpenTempFile(g)) return RC_FX; InitUpdate = false; // Done @@ -2360,17 +2232,12 @@ int VECFAM::DeleteRecords(PGLOBAL g, int irc) /*****************************************************************/ Spos = Tpos = Fpos; - Indxd = Tdbp->GetKindex() != NULL; } // endif Tpos == Spos /*********************************************************************/ /* Move any intermediate lines. */ /*********************************************************************/ - if (Indxd) { - // Moving will be done later, must be done in sequential order - (void)AddListValue(g, TYPE_INT, &Fpos, &To_Pos); - Spos = Fpos; - } else if (MoveIntermediateLines(g)) + if (MoveIntermediateLines(g)) return RC_FX; if (irc == RC_OK) { @@ -2386,11 +2253,6 @@ int VECFAM::DeleteRecords(PGLOBAL g, int irc) /*******************************************************************/ /* Last call after EOF has been reached. */ /*******************************************************************/ - if (Indxd && (Abort = MakeDeletedFile(g))) - return RC_FX; -// else -// Indxd = false; // Not to be redone by RenameTempFile - if (!UseTemp) { /*****************************************************************/ /* Because the chsize functionality is only accessible with a */ @@ -2560,56 +2422,6 @@ bool VECFAM::MoveIntermediateLines(PGLOBAL g, bool *bn) return false; } // end of MoveIntermediate Lines -/***********************************************************************/ -/* MakeDeletedFile. When deleting using indexing, the issue is that */ -/* record are not necessarily deleted in sequential order. Moving */ -/* intermediate lines cannot be done while deleing them because */ -/* this can cause extra wrong records to be included in the new file. */ -/* What we do here is to reorder the deleted record and make the new */ -/* deleted file from the ordered deleted records. */ -/***********************************************************************/ -bool VECFAM::MakeDeletedFile(PGLOBAL g) - { - int *ix, i, n; - - /*********************************************************************/ - /* Open the temporary file, Spos is at the beginning of file. */ - /*********************************************************************/ - if (!(Posar = MakeValueArray(g, To_Pos))) { - strcpy(g->Message, "Position array is null"); - goto err; - } else if (!(ix = (int*)Posar->GetSortIndex(g))) { - strcpy(g->Message, "Error getting array sort index"); - goto err; - } // endif's - - n = Posar->GetNval(); - Spos = 0; - - for (i = 0; i < n; i++) { - Fpos = Posar->GetIntValue(ix[i]); - - if (i || UseTemp) { - // Copy all not updated lines preceding this one - if (MoveIntermediateLines(g)) - goto err; - - } else - Tpos = Fpos; - - // New start position - Spos = Fpos + 1; - } // endfor i - - return false; - -err: - if (trace) - htrc("%s\n", g->Message); - - return true; - } // end of MakeDeletedFile - /***********************************************************************/ /* Delete the old files and rename the new temporary files. */ /***********************************************************************/ @@ -3109,13 +2921,7 @@ int VMPFAM::DeleteRecords(PGLOBAL g, int irc) /* not required here, just setting of future Spos and Tpos. */ /*******************************************************************/ Tpos = Fpos; // Spos is set below - Indxd = Tdbp->GetKindex() != NULL; - } // endif Tpos - - if (Indxd) - // Moving will be done later, must be done in sequential order - (void)AddListValue(g, TYPE_INT, &Fpos, &To_Pos); - else if ((n = Fpos - Spos) > 0) { + } else if ((n = Fpos - Spos) > 0) { /*******************************************************************/ /* Non consecutive line to delete. Move intermediate lines. */ /*******************************************************************/ @@ -3137,7 +2943,7 @@ int VMPFAM::DeleteRecords(PGLOBAL g, int irc) if (trace) htrc("after: Tpos=%p Spos=%p\n", Tpos, Spos); - } else if (!(Abort = (Indxd && MakeDeletedFile(g)))) { + } else { /*******************************************************************/ /* Last call after EOF has been reached. */ /* We must firstly Unmap the view and use the saved file handle */ @@ -3198,55 +3004,6 @@ int VMPFAM::DeleteRecords(PGLOBAL g, int irc) return RC_OK; // All is correct } // end of DeleteRecords -/***********************************************************************/ -/* MakeDeletedFile. When deleting using indexing, the issue is that */ -/* record are not necessarily deleted in sequential order. Moving */ -/* intermediate lines cannot be done while deleting them. */ -/* What we do here is to reorder the deleted records and move the */ -/* intermediate files from the ordered deleted record positions. */ -/***********************************************************************/ -bool VMPFAM::MakeDeletedFile(PGLOBAL g) - { - int *ix, i, j, m, n; - - /*********************************************************************/ - /* Make and order the arrays from the saved values. */ - /*********************************************************************/ - if (!(Posar = MakeValueArray(g, To_Pos))) { - strcpy(g->Message, "Position array is null"); - goto err; - } else if (!(ix = (int*)Posar->GetSortIndex(g))) { - strcpy(g->Message, "Error getting array sort index"); - goto err; - } // endif's - - for (i = 0; i < Posar->GetNval(); i++) { - Fpos = Posar->GetIntValue(ix[i]); - - if (!i) { - Tpos = Fpos; - } else if ((n = Fpos - Spos) > 0) { - for (j = 0; j < Ncol; j++) { - m = Clens[j]; - memmove(Memcol[j] + Tpos * m, Memcol[j] + Spos * m, m * n); - } // endif j - - Tpos += n; - } // endif n - - // New start position - Spos = Fpos + 1; - } // endfor i - - return false; - -err: - if (trace) - htrc("%s\n", g->Message); - - return true; - } // end of MakeDeletedFile - /***********************************************************************/ /* Data Base close routine for VMP access method. */ /***********************************************************************/ @@ -3969,10 +3726,7 @@ int BGVFAM::WriteBuffer(PGLOBAL g) // Mode Update is done in ReadDB, we just initialize it here if (Tfile == INVALID_HANDLE_VALUE) { if (UseTemp) { - if ((Indxd = Tdbp->GetKindex() != NULL)) { - strcpy(g->Message, "VEC indexed udate using temp file NIY"); - return RC_FX; - } else if (OpenTempFile(g)) + if (OpenTempFile(g)) return RC_FX; // Most of the time, not all table columns are updated. @@ -4099,17 +3853,12 @@ int BGVFAM::DeleteRecords(PGLOBAL g, int irc) Spos = Tpos = Fpos; } // endif UseTemp - Indxd = Tdbp->GetKindex() != NULL; } // endif Tpos == Spos /*********************************************************************/ /* Move any intermediate lines. */ /*********************************************************************/ - if (Indxd) { - // Moving will be done later, must be done in sequential order - (void)AddListValue(g, TYPE_INT, &Fpos, &To_Pos); - Spos = Fpos; - } else if (MoveIntermediateLines(g, &eof)) + if (MoveIntermediateLines(g, &eof)) return RC_FX; if (irc == RC_OK) { @@ -4125,11 +3874,6 @@ int BGVFAM::DeleteRecords(PGLOBAL g, int irc) /*******************************************************************/ /* Last call after EOF has been reached. */ /*******************************************************************/ - if (Indxd && (Abort = MakeDeletedFile(g))) - return RC_FX; - else - Indxd = false; // Not to be redone by RenameTempFile - Block = (Tpos > 0) ? (Tpos + Nrec - 1) / Nrec : 0; Last = (Tpos + Nrec - 1) % Nrec + 1; diff --git a/storage/connect/filamvct.h b/storage/connect/filamvct.h index 8acb62b14dc..be66232acfb 100644 --- a/storage/connect/filamvct.h +++ b/storage/connect/filamvct.h @@ -66,7 +66,6 @@ class DllExport VCTFAM : public FIXFAM { virtual bool MoveLines(PGLOBAL g) {return false;} virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL); virtual bool CleanUnusedSpace(PGLOBAL g); - virtual bool MakeDeletedFile(PGLOBAL g); virtual int GetBlockInfo(PGLOBAL g); virtual bool SetBlockInfo(PGLOBAL g); bool ResetTableSize(PGLOBAL g, int block, int last); @@ -116,7 +115,6 @@ class DllExport VCMFAM : public VCTFAM { protected: // Specific functions virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL); - virtual bool MakeDeletedFile(PGLOBAL g); virtual bool ReadBlock(PGLOBAL g, PVCTCOL colp); virtual bool WriteBlock(PGLOBAL g, PVCTCOL colp); @@ -162,7 +160,6 @@ class DllExport VECFAM : public VCTFAM { virtual bool MoveLines(PGLOBAL g); virtual bool MoveIntermediateLines(PGLOBAL g, bool *b = NULL); virtual int RenameTempFile(PGLOBAL g); - virtual bool MakeDeletedFile(PGLOBAL g); bool OpenColumnFile(PGLOBAL g, char *opmode, int i); // Members @@ -199,7 +196,6 @@ class DllExport VMPFAM : public VCMFAM { virtual void CloseTableFile(PGLOBAL g, bool abort); protected: - virtual bool MakeDeletedFile(PGLOBAL g); bool MapColumnFile(PGLOBAL g, MODE mode, int i); // Members diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp index 4a04b0c2db4..861a9da106d 100644 --- a/storage/connect/tabdos.cpp +++ b/storage/connect/tabdos.cpp @@ -432,6 +432,7 @@ TDBDOS::TDBDOS(PDOSDEF tdp, PTXF txfp) : TDBASE(tdp) //Xeval = 0; Beval = 0; Abort = false; + Indxd = false; } // end of TDBDOS standard constructor TDBDOS::TDBDOS(PGLOBAL g, PTDBDOS tdbp) : TDBASE(tdbp) @@ -446,6 +447,8 @@ TDBDOS::TDBDOS(PGLOBAL g, PTDBDOS tdbp) : TDBASE(tdbp) SavFil = tdbp->SavFil; //Xeval = tdbp->Xeval; Beval = tdbp->Beval; + Abort = tdbp->Abort; + Indxd = tdbp->Indxd; } // end of TDBDOS copy constructor // Method @@ -1807,7 +1810,11 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, PIXDEF xdp) To_BlkFil = NULL; } // endif AmType - To_Kindex= kxp; + if (!(To_Kindex= kxp)->IsSorted() && + ((Mode == MODE_UPDATE && IsUsingTemp(g)) || + (Mode == MODE_DELETE && Txfp->GetAmType() != TYPE_AM_DBF))) + Indxd = true; + } // endif brc } else @@ -2153,13 +2160,10 @@ int TDBDOS::ReadDB(PGLOBAL g) } // end of ReadDB /***********************************************************************/ -/* WriteDB: Data Base write routine for DOS access method. */ +/* PrepareWriting: Prepare the line to write. */ /***********************************************************************/ -int TDBDOS::WriteDB(PGLOBAL g) +bool TDBDOS::PrepareWriting(PGLOBAL g) { - if (trace > 1) - htrc("DOS WriteDB: R%d Mode=%d \n", Tdb_No, Mode); - if (!Ftype && (Mode == MODE_INSERT || Txfp->GetUseTemp())) { char *p; @@ -2174,6 +2178,20 @@ int TDBDOS::WriteDB(PGLOBAL g) *(++p) = '\0'; } // endif Mode + return false; + } // end of WriteDB + +/***********************************************************************/ +/* WriteDB: Data Base write routine for DOS access method. */ +/***********************************************************************/ +int TDBDOS::WriteDB(PGLOBAL g) + { + if (trace > 1) + htrc("DOS WriteDB: R%d Mode=%d \n", Tdb_No, Mode); + + // Make the line to write + (void)PrepareWriting(g); + if (trace > 1) htrc("Write: line is='%s'\n", To_Line); diff --git a/storage/connect/tabdos.h b/storage/connect/tabdos.h index 7f2c4f5e7ee..e49f3188795 100644 --- a/storage/connect/tabdos.h +++ b/storage/connect/tabdos.h @@ -136,6 +136,7 @@ class DllExport TDBDOS : public TDBASE { virtual PTDB CopyOne(PTABS t); virtual void ResetDB(void) {Txfp->Reset();} virtual bool IsUsingTemp(PGLOBAL g); + virtual bool IsIndexed(void) {return Indxd;} virtual void ResetSize(void) {MaxSize = Cardinal = -1;} virtual int ResetTableOpt(PGLOBAL g, bool dop, bool dox); virtual int MakeBlockValues(PGLOBAL g); @@ -176,6 +177,7 @@ class DllExport TDBDOS : public TDBASE { bool GetDistinctColumnValues(PGLOBAL g, int nrec); protected: + virtual bool PrepareWriting(PGLOBAL g); PBF CheckBlockFilari(PGLOBAL g, PXOB *arg, int op, bool *cnv); // Members @@ -185,6 +187,7 @@ class DllExport TDBDOS : public TDBASE { PFIL SavFil; // Saved hidden filter char *To_Line; // Points to current processed line bool Abort; // TRUE when aborting UPDATE/DELETE + bool Indxd; // TRUE for indexed UPDATE/DELETE int Lrecl; // Logical Record Length int AvgLen; // Logical Record Average Length //int Xeval; // BlockTest return value diff --git a/storage/connect/tabfix.h b/storage/connect/tabfix.h index 5feb3589928..00439fea0e8 100644 --- a/storage/connect/tabfix.h +++ b/storage/connect/tabfix.h @@ -51,6 +51,8 @@ class DllExport TDBFIX : public TDBDOS { virtual int WriteDB(PGLOBAL g); protected: + virtual bool PrepareWriting(PGLOBAL g) {return false;} + // Members are inherited from TDBDOS }; // end of class TDBFIX diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp index c015b6adad3..b2d60d87f3b 100644 --- a/storage/connect/tabfmt.cpp +++ b/storage/connect/tabfmt.cpp @@ -899,9 +899,9 @@ int TDBCSV::ReadBuffer(PGLOBAL g) } // end of ReadBuffer /***********************************************************************/ -/* Data Base write routine CSV file access method. */ +/* Prepare the line to write. */ /***********************************************************************/ -int TDBCSV::WriteDB(PGLOBAL g) +bool TDBCSV::PrepareWriting(PGLOBAL g) { char sep[2], qot[2]; int i, nlen, oldlen = strlen(To_Line); @@ -912,7 +912,7 @@ int TDBCSV::WriteDB(PGLOBAL g) // Before writing the line we must check its length if ((nlen = CheckWrite(g)) < 0) - return RC_FX; + return true; // Before writing the line we must make it sep[0] = Sep; @@ -975,6 +975,18 @@ int TDBCSV::WriteDB(PGLOBAL g) if (trace > 1) htrc("Write: line is=%s", To_Line); + return false; + } // end of PrepareWriting + +/***********************************************************************/ +/* Data Base write routine CSV file access method. */ +/***********************************************************************/ +int TDBCSV::WriteDB(PGLOBAL g) + { + // Before writing the line we must check and prepare it + if (PrepareWriting(g)) + return RC_FX; + /*********************************************************************/ /* Now start the writing process. */ /*********************************************************************/ diff --git a/storage/connect/tabfmt.h b/storage/connect/tabfmt.h index aa14b4481f0..939c1677f93 100644 --- a/storage/connect/tabfmt.h +++ b/storage/connect/tabfmt.h @@ -1,188 +1,193 @@ -/*************** TabFmt H Declares Source Code File (.H) ***************/ -/* Name: TABFMT.H Version 2.4 */ -/* */ -/* (C) Copyright to the author Olivier BERTRAND 2001-2014 */ -/* */ -/* This file contains the CSV and FMT classes declares. */ -/***********************************************************************/ -#include "xtable.h" // Base class declares -#include "tabdos.h" - -typedef class TDBFMT *PTDBFMT; - -/***********************************************************************/ -/* Functions used externally. */ -/***********************************************************************/ -PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q, - int hdr, int mxr, bool info); - -/***********************************************************************/ -/* CSV table. */ -/***********************************************************************/ -class DllExport CSVDEF : public DOSDEF { /* Logical table description */ - friend class TDBCSV; - friend class TDBCCL; - public: - // Constructor - CSVDEF(void); - - // Implementation - virtual const char *GetType(void) {return "CSV";} - char GetSep(void) {return Sep;} - char GetQot(void) {return Qot;} - - // Methods - virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); - virtual PTDB GetTable(PGLOBAL g, MODE mode); - - protected: - // Members - bool Fmtd; /* true for formatted files */ -//bool Accept; /* true if wrong lines are accepted */ - bool Header; /* true if first line contains headers */ -//int Maxerr; /* Maximum number of bad records */ - int Quoted; /* Quoting level for quoted fields */ - char Sep; /* Separator for standard CSV files */ - char Qot; /* Character for quoted strings */ - }; // end of CSVDEF - -/***********************************************************************/ -/* This is the DOS/UNIX Access Method class declaration for files */ -/* that are CSV files with columns separated by the Sep character. */ -/***********************************************************************/ -class TDBCSV : public TDBDOS { - friend class CSVCOL; - public: - // Constructor - TDBCSV(PCSVDEF tdp, PTXF txfp); - TDBCSV(PGLOBAL g, PTDBCSV tdbp); - - // Implementation - virtual AMT GetAmType(void) {return TYPE_AM_CSV;} - virtual PTDB Duplicate(PGLOBAL g) - {return (PTDB)new(g) TDBCSV(g, this);} - - // Methods - virtual PTDB CopyOne(PTABS t); -//virtual bool IsUsingTemp(PGLOBAL g); - virtual int GetBadLines(void) {return (int)Nerr;} - - // Database routines - virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); - virtual bool OpenDB(PGLOBAL g); - virtual int WriteDB(PGLOBAL g); - virtual int CheckWrite(PGLOBAL g); - virtual int ReadBuffer(PGLOBAL g); // Physical file read - - // Specific routines - virtual int EstimatedLength(PGLOBAL g); - virtual bool SkipHeader(PGLOBAL g); - virtual bool CheckErr(void); - - protected: - // Members - PSZ *Field; // Field to write to current line - int *Offset; // Column offsets for current record - int *Fldlen; // Column field length for current record - bool *Fldtyp; // true for numeric fields - int Fields; // Number of fields to handle - int Nerr; // Number of bad records - int Maxerr; // Maximum number of bad records - int Quoted; // Quoting level for quoted fields - bool Accept; // true if bad lines are accepted - bool Header; // true if first line contains column headers - char Sep; // Separator - char Qot; // Quoting character - }; // end of class TDBCSV - -/***********************************************************************/ -/* Class CSVCOL: CSV access method column descriptor. */ -/* This A.M. is used for Comma Separated V(?) files. */ -/***********************************************************************/ -class CSVCOL : public DOSCOL { - friend class TDBCSV; - friend class TDBFMT; - public: - // Constructors - CSVCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i); - CSVCOL(CSVCOL *colp, PTDB tdbp); // Constructor used in copy process - - // Implementation - virtual int GetAmType() {return TYPE_AM_CSV;} - - // Methods - virtual bool VarSize(void); - virtual void ReadColumn(PGLOBAL g); - virtual void WriteColumn(PGLOBAL g); - - protected: - // Default constructor not to be used - CSVCOL(void) {} - - // Members - int Fldnum; // Field ordinal number (0 based) - }; // end of class CSVCOL - -/***********************************************************************/ -/* This is the DOS/UNIX Access Method class declaration for files */ -/* whose record format is described by a Format keyword. */ -/***********************************************************************/ -class TDBFMT : public TDBCSV { - friend class CSVCOL; -//friend class FMTCOL; - public: - // Standard constructor - TDBFMT(PCSVDEF tdp, PTXF txfp) : TDBCSV(tdp, txfp) - {FldFormat = NULL; To_Fld = NULL; FmtTest = NULL; Linenum = 0;} - - // Copy constructor - TDBFMT(PGLOBAL g, PTDBFMT tdbp); - - // Implementation - virtual AMT GetAmType(void) {return TYPE_AM_FMT;} - virtual PTDB Duplicate(PGLOBAL g) - {return (PTDB)new(g) TDBFMT(g, this);} - - // Methods - virtual PTDB CopyOne(PTABS t); - - // Database routines - virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); -//virtual int GetMaxSize(PGLOBAL g); - virtual bool OpenDB(PGLOBAL g); - virtual int WriteDB(PGLOBAL g); -//virtual int CheckWrite(PGLOBAL g); - virtual int ReadBuffer(PGLOBAL g); // Physical file read - - // Specific routines - virtual int EstimatedLength(PGLOBAL g); - - protected: - // Members - PSZ *FldFormat; // Field read format - void *To_Fld; // To field test buffer - int *FmtTest; // Test on ending by %n or %m - int Linenum; // Last read line - }; // end of class TDBFMT - -/***********************************************************************/ -/* This is the class declaration for the CSV catalog table. */ -/***********************************************************************/ -class TDBCCL : public TDBCAT { - public: - // Constructor - TDBCCL(PCSVDEF tdp); - - protected: - // Specific routines - virtual PQRYRES GetResult(PGLOBAL g); - - // Members - char *Fn; // The CSV file (path) name - bool Hdr; // true if first line contains headers - int Mxr; // Maximum number of bad records - int Qtd; // Quoting level for quoted fields - char Sep; // Separator for standard CSV files - }; // end of class TDBCCL - -/* ------------------------- End of TabFmt.H ------------------------- */ +/*************** TabFmt H Declares Source Code File (.H) ***************/ +/* Name: TABFMT.H Version 2.4 */ +/* */ +/* (C) Copyright to the author Olivier BERTRAND 2001-2014 */ +/* */ +/* This file contains the CSV and FMT classes declares. */ +/***********************************************************************/ +#include "xtable.h" // Base class declares +#include "tabdos.h" + +typedef class TDBFMT *PTDBFMT; + +/***********************************************************************/ +/* Functions used externally. */ +/***********************************************************************/ +PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q, + int hdr, int mxr, bool info); + +/***********************************************************************/ +/* CSV table. */ +/***********************************************************************/ +class DllExport CSVDEF : public DOSDEF { /* Logical table description */ + friend class TDBCSV; + friend class TDBCCL; + public: + // Constructor + CSVDEF(void); + + // Implementation + virtual const char *GetType(void) {return "CSV";} + char GetSep(void) {return Sep;} + char GetQot(void) {return Qot;} + + // Methods + virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); + virtual PTDB GetTable(PGLOBAL g, MODE mode); + + protected: + // Members + bool Fmtd; /* true for formatted files */ +//bool Accept; /* true if wrong lines are accepted */ + bool Header; /* true if first line contains headers */ +//int Maxerr; /* Maximum number of bad records */ + int Quoted; /* Quoting level for quoted fields */ + char Sep; /* Separator for standard CSV files */ + char Qot; /* Character for quoted strings */ + }; // end of CSVDEF + +/***********************************************************************/ +/* This is the DOS/UNIX Access Method class declaration for files */ +/* that are CSV files with columns separated by the Sep character. */ +/***********************************************************************/ +class TDBCSV : public TDBDOS { + friend class CSVCOL; + public: + // Constructor + TDBCSV(PCSVDEF tdp, PTXF txfp); + TDBCSV(PGLOBAL g, PTDBCSV tdbp); + + // Implementation + virtual AMT GetAmType(void) {return TYPE_AM_CSV;} + virtual PTDB Duplicate(PGLOBAL g) + {return (PTDB)new(g) TDBCSV(g, this);} + + // Methods + virtual PTDB CopyOne(PTABS t); +//virtual bool IsUsingTemp(PGLOBAL g); + virtual int GetBadLines(void) {return (int)Nerr;} + + // Database routines + virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); + virtual bool OpenDB(PGLOBAL g); + virtual int WriteDB(PGLOBAL g); + virtual int CheckWrite(PGLOBAL g); + virtual int ReadBuffer(PGLOBAL g); // Physical file read + + // Specific routines + virtual int EstimatedLength(PGLOBAL g); + virtual bool SkipHeader(PGLOBAL g); + virtual bool CheckErr(void); + + protected: + virtual bool PrepareWriting(PGLOBAL g); + + // Members + PSZ *Field; // Field to write to current line + int *Offset; // Column offsets for current record + int *Fldlen; // Column field length for current record + bool *Fldtyp; // true for numeric fields + int Fields; // Number of fields to handle + int Nerr; // Number of bad records + int Maxerr; // Maximum number of bad records + int Quoted; // Quoting level for quoted fields + bool Accept; // true if bad lines are accepted + bool Header; // true if first line contains column headers + char Sep; // Separator + char Qot; // Quoting character + }; // end of class TDBCSV + +/***********************************************************************/ +/* Class CSVCOL: CSV access method column descriptor. */ +/* This A.M. is used for Comma Separated V(?) files. */ +/***********************************************************************/ +class CSVCOL : public DOSCOL { + friend class TDBCSV; + friend class TDBFMT; + public: + // Constructors + CSVCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i); + CSVCOL(CSVCOL *colp, PTDB tdbp); // Constructor used in copy process + + // Implementation + virtual int GetAmType() {return TYPE_AM_CSV;} + + // Methods + virtual bool VarSize(void); + virtual void ReadColumn(PGLOBAL g); + virtual void WriteColumn(PGLOBAL g); + + protected: + // Default constructor not to be used + CSVCOL(void) {} + + // Members + int Fldnum; // Field ordinal number (0 based) + }; // end of class CSVCOL + +/***********************************************************************/ +/* This is the DOS/UNIX Access Method class declaration for files */ +/* whose record format is described by a Format keyword. */ +/***********************************************************************/ +class TDBFMT : public TDBCSV { + friend class CSVCOL; +//friend class FMTCOL; + public: + // Standard constructor + TDBFMT(PCSVDEF tdp, PTXF txfp) : TDBCSV(tdp, txfp) + {FldFormat = NULL; To_Fld = NULL; FmtTest = NULL; Linenum = 0;} + + // Copy constructor + TDBFMT(PGLOBAL g, PTDBFMT tdbp); + + // Implementation + virtual AMT GetAmType(void) {return TYPE_AM_FMT;} + virtual PTDB Duplicate(PGLOBAL g) + {return (PTDB)new(g) TDBFMT(g, this);} + + // Methods + virtual PTDB CopyOne(PTABS t); + + // Database routines + virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); +//virtual int GetMaxSize(PGLOBAL g); + virtual bool OpenDB(PGLOBAL g); + virtual int WriteDB(PGLOBAL g); +//virtual int CheckWrite(PGLOBAL g); + virtual int ReadBuffer(PGLOBAL g); // Physical file read + + // Specific routines + virtual int EstimatedLength(PGLOBAL g); + + protected: + virtual bool PrepareWriting(PGLOBAL g) + {strcpy(g->Message, "FMT is read only"); return true;} + + // Members + PSZ *FldFormat; // Field read format + void *To_Fld; // To field test buffer + int *FmtTest; // Test on ending by %n or %m + int Linenum; // Last read line + }; // end of class TDBFMT + +/***********************************************************************/ +/* This is the class declaration for the CSV catalog table. */ +/***********************************************************************/ +class TDBCCL : public TDBCAT { + public: + // Constructor + TDBCCL(PCSVDEF tdp); + + protected: + // Specific routines + virtual PQRYRES GetResult(PGLOBAL g); + + // Members + char *Fn; // The CSV file (path) name + bool Hdr; // true if first line contains headers + int Mxr; // Maximum number of bad records + int Qtd; // Quoting level for quoted fields + char Sep; // Separator for standard CSV files + }; // end of class TDBCCL + +/* ------------------------- End of TabFmt.H ------------------------- */ diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp index 12781b2ac05..7b339be9ed2 100755 --- a/storage/connect/xindex.cpp +++ b/storage/connect/xindex.cpp @@ -50,7 +50,7 @@ /***********************************************************************/ /* Macro or external routine definition */ /***********************************************************************/ -#define NZ 7 +#define NZ 8 #define NW 5 #define MAX_INDX 10 #ifndef INVALID_SET_FILE_POINTER @@ -869,17 +869,18 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp) /*********************************************************************/ /* Write the index values on the index file. */ /*********************************************************************/ - n[0] = ID; // To check validity + n[0] = ID + MAX_INDX; // To check validity n[1] = Nk; // The number of indexed columns n[2] = nof; // The offset array size or 0 n[3] = Num_K; // The index size n[4] = Incr; // Increment of record positions n[5] = Nblk; n[6] = Sblk; + n[7] = Srtd ? 1 : 0; // Values are sorted in the file if (trace) { htrc("Saving index %s\n", Xdp->GetName()); - htrc("ID=%d Nk=%d nof=%d Num_K=%d Incr=%d Nblk=%d Sblk=%d\n", - ID, Nk, nof, Num_K, Incr, Nblk, Sblk); + htrc("ID=%d Nk=%d nof=%d Num_K=%d Incr=%d Nblk=%d Sblk=%d Srtd=%d\n", + ID, Nk, nof, Num_K, Incr, Nblk, Sblk, Srtd); } // endif trace size = X->Write(g, n, NZ, sizeof(int), rc); @@ -1019,12 +1020,22 @@ bool XINDEX::Init(PGLOBAL g) goto err; // No saved values // Now start the reading process. - if (X->Read(g, nv, NZ, sizeof(int))) + if (X->Read(g, nv, NZ - 1, sizeof(int))) goto err; + if (nv[0] >= MAX_INDX) { + // New index format + if (X->Read(g, nv + 7, 1, sizeof(int))) + goto err; + + Srtd = nv[7] != 0; + nv[0] -= MAX_INDX; + } else + Srtd = false; + if (trace) - htrc("nv=%d %d %d %d %d %d %d\n", - nv[0], nv[1], nv[2], nv[3], nv[4], nv[5], nv[6]); + htrc("nv=%d %d %d %d %d %d %d (%d)\n", + nv[0], nv[1], nv[2], nv[3], nv[4], nv[5], nv[6], Srtd); // The test on ID was suppressed because MariaDB can change an index ID // when other indexes are added or deleted @@ -1271,11 +1282,20 @@ bool XINDEX::MapInit(PGLOBAL g) // Now start the mapping process. nv = (int*)mbase; - mbase += NZ * sizeof(int); + + if (nv[0] >= MAX_INDX) { + // New index format + Srtd = nv[7] != 0; + nv[0] -= MAX_INDX; + mbase += NZ * sizeof(int); + } else { + Srtd = false; + mbase += (NZ - 1) * sizeof(int); + } // endif nv if (trace) - htrc("nv=%d %d %d %d %d %d %d\n", - nv[0], nv[1], nv[2], nv[3], nv[4], nv[5], nv[6]); + htrc("nv=%d %d %d %d %d %d %d %d\n", + nv[0], nv[1], nv[2], nv[3], nv[4], nv[5], nv[6], Srtd); // The test on ID was suppressed because MariaDB can change an index ID // when other indexes are added or deleted diff --git a/storage/connect/xindex.h b/storage/connect/xindex.h index 4988a12326a..c702baeec83 100644 --- a/storage/connect/xindex.h +++ b/storage/connect/xindex.h @@ -192,6 +192,7 @@ class DllExport XXBASE : public CSORT, public BLOCK { void SetNth(int n) {Nth = n;} int *GetPof(void) {return Pof;} int *GetPex(void) {return Pex;} + bool IsSorted(void) {return Srtd;} void FreeIndex(void) {PlgDBfree(Index);} // Methods diff --git a/storage/connect/xtable.h b/storage/connect/xtable.h index 2d95acdb6d4..628ab96135d 100644 --- a/storage/connect/xtable.h +++ b/storage/connect/xtable.h @@ -147,6 +147,7 @@ class DllExport TDBASE : public TDB { inline PKXBASE GetKindex(void) {return To_Kindex;} inline PCOL GetSetCols(void) {return To_SetCols;} inline void SetSetCols(PCOL colp) {To_SetCols = colp;} + inline void SetKey_Col(PCOL *cpp) {To_Key_Col = cpp;} inline void SetXdp(PIXDEF xdp) {To_Xdp = xdp;} inline void SetKindex(PKXBASE kxp) {To_Kindex = kxp;} @@ -156,6 +157,7 @@ class DllExport TDBASE : public TDB { // Methods virtual bool IsUsingTemp(PGLOBAL g) {return false;} + virtual bool IsIndexed(void) {return false;} virtual PCATLG GetCat(void); virtual PSZ GetPath(void); virtual void PrintAM(FILE *f, char *m); @@ -190,6 +192,9 @@ class DllExport TDBASE : public TDB { {assert(false); return true;} protected: + virtual bool PrepareWriting(PGLOBAL g) {strcpy(g->Message, + "This function should not be called for this table"); return true;} + // Members PTABDEF To_Def; // Points to catalog description block PXOB *To_Link; // Points to column of previous relations From 8b9ed85b8a198e4de71677e3e9478c9162471e1b Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Fri, 15 Aug 2014 18:05:10 +0200 Subject: [PATCH 04/15] - Remove a gcc warning modified: storage/connect/xindex.cpp --- storage/connect/xindex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp index 7b339be9ed2..27770ef539a 100755 --- a/storage/connect/xindex.cpp +++ b/storage/connect/xindex.cpp @@ -411,7 +411,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) kcp = new(g) KXYCOL(this); - if (kcp->Init(g, colp, n, true, NULL)) + if (kcp->Init(g, colp, n, true, 0)) return true; if (trace) From f930f4eda9dd849b48e67eaecc8c130bb9310107 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Fri, 22 Aug 2014 17:30:22 +0200 Subject: [PATCH 05/15] - Add a new CONNECT global variable allowing to tell whether or not a temporary file should be used for UPDATE/DELETE of file tables. Also use the "sorted" argument of index_init to help decide if sorting of positions must be done. modified: storage/connect/checklvl.h storage/connect/connect.cc storage/connect/connect.h storage/connect/filamdbf.cpp storage/connect/filamfix.cpp storage/connect/filamfix.h storage/connect/filamtxt.cpp storage/connect/ha_connect.cc storage/connect/mysql-test/connect/r/part_table.result storage/connect/plgdbsem.h storage/connect/plgdbutl.cpp storage/connect/reldef.cpp storage/connect/tabdos.cpp storage/connect/tabdos.h storage/connect/tabfix.cpp storage/connect/tabfmt.cpp storage/connect/tabvct.cpp storage/connect/tabvct.h storage/connect/xindex.cpp - Fix a bug in TDBASE::ColDB that caused some special columns not to be found in the column list and reallocated without their Value causing a crash of some queries. modified: storage/connect/table.cpp - Fix a bug causing RestoreNrec to be called before closing a table causing a wrong value given to Spos modified: storage/connect/tabdos.cpp storage/connect/xindex.cpp - Add a new CONNECT global variable connect_exact_info. Set to ON, it tells CONNECT to return exact record numbers on info queries. If OFF it just gives an estimate. In version 10.0.13 this was unconditionally ON and caused info queries on remote tables to be extremely long and was the subject of MDEV-6612. modified: storage/connect/ha_connect.cc storage/connect/tabdos.cpp storage/connect/tabmysql.cpp storage/connect/tabodbc.cpp --- storage/connect/checklvl.h | 7 +- storage/connect/connect.cc | 34 +- storage/connect/connect.h | 8 +- storage/connect/filamdbf.cpp | 2 +- storage/connect/filamfix.cpp | 310 +++++++++--------- storage/connect/filamfix.h | 2 + storage/connect/filamtxt.cpp | 24 +- storage/connect/ha_connect.cc | 90 ++++- .../mysql-test/connect/r/part_file.result | 2 + .../mysql-test/connect/r/part_table.result | 3 + .../mysql-test/connect/t/part_file.test | 4 + .../mysql-test/connect/t/part_table.test | 7 + storage/connect/plgdbsem.h | 2 +- storage/connect/plgdbutl.cpp | 2 +- storage/connect/reldef.cpp | 4 +- storage/connect/tabdos.cpp | 36 +- storage/connect/tabdos.h | 2 +- storage/connect/tabfix.cpp | 29 +- storage/connect/tabfmt.cpp | 43 ++- storage/connect/table.cpp | 7 +- storage/connect/tabmysql.cpp | 3 +- storage/connect/tabodbc.cpp | 7 +- storage/connect/tabvct.cpp | 14 +- storage/connect/tabvct.h | 1 + storage/connect/xindex.cpp | 3 - 25 files changed, 396 insertions(+), 250 deletions(-) diff --git a/storage/connect/checklvl.h b/storage/connect/checklvl.h index 5505534678d..d1e37afbc93 100644 --- a/storage/connect/checklvl.h +++ b/storage/connect/checklvl.h @@ -34,9 +34,10 @@ enum XMOD {XMOD_EXECUTE = 0, /* DOS execution mode */ /***********************************************************************/ /* Following definitions indicate the use of a temporay file. */ /***********************************************************************/ -enum USETEMP {TMP_AUTO = 0, /* Best choice */ - TMP_NO = 1, /* Never */ +enum USETEMP {TMP_NO = 0, /* Never */ + TMP_AUTO = 1, /* Best choice */ TMP_YES = 2, /* Always */ - TMP_FORCE = 3}; /* Forced for MAP tables */ + TMP_FORCE = 3, /* Forced for MAP tables */ + TMP_TEST = 4}; /* Testing value */ #endif // _CHKLVL_DEFINED_ diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc index a458c0e0c5a..c835d8c8233 100644 --- a/storage/connect/connect.cc +++ b/storage/connect/connect.cc @@ -142,7 +142,7 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname) return true; ((MYCAT *)dbuserp->Catalog)->SetDataPath(g, pathname); - dbuserp->UseTemp= TMP_AUTO; +//dbuserp->UseTemp= TMP_AUTO; /*********************************************************************/ /* All is correct. */ @@ -503,8 +503,6 @@ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp) if (!colp->GetColUse(U_VIRTUAL)) colp->WriteColumn(g); -//if (tp->GetMode() == MODE_UPDATE && tp->IsUsingTemp(g) && -// tp->GetKindex() && !tp->GetKindex()->IsSorted()) if (tp->IsIndexed()) // Index values must be sorted before updating rc= (RCODE)((PTDBDOS)tp)->GetTxfp()->StoreValues(g, true); @@ -580,21 +578,6 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort) printf("CntCloseTable: tdbp=%p mode=%d nox=%d abort=%d\n", tdbp, tdbp->GetMode(), nox, abort); -#if 0 - if (tbxp->GetMode() == MODE_UPDATE && - tbxp->GetKindex() && !tbxp->GetKindex()->IsSorted()) { - rc= tbxp->Txfp->UpdateSortedRows(g); - } else - if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN) { - if (tbxp->GetKindex() && !tbxp->GetKindex()->IsSorted()) - rc= tbxp->Txfp->DeleteSortedRows(g); - - if (!rc) - rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine - - } // endif Mode -#endif // 0 - if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN) { if (tbxp->IsIndexed()) rc= ((PTDBDOS)tdbp)->GetTxfp()->DeleteSortedRows(g); @@ -605,6 +588,15 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort) } else if (tbxp->GetMode() == MODE_UPDATE && tbxp->IsIndexed()) rc= ((PTDBDOX)tdbp)->Txfp->UpdateSortedRows(g); + switch(rc) { + case RC_FX: + abort= true; + break; + case RC_INFO: + PushWarning(g, tbxp); + break; + } // endswitch rc + // Prepare error return if (g->jump_level == MAX_JUMP) { strcpy(g->Message, MSG(TOO_MANY_JUMPS)); @@ -655,7 +647,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort) /* This is the condition(s) for doing indexing. */ /* Note: FIX table are not reset here to Nrec= 1. */ /***********************************************************************/ -int CntIndexInit(PGLOBAL g, PTDB ptdb, int id) +int CntIndexInit(PGLOBAL g, PTDB ptdb, int id, bool sorted) { PIXDEF xdp; PTDBDOX tdbp; @@ -707,7 +699,7 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id) #endif // 0 // Static indexes must be initialized now for records_in_range - if (tdbp->InitialyzeIndex(g, xdp)) + if (tdbp->InitialyzeIndex(g, xdp, sorted)) return 0; return (tdbp->To_Kindex->IsMul()) ? 2 : 1; @@ -754,7 +746,7 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op, #if 0 } // endif !To_Xdp // Now it's time to make the dynamic index - if (tdbp->InitialyzeIndex(g, NULL)) { + if (tdbp->InitialyzeIndex(g, NULL, false)) { sprintf(g->Message, "Fail to make dynamic index %s", tdbp->To_Xdp->GetName()); return RC_FX; diff --git a/storage/connect/connect.h b/storage/connect/connect.h index 145991a3b74..fd8b7e9442f 100644 --- a/storage/connect/connect.h +++ b/storage/connect/connect.h @@ -34,7 +34,7 @@ PTDB CntGetTDB(PGLOBAL g, const char *name, MODE xmod, PHC); bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE, char *, char *, bool, PHC); bool CntRewindTable(PGLOBAL g, PTDB tdbp); int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort); -int CntIndexInit(PGLOBAL g, PTDB tdbp, int id); +int CntIndexInit(PGLOBAL g, PTDB tdbp, int id, bool sorted); RCODE CntReadNext(PGLOBAL g, PTDB tdbp); RCODE CntIndexRead(PGLOBAL g, PTDB, OPVAL op, const void *k, int n, bool mrr); RCODE CntWriteRow(PGLOBAL g, PTDB tdbp); @@ -50,7 +50,7 @@ PGLOBAL CntExit(PGLOBAL g); /* These classes purpose is chiefly to access protected items! */ /***********************************************************************/ class DOXDEF: public DOSDEF { - friend int CntIndexInit(PGLOBAL, PTDB, int); + friend int CntIndexInit(PGLOBAL, PTDB, int, bool); }; // end of class DOXDEF /***********************************************************************/ @@ -59,7 +59,7 @@ class DOXDEF: public DOSDEF { class TDBDOX: public TDBDOS { friend int MakeIndex(PGLOBAL, PTDB, PIXDEF); friend int CntCloseTable(PGLOBAL, PTDB, bool, bool); - friend int CntIndexInit(PGLOBAL, PTDB, int); + friend int CntIndexInit(PGLOBAL, PTDB, int, bool); friend RCODE CntIndexRead(PGLOBAL, PTDB, OPVAL, const void*, int, bool); friend RCODE CntDeleteRow(PGLOBAL, PTDB, bool); friend int CntIndexRange(PGLOBAL, PTDB, const uchar**, uint*, @@ -70,7 +70,7 @@ class TDBDOX: public TDBDOS { class XKPDEF: public KPARTDEF { friend class TDBDOX; friend class ha_connect; - friend int CntIndexInit(PGLOBAL, PTDB, int); + friend int CntIndexInit(PGLOBAL, PTDB, int, bool); public: XKPDEF(const char *name, int n) : KPARTDEF((PSZ)name, n) {} }; // end of class XKPDEF diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp index 50a97739002..e2c3a27d98f 100644 --- a/storage/connect/filamdbf.cpp +++ b/storage/connect/filamdbf.cpp @@ -835,7 +835,7 @@ void DBFFAM::CloseTableFile(PGLOBAL g, bool abort) if (Modif && !Closing) { // Last updated block remains to be written Closing = true; - wrc = ReadBuffer(g); + wrc = WriteModifiedBlock(g); } // endif Modif if (UseTemp && T_Stream && wrc == RC_OK) { diff --git a/storage/connect/filamfix.cpp b/storage/connect/filamfix.cpp index 1c9451bb982..da05e7b824f 100644 --- a/storage/connect/filamfix.cpp +++ b/storage/connect/filamfix.cpp @@ -171,6 +171,45 @@ void FIXFAM::ResetBuffer(PGLOBAL g) } // end of ResetBuffer +/***********************************************************************/ +/* WriteModifiedBlock: Used when updating. */ +/***********************************************************************/ +int FIXFAM::WriteModifiedBlock(PGLOBAL g) + { + /*********************************************************************/ + /* The old block was modified in Update mode. */ + /* In Update mode we simply rewrite the old block on itself. */ + /*********************************************************************/ + int rc = RC_OK; + bool moved = false; + + // Using temp copy any intermediate lines. + if (UseTemp && MoveIntermediateLines(g, &moved)) + rc = RC_FX; + + // Fpos is last position, Headlen is DBF file header length + else if (!moved && fseek(Stream, Headlen + Fpos * Lrecl, SEEK_SET)) { + sprintf(g->Message, MSG(FSETPOS_ERROR), 0); + rc = RC_FX; + } else if (fwrite(To_Buf, Lrecl, Rbuf, T_Stream) != (size_t)Rbuf) { + sprintf(g->Message, MSG(FWRITE_ERROR), strerror(errno)); + rc = RC_FX; + } else + Spos = Fpos + Nrec; // + Rbuf ??? + + if (Closing || rc != RC_OK) { // Error or called from CloseDB + Closing = true; // To tell CloseDB about error + return rc; + } // endif Closing + + // NOTE: Next line was added to avoid a very strange fread bug. + // When the fseek is not executed (even the file has the good + // pointer position) the next read can happen anywhere in the file. + OldBlk = CurBlk; // This will force fseek to be executed + Modif = 0; + return rc; + } // end of WriteModifiedBlock + /***********************************************************************/ /* ReadBuffer: Read one line for a FIX file. */ /***********************************************************************/ @@ -178,84 +217,48 @@ int FIXFAM::ReadBuffer(PGLOBAL g) { int n, rc = RC_OK; - if (!Closing) { + /*********************************************************************/ + /* Sequential reading when Placed is not true. */ + /*********************************************************************/ + if (Placed) { + Tdbp->SetLine(To_Buf + CurNum * Lrecl); + Placed = false; + } else if (++CurNum < Rbuf) { + Tdbp->IncLine(Lrecl); // Used by DOSCOL functions + return RC_OK; + } else if (Rbuf < Nrec && CurBlk != -1) { + return RC_EF; + } else { /*******************************************************************/ - /* Sequential reading when Placed is not true. */ + /* New block. */ /*******************************************************************/ - if (Placed) { - Tdbp->SetLine(To_Buf + CurNum * Lrecl); - Placed = false; - } else if (++CurNum < Rbuf) { - Tdbp->IncLine(Lrecl); // Used by DOSCOL functions - return RC_OK; - } else if (Rbuf < Nrec && CurBlk != -1) { + CurNum = 0; + Tdbp->SetLine(To_Buf); + + next: + if (++CurBlk >= Block) return RC_EF; - } else { - /*****************************************************************/ - /* New block. */ - /*****************************************************************/ - CurNum = 0; - Tdbp->SetLine(To_Buf); - next: - if (++CurBlk >= Block) + /*******************************************************************/ + /* Before reading a new block, check whether block indexing */ + /* can be done, as well as for join as for local filtering. */ + /*******************************************************************/ + switch (Tdbp->TestBlock(g)) { + case RC_EF: return RC_EF; + case RC_NF: + goto next; + } // endswitch rc + } // endif's - /*****************************************************************/ - /* Before reading a new block, check whether block indexing */ - /* can be done, as well as for join as for local filtering. */ - /*****************************************************************/ - switch (Tdbp->TestBlock(g)) { - case RC_EF: - return RC_EF; - case RC_NF: - goto next; - } // endswitch rc - } // endif's + if (OldBlk == CurBlk) { + IsRead = true; // Was read indeed + return RC_OK; // Block is already there + } // endif OldBlk - if (OldBlk == CurBlk) { - IsRead = true; // Was read indeed - return RC_OK; // Block is already there - } // endif OldBlk - - } // endif !Closing - - if (Modif) { - /*******************************************************************/ - /* The old block was modified in Update mode. */ - /* In Update mode we simply rewrite the old block on itself. */ - /*******************************************************************/ - bool moved = false; - - if (UseTemp) // Copy any intermediate lines. - if (MoveIntermediateLines(g, &moved)) - rc = RC_FX; - - if (rc == RC_OK) { - // Fpos is last position, Headlen is DBF file header length - if (!moved && fseek(Stream, Headlen + Fpos * Lrecl, SEEK_SET)) { - sprintf(g->Message, MSG(FSETPOS_ERROR), 0); - rc = RC_FX; - } else if (fwrite(To_Buf, Lrecl, Rbuf, T_Stream) != (size_t)Rbuf) { - sprintf(g->Message, MSG(FWRITE_ERROR), strerror(errno)); - rc = RC_FX; - } // endif fwrite - - Spos = Fpos + Nrec; // + Rbuf ??? - } // endif rc - - if (Closing || rc != RC_OK) { // Error or called from CloseDB - Closing = true; // To tell CloseDB about error - return rc; - } // endif Closing - - // NOTE: Next line was added to avoid a very strange fread bug. - // When the fseek is not executed (even the file has the good - // pointer position) the next read can happen anywhere in the file. - OldBlk = CurBlk; // This will force fseek to be executed - Modif = 0; -// Spos = Fpos + Nrec; done above - } // endif Mode + // Write modified block in mode UPDATE + if (Modif && (rc = WriteModifiedBlock(g)) != RC_OK) + return rc; // This could be done only for new block. However note that FPOS // is used as block position when updating and as line position @@ -273,8 +276,6 @@ int FIXFAM::ReadBuffer(PGLOBAL g) if (trace > 1) htrc("File position is now %d\n", ftell(Stream)); -//long tell = ftell(Stream); not used - if (Padded) n = fread(To_Buf, (size_t)Blksize, 1, Stream); else @@ -355,7 +356,11 @@ int FIXFAM::WriteBuffer(PGLOBAL g) } // endif T_Stream - Modif++; // Modified line in Update mode + if (Nrec > 1) + Modif++; // Modified line in blocked mode + else if (WriteModifiedBlock(g)) // Indexed update + return RC_FX; + } // endif Mode return RC_OK; @@ -566,13 +571,12 @@ void FIXFAM::CloseTableFile(PGLOBAL g, bool abort) if (mode == MODE_INSERT && CurNum && !Closing) { // Some more inserted lines remain to be written Rbuf = CurNum--; -// Closing = true; wrc = WriteBuffer(g); } else if (mode == MODE_UPDATE) { if (Modif && !Closing) { // Last updated block remains to be written - Closing = true; - wrc = ReadBuffer(g); + Closing = true; // ??? + wrc = WriteModifiedBlock(g); } // endif Modif if (UseTemp && T_Stream && wrc == RC_OK) { @@ -1028,6 +1032,43 @@ int BGXFAM::Cardinality(PGLOBAL g) } // end of Cardinality +/***********************************************************************/ +/* WriteModifiedBlock: Used when updating. */ +/***********************************************************************/ +int BGXFAM::WriteModifiedBlock(PGLOBAL g) + { + /*********************************************************************/ + /* The old block was modified in Update mode. */ + /* In Update mode we simply rewrite the old block on itself. */ + /*********************************************************************/ + int rc = RC_OK; + bool moved = false; + + if (UseTemp) // Copy any intermediate lines. + if (MoveIntermediateLines(g, &moved)) + rc = RC_FX; + + if (rc == RC_OK) { + // Set file position to OldBlk position (Fpos) + if (!moved && BigSeek(g, Hfile, (BIGINT)Fpos * (BIGINT)Lrecl)) + rc = RC_FX; + else if (BigWrite(g, Tfile, To_Buf, Lrecl * Rbuf)) + rc = RC_FX; + + Spos = Fpos + Nrec; // + Rbuf ??? + } // endif rc + + if (Closing || rc != RC_OK) // Error or called from CloseDB + return rc; + + // NOTE: Next line was added to avoid a very strange fread bug. + // When the fseek is not executed (even the file has the good + // pointer position) the next read can happen anywhere in the file. + OldBlk = CurBlk; // This will force fseek to be executed + Modif = 0; + return rc; + } // end of WriteModifiedBlock + /***********************************************************************/ /* ReadBuffer: Read Nrec lines for a big fixed/binary file. */ /***********************************************************************/ @@ -1035,79 +1076,49 @@ int BGXFAM::ReadBuffer(PGLOBAL g) { int nbr, rc = RC_OK; - if (!Closing) { + /*********************************************************************/ + /* Sequential reading when Placed is not true. */ + /*********************************************************************/ + if (Placed) { + Tdbp->SetLine(To_Buf + CurNum * Lrecl); + Placed = false; + } else if (++CurNum < Rbuf) { + Tdbp->IncLine(Lrecl); // Used by DOSCOL functions + return RC_OK; + } else if (Rbuf < Nrec && CurBlk != -1) { + return RC_EF; + } else { /*******************************************************************/ - /* Sequential reading when Placed is not true. */ + /* New block. */ /*******************************************************************/ - if (Placed) { - Tdbp->SetLine(To_Buf + CurNum * Lrecl); - Placed = false; - } else if (++CurNum < Rbuf) { - Tdbp->IncLine(Lrecl); // Used by DOSCOL functions - return RC_OK; - } else if (Rbuf < Nrec && CurBlk != -1) { + CurNum = 0; + Tdbp->SetLine(To_Buf); + + next: + if (++CurBlk >= Block) return RC_EF; - } else { - /*****************************************************************/ - /* New block. */ - /*****************************************************************/ - CurNum = 0; - Tdbp->SetLine(To_Buf); - next: - if (++CurBlk >= Block) + /*******************************************************************/ + /* Before reading a new block, check whether block optimization */ + /* can be done, as well as for join as for local filtering. */ + /*******************************************************************/ + switch (Tdbp->TestBlock(g)) { + case RC_EF: return RC_EF; + case RC_NF: + goto next; + } // endswitch rc - /*****************************************************************/ - /* Before reading a new block, check whether block optimization */ - /* can be done, as well as for join as for local filtering. */ - /*****************************************************************/ - switch (Tdbp->TestBlock(g)) { - case RC_EF: - return RC_EF; - case RC_NF: - goto next; - } // endswitch rc + } // endif's - } // endif's + if (OldBlk == CurBlk) { + IsRead = true; // Was read indeed + return RC_OK; // Block is already there + } // endif OldBlk - if (OldBlk == CurBlk) { - IsRead = true; // Was read indeed - return RC_OK; // Block is already there - } // endif OldBlk - - } // endif !Closing - - if (Modif) { - /*******************************************************************/ - /* The old block was modified in Update mode. */ - /* In Update mode we simply rewrite the old block on itself. */ - /*******************************************************************/ - bool moved = false; - - if (UseTemp) // Copy any intermediate lines. - if (MoveIntermediateLines(g, &moved)) - rc = RC_FX; - - if (rc == RC_OK) { - // Set file position to OldBlk position (Fpos) - if (!moved && BigSeek(g, Hfile, (BIGINT)Fpos * (BIGINT)Lrecl)) - rc = RC_FX; - else if (BigWrite(g, Tfile, To_Buf, Lrecl * Rbuf)) - rc = RC_FX; - - Spos = Fpos + Nrec; // + Rbuf ??? - } // endif rc - - if (Closing || rc != RC_OK) // Error or called from CloseDB - return rc; - - // NOTE: Next line was added to avoid a very strange fread bug. - // When the fseek is not executed (even the file has the good - // pointer position) the next read can happen anywhere in the file. - OldBlk = CurBlk; // This will force fseek to be executed - Modif = 0; - } // endif Mode + // Write modified block in mode UPDATE + if (Modif && (rc = WriteModifiedBlock(g)) != RC_OK) + return rc; Fpos = CurBlk * Nrec; @@ -1169,16 +1180,21 @@ int BGXFAM::WriteBuffer(PGLOBAL g) } else { // Mode == MODE_UPDATE // Tfile is the temporary file or the table file handle itself - if (Tfile == INVALID_HANDLE_VALUE) - { + if (Tfile == INVALID_HANDLE_VALUE) { if (UseTemp /*&& Tdbp->GetMode() == MODE_UPDATE*/) { if (OpenTempFile(g)) return RC_FX; } else Tfile = Hfile; - } - Modif++; // Modified line in Update mode + + } // endif Tfile + + if (Nrec > 1) + Modif++; // Modified line in blocked mode + else if (WriteModifiedBlock(g)) // Indexed update + return RC_FX; + } // endif Mode return RC_OK; @@ -1417,7 +1433,7 @@ void BGXFAM::CloseTableFile(PGLOBAL g, bool abort) if (Modif && !Closing) { // Last updated block remains to be written Closing = true; - wrc = ReadBuffer(g); + wrc = WriteModifiedBlock(g); } // endif Modif if (UseTemp && Tfile && wrc == RC_OK) { diff --git a/storage/connect/filamfix.h b/storage/connect/filamfix.h index 694e653898a..a99a36af232 100644 --- a/storage/connect/filamfix.h +++ b/storage/connect/filamfix.h @@ -37,6 +37,7 @@ class DllExport FIXFAM : public BLKFAM { virtual int GetNextPos(void) {return Fpos + 1;} virtual bool AllocateBuffer(PGLOBAL g); virtual void ResetBuffer(PGLOBAL g); + virtual int WriteModifiedBlock(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g); virtual int DeleteRecords(PGLOBAL g, int irc); @@ -69,6 +70,7 @@ class BGXFAM : public FIXFAM { // Methods virtual int Cardinality(PGLOBAL g); virtual bool OpenTableFile(PGLOBAL g); + virtual int WriteModifiedBlock(PGLOBAL g); virtual int ReadBuffer(PGLOBAL g); virtual int WriteBuffer(PGLOBAL g); virtual int DeleteRecords(PGLOBAL g, int irc); diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp index 3e4c5adc319..8f04cb358d0 100644 --- a/storage/connect/filamtxt.cpp +++ b/storage/connect/filamtxt.cpp @@ -337,14 +337,14 @@ int TXTFAM::StoreValues(PGLOBAL g, bool upd) /***********************************************************************/ int TXTFAM::UpdateSortedRows(PGLOBAL g) { - int *ix, i, rc = RC_OK; + int *ix, i; /*********************************************************************/ /* Get the stored update values and sort them. */ /*********************************************************************/ if (!(Posar = MakeValueArray(g, To_Pos))) { strcpy(g->Message, "Position array is null"); - goto err; + return RC_INFO; } else if (!(Sosar = MakeValueArray(g, To_Sos))) { strcpy(g->Message, "Start position array is null"); goto err; @@ -364,16 +364,18 @@ int TXTFAM::UpdateSortedRows(PGLOBAL g) strcpy(Tdbp->To_Line, Updar->GetStringValue(ix[i])); // Now write the updated line. - if ((rc = WriteBuffer(g))) + if (WriteBuffer(g)) goto err; } // endfor i + return RC_OK; + err: - if (trace && rc) + if (trace) htrc("%s\n", g->Message); - return rc; + return RC_FX; } // end of UpdateSortedRows /***********************************************************************/ @@ -386,14 +388,14 @@ err: /***********************************************************************/ int TXTFAM::DeleteSortedRows(PGLOBAL g) { - int *ix, i, irc, rc = RC_OK; + int *ix, i, irc; /*********************************************************************/ /* Get the stored delete values and sort them. */ /*********************************************************************/ if (!(Posar = MakeValueArray(g, To_Pos))) { strcpy(g->Message, "Position array is null"); - goto err; + return RC_INFO; } else if (!(Sosar = MakeValueArray(g, To_Sos))) { strcpy(g->Message, "Start position array is null"); goto err; @@ -410,16 +412,18 @@ int TXTFAM::DeleteSortedRows(PGLOBAL g) goto err; // Now delete the sorted rows - if ((rc = DeleteRecords(g, irc))) + if (DeleteRecords(g, irc)) goto err; } // endfor i + return RC_OK; + err: - if (trace && rc) + if (trace) htrc("%s\n", g->Message); - return rc; + return RC_FX; } // end of DeleteSortedRows /***********************************************************************/ diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 639d0020d67..b59b16db2c6 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -170,8 +170,8 @@ #define SZWMIN 4194304 // Minimum work area size 4M extern "C" { - char version[]= "Version 1.03.0002 July 17, 2014"; - char compver[]= "Version 1.03.0002 " __DATE__ " " __TIME__; + char version[]= "Version 1.03.0003 August 22, 2014"; + char compver[]= "Version 1.03.0003 " __DATE__ " " __TIME__; #if defined(WIN32) char slash= '\\'; @@ -185,11 +185,13 @@ extern "C" { int trace= 0; // The general trace value int xconv= 0; // The type conversion option int zconv= SZCONV; // The text conversion size + USETEMP Use_Temp= TMP_AUTO; // The temporary file use } // extern "C" #if defined(XMAP) bool xmap= false; #endif // XMAP + bool xinfo= false; uint worksize= SZWORK; ulong ha_connect::num= 0; @@ -200,9 +202,11 @@ static int xtrace= 0; static int conv_size= SZCONV; static uint work_size= SZWORK; static ulong type_conv= 0; +static ulong use_tempfile= 1; #if defined(XMAP) static my_bool indx_map= 0; #endif // XMAP +static my_bool exact_info= 0; /***********************************************************************/ /* Utility functions. */ @@ -224,11 +228,14 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, TABLE_SHARE *table_s, HA_CREATE_INFO *info); +/***********************************************************************/ +/* Global variables update functions. */ +/***********************************************************************/ static void update_connect_xtrace(MYSQL_THD thd, struct st_mysql_sys_var *var, void *var_ptr, const void *save) { - xtrace= *(int *)var_ptr= *(int *)save; + trace= *(int *)var_ptr= *(int *)save; } // end of update_connect_xtrace static void update_connect_zconv(MYSQL_THD thd, @@ -252,6 +259,13 @@ static void update_connect_worksize(MYSQL_THD thd, worksize= (uint)(*(ulong *)var_ptr= *(ulong *)save); } // end of update_connect_worksize +static void update_connect_usetemp(MYSQL_THD thd, + struct st_mysql_sys_var *var, + void *var_ptr, const void *save) +{ + Use_Temp= (USETEMP)(*(ulong *)var_ptr= *(ulong *)save); +} // end of update_connect_usetemp + #if defined(XMAP) static void update_connect_xmap(MYSQL_THD thd, struct st_mysql_sys_var *var, @@ -261,6 +275,13 @@ static void update_connect_xmap(MYSQL_THD thd, } // end of update_connect_xmap #endif // XMAP +static void update_connect_xinfo(MYSQL_THD thd, + struct st_mysql_sys_var *var, + void *var_ptr, const void *save) +{ + xinfo= (bool)(*(my_bool *)var_ptr= *(my_bool *)save); +} // end of update_connect_xinfo + /***********************************************************************/ /* The CONNECT handlerton object. */ /***********************************************************************/ @@ -555,7 +576,7 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg) stop= false; alter= false; mrr= false; - nox= false; + nox= true; abort= false; indexing= -1; locked= 0; @@ -1590,7 +1611,7 @@ int ha_connect::CloseTable(PGLOBAL g) sdvalout=NULL; valid_info= false; indexing= -1; - nox= false; + nox= true; abort= false; return rc; } // end of CloseTable @@ -2642,7 +2663,6 @@ int ha_connect::open(const char *name, int mode, uint test_if_locked) int ha_connect::optimize(THD* thd, HA_CHECK_OPT* check_opt) { int rc= 0; - bool dop= (check_opt != NULL); PGLOBAL& g= xp->g; PDBUSER dup= PlgGetUser(g); @@ -2652,9 +2672,10 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT* check_opt) dup->Check |= CHK_OPT; if (tdbp) { - bool b= (((PTDBASE)tdbp)->GetDef()->Indexable() == 1); + bool dop= IsTypeIndexable(GetRealType(NULL)); + bool dox= (((PTDBASE)tdbp)->GetDef()->Indexable() == 1); - if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, dop, b))) { + if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, dop, dox))) { if (rc == RC_INFO) { push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); rc= 0; @@ -2771,7 +2792,8 @@ int ha_connect::write_row(uchar *buf) DBUG_PRINT("write_row", ("%s", g->Message)); htrc("write_row: %s\n", g->Message); rc= HA_ERR_INTERNAL_ERROR; - } // endif RC + } else // Table is modified + nox= false; // Indexes to be remade DBUG_RETURN(rc); } // end of write_row @@ -2816,7 +2838,8 @@ int ha_connect::update_row(const uchar *old_data, uchar *new_data) DBUG_PRINT("update_row", ("%s", g->Message)); htrc("update_row CONNECT: %s\n", g->Message); rc= HA_ERR_INTERNAL_ERROR; - } // endif RC + } else + nox= false; // Table is modified DBUG_RETURN(rc); } // end of update_row @@ -2849,7 +2872,8 @@ int ha_connect::delete_row(const uchar *buf) if (CntDeleteRow(xp->g, tdbp, false)) { rc= HA_ERR_INTERNAL_ERROR; htrc("delete_row CONNECT: %s\n", xp->g->Message); - } // endif DeleteRow + } else + nox= false; // To remake indexes DBUG_RETURN(rc); } // end of delete_row @@ -2896,7 +2920,7 @@ int ha_connect::index_init(uint idx, bool sorted) DBUG_RETURN(0); } // endif locked - indexing= CntIndexInit(g, tdbp, (signed)idx); + indexing= CntIndexInit(g, tdbp, (signed)idx, sorted); if (indexing <= 0) { DBUG_PRINT("index_init", ("%s", g->Message)); @@ -3533,7 +3557,8 @@ int ha_connect::delete_all_rows() if (CntDeleteRow(g, tdbp, true)) { htrc("%s\n", g->Message); rc= HA_ERR_INTERNAL_ERROR; - } // endif + } else + nox= false; } // endif rc @@ -6194,6 +6219,9 @@ Item *ha_connect::idx_cond_push(uint keyno_arg, Item* idx_cond_arg) struct st_mysql_storage_engine connect_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; +/***********************************************************************/ +/* CONNECT global variables definitions. */ +/***********************************************************************/ // Tracing: 0 no, 1 yes, >1 more tracing static MYSQL_SYSVAR_INT(xtrace, xtrace, PLUGIN_VAR_RQCMDARG, "Console trace value.", @@ -6231,6 +6259,35 @@ static MYSQL_SYSVAR_ENUM( 0, // def (no) &xconv_typelib); // typelib +/** + Temporary file usage: + no: Not using temporary file + auto: Using temporary file when needed + yes: Allways using temporary file + force: Force using temporary file (no MAP) + test: Reserved +*/ +const char *usetemp_names[]= +{ + "NO", "AUTO", "YES", "FORCE", "TEST", NullS +}; + +TYPELIB usetemp_typelib= +{ + array_elements(usetemp_names) - 1, "usetemp_typelib", + usetemp_names, NULL +}; + +static MYSQL_SYSVAR_ENUM( + use_tempfile, // name + use_tempfile, // varname + PLUGIN_VAR_RQCMDARG, // opt + "Temporary file use.", // comment + NULL, // check + update_connect_usetemp, // update function + 1, // def (AUTO) + &usetemp_typelib); // typelib + #if defined(XMAP) // Using file mapping for indexes if true static MYSQL_SYSVAR_BOOL(indx_map, indx_map, PLUGIN_VAR_RQCMDARG, @@ -6243,6 +6300,11 @@ static MYSQL_SYSVAR_UINT(work_size, work_size, PLUGIN_VAR_RQCMDARG, "Size of the CONNECT work area.", NULL, update_connect_worksize, SZWORK, SZWMIN, UINT_MAX, 1); +// Getting exact info values +static MYSQL_SYSVAR_BOOL(exact_info, exact_info, PLUGIN_VAR_RQCMDARG, + "Getting exact info values", + NULL, update_connect_xinfo, 0); + static struct st_mysql_sys_var* connect_system_variables[]= { MYSQL_SYSVAR(xtrace), MYSQL_SYSVAR(conv_size), @@ -6251,6 +6313,8 @@ static struct st_mysql_sys_var* connect_system_variables[]= { MYSQL_SYSVAR(indx_map), #endif // XMAP MYSQL_SYSVAR(work_size), + MYSQL_SYSVAR(use_tempfile), + MYSQL_SYSVAR(exact_info), NULL }; diff --git a/storage/connect/mysql-test/connect/r/part_file.result b/storage/connect/mysql-test/connect/r/part_file.result index bd5c258a4e2..c679ed95062 100644 --- a/storage/connect/mysql-test/connect/r/part_file.result +++ b/storage/connect/mysql-test/connect/r/part_file.result @@ -1,3 +1,4 @@ +set @@global.connect_exact_info=ON; # This will be used to see what data files are created CREATE TABLE dr1 ( fname VARCHAR(256) NOT NULL FLAG=2, @@ -342,3 +343,4 @@ part2 .txt part3 .txt DROP TABLE t1; DROP TABLE dr1; +set @@global.connect_exact_info=OFF; diff --git a/storage/connect/mysql-test/connect/r/part_table.result b/storage/connect/mysql-test/connect/r/part_table.result index 09d46687f00..e447caca615 100644 --- a/storage/connect/mysql-test/connect/r/part_table.result +++ b/storage/connect/mysql-test/connect/r/part_table.result @@ -1,3 +1,4 @@ +set @@global.connect_exact_info=ON; CREATE TABLE xt1 ( id INT KEY NOT NULL, msg VARCHAR(32)) @@ -147,6 +148,7 @@ UPDATE t1 SET msg = 'number' WHERE id in (60,72); Warnings: Note 1105 xt3: 2 affected rows Note 1105 xt3: 0 affected rows +Warning 1105 xt3: (1105) Position array is null UPDATE t1 SET msg = 'soixante' WHERE id = 60; Warnings: Note 1105 xt3: 1 affected rows @@ -193,3 +195,4 @@ DROP TABLE t1; DROP TABLE xt1; DROP TABLE xt2; DROP TABLE xt3; +set @@global.connect_exact_info=OFF; diff --git a/storage/connect/mysql-test/connect/t/part_file.test b/storage/connect/mysql-test/connect/t/part_file.test index 159908b6d9b..6efd2b9b580 100644 --- a/storage/connect/mysql-test/connect/t/part_file.test +++ b/storage/connect/mysql-test/connect/t/part_file.test @@ -1,6 +1,8 @@ --source include/have_partition.inc let $MYSQLD_DATADIR= `select @@datadir`; +set @@global.connect_exact_info=ON; + --echo # This will be used to see what data files are created CREATE TABLE dr1 ( fname VARCHAR(256) NOT NULL FLAG=2, @@ -153,6 +155,8 @@ DROP TABLE dr1; # # Clean up # +set @@global.connect_exact_info=OFF; + --remove_file $MYSQLD_DATADIR/test/part1.txt --remove_file $MYSQLD_DATADIR/test/part2.txt --remove_file $MYSQLD_DATADIR/test/part3.txt diff --git a/storage/connect/mysql-test/connect/t/part_table.test b/storage/connect/mysql-test/connect/t/part_table.test index 34e224efa6f..c5358d63c8e 100644 --- a/storage/connect/mysql-test/connect/t/part_table.test +++ b/storage/connect/mysql-test/connect/t/part_table.test @@ -1,6 +1,8 @@ --source include/not_embedded.inc --source include/have_partition.inc +set @@global.connect_exact_info=ON; + # # These will be used by the t1 table partition table # @@ -83,3 +85,8 @@ DROP TABLE t1; DROP TABLE xt1; DROP TABLE xt2; DROP TABLE xt3; + +# +# Clean up +# +set @@global.connect_exact_info=OFF; diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h index 1e540dfb2fe..714a6a18ae5 100644 --- a/storage/connect/plgdbsem.h +++ b/storage/connect/plgdbsem.h @@ -423,7 +423,7 @@ typedef struct { /* User application block */ int Maxbmp; /* Maximum XDB2 bitmap size */ int Check; /* General level of checking */ int Numlines; /* Number of lines involved */ - USETEMP UseTemp; /* Use temporary file */ +//USETEMP UseTemp; /* Use temporary file */ int Vtdbno; /* Used for TDB number setting */ bool Remote; /* true: if remotely called */ bool Proginfo; /* true: return progress info */ diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp index 66f7332c56a..ba8e2fb9bb8 100644 --- a/storage/connect/plgdbutl.cpp +++ b/storage/connect/plgdbutl.cpp @@ -337,7 +337,7 @@ PDBUSER PlgMakeUser(PGLOBAL g) memset(dbuserp, 0, sizeof(DBUSERBLK)); dbuserp->Maxbmp = MAXBMP; - dbuserp->UseTemp = TMP_AUTO; +//dbuserp->UseTemp = TMP_AUTO; dbuserp->Check = CHK_ALL; strcpy(dbuserp->Server, "CONNECT"); return dbuserp; diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp index 58bcbd202f3..85295635fea 100644 --- a/storage/connect/reldef.cpp +++ b/storage/connect/reldef.cpp @@ -49,6 +49,8 @@ #include "tabmul.h" #include "ha_connect.h" +extern "C" int trace; +extern "C" USETEMP Use_Temp; /* --------------------------- Class RELDEF -------------------------- */ @@ -561,7 +563,7 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode) PTXF txfp = NULL; PDOSDEF defp = (PDOSDEF)Pxdef; bool map = defp->Mapped && mode != MODE_INSERT && - !(PlgGetUser(g)->UseTemp == TMP_FORCE && + !(Use_Temp == TMP_FORCE && (mode == MODE_UPDATE || mode == MODE_DELETE)); int cmpr = defp->Compressed; diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp index 861a9da106d..4a62b20cfbd 100644 --- a/storage/connect/tabdos.cpp +++ b/storage/connect/tabdos.cpp @@ -64,7 +64,10 @@ /* DB static variables. */ /***********************************************************************/ int num_read, num_there, num_eq[2]; // Statistics -extern "C" int trace; + +extern "C" int trace; +extern "C" USETEMP Use_Temp; +extern bool xinfo; /***********************************************************************/ /* Size of optimize file header. */ @@ -75,8 +78,8 @@ extern "C" int trace; /* Min and Max blocks contains zero ended fields (blank = false). */ /* No conversion of block values (check = true). */ /***********************************************************************/ -PVBLK AllocValBlock(PGLOBAL, void *, int, int, int len = 0, int prec = 0, - bool check = true, bool blank = false, bool un = false); +PVBLK AllocValBlock(PGLOBAL, void *, int, int, int len= 0, int prec= 0, + bool check= true, bool blank= false, bool un= false); /* --------------------------- Class DOSDEF -------------------------- */ @@ -313,7 +316,7 @@ bool DOSDEF::InvalidateIndex(PGLOBAL g) PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode) { // Mapping not used for insert - USETEMP tmp = PlgGetUser(g)->UseTemp; + USETEMP tmp = Use_Temp; bool map = Mapped && mode != MODE_INSERT && !(tmp != TMP_NO && Recfm == RECFM_VAR && mode == MODE_UPDATE) && @@ -545,8 +548,8 @@ int TDBDOS::ResetTableOpt(PGLOBAL g, bool dop, bool dox) if (dox && (rc == RC_OK || rc == RC_INFO)) { // Remake eventual indexes - if (Mode != MODE_UPDATE) - To_SetCols = NULL; // Only used on Update +// if (Mode != MODE_UPDATE) + To_SetCols = NULL; // Positions are changed Columns = NULL; // Not used anymore Txfp->Reset(); // New start @@ -1722,7 +1725,7 @@ err: /***********************************************************************/ /* Make a dynamic index. */ /***********************************************************************/ -bool TDBDOS::InitialyzeIndex(PGLOBAL g, PIXDEF xdp) +bool TDBDOS::InitialyzeIndex(PGLOBAL g, PIXDEF xdp, bool sorted) { int k, rc; bool brc, dynamic; @@ -1810,7 +1813,9 @@ bool TDBDOS::InitialyzeIndex(PGLOBAL g, PIXDEF xdp) To_BlkFil = NULL; } // endif AmType - if (!(To_Kindex= kxp)->IsSorted() && + To_Kindex= kxp; + + if (!(sorted && To_Kindex->IsSorted()) && ((Mode == MODE_UPDATE && IsUsingTemp(g)) || (Mode == MODE_DELETE && Txfp->GetAmType() != TYPE_AM_DBF))) Indxd = true; @@ -1891,7 +1896,7 @@ int TDBDOS::Cardinality(PGLOBAL g) } // endif Mode - if (Mode == MODE_ANY) { + if (Mode == MODE_ANY && xinfo) { // Using index impossible or failed, do it the hard way Mode = MODE_READ; To_Line = (char*)PlugSubAlloc(g, NULL, Lrecl + 1); @@ -2004,10 +2009,8 @@ int TDBDOS::EstimatedLength(PGLOBAL g) /***********************************************************************/ bool TDBDOS::IsUsingTemp(PGLOBAL g) { - USETEMP usetemp = PlgGetUser(g)->UseTemp; - - return (usetemp == TMP_YES || usetemp == TMP_FORCE || - (usetemp == TMP_AUTO && Mode == MODE_UPDATE)); + return (Use_Temp == TMP_YES || Use_Temp == TMP_FORCE || + (Use_Temp == TMP_AUTO && Mode == MODE_UPDATE)); } // end of IsUsingTemp /***********************************************************************/ @@ -2047,7 +2050,7 @@ bool TDBDOS::OpenDB(PGLOBAL g) Txfp = new(g) DOSFAM((PDOSDEF)To_Def); Txfp->SetTdbp(this); } else if (Txfp->Blocked && (Mode == MODE_DELETE || - (Mode == MODE_UPDATE && PlgGetUser(g)->UseTemp != TMP_NO))) { + (Mode == MODE_UPDATE && Use_Temp != TMP_NO))) { /*******************************************************************/ /* Delete is not currently handled in block mode neither Update */ /* when using a temporary file. */ @@ -2219,6 +2222,7 @@ void TDBDOS::CloseDB(PGLOBAL g) } // endif Txfp->CloseTableFile(g, Abort); + RestoreNrec(); } // end of CloseDB // ------------------------ DOSCOL functions ---------------------------- @@ -2247,8 +2251,8 @@ DOSCOL::DOSCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am) Deplac = cdp->GetOffset(); Long = cdp->GetLong(); To_Val = NULL; - Clustered = 0; - Sorted = 0; + Clustered = cdp->GetOpt(); + Sorted = (cdp->GetOpt() == 2) ? 1 : 0; Ndv = 0; // Currently used only for XDB2 Nbm = 0; // Currently used only for XDB2 Min = NULL; diff --git a/storage/connect/tabdos.h b/storage/connect/tabdos.h index e49f3188795..1c772e8bf23 100644 --- a/storage/connect/tabdos.h +++ b/storage/connect/tabdos.h @@ -172,7 +172,7 @@ class DllExport TDBDOS : public TDBASE { // Optimization routines virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add); - bool InitialyzeIndex(PGLOBAL g, PIXDEF xdp); + bool InitialyzeIndex(PGLOBAL g, PIXDEF xdp, bool sorted); void ResetBlockFilter(PGLOBAL g); bool GetDistinctColumnValues(PGLOBAL g, int nrec); diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp index fe04fe52627..91f06536272 100644 --- a/storage/connect/tabfix.cpp +++ b/storage/connect/tabfix.cpp @@ -51,7 +51,9 @@ /***********************************************************************/ /* DB static variables. */ /***********************************************************************/ -extern "C" int trace; +extern "C" int trace; +extern "C" USETEMP Use_Temp; + extern int num_read, num_there, num_eq[2]; // Statistics static const longlong M2G = 0x80000000; static const longlong M4G = (longlong)2 * M2G; @@ -135,6 +137,10 @@ int TDBFIX::ResetTableOpt(PGLOBAL g, bool dop, bool dox) MaxSize = -1; // Size must be recalculated Cardinal = -1; // as well as Cardinality + // After the table was modified the indexes + // are invalid and we should mark them as such... + rc = ((PDOSDEF)To_Def)->InvalidateIndex(g); + if (dop) { Columns = NULL; // Not used anymore Txfp->Reset(); @@ -153,12 +159,8 @@ int TDBFIX::ResetTableOpt(PGLOBAL g, bool dop, bool dox) Mode = MODE_READ; // New mode prc = rc; - if (!(PlgGetUser(g)->Check & CHK_OPT)) { - // After the table was modified the indexes - // are invalid and we should mark them as such... - rc = ((PDOSDEF)To_Def)->InvalidateIndex(g); - } else - // ... or we should remake them. + if (PlgGetUser(g)->Check & CHK_OPT) + // We must remake indexes. rc = MakeIndex(g, NULL, FALSE); rc = (rc == RC_INFO) ? prc : rc; @@ -269,9 +271,11 @@ int TDBFIX::RowNumber(PGLOBAL g, bool b) /***********************************************************************/ bool TDBFIX::IsUsingTemp(PGLOBAL g) { - USETEMP usetemp = PlgGetUser(g)->UseTemp; - - return (usetemp == TMP_YES || usetemp == TMP_FORCE); + // Not ready yet to handle using a temporary file with mapping + // or while deleting from DBF files. + return ((Use_Temp == TMP_YES && Txfp->GetAmType() != TYPE_AM_MAP && + !(Mode == MODE_DELETE && Txfp->GetAmType() == TYPE_AM_DBF)) || + Use_Temp == TMP_FORCE || Use_Temp == TMP_TEST); } // end of IsUsingTemp /***********************************************************************/ @@ -302,8 +306,9 @@ bool TDBFIX::OpenDB(PGLOBAL g) return false; } // endif use - if (Mode == MODE_DELETE && !Next && Txfp->GetAmType() == TYPE_AM_MAP) { - // Delete all lines. Not handled in MAP mode + if (Mode == MODE_DELETE && Txfp->GetAmType() == TYPE_AM_MAP && + (!Next || Use_Temp == TMP_FORCE)) { + // Delete all lines or using temp. Not handled in MAP mode Txfp = new(g) FIXFAM((PDOSDEF)To_Def); Txfp->SetTdbp(this); } // endif Mode diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp index b2d60d87f3b..a011b62dc7c 100644 --- a/storage/connect/tabfmt.cpp +++ b/storage/connect/tabfmt.cpp @@ -66,7 +66,8 @@ #define MAXCOL 200 /* Default max column nb in result */ #define TYPE_UNKNOWN 10 /* Must be greater than other types */ -extern "C" int trace; +extern "C" int trace; +extern "C" USETEMP Use_Temp; /***********************************************************************/ /* CSVColumns: constructs the result blocks containing the description */ @@ -441,7 +442,7 @@ PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode) PTDBASE tdbp; if (Catfunc != FNC_COL) { - USETEMP tmp = PlgGetUser(g)->UseTemp; + USETEMP tmp = Use_Temp; bool map = Mapped && mode != MODE_INSERT && !(tmp != TMP_NO && mode == MODE_UPDATE) && !(tmp == TMP_FORCE && @@ -479,6 +480,36 @@ PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode) if (Multiple) tdbp = new(g) TDBMUL(tdbp); + else + /*****************************************************************/ + /* For block tables, get eventually saved optimization values. */ + /*****************************************************************/ + if (tdbp->GetBlockValues(g)) { + PushWarning(g, tdbp); +// return NULL; // causes a crash when deleting index + } else { + if (IsOptimized()) { + if (map) { + txfp = new(g) MBKFAM(this); + } else if (Compressed) { +#if defined(ZIP_SUPPORT) + if (Compressed == 1) + txfp = new(g) ZBKFAM(this); + else { + txfp->SetBlkPos(To_Pos); + ((PZLBFAM)txfp)->SetOptimized(To_Pos != NULL); + } // endelse +#else + sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP"); + return NULL; +#endif + } else + txfp = new(g) BLKFAM(this); + + ((PTDBDOS)tdbp)->SetTxfp(txfp); + } // endif Optimized + + } // endelse } else tdbp = new(g)TDBCCL(this); @@ -605,14 +636,12 @@ int TDBCSV::EstimatedLength(PGLOBAL g) #if 0 /***********************************************************************/ -/* CSV tables favor the use temporary files for Update. */ +/* CSV tables needs the use temporary files for Update. */ /***********************************************************************/ bool TDBCSV::IsUsingTemp(PGLOBAL g) { - USETEMP usetemp = PlgGetUser(g)->UseTemp; - - return (usetemp == TMP_YES || usetemp == TMP_FORCE || - (usetemp == TMP_AUTO && Mode == MODE_UPDATE)); + return (Use_Temp == TMP_YES || Use_Temp == TMP_FORCE || + (Use_Temp == TMP_AUTO && Mode == MODE_UPDATE)); } // end of IsUsingTemp #endif // 0 (Same as TDBDOS one) diff --git a/storage/connect/table.cpp b/storage/connect/table.cpp index 94c00ebb061..5db50d44787 100644 --- a/storage/connect/table.cpp +++ b/storage/connect/table.cpp @@ -216,10 +216,11 @@ PCOL TDBASE::ColDB(PGLOBAL g, PSZ name, int num) /* Also find where to insert the new block. */ /*****************************************************************/ for (cp = Columns; cp; cp = cp->GetNext()) - if (cp->GetIndex() < i) + if ((num && cp->GetIndex() == i) || + (name && !stricmp(cp->GetName(), name))) + break; // Found + else if (cp->GetIndex() < i) cprec = cp; - else if (cp->GetIndex() == i) - break; if (trace) htrc("cdp(%d).Name=%s cp=%p\n", i, cdp->GetName(), cp); diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp index d84f6c9aab4..e11fac3a6b2 100644 --- a/storage/connect/tabmysql.cpp +++ b/storage/connect/tabmysql.cpp @@ -68,6 +68,7 @@ void PrintResult(PGLOBAL, PSEM, PQRYRES); #endif // _CONSOLE extern "C" int trace; +extern bool xinfo; // Used to check whether a MYSQL table is created on itself bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host, @@ -754,7 +755,7 @@ int TDBMYSQL::Cardinality(PGLOBAL g) if (!g) return (Mode == MODE_ANY && !Srcdef) ? 1 : 0; - if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef) { + if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef && xinfo) { // Info command, we must return the exact table row number char query[96]; MYSQLC myc; diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp index 5542e832a54..023d7efa708 100644 --- a/storage/connect/tabodbc.cpp +++ b/storage/connect/tabodbc.cpp @@ -1,11 +1,11 @@ /************* Tabodbc C++ Program Source Code File (.CPP) *************/ /* PROGRAM NAME: TABODBC */ /* ------------- */ -/* Version 2.7 */ +/* Version 2.8 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2000-2013 */ +/* (C) Copyright to the author Olivier BERTRAND 2000-2014 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -76,6 +76,7 @@ #include "sql_string.h" extern "C" int trace; +extern bool xinfo; /***********************************************************************/ /* DB static variables. */ @@ -671,7 +672,7 @@ int TDBODBC::Cardinality(PGLOBAL g) if (!g) return (Mode == MODE_ANY && !Srcdef) ? 1 : 0; - if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef) { + if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef && xinfo) { // Info command, we must return the exact table row number char qry[96], tbn[64]; ODBConn *ocp = new(g) ODBConn(g, this); diff --git a/storage/connect/tabvct.cpp b/storage/connect/tabvct.cpp index 043d3c2c496..6d7059e2306 100644 --- a/storage/connect/tabvct.cpp +++ b/storage/connect/tabvct.cpp @@ -76,7 +76,8 @@ char *strerror(int num); #endif // UNIX -extern "C" int trace; +extern "C" int trace; +extern "C" USETEMP Use_Temp; /***********************************************************************/ /* Char VCT column blocks are right filled with blanks (blank = true) */ @@ -208,7 +209,7 @@ PTDB VCTDEF::GetTable(PGLOBAL g, MODE mode) // Mapping not used for insert (except for true VEC not split tables) // or when UseTemp is forced bool map = Mapped && (Estimate || mode != MODE_INSERT) && - !(PlgGetUser(g)->UseTemp == TMP_FORCE && + !(Use_Temp == TMP_FORCE && (mode == MODE_UPDATE || mode == MODE_DELETE)); PTXF txfp; PTDB tdbp; @@ -284,6 +285,15 @@ PCOL TDBVCT::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) return new(g) VCTCOL(g, cdp, this, cprec, n); } // end of MakeCol +/***********************************************************************/ +/* VEC tables are not ready yet to use temporary files. */ +/***********************************************************************/ +bool TDBVCT::IsUsingTemp(PGLOBAL g) + { + // For developpers + return (Use_Temp == TMP_TEST); + } // end of IsUsingTemp + /***********************************************************************/ /* VCT Access Method opening routine. */ /* New method now that this routine is called recursively (last table */ diff --git a/storage/connect/tabvct.h b/storage/connect/tabvct.h index 0a67a5e03b2..7e48051a4f9 100644 --- a/storage/connect/tabvct.h +++ b/storage/connect/tabvct.h @@ -69,6 +69,7 @@ class DllExport TDBVCT : public TDBFIX { // Methods virtual PTDB CopyOne(PTABS t); + virtual bool IsUsingTemp(PGLOBAL g); // Database routines virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp index 27770ef539a..6d1b2a13ea3 100755 --- a/storage/connect/xindex.cpp +++ b/storage/connect/xindex.cpp @@ -264,9 +264,6 @@ void XINDEX::Close(void) kcp->FreeData(); } // endfor kcp - if (Tdbp) - Tdbp->RestoreNrec(); - } // end of Close /***********************************************************************/ From 74a46726227b5f34dedb28ff6d7a4d81b157d764 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sat, 23 Aug 2014 19:17:15 +0200 Subject: [PATCH 06/15] - Move DataPath from the MYCAT catalog to the ha_connect handler. Indeed it belongs to each tables and the catalog being share between several instances of CONNECT, when a query implied several tables belonging to different databases, some where pointing on the wrong database. This fix bugs occuring in queries such as: INSERT into db1.t1 select * from db2.t2; Where the t1 data file was made in db2. modified: storage/connect/catalog.h storage/connect/connect.cc storage/connect/filamdbf.cpp storage/connect/filamdbf.h storage/connect/ha_connect.cc storage/connect/ha_connect.h storage/connect/mycat.cc storage/connect/mycat.h storage/connect/plgdbsem.h storage/connect/plgdbutl.cpp storage/connect/reldef.cpp storage/connect/reldef.h storage/connect/tabfix.h storage/connect/tabfmt.cpp storage/connect/tabfmt.h storage/connect/tabmul.cpp --- storage/connect/catalog.h | 10 ++++----- storage/connect/connect.cc | 7 +++++-- storage/connect/filamdbf.cpp | 4 ++-- storage/connect/filamdbf.h | 6 +++--- storage/connect/ha_connect.cc | 39 ++++++++++++++++++++++++++--------- storage/connect/ha_connect.h | 3 +++ storage/connect/mycat.cc | 8 ++++--- storage/connect/mycat.h | 6 +++--- storage/connect/plgdbsem.h | 3 ++- storage/connect/plgdbutl.cpp | 34 ++++++++++++++++++++++++++++++ storage/connect/reldef.cpp | 8 +++++++ storage/connect/reldef.h | 7 ++++--- storage/connect/tabfix.h | 3 ++- storage/connect/tabfmt.cpp | 9 ++++---- storage/connect/tabfmt.h | 4 ++-- storage/connect/tabmul.cpp | 2 +- 16 files changed, 113 insertions(+), 40 deletions(-) diff --git a/storage/connect/catalog.h b/storage/connect/catalog.h index 411660431b9..5baab294737 100644 --- a/storage/connect/catalog.h +++ b/storage/connect/catalog.h @@ -1,7 +1,7 @@ /*************** Catalog H Declares Source Code File (.H) **************/ -/* Name: CATALOG.H Version 3.2 */ +/* Name: CATALOG.H Version 3.3 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2000-2012 */ +/* (C) Copyright to the author Olivier BERTRAND 2000-2014 */ /* */ /* This file contains the CATALOG PlugDB classes definitions. */ /***********************************************************************/ @@ -68,11 +68,11 @@ class DllExport CATALOG { bool GetDefHuge(void) {return DefHuge;} void SetDefHuge(bool b) {DefHuge = b;} char *GetCbuf(void) {return Cbuf;} - char *GetDataPath(void) {return (char*)DataPath;} +//char *GetDataPath(void) {return (char*)DataPath;} // Methods virtual void Reset(void) {} - virtual void SetDataPath(PGLOBAL g, const char *path) {} +//virtual void SetDataPath(PGLOBAL g, const char *path) {} virtual bool CheckName(PGLOBAL g, char *name) {return true;} virtual bool ClearName(PGLOBAL g, PSZ name) {return true;} virtual PRELDEF MakeOneTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am) {return NULL;} @@ -106,7 +106,7 @@ class DllExport CATALOG { int Cblen; /* Length of suballoc. buffer */ CURTAB Ctb; /* Used to enumerate tables */ bool DefHuge; /* true: tables default to huge */ - LPCSTR DataPath; /* Is the Path of DB data dir */ +//LPCSTR DataPath; /* Is the Path of DB data dir */ }; // end of class CATALOG #endif // __CATALOG__H diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc index c835d8c8233..381e437f9ec 100644 --- a/storage/connect/connect.cc +++ b/storage/connect/connect.cc @@ -122,9 +122,12 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname) (dbuserp->Catalog) ? ((MYCAT*)dbuserp->Catalog)->GetHandler() : NULL, handler); + // Set the database path for this table + handler->SetDataPath(g, pathname); + if (dbuserp->Catalog) { // ((MYCAT *)dbuserp->Catalog)->SetHandler(handler); done later - ((MYCAT *)dbuserp->Catalog)->SetDataPath(g, pathname); +// ((MYCAT *)dbuserp->Catalog)->SetDataPath(g, pathname); return false; // Nothing else to do } // endif Catalog @@ -141,7 +144,7 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname) if (!(dbuserp->Catalog= new MYCAT(handler))) return true; - ((MYCAT *)dbuserp->Catalog)->SetDataPath(g, pathname); +//((MYCAT *)dbuserp->Catalog)->SetDataPath(g, pathname); //dbuserp->UseTemp= TMP_AUTO; /*********************************************************************/ diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp index e2c3a27d98f..ea1850b5c85 100644 --- a/storage/connect/filamdbf.cpp +++ b/storage/connect/filamdbf.cpp @@ -176,7 +176,7 @@ static int dbfhead(PGLOBAL g, FILE *file, PSZ fn, DBFHEADER *buf) /* DBFColumns: constructs the result blocks containing the description */ /* of all the columns of a DBF file that will be retrieved by #GetData. */ /****************************************************************************/ -PQRYRES DBFColumns(PGLOBAL g, const char *fn, BOOL info) +PQRYRES DBFColumns(PGLOBAL g, char *dp, const char *fn, BOOL info) { int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT, TYPE_SHORT}; @@ -205,7 +205,7 @@ PQRYRES DBFColumns(PGLOBAL g, const char *fn, BOOL info) /************************************************************************/ /* Open the input file. */ /************************************************************************/ - PlugSetPath(filename, fn, PlgGetDataPath(g)); + PlugSetPath(filename, fn, dp); if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb"))) return NULL; diff --git a/storage/connect/filamdbf.h b/storage/connect/filamdbf.h index 9be8bfd980d..49bf5f0db93 100644 --- a/storage/connect/filamdbf.h +++ b/storage/connect/filamdbf.h @@ -1,7 +1,7 @@ /***************** FilAmDbf H Declares Source Code File (.H) ****************/ -/* Name: filamdbf.h Version 1.3 */ +/* Name: filamdbf.h Version 1.4 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2005-2012 */ +/* (C) Copyright to the author Olivier BERTRAND 2005-2014 */ /* */ /* This file contains the DBF file access method classes declares. */ /****************************************************************************/ @@ -19,7 +19,7 @@ typedef class DBMFAM *PDBMFAM; /****************************************************************************/ /* Functions used externally. */ /****************************************************************************/ -PQRYRES DBFColumns(PGLOBAL g, const char *fn, BOOL info); +PQRYRES DBFColumns(PGLOBAL g, char *dp, const char *fn, BOOL info); /****************************************************************************/ /* This is the base class for dBASE file access methods. */ diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index b59b16db2c6..5fbd86b0ce1 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -563,6 +563,11 @@ ha_connect::ha_connect(handlerton *hton, TABLE_SHARE *table_arg) xp= (table) ? GetUser(ha_thd(), NULL) : NULL; if (xp) xp->SetHandler(this); +#if defined(WIN32) + datapath= ".\\"; +#else // !WIN32 + datapath= "./"; +#endif // !WIN32 tdbp= NULL; sdvalin= NULL; sdvalout= NULL; @@ -1402,6 +1407,14 @@ void ha_connect::AddColName(char *cp, Field *fp) } // end of AddColName #endif // 0 +/***********************************************************************/ +/* This function sets the current database path. */ +/***********************************************************************/ +void ha_connect::SetDataPath(PGLOBAL g, const char *path) +{ + datapath= SetPath(g, path); +} // end of SetDataPath + /****************************************************************************/ /* Get the table description block of a CONNECT table. */ /****************************************************************************/ @@ -3440,8 +3453,10 @@ int ha_connect::info(uint flag) } // endif xmod // This is necessary for getting file length - if (cat && table) - cat->SetDataPath(g, table->s->db.str); +// if (cat && table) +// cat->SetDataPath(g, table->s->db.str); + if (table) + SetDataPath(g, table->s->db.str); else DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen @@ -4764,7 +4779,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, const char *fncn= "?"; const char *user, *fn, *db, *host, *pwd, *sep, *tbl, *src; const char *col, *ocl, *rnk, *pic, *fcl, *skc; - char *tab, *dsn, *shm; + char *tab, *dsn, *shm, *dpath; #if defined(WIN32) char *nsp= NULL, *cls= NULL; #endif // WIN32 @@ -5009,10 +5024,12 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, char *cnm, *rem, *dft, *xtra; int i, len, prec, dec, typ, flg; - if (cat) - cat->SetDataPath(g, table_s->db.str); - else - return HA_ERR_INTERNAL_ERROR; // Should never happen +// if (cat) +// cat->SetDataPath(g, table_s->db.str); +// else +// return HA_ERR_INTERNAL_ERROR; // Should never happen + + dpath= SetPath(g, table_s->db.str); if (src && ttp != TAB_PIVOT && ttp != TAB_ODBC) { qrp= SrcColumns(g, host, db, user, pwd, src, port); @@ -5025,7 +5042,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, } else switch (ttp) { case TAB_DBF: - qrp= DBFColumns(g, fn, fnc == FNC_COL); + qrp= DBFColumns(g, dpath, fn, fnc == FNC_COL); break; #if defined(ODBC_SUPPORT) case TAB_ODBC: @@ -5062,7 +5079,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, break; #endif // MYSQL_SUPPORT case TAB_CSV: - qrp= CSVColumns(g, fn, spc, qch, hdr, mxe, fnc == FNC_COL); + qrp= CSVColumns(g, dpath, fn, spc, qch, hdr, mxe, fnc == FNC_COL); break; #if defined(WIN32) case TAB_WMI: @@ -5728,8 +5745,10 @@ int ha_connect::create(const char *name, TABLE *table_arg, PDBUSER dup= PlgGetUser(g); PCATLG cat= (dup) ? dup->Catalog : NULL; + SetDataPath(g, table_arg->s->db.str); + if (cat) { - cat->SetDataPath(g, table_arg->s->db.str); +// cat->SetDataPath(g, table_arg->s->db.str); #if defined(WITH_PARTITION_STORAGE_ENGINE) if (part_info) diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h index f12582b9b19..9a73c85cdc7 100644 --- a/storage/connect/ha_connect.h +++ b/storage/connect/ha_connect.h @@ -210,7 +210,9 @@ public: bool IsSameIndex(PIXDEF xp1, PIXDEF xp2); bool IsPartitioned(void); bool IsUnique(uint n); + char *GetDataPath(void) {return (char*)datapath;} + void SetDataPath(PGLOBAL g, const char *path); PTDB GetTDB(PGLOBAL g); int OpenTable(PGLOBAL g, bool del= false); bool CheckColumnList(PGLOBAL g); @@ -521,6 +523,7 @@ protected: ulong hnum; // The number of this handler query_id_t valid_query_id; // The one when tdbp was allocated query_id_t creat_query_id; // The one when handler was allocated + char *datapath; // Is the Path of DB data directory PTDB tdbp; // To table class object PVAL sdvalin; // Used to convert date values PVAL sdvalout; // Used to convert date values diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc index ca09e877b1a..660e2adec2f 100644 --- a/storage/connect/mycat.cc +++ b/storage/connect/mycat.cc @@ -405,9 +405,9 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info) CATALOG::CATALOG(void) { #if defined(WIN32) - DataPath= ".\\"; +//DataPath= ".\\"; #else // !WIN32 - DataPath= "./"; +//DataPath= "./"; #endif // !WIN32 memset(&Ctb, 0, sizeof(CURTAB)); Cbuf= NULL; @@ -433,6 +433,7 @@ void MYCAT::Reset(void) { } // end of Reset +#if 0 /***********************************************************************/ /* This function sets the current database path. */ /***********************************************************************/ @@ -463,6 +464,7 @@ void MYCAT::SetPath(PGLOBAL g, LPCSTR *datapath, const char *path) } // endif path } // end of SetDataPath +#endif // 0 /***********************************************************************/ /* GetTableDesc: retrieve a table descriptor. */ @@ -560,7 +562,7 @@ PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type) printf("tdb=%p type=%s\n", tdp, tdp->GetType()); if (tablep->GetQualifier()) - SetPath(g, &tdp->Database, tablep->GetQualifier()); + tdp->Database = SetPath(g, tablep->GetQualifier()); tdbp= tdp->GetTable(g, mode); } // endif tdp diff --git a/storage/connect/mycat.h b/storage/connect/mycat.h index b45d3a08725..1aaee4ed1e8 100644 --- a/storage/connect/mycat.h +++ b/storage/connect/mycat.h @@ -56,8 +56,8 @@ class MYCAT : public CATALOG { // Methods void Reset(void); - void SetDataPath(PGLOBAL g, const char *path) - {SetPath(g, &DataPath, path);} +//void SetDataPath(PGLOBAL g, const char *path) +// {SetPath(g, &DataPath, path);} bool StoreIndex(PGLOBAL g, PTABDEF defp) {return false;} // Temporary PRELDEF GetTableDesc(PGLOBAL g, LPCSTR name, LPCSTR type, PRELDEF *prp = NULL); @@ -67,7 +67,7 @@ class MYCAT : public CATALOG { protected: PRELDEF MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am); - void SetPath(PGLOBAL g, LPCSTR *datapath, const char *path); +//void SetPath(PGLOBAL g, LPCSTR *datapath, const char *path); // Members ha_connect *Hc; // The Connect handler diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h index 714a6a18ae5..7d5931285ce 100644 --- a/storage/connect/plgdbsem.h +++ b/storage/connect/plgdbsem.h @@ -549,7 +549,8 @@ typedef struct _colres { PPARM Vcolist(PGLOBAL, PTDB, PSZ, bool); void PlugPutOut(PGLOBAL, FILE *, short, void *, uint); void PlugLineDB(PGLOBAL, PSZ, short, void *, uint); -char *PlgGetDataPath(PGLOBAL g); +//ar *PlgGetDataPath(PGLOBAL g); +char *SetPath(PGLOBAL g, const char *path); char *ExtractFromPath(PGLOBAL, char *, char *, OPVAL); void AddPointer(PTABS, void *); PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int); diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp index ba8e2fb9bb8..c5b66e8f5e6 100644 --- a/storage/connect/plgdbutl.cpp +++ b/storage/connect/plgdbutl.cpp @@ -373,6 +373,7 @@ PCATLG PlgGetCatalog(PGLOBAL g, bool jump) return cat; } // end of PlgGetCatalog +#if 0 /***********************************************************************/ /* PlgGetDataPath: returns the default data path. */ /***********************************************************************/ @@ -382,6 +383,39 @@ char *PlgGetDataPath(PGLOBAL g) return (cat) ? cat->GetDataPath() : NULL; } // end of PlgGetDataPath +#endif // 0 + +/***********************************************************************/ +/* This function returns a database path. */ +/***********************************************************************/ +char *SetPath(PGLOBAL g, const char *path) +{ + char *buf= NULL; + + if (path) { + size_t len= strlen(path) + (*path != '.' ? 4 : 1); + + buf= (char*)PlugSubAlloc(g, NULL, len); + + if (PlugIsAbsolutePath(path)) { + strcpy(buf, path); + return buf; + } // endif path + + if (*path != '.') { +#if defined(WIN32) + char *s= "\\"; +#else // !WIN32 + char *s= "/"; +#endif // !WIN32 + strcat(strcat(strcat(strcpy(buf, "."), s), path), s); + } else + strcpy(buf, path); + + } // endif path + + return buf; +} // end of SetPath /***********************************************************************/ /* Extract from a path name the required component. */ diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp index 85295635fea..22076b78086 100644 --- a/storage/connect/reldef.cpp +++ b/storage/connect/reldef.cpp @@ -227,6 +227,14 @@ bool TABDEF::Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am) return DefineAM(g, am, poff); } // end of Define +/***********************************************************************/ +/* This function returns the database data path. */ +/***********************************************************************/ +PSZ TABDEF::GetPath(void) + { + return (Database) ? (PSZ)Database : Hc->GetDataPath(); + } // end of GetPath + /***********************************************************************/ /* This function returns column table information. */ /***********************************************************************/ diff --git a/storage/connect/reldef.h b/storage/connect/reldef.h index b6bd3cafc30..a1dfe87dca8 100644 --- a/storage/connect/reldef.h +++ b/storage/connect/reldef.h @@ -1,5 +1,5 @@ /*************** RelDef H Declares Source Code File (.H) ***************/ -/* Name: RELDEF.H Version 1.4 */ +/* Name: RELDEF.H Version 1.5 */ /* */ /* (C) Copyright to the author Olivier BERTRAND 2004-2014 */ /* */ @@ -79,8 +79,9 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */ void SetNext(PTABDEF tdfp) {Next = tdfp;} int GetMultiple(void) {return Multiple;} int GetPseudo(void) {return Pseudo;} - PSZ GetPath(void) - {return (Database) ? (PSZ)Database : Cat->GetDataPath();} + PSZ GetPath(void); +//PSZ GetPath(void) +// {return (Database) ? (PSZ)Database : Cat->GetDataPath();} bool SepIndex(void) {return GetBoolCatInfo("SepIndex", false);} bool IsReadOnly(void) {return Read_Only;} virtual AMT GetDefType(void) {return TYPE_AM_TAB;} diff --git a/storage/connect/tabfix.h b/storage/connect/tabfix.h index 00439fea0e8..7d5b964da2a 100644 --- a/storage/connect/tabfix.h +++ b/storage/connect/tabfix.h @@ -91,7 +91,8 @@ class TDBDCL : public TDBCAT { protected: // Specific routines - virtual PQRYRES GetResult(PGLOBAL g) {return DBFColumns(g, Fn, false);} + virtual PQRYRES GetResult(PGLOBAL g) + {return DBFColumns(g, ((PTABDEF)To_Def)->GetPath(), Fn, false);} // Members char *Fn; // The DBF file (path) name diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp index a011b62dc7c..c1119c57065 100644 --- a/storage/connect/tabfmt.cpp +++ b/storage/connect/tabfmt.cpp @@ -76,8 +76,8 @@ extern "C" USETEMP Use_Temp; /* of types (TYPE_STRING < TYPE_DOUBLE < TYPE_INT) (1 < 2 < 7). */ /* If these values are changed, this will have to be revisited. */ /***********************************************************************/ -PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q, - int hdr, int mxr, bool info) +PQRYRES CSVColumns(PGLOBAL g, char *dp, const char *fn, char sep, + char q, int hdr, int mxr, bool info) { static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT, TYPE_SHORT}; @@ -131,7 +131,7 @@ PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q, /*********************************************************************/ /* Open the input file. */ /*********************************************************************/ - PlugSetPath(filename, fn, PlgGetDataPath(g)); + PlugSetPath(filename, fn, dp); if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "r"))) return NULL; @@ -1471,7 +1471,8 @@ TDBCCL::TDBCCL(PCSVDEF tdp) : TDBCAT(tdp) /***********************************************************************/ PQRYRES TDBCCL::GetResult(PGLOBAL g) { - return CSVColumns(g, Fn, Sep, Qtd, Hdr, Mxr, false); + return CSVColumns(g, ((PTABDEF)To_Def)->GetPath(), + Fn, Sep, Qtd, Hdr, Mxr, false); } // end of GetResult /* ------------------------ End of TabFmt ---------------------------- */ diff --git a/storage/connect/tabfmt.h b/storage/connect/tabfmt.h index 939c1677f93..1b39a47e7d9 100644 --- a/storage/connect/tabfmt.h +++ b/storage/connect/tabfmt.h @@ -13,8 +13,8 @@ typedef class TDBFMT *PTDBFMT; /***********************************************************************/ /* Functions used externally. */ /***********************************************************************/ -PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q, - int hdr, int mxr, bool info); +PQRYRES CSVColumns(PGLOBAL g, char *dp, const char *fn, char sep, + char q, int hdr, int mxr, bool info); /***********************************************************************/ /* CSV table. */ diff --git a/storage/connect/tabmul.cpp b/storage/connect/tabmul.cpp index 6e4a63d0f6d..047b4d3aeec 100755 --- a/storage/connect/tabmul.cpp +++ b/storage/connect/tabmul.cpp @@ -680,7 +680,7 @@ char* TDBDIR::Path(PGLOBAL g) #if defined(WIN32) if (!*Drive) { - PlugSetPath(Fpath, To_File, cat->GetDataPath()); + PlugSetPath(Fpath, To_File, ((PTABDEF)To_Def)->GetPath()); _splitpath(Fpath, Drive, Direc, Fname, Ftype); } else _makepath(Fpath, Drive, Direc, Fname, Ftype); // Usefull ??? From 22e8ab422cab074ba057bf7d0cf15c8c6dad2d8b Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sun, 24 Aug 2014 11:19:02 +0200 Subject: [PATCH 07/15] - Fix a compile error on Linux modified: storage/connect/tabmul.cpp --- storage/connect/tabmul.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/connect/tabmul.cpp b/storage/connect/tabmul.cpp index 047b4d3aeec..4b40e6c5509 100755 --- a/storage/connect/tabmul.cpp +++ b/storage/connect/tabmul.cpp @@ -688,7 +688,7 @@ char* TDBDIR::Path(PGLOBAL g) return Fpath; #else // !WIN32 if (!Done) { - PlugSetPath(Fpath, To_File, cat->GetDataPath()); + PlugSetPath(Fpath, To_File, ((PTABDEF)To_Def)->GetPath()); _splitpath(Fpath, NULL, Direc, Fname, Ftype); strcat(strcpy(Pattern, Fname), Ftype); Done = true; From da69d41a29672ca9709a16144758f9d1de9908a6 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Mon, 25 Aug 2014 18:34:51 +0200 Subject: [PATCH 08/15] - Make storing and sorting values using less memory allocation (while doing indexed UPDATE/DELETE) modified: storage/connect/array.cpp storage/connect/filamtxt.cpp - Force unix like line endings modified: storage/connect/tabvct.h --- storage/connect/array.cpp | 11 +- storage/connect/filamtxt.cpp | 27 ++-- storage/connect/tabvct.h | 246 +++++++++++++++++------------------ 3 files changed, 149 insertions(+), 135 deletions(-) diff --git a/storage/connect/array.cpp b/storage/connect/array.cpp index 6cd175a0f0a..fb8dbfd7869 100644 --- a/storage/connect/array.cpp +++ b/storage/connect/array.cpp @@ -127,6 +127,10 @@ PARRAY MakeValueArray(PGLOBAL g, PPARM pp) case TYPE_PCHAR: par->AddValue(g, parmp->Value); break; + case TYPE_VOID: + // Integer stored inside pp->Value + par->AddValue(g, (int)parmp->Value); + break; } // endswitch valtyp /*********************************************************************/ @@ -152,14 +156,17 @@ ARRAY::ARRAY(PGLOBAL g, int type, int size, int length, int prec) Xsize = -1; Len = 1; - switch ((Type = type)) { + switch (type) { case TYPE_STRING: Len = length; - break; case TYPE_SHORT: case TYPE_INT: case TYPE_DOUBLE: case TYPE_PCHAR: + Type = type; + break; + case TYPE_VOID: + Type = TYPE_INT; break; #if 0 case TYPE_TOKEN: diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp index 8f04cb358d0..a3ca20bbdb4 100644 --- a/storage/connect/filamtxt.cpp +++ b/storage/connect/filamtxt.cpp @@ -282,14 +282,17 @@ bool TXTFAM::AddListValue(PGLOBAL g, int type, void *val, PPARM *top) PPARM pp = (PPARM)PlugSubAlloc(g, NULL, sizeof(PARM)); switch (type) { - case TYPE_INT: - pp->Value = PlugSubAlloc(g, NULL, sizeof(int)); - *((int*)pp->Value) = *((int*)val); - break; - case TYPE_STRING: - pp->Value = PlugSubAlloc(g, NULL, strlen((char*)val) + 1); - strcpy((char*)pp->Value, (char*)val); +// case TYPE_INT: +// pp->Value = PlugSubAlloc(g, NULL, sizeof(int)); +// *((int*)pp->Value) = *((int*)val); +// break; + case TYPE_VOID: + pp->Value = (void*)*(int*)val; break; +// case TYPE_STRING: +// pp->Value = PlugSubAlloc(g, NULL, strlen((char*)val) + 1); +// strcpy((char*)pp->Value, (char*)val); +// break; case TYPE_PCHAR: pp->Value = val; break; @@ -310,18 +313,22 @@ bool TXTFAM::AddListValue(PGLOBAL g, int type, void *val, PPARM *top) int TXTFAM::StoreValues(PGLOBAL g, bool upd) { int pos = GetPos(); - bool rc = AddListValue(g, TYPE_INT, &pos, &To_Pos); + bool rc = AddListValue(g, TYPE_VOID, &pos, &To_Pos); if (!rc) { pos = GetNextPos(); - rc = AddListValue(g, TYPE_INT, &pos, &To_Sos); + rc = AddListValue(g, TYPE_VOID, &pos, &To_Sos); } // endif rc if (upd && !rc) { + char *buf; + if (Tdbp->PrepareWriting(g)) return RC_FX; - rc = AddListValue(g, TYPE_STRING, Tdbp->GetLine(), &To_Upd); + buf = (char*)PlugSubAlloc(g, NULL, strlen(Tdbp->GetLine()) + 1); + strcpy(buf, Tdbp->GetLine()); + rc = AddListValue(g, TYPE_PCHAR, buf, &To_Upd); } // endif upd return rc ? RC_FX : RC_OK; diff --git a/storage/connect/tabvct.h b/storage/connect/tabvct.h index 7e48051a4f9..8ad3c8e21be 100644 --- a/storage/connect/tabvct.h +++ b/storage/connect/tabvct.h @@ -1,124 +1,124 @@ -/*************** TabVct H Declares Source Code File (.H) ***************/ -/* Name: TABVCT.H Version 3.4 */ -/* */ -/* (C) Copyright to the author Olivier BERTRAND 1999-2011 */ -/* */ -/* This file contains the TDBVCT class declares. */ -/***********************************************************************/ -#ifndef __TABVCT__ -#define __TABVCT__ - -#include "tabfix.h" -#if defined(UNIX) -//#include -#endif - -typedef class TDBVCT *PTDBVCT; -typedef class VCTCOL *PVCTCOL; - -/***********************************************************************/ -/* VCT table. */ -/***********************************************************************/ -class DllExport VCTDEF : public DOSDEF { /* Logical table description */ - friend class TDBVCT; - friend class VCTFAM; - friend class VECFAM; - friend class VMPFAM; - public: - // Constructor - VCTDEF(void) {Split = false; Estimate = Header = 0;} - - // Implementation - virtual const char *GetType(void) {return "VCT";} - int GetEstimate(void) {return Estimate;} - - // Methods - virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); - virtual PTDB GetTable(PGLOBAL g, MODE mode); - - protected: - int MakeFnPattern(char *fpat); - - // Members - bool Split; /* Columns in separate files */ - int Estimate; /* Estimated maximum size of table */ - int Header; /* 0: no, 1: separate, 2: in data file */ - }; // end of VCTDEF - -/***********************************************************************/ -/* This is the DOS/UNIX Access Method class declaration for files */ -/* in blocked vector format. In each block containing "Elements" */ -/* records, values of each columns are consecutively stored (vector). */ -/***********************************************************************/ -class DllExport TDBVCT : public TDBFIX { - friend class VCTCOL; - friend class VCTFAM; - friend class VCMFAM; - friend class VECFAM; - friend class VMPFAM; - public: - // Constructors - TDBVCT(PVCTDEF tdp, PTXF txfp); - TDBVCT(PGLOBAL g, PTDBVCT tdbp); - - // Implementation - virtual AMT GetAmType(void) {return TYPE_AM_VCT;} - virtual PTDB Duplicate(PGLOBAL g) - {return (PTDB)new(g) TDBVCT(g, this);} - bool IsSplit(void) {return ((VCTDEF*)To_Def)->Split;} - - // Methods - virtual PTDB CopyOne(PTABS t); +/*************** TabVct H Declares Source Code File (.H) ***************/ +/* Name: TABVCT.H Version 3.4 */ +/* */ +/* (C) Copyright to the author Olivier BERTRAND 1999-2011 */ +/* */ +/* This file contains the TDBVCT class declares. */ +/***********************************************************************/ +#ifndef __TABVCT__ +#define __TABVCT__ + +#include "tabfix.h" +#if defined(UNIX) +//#include +#endif + +typedef class TDBVCT *PTDBVCT; +typedef class VCTCOL *PVCTCOL; + +/***********************************************************************/ +/* VCT table. */ +/***********************************************************************/ +class DllExport VCTDEF : public DOSDEF { /* Logical table description */ + friend class TDBVCT; + friend class VCTFAM; + friend class VECFAM; + friend class VMPFAM; + public: + // Constructor + VCTDEF(void) {Split = false; Estimate = Header = 0;} + + // Implementation + virtual const char *GetType(void) {return "VCT";} + int GetEstimate(void) {return Estimate;} + + // Methods + virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); + virtual PTDB GetTable(PGLOBAL g, MODE mode); + + protected: + int MakeFnPattern(char *fpat); + + // Members + bool Split; /* Columns in separate files */ + int Estimate; /* Estimated maximum size of table */ + int Header; /* 0: no, 1: separate, 2: in data file */ + }; // end of VCTDEF + +/***********************************************************************/ +/* This is the DOS/UNIX Access Method class declaration for files */ +/* in blocked vector format. In each block containing "Elements" */ +/* records, values of each columns are consecutively stored (vector). */ +/***********************************************************************/ +class DllExport TDBVCT : public TDBFIX { + friend class VCTCOL; + friend class VCTFAM; + friend class VCMFAM; + friend class VECFAM; + friend class VMPFAM; + public: + // Constructors + TDBVCT(PVCTDEF tdp, PTXF txfp); + TDBVCT(PGLOBAL g, PTDBVCT tdbp); + + // Implementation + virtual AMT GetAmType(void) {return TYPE_AM_VCT;} + virtual PTDB Duplicate(PGLOBAL g) + {return (PTDB)new(g) TDBVCT(g, this);} + bool IsSplit(void) {return ((VCTDEF*)To_Def)->Split;} + + // Methods + virtual PTDB CopyOne(PTABS t); virtual bool IsUsingTemp(PGLOBAL g); - - // Database routines - virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); - virtual bool OpenDB(PGLOBAL g); - virtual int ReadDB(PGLOBAL g); - virtual void CloseDB(PGLOBAL g); - - protected: - // Members - }; // end of class TDBVCT - -/***********************************************************************/ -/* Class VCTCOL: VCT access method column descriptor. */ -/* This A.M. is used for file having column wise organization. */ -/***********************************************************************/ -class DllExport VCTCOL : public DOSCOL { - friend class TDBVCT; - friend class VCTFAM; - friend class VCMFAM; - friend class VECFAM; - friend class VMPFAM; - friend class BGVFAM; - public: - // Constructors - VCTCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i); - VCTCOL(VCTCOL *colp, PTDB tdbp); // Constructor used in copy process - - // Implementation - virtual int GetAmType(void) {return TYPE_AM_VCT;} - - // Methods - virtual void ReadColumn(PGLOBAL g); - virtual void WriteColumn(PGLOBAL g); - virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); - virtual void SetOk(void); - - protected: - virtual void ReadBlock(PGLOBAL g); - virtual void WriteBlock(PGLOBAL g); - - VCTCOL(void) {} // Default constructor not to be used - - // Members - PVBLK Blk; // Block buffer - int Clen; // Internal length in table - int ColBlk; // Block pointed by column - int ColPos; // Last position read - int Modif; // Number of modified lines in block - }; // end of class VCTCOL - -#endif // __TABVCT__ - + + // Database routines + virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); + virtual bool OpenDB(PGLOBAL g); + virtual int ReadDB(PGLOBAL g); + virtual void CloseDB(PGLOBAL g); + + protected: + // Members + }; // end of class TDBVCT + +/***********************************************************************/ +/* Class VCTCOL: VCT access method column descriptor. */ +/* This A.M. is used for file having column wise organization. */ +/***********************************************************************/ +class DllExport VCTCOL : public DOSCOL { + friend class TDBVCT; + friend class VCTFAM; + friend class VCMFAM; + friend class VECFAM; + friend class VMPFAM; + friend class BGVFAM; + public: + // Constructors + VCTCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i); + VCTCOL(VCTCOL *colp, PTDB tdbp); // Constructor used in copy process + + // Implementation + virtual int GetAmType(void) {return TYPE_AM_VCT;} + + // Methods + virtual void ReadColumn(PGLOBAL g); + virtual void WriteColumn(PGLOBAL g); + virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); + virtual void SetOk(void); + + protected: + virtual void ReadBlock(PGLOBAL g); + virtual void WriteBlock(PGLOBAL g); + + VCTCOL(void) {} // Default constructor not to be used + + // Members + PVBLK Blk; // Block buffer + int Clen; // Internal length in table + int ColBlk; // Block pointed by column + int ColPos; // Last position read + int Modif; // Number of modified lines in block + }; // end of class VCTCOL + +#endif // __TABVCT__ + From 8f0e75285ec999abbe73efe7a9c12a474c896ba0 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Mon, 25 Aug 2014 18:51:53 +0200 Subject: [PATCH 09/15] - Adding a test for indexed UPDATE/DELETE added: storage/connect/mysql-test/connect/r/updelx.result storage/connect/mysql-test/connect/t/updelx.inc storage/connect/mysql-test/connect/t/updelx.test --- .../mysql-test/connect/r/updelx.result | 2570 +++++++++++++++++ .../connect/mysql-test/connect/t/updelx.inc | 25 + .../connect/mysql-test/connect/t/updelx.test | 96 + 3 files changed, 2691 insertions(+) create mode 100644 storage/connect/mysql-test/connect/r/updelx.result create mode 100644 storage/connect/mysql-test/connect/t/updelx.inc create mode 100644 storage/connect/mysql-test/connect/t/updelx.test diff --git a/storage/connect/mysql-test/connect/r/updelx.result b/storage/connect/mysql-test/connect/r/updelx.result new file mode 100644 index 00000000000..1c9df294e00 --- /dev/null +++ b/storage/connect/mysql-test/connect/r/updelx.result @@ -0,0 +1,2570 @@ +# +# Testing indexed UPDATE and DELETE for all table types +# +# CSV table +CREATE TABLE t1 ( +id INT KEY NOT NULL, +msg VARCHAR(32)) +ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=6; +Warnings: +Warning 1105 No file name. Table will use t1.csv +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +ALTER TABLE t1 MAPPED=YES; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +ALTER TABLE t1 MAPPED=NO BLOCK_SIZE=6; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +ALTER TABLE t1 MAPPED=YES; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +DROP TABLE t1; +# DOS table +CREATE TABLE t1 ( +id INT(4) KEY NOT NULL, +msg VARCHAR(16)) +ENGINE=CONNECT TABLE_TYPE=DOS; +Warnings: +Warning 1105 No file name. Table will use t1.dos +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +ALTER TABLE t1 MAPPED=YES; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +ALTER TABLE t1 MAPPED=NO BLOCK_SIZE=4; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +ALTER TABLE t1 MAPPED=YES; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +DROP TABLE t1; +# FIX table +CREATE TABLE t1 ( +id INT(4) KEY NOT NULL, +msg VARCHAR(16) CHARSET BINARY DISTRIB=CLUSTERED) +ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=4; +Warnings: +Warning 1105 No file name. Table will use t1.fix +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +ALTER TABLE t1 MAPPED=YES; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +ALTER TABLE t1 MAPPED=NO HUGE=YES; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +DROP TABLE t1; +# BIN table +CREATE TABLE t1 ( +id INT(4) KEY NOT NULL, +msg VARCHAR(16) CHARSET BINARY DISTRIB=CLUSTERED) +ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=8; +Warnings: +Warning 1105 No file name. Table will use t1.bin +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +ALTER TABLE t1 MAPPED=YES; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +ALTER TABLE t1 MAPPED=NO HUGE=YES; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +DROP TABLE t1; +# DBF table +CREATE TABLE t1 ( +id INT(4) KEY NOT NULL, +msg VARCHAR(16)) +ENGINE=CONNECT TABLE_TYPE=DBF BLOCK_SIZE=12; +Warnings: +Warning 1105 No file name. Table will use t1.dbf +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +ALTER TABLE t1 MAPPED=YES; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +DROP TABLE t1; +# VEC table +CREATE TABLE t1 ( +id INT(4) KEY NOT NULL, +msg VARCHAR(16)) +ENGINE=CONNECT TABLE_TYPE=VEC BLOCK_SIZE=6 MAX_ROWS=16; +Warnings: +Warning 1105 No file name. Table will use t1.vec +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +ALTER TABLE t1 MAPPED=YES; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +ALTER TABLE t1 MAPPED=NO HUGE=YES; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +DROP TABLE t1; +# Split VEC table (outward) +CREATE TABLE t1 ( +id INT(4) KEY NOT NULL, +msg VARCHAR(16)) +ENGINE=CONNECT TABLE_TYPE=VEC BLOCK_SIZE=6 FILE_NAME='tx.vec'; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +ALTER TABLE t1 MAPPED=YES; +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 thirty five +8 eight +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 sixty +81 eighty one +72 seventy two +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 big +81 big +72 big +11 eleven +1 one +35 bof +8 eight +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +id msg +4 four +7 seven +10 ten +40 forty +60 updated +81 big +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +id msg +4 four +7 seven +10 twin +40 forty +60 updated +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +id msg +60 sixty +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +id msg +7 seven +10 twin +40 forty +60 sixty +81 twin +72 updated +11 eleven +1 one +35 updated +8 updated +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +id msg +7 seven +10 twin +60 sixty +81 twin +72 updated +1 one +8 updated +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +msg +seven +twin +twin +updated +updated +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +id +7 +8 +10 +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +id msg +8 updated +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; +id msg +DROP TABLE t1; diff --git a/storage/connect/mysql-test/connect/t/updelx.inc b/storage/connect/mysql-test/connect/t/updelx.inc new file mode 100644 index 00000000000..f38a59b9983 --- /dev/null +++ b/storage/connect/mysql-test/connect/t/updelx.inc @@ -0,0 +1,25 @@ +DELETE FROM t1; +INSERT INTO t1 VALUES(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),(60,'sixty'),(81,'eighty one'),(72,'seventy two'),(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight'); +SELECT * FROM t1; +UPDATE t1 SET msg = 'bof' WHERE id = 35; +SELECT * FROM t1; +UPDATE t1 SET msg = 'big' WHERE id > 50; +SELECT * FROM t1; +UPDATE t1 SET msg = 'updated' WHERE id IN (8,35,60,72); +SELECT * FROM t1; +UPDATE t1 SET msg = 'twin' WHERE id IN (81,10); +SELECT * FROM t1; +UPDATE t1 SET msg = 'sixty' WHERE id = 60; +SELECT * FROM t1 WHERE id = 60; +DELETE FROM t1 WHERE id = 4; +SELECT * FROM t1; +DELETE FROM t1 WHERE id IN (40,11,35); +SELECT * FROM t1; +DELETE FROM t1 WHERE id IN (4,60,1); +SELECT msg FROM t1; +DELETE FROM t1 WHERE id IN (81,72); +SELECT id FROM t1; +DELETE FROM t1 WHERE id IN (7,10); +SELECT * FROM t1; +DELETE FROM t1 WHERE id = 8; +SELECT * FROM t1; diff --git a/storage/connect/mysql-test/connect/t/updelx.test b/storage/connect/mysql-test/connect/t/updelx.test new file mode 100644 index 00000000000..ab336d4b168 --- /dev/null +++ b/storage/connect/mysql-test/connect/t/updelx.test @@ -0,0 +1,96 @@ +-- source include/not_embedded.inc +let $MYSQLD_DATADIR= `select @@datadir`; + +--echo # +--echo # Testing indexed UPDATE and DELETE for all table types +--echo # + +--echo # CSV table +CREATE TABLE t1 ( +id INT KEY NOT NULL, +msg VARCHAR(32)) +ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=6; +-- source updelx.inc +ALTER TABLE t1 MAPPED=YES; +-- source updelx.inc +ALTER TABLE t1 MAPPED=NO BLOCK_SIZE=6; +-- source updelx.inc +ALTER TABLE t1 MAPPED=YES; +-- source updelx.inc +DROP TABLE t1; + +--echo # DOS table +CREATE TABLE t1 ( +id INT(4) KEY NOT NULL, +msg VARCHAR(16)) +ENGINE=CONNECT TABLE_TYPE=DOS; +-- source updelx.inc +ALTER TABLE t1 MAPPED=YES; +-- source updelx.inc +ALTER TABLE t1 MAPPED=NO BLOCK_SIZE=4; +-- source updelx.inc +ALTER TABLE t1 MAPPED=YES; +-- source updelx.inc +DROP TABLE t1; + +--echo # FIX table +CREATE TABLE t1 ( +id INT(4) KEY NOT NULL, +msg VARCHAR(16) CHARSET BINARY DISTRIB=CLUSTERED) +ENGINE=CONNECT TABLE_TYPE=FIX BLOCK_SIZE=4; +-- source updelx.inc +ALTER TABLE t1 MAPPED=YES; +-- source updelx.inc +ALTER TABLE t1 MAPPED=NO HUGE=YES; +-- source updelx.inc +DROP TABLE t1; + +--echo # BIN table +CREATE TABLE t1 ( +id INT(4) KEY NOT NULL, +msg VARCHAR(16) CHARSET BINARY DISTRIB=CLUSTERED) +ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=8; +-- source updelx.inc +ALTER TABLE t1 MAPPED=YES; +-- source updelx.inc +ALTER TABLE t1 MAPPED=NO HUGE=YES; +-- source updelx.inc +DROP TABLE t1; + +--echo # DBF table +CREATE TABLE t1 ( +id INT(4) KEY NOT NULL, +msg VARCHAR(16)) +ENGINE=CONNECT TABLE_TYPE=DBF BLOCK_SIZE=12; +-- source updelx.inc +ALTER TABLE t1 MAPPED=YES; +-- source updelx.inc +#ALTER TABLE t1 MAPPED=NO HUGE=YES; +#-- source updelx.inc +DROP TABLE t1; + +--echo # VEC table +CREATE TABLE t1 ( +id INT(4) KEY NOT NULL, +msg VARCHAR(16)) +ENGINE=CONNECT TABLE_TYPE=VEC BLOCK_SIZE=6 MAX_ROWS=16; +-- source updelx.inc +ALTER TABLE t1 MAPPED=YES; +-- source updelx.inc +ALTER TABLE t1 MAPPED=NO HUGE=YES; +-- source updelx.inc +DROP TABLE t1; + +--echo # Split VEC table (outward) +CREATE TABLE t1 ( +id INT(4) KEY NOT NULL, +msg VARCHAR(16)) +ENGINE=CONNECT TABLE_TYPE=VEC BLOCK_SIZE=6 FILE_NAME='tx.vec'; +-- source updelx.inc +ALTER TABLE t1 MAPPED=YES; +-- source updelx.inc +DROP TABLE t1; + +# Cleanup +--remove_file $MYSQLD_DATADIR/test/tx1.vec +--remove_file $MYSQLD_DATADIR/test/tx2.vec From 66ffa09491e19a2d8c2f7638741909d13c7b25d7 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Wed, 27 Aug 2014 00:49:07 +0200 Subject: [PATCH 10/15] - Fix a test failure. Due to mmap on void file being accepted on Windows while returning an error on Linux. Now accepted on linux. modified: storage/connect/maputil.cpp - Fix a BUG in the XHUGE class. lseek64 was wrongly regarded as in error when returning 0 instead of -1. This produced wrong index files. modified: storage/connect/filamfix.cpp storage/connect/maputil.cpp storage/connect/xindex.cpp - Fix length mismatch (tab instead of blanks?) modified: storage/connect/mysql-test/connect/r/updelx.result --- storage/connect/filamfix.cpp | 8 ++-- storage/connect/maputil.cpp | 14 +++--- .../mysql-test/connect/r/updelx.result | 4 +- storage/connect/xindex.cpp | 46 ++++++++++++++----- 4 files changed, 49 insertions(+), 23 deletions(-) diff --git a/storage/connect/filamfix.cpp b/storage/connect/filamfix.cpp index da05e7b824f..1fa72d52746 100644 --- a/storage/connect/filamfix.cpp +++ b/storage/connect/filamfix.cpp @@ -647,7 +647,9 @@ bool BGXFAM::BigSeek(PGLOBAL g, HANDLE h, BIGINT pos, int org) } // endif #else // !WIN32 if (lseek64(h, pos, org) < 0) { - sprintf(g->Message, MSG(ERROR_IN_LSK), errno); +// sprintf(g->Message, MSG(ERROR_IN_LSK), errno); + sprintf(g->Message, "lseek64: %s", strerror(errno)); + printf("%s\n", g->Message); return true; } // endif #endif // !WIN32 @@ -849,7 +851,7 @@ bool BGXFAM::OpenTableFile(PGLOBAL g) #else // UNIX int rc = 0; int oflag = O_LARGEFILE; // Enable file size > 2G - mode_t tmode = 0; + mode_t tmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; /*********************************************************************/ /* Create the file object according to access mode */ @@ -874,7 +876,7 @@ bool BGXFAM::OpenTableFile(PGLOBAL g) break; case MODE_INSERT: oflag |= (O_WRONLY | O_CREAT | O_APPEND); - tmode = S_IREAD | S_IWRITE; + // tmode = S_IREAD | S_IWRITE; break; default: sprintf(g->Message, MSG(BAD_OPEN_MODE), mode); diff --git a/storage/connect/maputil.cpp b/storage/connect/maputil.cpp index 7104259ebad..97c638b4254 100644 --- a/storage/connect/maputil.cpp +++ b/storage/connect/maputil.cpp @@ -154,7 +154,7 @@ HANDLE CreateFileMap(PGLOBAL g, LPCSTR fileName, } // endswitch // Try to open the addressed file. - fd= global_open(g, MSGID_NONE, fileName, openMode); + fd= global_open(g, MSGID_NONE, fileName, openMode); if (fd != INVALID_HANDLE_VALUE && mode != MODE_INSERT) { /* We must know about the size of the file. */ @@ -164,17 +164,19 @@ HANDLE CreateFileMap(PGLOBAL g, LPCSTR fileName, return INVALID_HANDLE_VALUE; } // endif fstat - filesize = st.st_size; - - // Now we are ready to load the file. If mmap() is available we try - // this first. If not available or it failed we try to load it. - mm->memory = mmap(NULL, filesize, protmode, MAP_SHARED, fd, 0); + if ((filesize = st.st_size)) + // Now we are ready to load the file. If mmap() is available we try + // this first. If not available or it failed we try to load it. + mm->memory = mmap(NULL, filesize, protmode, MAP_SHARED, fd, 0); + else + mm->memory = 0; if (mm->memory != MAP_FAILED) { mm->lenL = (mm->memory != 0) ? filesize : 0; mm->lenH = 0; } else { strcpy(g->Message, "Memory mapping failed"); + close(fd); return INVALID_HANDLE_VALUE; } // endif memory diff --git a/storage/connect/mysql-test/connect/r/updelx.result b/storage/connect/mysql-test/connect/r/updelx.result index 1c9df294e00..2aed1e06928 100644 --- a/storage/connect/mysql-test/connect/r/updelx.result +++ b/storage/connect/mysql-test/connect/r/updelx.result @@ -322,7 +322,7 @@ id msg UPDATE t1 SET msg = 'sixty' WHERE id = 60; SELECT * FROM t1 WHERE id = 60; id msg -60 sixty +60 sixty DELETE FROM t1 WHERE id = 4; SELECT * FROM t1; id msg @@ -809,7 +809,7 @@ id msg UPDATE t1 SET msg = 'sixty' WHERE id = 60; SELECT * FROM t1 WHERE id = 60; id msg -60 sixty +60 sixty DELETE FROM t1 WHERE id = 4; SELECT * FROM t1; id msg diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp index 6d1b2a13ea3..b121968277f 100755 --- a/storage/connect/xindex.cpp +++ b/storage/connect/xindex.cpp @@ -2470,7 +2470,7 @@ void *XFILE::FileView(PGLOBAL g, char *fn) /***********************************************************************/ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode) { - IOFF noff[MAX_INDX]; + IOFF noff[MAX_INDX]; if (Hfile != INVALID_HANDLE_VALUE) { sprintf(g->Message, MSG(FILE_OPEN_YET), filename); @@ -2478,7 +2478,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode) } // endif if (trace) - htrc(" Xopen: filename=%s mode=%d\n", filename, mode); + htrc(" Xopen: filename=%s id=%d mode=%d\n", filename, id, mode); #if defined(WIN32) LONG high = 0; @@ -2570,7 +2570,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode) #else // UNIX int oflag = O_LARGEFILE; // Enable file size > 2G - mode_t pmod = 0; + mode_t pmod = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; /*********************************************************************/ /* Create the file object according to access mode */ @@ -2581,7 +2581,7 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode) break; case MODE_WRITE: oflag |= O_WRONLY | O_CREAT | O_TRUNC; - pmod = S_IREAD | S_IWRITE; +// pmod = S_IREAD | S_IWRITE; break; case MODE_INSERT: oflag |= (O_WRONLY | O_APPEND); @@ -2614,6 +2614,9 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode) return true; } // endif + if (trace) + htrc("INSERT: NewOff=%lld\n", NewOff.Val); + } else if (mode == MODE_WRITE) { if (id >= 0) { // New not sep index file. Write the header. @@ -2621,18 +2624,26 @@ bool XHUGE::Open(PGLOBAL g, char *filename, int id, MODE mode) NewOff.Low = write(Hfile, &noff, sizeof(noff)); } // endif id + if (trace) + htrc("WRITE: NewOff=%lld\n", NewOff.Val); + } else if (mode == MODE_READ && id >= 0) { // Get offset from the header if (read(Hfile, noff, sizeof(noff)) != sizeof(noff)) { sprintf(g->Message, MSG(READ_ERROR), "Index file", strerror(errno)); return true; - } // endif MAX_INDX + } // endif read + + if (trace) + htrc("noff[%d]=%lld\n", id, noff[id].Val); // Position the cursor at the offset of this index - if (!lseek64(Hfile, noff[id].Val, SEEK_SET)) { - sprintf(g->Message, MSG(FUNC_ERRNO), errno, "Hseek"); + if (lseek64(Hfile, noff[id].Val, SEEK_SET) < 0) { + sprintf(g->Message, "(XHUGE)lseek64: %s (%lld)", strerror(errno), noff[id].Val); + printf("%s\n", g->Message); +// sprintf(g->Message, MSG(FUNC_ERRNO), errno, "Hseek"); return true; - } // endif + } // endif lseek64 } // endif mode #endif // UNIX @@ -2766,6 +2777,9 @@ int XHUGE::Write(PGLOBAL g, void *buf, int n, int size, bool& rc) /***********************************************************************/ void XHUGE::Close(char *fn, int id) { + if (trace) + htrc("XHUGE::Close: fn=%s id=%d NewOff=%lld\n", fn, id, NewOff.Val); + #if defined(WIN32) if (id >= 0 && fn) { CloseFileHandle(Hfile); @@ -2783,10 +2797,18 @@ void XHUGE::Close(char *fn, int id) } // endif id #else // !WIN32 if (id >= 0 && fn) { - fcntl(Hfile, F_SETFD, O_WRONLY); - - if (lseek(Hfile, id * sizeof(IOFF), SEEK_SET)) - write(Hfile, &NewOff, sizeof(IOFF)); + if (Hfile != INVALID_HANDLE_VALUE) { + if (lseek64(Hfile, id * sizeof(IOFF), SEEK_SET) >= 0) { + ssize_t nbw = write(Hfile, &NewOff, sizeof(IOFF)); + + if (nbw != (signed)sizeof(IOFF)) + htrc("Error writing index file header: %s\n", strerror(errno)); + + } else + htrc("(XHUGE::Close)lseek64: %s (%d)\n", strerror(errno), id); + + } else + htrc("(XHUGE)error reopening %s: %s\n", fn, strerror(errno)); } // endif id #endif // !WIN32 From 86a3343191780854b3bed4ccedc8e56f72f2faab Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Wed, 27 Aug 2014 14:56:20 +0200 Subject: [PATCH 11/15] - Fix a bug in DOSFAM::OpenTableFile. Bin was not set to TRUE for blocked tables. This caused a CR character to be left in the line and in particular caused the updelx test to fail on Windows. modified: storage/connect/filamtxt.cpp --- storage/connect/filamtxt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp index a3ca20bbdb4..5cabf980554 100644 --- a/storage/connect/filamtxt.cpp +++ b/storage/connect/filamtxt.cpp @@ -536,7 +536,7 @@ bool DOSFAM::OpenTableFile(PGLOBAL g) PDBUSER dbuserp = PlgGetUser(g); // This is required when using Unix files under Windows and vice versa - Bin = (Ending != CRLF); + Bin = (Blocked || Ending != CRLF); switch (mode) { case MODE_READ: @@ -578,7 +578,7 @@ bool DOSFAM::OpenTableFile(PGLOBAL g) } // endswitch Mode // For blocked I/O or for moving lines, open the table in binary - strcat(opmode, (Blocked || Bin) ? "b" : "t"); + strcat(opmode, (Bin) ? "b" : "t"); // Now open the file stream PlugSetPath(filename, To_File, Tdbp->GetPath()); From 16de35114eabca16b60849989244ed491cbd3fda Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Fri, 29 Aug 2014 14:22:25 +0200 Subject: [PATCH 12/15] - Avoid uninitialised warning from valgrind modified: storage/connect/tabdos.cpp --- storage/connect/tabdos.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp index 4a62b20cfbd..eca6b68f656 100644 --- a/storage/connect/tabdos.cpp +++ b/storage/connect/tabdos.cpp @@ -842,6 +842,8 @@ bool TDBDOS::SaveBlockValues(PGLOBAL g) return true; } // endif opfile + memset(n, 0, sizeof(n)); // To avoid valgrind warning + if (Ftype == RECFM_VAR || defp->Compressed == 2) { /*******************************************************************/ /* Write block starting positions into the opt file. */ From 7c1af793fc57e711fb0c8fdd12a3de5e45ad2bf7 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Tue, 2 Sep 2014 01:40:15 +0200 Subject: [PATCH 13/15] - Initialise min/max buffer to 0 to avoid valgrind complaining that uninitialised characters be written in op file. modified: storage/connect/tabdos.cpp - Typo modified: storage/connect/filamap.cpp storage/connect/filamdbf.cpp storage/connect/filamdbf.h storage/connect/valblk.cpp storage/connect/xindex.cpp --- storage/connect/filamap.cpp | 15 ++++++++------- storage/connect/filamdbf.cpp | 4 ++-- storage/connect/filamdbf.h | 2 +- storage/connect/tabdos.cpp | 7 +++++++ storage/connect/valblk.cpp | 4 ++-- storage/connect/xindex.cpp | 25 +++++++++++++------------ 6 files changed, 33 insertions(+), 24 deletions(-) diff --git a/storage/connect/filamap.cpp b/storage/connect/filamap.cpp index 3523c688788..c0ca40f4c01 100644 --- a/storage/connect/filamap.cpp +++ b/storage/connect/filamap.cpp @@ -129,9 +129,9 @@ bool MAPFAM::OpenTableFile(PGLOBAL g) && fp->Count && fp->Mode == mode) break; -#ifdef DEBTRACE - htrc("Mapping file, fp=%p\n", fp); -#endif + if (trace) + htrc("Mapping file, fp=%p\n", fp); + } else fp = NULL; @@ -347,11 +347,12 @@ int MAPFAM::ReadBuffer(PGLOBAL g) return RC_EF; case RC_NF: // Skip this record - if ((rc = SkipRecord(g, FALSE)) != RC_OK) + if ((rc = SkipRecord(g, false)) != RC_OK) return rc; goto next; } // endswitch rc + } else Placed = false; @@ -415,9 +416,9 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc) /*******************************************************************/ Tpos = Spos = Fpos; } else if ((n = Fpos - Spos) > 0) { - /*****************************************************************/ - /* Non consecutive line to delete. Move intermediate lines. */ - /*****************************************************************/ + /*******************************************************************/ + /* Non consecutive line to delete. Move intermediate lines. */ + /*******************************************************************/ memmove(Tpos, Spos, n); Tpos += n; diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp index ea1850b5c85..a214ab8acf2 100644 --- a/storage/connect/filamdbf.cpp +++ b/storage/connect/filamdbf.cpp @@ -176,7 +176,7 @@ static int dbfhead(PGLOBAL g, FILE *file, PSZ fn, DBFHEADER *buf) /* DBFColumns: constructs the result blocks containing the description */ /* of all the columns of a DBF file that will be retrieved by #GetData. */ /****************************************************************************/ -PQRYRES DBFColumns(PGLOBAL g, char *dp, const char *fn, BOOL info) +PQRYRES DBFColumns(PGLOBAL g, char *dp, const char *fn, bool info) { int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT, TYPE_SHORT}; @@ -186,7 +186,7 @@ PQRYRES DBFColumns(PGLOBAL g, char *dp, const char *fn, BOOL info) char buf[2], filename[_MAX_PATH]; int ncol = sizeof(buftyp) / sizeof(int); int rc, type, len, field, fields; - BOOL bad; + bool bad; DBFHEADER mainhead; DESCRIPTOR thisfield; FILE *infile = NULL; diff --git a/storage/connect/filamdbf.h b/storage/connect/filamdbf.h index 49bf5f0db93..da84d7685a8 100644 --- a/storage/connect/filamdbf.h +++ b/storage/connect/filamdbf.h @@ -19,7 +19,7 @@ typedef class DBMFAM *PDBMFAM; /****************************************************************************/ /* Functions used externally. */ /****************************************************************************/ -PQRYRES DBFColumns(PGLOBAL g, char *dp, const char *fn, BOOL info); +PQRYRES DBFColumns(PGLOBAL g, char *dp, const char *fn, bool info); /****************************************************************************/ /* This is the base class for dBASE file access methods. */ diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp index eca6b68f656..054e46f7f10 100644 --- a/storage/connect/tabdos.cpp +++ b/storage/connect/tabdos.cpp @@ -664,6 +664,13 @@ int TDBDOS::MakeBlockValues(PGLOBAL g) cdp->SetMin(PlugSubAlloc(g, NULL, block * lg)); cdp->SetMax(PlugSubAlloc(g, NULL, block * lg)); + // Valgrind complains if there are uninitialised bytes + // after the null character ending + if (IsTypeChar(cdp->GetType())) { + memset(cdp->GetMin(), 0, block * lg); + memset(cdp->GetMax(), 0, block * lg); + } // endif Type + if (trace) htrc("min(%p) max(%p) col(%d) %s Block=%d lg=%d\n", cdp->GetMin(), cdp->GetMax(), i, cdp->GetName(), block, lg); diff --git a/storage/connect/valblk.cpp b/storage/connect/valblk.cpp index e435a49cbd2..3827deec43d 100644 --- a/storage/connect/valblk.cpp +++ b/storage/connect/valblk.cpp @@ -827,12 +827,12 @@ void CHRBLK::SetValue(PVBLK pv, int n1, int n2) longjmp(g->jumper[g->jump_level], Type); } // endif Type - if (!(b = pv->IsNull(n2) && Nullable)) + if (!(b = pv->IsNull(n2))) memcpy(Chrp + n1 * Long, ((CHRBLK*)pv)->Chrp + n2 * Long, Long); else Reset(n1); - SetNull(n1, b); + SetNull(n1, b && Nullable); } // end of SetValue /***********************************************************************/ diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp index b121968277f..7cc52580760 100755 --- a/storage/connect/xindex.cpp +++ b/storage/connect/xindex.cpp @@ -544,7 +544,7 @@ bool XINDEX::Make(PGLOBAL g, PIXDEF sxp) if ((Ndif = Qsort(g, Num_K)) < 0) goto err; // Error during sort -// if (trace) + if (trace) htrc("Make: Nk=%d n=%d Num_K=%d Ndif=%d addcolp=%p BlkFil=%p X=%p\n", Nk, n, Num_K, Ndif, addcolp, Tdbp->To_BlkFil, X); @@ -817,11 +817,11 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp) bool sep, rc = false; PXCOL kcp = To_KeyCol; PDOSDEF defp = (PDOSDEF)Tdbp->To_Def; - PDBUSER dup = PlgGetUser(g); +//PDBUSER dup = PlgGetUser(g); - dup->Step = STEP(SAVING_INDEX); - dup->ProgMax = 15 + 16 * Nk; - dup->ProgCur = 0; +//dup->Step = STEP(SAVING_INDEX); +//dup->ProgMax = 15 + 16 * Nk; +//dup->ProgCur = 0; switch (Tdbp->Ftype) { case RECFM_VAR: ftype = ".dnx"; break; @@ -881,17 +881,17 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp) } // endif trace size = X->Write(g, n, NZ, sizeof(int), rc); - dup->ProgCur = 1; +//dup->ProgCur = 1; if (Mul) // Write the offset array size += X->Write(g, Pof, nof, sizeof(int), rc); - dup->ProgCur = 5; +//dup->ProgCur = 5; if (!Incr) // Write the record position array(s) size += X->Write(g, To_Rec, Num_K, sizeof(int), rc); - dup->ProgCur = 15; +//dup->ProgCur = 15; for (; kcp; kcp = kcp->Next) { n[0] = kcp->Ndf; // Number of distinct sub-values @@ -901,20 +901,20 @@ bool XINDEX::SaveIndex(PGLOBAL g, PIXDEF sxp) n[4] = kcp->Type; // To be checked later size += X->Write(g, n, NW, sizeof(int), rc); - dup->ProgCur += 1; +// dup->ProgCur += 1; if (n[2]) size += X->Write(g, kcp->To_Bkeys, Nblk, kcp->Klen, rc); - dup->ProgCur += 5; +// dup->ProgCur += 5; size += X->Write(g, kcp->To_Keys, n[0], kcp->Klen, rc); - dup->ProgCur += 5; +// dup->ProgCur += 5; if (n[1]) size += X->Write(g, kcp->Kof, n[1], sizeof(int), rc); - dup->ProgCur += 5; +// dup->ProgCur += 5; } // endfor kcp if (trace) @@ -2834,6 +2834,7 @@ void *XHUGE::FileView(PGLOBAL g, char *fn) /***********************************************************************/ XXROW::XXROW(PTDBDOS tdbp) : XXBASE(tdbp, false) { + Srtd = true; Tdbp = tdbp; Valp = NULL; } // end of XXROW constructor From 4aac44d257c122920682ecea3501efb06eefe2cd Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Fri, 5 Sep 2014 14:18:31 +0200 Subject: [PATCH 14/15] - Fix MDEV-6686 (buffer overflow in MakeRecord) modified: storage/connect/ha_connect.cc --- storage/connect/ha_connect.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 5fbd86b0ce1..da491c7fa16 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -1731,10 +1731,10 @@ int ha_connect::MakeRecord(char *buf) // Store functions returns 1 on overflow and -1 on fatal error if (rc > 0) { - char buf[128]; + char buf[256]; THD *thd= ha_thd(); - sprintf(buf, "Out of range value %s for column '%s' at row %ld", + sprintf(buf, "Out of range value %.140s for column '%s' at row %ld", value->GetCharString(val), fp->field_name, thd->get_stmt_da()->current_row_for_warning()); From a1c3656e01f26712a1fd9fca043b0280c2b9cea3 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sat, 6 Sep 2014 18:08:28 +0200 Subject: [PATCH 15/15] - Fix MDEV-6624 (indexing on void table) modified: storage/connect/ha_connect.cc - Suppress "Position array is null" warning. modified: storage/connect/filamtxt.cpp storage/connect/mysql-test/connect/r/part_table.result --- storage/connect/filamtxt.cpp | 10 ++++++---- storage/connect/ha_connect.cc | 6 ++++-- storage/connect/mysql-test/connect/r/part_table.result | 1 - 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp index 5cabf980554..9c23944ff42 100644 --- a/storage/connect/filamtxt.cpp +++ b/storage/connect/filamtxt.cpp @@ -350,8 +350,9 @@ int TXTFAM::UpdateSortedRows(PGLOBAL g) /* Get the stored update values and sort them. */ /*********************************************************************/ if (!(Posar = MakeValueArray(g, To_Pos))) { - strcpy(g->Message, "Position array is null"); - return RC_INFO; +// strcpy(g->Message, "Position array is null"); +// return RC_INFO; + return RC_OK; // Nothing to do } else if (!(Sosar = MakeValueArray(g, To_Sos))) { strcpy(g->Message, "Start position array is null"); goto err; @@ -401,8 +402,9 @@ int TXTFAM::DeleteSortedRows(PGLOBAL g) /* Get the stored delete values and sort them. */ /*********************************************************************/ if (!(Posar = MakeValueArray(g, To_Pos))) { - strcpy(g->Message, "Position array is null"); - return RC_INFO; +// strcpy(g->Message, "Position array is null"); +// return RC_INFO; + return RC_OK; // Nothing to do } else if (!(Sosar = MakeValueArray(g, To_Sos))) { strcpy(g->Message, "Start position array is null"); goto err; diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index da491c7fa16..2e1d59ff632 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -2946,8 +2946,10 @@ int ha_connect::index_init(uint idx, bool sorted) ((PTDBDOX)tdbp)->GetTxfp()->ResetBuffer(g); active_index= idx; - } else // Void table - indexing= 0; +// } else { // Void table +// active_index= MAX_KEY; +// indexing= 0; + } // endif Num rc= 0; } // endif indexing diff --git a/storage/connect/mysql-test/connect/r/part_table.result b/storage/connect/mysql-test/connect/r/part_table.result index e447caca615..122c328fa59 100644 --- a/storage/connect/mysql-test/connect/r/part_table.result +++ b/storage/connect/mysql-test/connect/r/part_table.result @@ -148,7 +148,6 @@ UPDATE t1 SET msg = 'number' WHERE id in (60,72); Warnings: Note 1105 xt3: 2 affected rows Note 1105 xt3: 0 affected rows -Warning 1105 xt3: (1105) Position array is null UPDATE t1 SET msg = 'soixante' WHERE id = 60; Warnings: Note 1105 xt3: 1 affected rows