From decc23cbc2d0ece2217f3d70173cc4dd7088da5c Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Tue, 22 Jul 2014 15:51:21 +0200 Subject: [PATCH] - Fix bugs in handling of remote index when updating and deleting modified: storage/connect/ha_connect.cc storage/connect/tabdos.cpp storage/connect/tabfmt.cpp storage/connect/tabmysql.cpp - add AVG_REC_LENGTH option to avoid result mismatch between Windows and Linux modified: storage/connect/mysql-test/connect/r/part_file.result storage/connect/mysql-test/connect/r/part_table.result storage/connect/mysql-test/connect/t/part_file.test --- storage/connect/ha_connect.cc | 18 +++++++-------- .../mysql-test/connect/r/part_file.result | 8 +++---- .../mysql-test/connect/r/part_table.result | 2 +- .../mysql-test/connect/t/part_file.test | 2 +- storage/connect/tabdos.cpp | 23 ++++++++----------- storage/connect/tabfmt.cpp | 19 ++++++--------- storage/connect/tabmysql.cpp | 8 ++++--- 7 files changed, 36 insertions(+), 44 deletions(-) diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 6fcb56966c7..eacfe293b7c 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -966,21 +966,21 @@ bool ha_connect::SetBooleanOption(char *opname, bool b) /****************************************************************************/ int ha_connect::GetIntegerOption(char *opname) { - ulonglong opval= NO_IVAL; - char *pv; - PTOS options= GetTableOptionStruct(); + ulonglong opval= NO_IVAL; + char *pv; + PTOS options= GetTableOptionStruct(); + TABLE_SHARE *tsp= (tshp) ? tshp : table_share; - if (!options) + if (!stricmp(opname, "Avglen")) + opval= (ulonglong)tsp->avg_row_length; + else if (!stricmp(opname, "Estimate")) + opval= (ulonglong)tsp->max_rows; + else if (!options) ; else if (!stricmp(opname, "Lrecl")) opval= options->lrecl; else if (!stricmp(opname, "Elements")) opval= options->elements; - else if (!stricmp(opname, "Estimate")) -// opval= options->estimate; - opval= (int)table->s->max_rows; - else if (!stricmp(opname, "Avglen")) - opval= (int)table->s->avg_row_length; else if (!stricmp(opname, "Multiple")) opval= options->multiple; else if (!stricmp(opname, "Header")) diff --git a/storage/connect/mysql-test/connect/r/part_file.result b/storage/connect/mysql-test/connect/r/part_file.result index 55f7c44fdfc..15f60cfc488 100644 --- a/storage/connect/mysql-test/connect/r/part_file.result +++ b/storage/connect/mysql-test/connect/r/part_file.result @@ -10,7 +10,7 @@ ftype CHAR(8) NOT NULL FLAG=3 CREATE TABLE t1 ( id INT NOT NULL, msg VARCHAR(32) -) ENGINE=CONNECT TABLE_TYPE=CSV +) ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=8 PARTITION BY RANGE(id) ( PARTITION first VALUES LESS THAN(10), PARTITION middle VALUES LESS THAN(50), @@ -33,14 +33,14 @@ id msg 81 eighty one EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id > 50; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 last ALL NULL NULL NULL NULL 23 Using where +1 SIMPLE t1 last ALL NULL NULL NULL NULL 4 Using where SELECT * FROM t1 WHERE id > 50; id msg 60 sixty 81 eighty one SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 CONNECT 10 Dynamic 7 9 69 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned `TABLE_TYPE`=CSV +t1 CONNECT 10 Dynamic 7 10 76 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL avg_row_length=8 partitioned `TABLE_TYPE`=CSV UPDATE t1 set id = 41 WHERE msg = 'four'; ERROR HY000: Got error 174 'Cannot update column id because it is used for partitioning' from CONNECT UPDATE t1 set msg = 'quatre' WHERE id = 4; @@ -69,7 +69,7 @@ t1#P#last .csv t1#P#middle .csv EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id=10; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 first ALL NULL NULL NULL NULL 24 Using where +1 SIMPLE t1 first ALL NULL NULL NULL NULL 4 Using where SELECT * FROM t1 WHERE id=10; id msg 10 ten diff --git a/storage/connect/mysql-test/connect/r/part_table.result b/storage/connect/mysql-test/connect/r/part_table.result index 9c191a8362d..dae7eb7b5b1 100644 --- a/storage/connect/mysql-test/connect/r/part_table.result +++ b/storage/connect/mysql-test/connect/r/part_table.result @@ -91,7 +91,7 @@ id msg EXPLAIN PARTITIONS SELECT * FROM t1 WHERE id = 81; id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 3 ALL NULL NULL NULL NULL 38 Using where +1 SIMPLE t1 3 ALL NULL NULL NULL NULL 14 Using where DELETE FROM t1; Warnings: Note 1105 xt1: 4 affected rows diff --git a/storage/connect/mysql-test/connect/t/part_file.test b/storage/connect/mysql-test/connect/t/part_file.test index 356be7d35b9..9ed6bb950c3 100644 --- a/storage/connect/mysql-test/connect/t/part_file.test +++ b/storage/connect/mysql-test/connect/t/part_file.test @@ -14,7 +14,7 @@ CREATE TABLE dr1 ( CREATE TABLE t1 ( id INT NOT NULL, msg VARCHAR(32) -) ENGINE=CONNECT TABLE_TYPE=CSV +) ENGINE=CONNECT TABLE_TYPE=CSV AVG_ROW_LENGTH=8 PARTITION BY RANGE(id) ( PARTITION first VALUES LESS THAN(10), PARTITION middle VALUES LESS THAN(50), diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp index bb532a141cf..d1ef94c6000 100644 --- a/storage/connect/tabdos.cpp +++ b/storage/connect/tabdos.cpp @@ -1894,30 +1894,25 @@ int TDBDOS::GetMaxSize(PGLOBAL g) int len = GetFileLength(g); if (len >= 0) { + int rec; + if (trace) - htrc("Estimating lines len=%d ending=%d\n", + htrc("Estimating lines len=%d ending=%d/n", len, ((PDOSDEF)To_Def)->Ending); /*****************************************************************/ /* Estimate the number of lines in the table (if not known) by */ - /* dividing the file length by the minimum line length assuming */ - /* only the last column can be of variable length. This will be */ - /* a ceiling estimate (as last column is never totally absent). */ + /* dividing the file length by average record length. */ /*****************************************************************/ - int rec = ((PDOSDEF)To_Def)->Ending; // +2: CRLF +1: LF - - if (AvgLen <= 0) // No given average estimate - rec += EstimatedLength(g); - else // A lower estimate was given for the average record length - rec += (int)AvgLen; - - if (trace) - htrc(" Filen=%d min_rec=%d\n", len, rec); + if (AvgLen <= 0) // No given average estimate + rec = EstimatedLength(g) + ((PDOSDEF)To_Def)->Ending; + else // An estimate was given for the average record length + rec = (int)AvgLen; // Including line ending MaxSize = (len + rec - 1) / rec; if (trace) - htrc(" Estimated max_K=%d\n", MaxSize); + htrc("avglen=%d MaxSize%d\n", rec, MaxSize); } // endif len diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp index 5a944db1948..c015b6adad3 100644 --- a/storage/connect/tabfmt.cpp +++ b/storage/connect/tabfmt.cpp @@ -590,22 +590,17 @@ bool TDBCSV::CheckErr(void) /***********************************************************************/ int TDBCSV::EstimatedLength(PGLOBAL g) { + int n = 0; + PCOLDEF cdp; + if (trace) htrc("EstimatedLength: Fields=%d Columns=%p\n", Fields, Columns); - if (!Fields) { - PCSVCOL colp; + for (cdp = To_Def->GetCols(); cdp; cdp = cdp->GetNext()) + if (!cdp->IsSpecial() && !cdp->IsVirtual()) // A true column + n++; - for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next) - if (!colp->IsSpecial() && !colp->IsVirtual()) // A true column - Fields = MY_MAX(Fields, (int)colp->Fldnum); - - if (Columns) - Fields++; // Fldnum was 0 based - - } // endif Fields - - return (int)Fields; // Number of separators if all fields are null + return --n; // Number of separators if all fields are null } // end of Estimated Length #if 0 diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp index 0d0b17c3dcc..6c7c58152b3 100644 --- a/storage/connect/tabmysql.cpp +++ b/storage/connect/tabmysql.cpp @@ -653,7 +653,7 @@ int TDBMYSQL::MakeCommand(PGLOBAL g) // Make a lower case copy of the originale query - qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1); + qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 5); strlwr(strcpy(qrystr, Qrystr)); // Check whether the table name is equal to a keyword @@ -673,6 +673,7 @@ int TDBMYSQL::MakeCommand(PGLOBAL g) strcat(Query, Tabname); strcat(Query, Qrystr + (p - qrystr) + strlen(name)); + strlwr(strcpy(qrystr, Query)); } else { sprintf(g->Message, "Cannot use this %s command", (Mode == MODE_UPDATE) ? "UPDATE" : "DELETE"); @@ -1035,7 +1036,8 @@ bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const void *key, int len) { int oldlen = strlen(Query); - if (!key || op == OP_NEXT) + if (!key || op == OP_NEXT || + Mode == MODE_UPDATE || Mode == MODE_DELETE) return false; else if (op == OP_FIRST) { if (To_CondFil) @@ -1054,7 +1056,7 @@ bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const void *key, int len) m_Rc = Myc.ExecSQL(g, Query); Query[oldlen] = 0; - return false; + return (m_Rc == RC_FX) ? true : false; } // end of ReadKey /***********************************************************************/