From ab9ecae47b4515b416167220f5da26f7fa28917d Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 11 Nov 2008 13:10:51 +0400 Subject: [PATCH 01/13] BUG#38842 - Fix for 25951 seems incorrect With fix for bug 25951 index hints are ignored for fulltext searches, as handling of fulltext indexes is different from handling regular indexes. Meaning it is not possible to implement true index hints support for fulltext indexes within the scope of current fulltext architecture. The problem is that prior to fix for bug 25951, some useful index hints still could be given for boolean mode searches. This patch implements special index hints support for fulltext indexes with the following characteristics: - all index hints are still ignored for NLQ mode searches - it cannot work without an index; - for 5.1 and up index hints FOR ORDER BY and FOR GROUP BY are still ignored for fulltext indexes; - boolean mode searches honor USE/FORCE/IGNORE INDEX hints; - as opposed to index hints for regular indexes, index hints for fulltext BOOLEAN mode searches affect the usage of the index for the whole query. mysql-test/r/fulltext.result: A test case for BUG#38842. mysql-test/t/fulltext.test: A test case for BUG#38842. sql/item_func.cc: For boolean mode searches, which can work without fulltext index, use keys_in_use_for_query bitmap instead of keys_in_use. The effect is that boolean mode searches now honor index hints. --- mysql-test/r/fulltext.result | 28 ++++++++++++++++++++++++++++ mysql-test/t/fulltext.test | 27 +++++++++++++++++++++++++++ sql/item_func.cc | 4 +++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 29fb430bb97..e73f8af405c 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -469,3 +469,31 @@ SELECT * FROM t1 WHERE MATCH(a) AGAINST ('"aaaa"' IN BOOLEAN MODE); a aaaaa aaaa DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(255), b INT, FULLTEXT(a), KEY(b)); +INSERT INTO t1 VALUES('test', 1),('test', 1),('test', 1),('test', 1), +('test', 1),('test', 2),('test', 3),('test', 4); +EXPLAIN SELECT * FROM t1 +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext b,a a 0 1 Using where +EXPLAIN SELECT * FROM t1 USE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext a a 0 1 Using where +EXPLAIN SELECT * FROM t1 FORCE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext a a 0 1 Using where +EXPLAIN SELECT * FROM t1 IGNORE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref b b 5 const 4 Using where +EXPLAIN SELECT * FROM t1 USE INDEX(b) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref b b 5 const 4 Using where +EXPLAIN SELECT * FROM t1 FORCE INDEX(b) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref b b 5 const 4 Using where +DROP TABLE t1; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index e5f1db14b7f..fa087d89efb 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -396,3 +396,30 @@ SELECT * FROM t1 WHERE MATCH(a) AGAINST ('"aaaa"' IN BOOLEAN MODE); DROP TABLE t1; # End of 4.1 tests + +# +# BUG#38842 - Fix for 25951 seems incorrect +# +CREATE TABLE t1 (a VARCHAR(255), b INT, FULLTEXT(a), KEY(b)); +INSERT INTO t1 VALUES('test', 1),('test', 1),('test', 1),('test', 1), + ('test', 1),('test', 2),('test', 3),('test', 4); + +EXPLAIN SELECT * FROM t1 +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 USE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 FORCE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 IGNORE INDEX(a) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 USE INDEX(b) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +EXPLAIN SELECT * FROM t1 FORCE INDEX(b) +WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1; + +DROP TABLE t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index e663e1fcf83..66fbf1eb4d2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5022,7 +5022,9 @@ bool Item_func_match::fix_index() for (keynr=0 ; keynr < table->s->keys ; keynr++) { if ((table->key_info[keynr].flags & HA_FULLTEXT) && - (table->s->keys_in_use.is_set(keynr))) + (flags & FT_BOOL ? table->keys_in_use_for_query.is_set(keynr) : + table->s->keys_in_use.is_set(keynr))) + { ft_to_key[fts]=keynr; ft_cnt[fts]=0; From c049fc6bd62f9ef3b836a04be49ddc0fd0e4edc0 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 13 Nov 2008 17:06:48 +0400 Subject: [PATCH 02/13] Bug#39541 CHECK TABLE on information_schema myisam tables produces error issue 'The storage engine for the table doesn't support check' note for I_S tables mysql-test/r/mysqlcheck.result: test result mysql-test/t/mysqlcheck.test: test case sql/sql_table.cc: issue 'The storage engine for the table doesn't support check' note for I_S tables --- mysql-test/r/mysqlcheck.result | 6 ++++++ mysql-test/t/mysqlcheck.test | 7 +++++++ sql/sql_table.cc | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index 8d7a2d41649..89f853e88f7 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -57,4 +57,10 @@ drop view v_bug25347; drop table t_bug25347; drop database d_bug25347; use test; +create view v1 as select * from information_schema.routines; +check table v1, information_schema.routines; +Table Op Msg_type Msg_text +test.v1 check status OK +information_schema.routines check note The storage engine for the table doesn't support check +drop view v1; End of 5.0 tests diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index 8d5e1a1c4c5..09ca98d01ad 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -58,4 +58,11 @@ drop table t_bug25347; drop database d_bug25347; use test; +# +# Bug#39541 CHECK TABLE on information_schema myisam tables produces error +# +create view v1 as select * from information_schema.routines; +check table v1, information_schema.routines; +drop view v1; + --echo End of 5.0 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 1724513eb8f..8baeca9ccf7 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2322,6 +2322,12 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, goto send_result; } + if (table->schema_table) + { + result_code= HA_ADMIN_NOT_IMPLEMENTED; + goto send_result; + } + if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify) { char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE]; From f5583481e3439a74e22170eab631755cc094c32c Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Thu, 13 Nov 2008 16:01:01 -0500 Subject: [PATCH 03/13] Bug#40645 Test main.federated_innodb does not always clean up after itself Reordered include files so that no mess will be left if this test is run without InnoDB Previously, this test would leave a database named 'federated' in such a case and would cause tests that examined existing databases to fail. --- mysql-test/t/federated_innodb.test | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mysql-test/t/federated_innodb.test b/mysql-test/t/federated_innodb.test index 772e37a2929..0617cb15d97 100644 --- a/mysql-test/t/federated_innodb.test +++ b/mysql-test/t/federated_innodb.test @@ -1,5 +1,10 @@ -source include/federated.inc; +# NOTE: Keep any include/ files that will kill / skip a test BEFORE any others +# having federated.inc before have_innodb.inc allows for an orphaned database +# that can cause other tests to fail. +# See Bug #40645 Test main.federated_innodb does not always clean up after itself + source include/have_innodb.inc; +source include/federated.inc; # # Bug#25513 Federated transaction failures From e3de8d361efbe43d505665ddc959fef77400ca8a Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 14 Nov 2008 11:40:46 +0400 Subject: [PATCH 04/13] Fix for bug#37527: mysqlcheck fails to report entire database when InnoDB frm file corruption Problem: mysqlcheck runs 'SHOW FULL TABLE' queries to get table lists. The query may fail for some reasons (e.g. null .frm file) then mysqlcheck doesn't process the database tables. Fix: try to run 'SHOW TABLES' if 'SHOW FULL TABLES' failed. client/mysqlcheck.c: Fix for bug#37527: mysqlcheck fails to report entire database when InnoDB frm file corruption - run "SHOW TABLES" query if "SHOW /*!50002 FULL*/ TABLES" failed; - print error info if both failed. mysql-test/r/mysqlcheck.result: Fix for bug#37527: mysqlcheck fails to report entire database when InnoDB frm file corruption - test result. mysql-test/t/mysqlcheck.test: Fix for bug#37527: mysqlcheck fails to report entire database when InnoDB frm file corruption - test case. --- client/mysqlcheck.c | 9 +++++++-- mysql-test/r/mysqlcheck.result | 7 +++++++ mysql-test/t/mysqlcheck.test | 20 ++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 473e172adf9..513d1974ed0 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -488,9 +488,14 @@ static int process_all_tables_in_db(char *database) LINT_INIT(res); if (use_db(database)) return 1; - if (mysql_query(sock, "SHOW /*!50002 FULL*/ TABLES") || - !((res= mysql_store_result(sock)))) + if ((mysql_query(sock, "SHOW /*!50002 FULL*/ TABLES") && + mysql_query(sock, "SHOW TABLES")) || + !(res= mysql_store_result(sock))) + { + my_printf_error(0, "Error: Couldn't get table list for database %s: %s", + MYF(0), database, mysql_error(sock)); return 1; + } num_columns= mysql_num_fields(res); diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index 89f853e88f7..f8dad6a7769 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -63,4 +63,11 @@ Table Op Msg_type Msg_text test.v1 check status OK information_schema.routines check note The storage engine for the table doesn't support check drop view v1; +CREATE TABLE t1(a INT); +CREATE TABLE t2(a INT); +test.t1 +Error : Incorrect information in file: './test/t1.frm' +error : Corrupt +test.t2 OK +DROP TABLE t1, t2; End of 5.0 tests diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index 09ca98d01ad..91006d280a8 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -65,4 +65,24 @@ create view v1 as select * from information_schema.routines; check table v1, information_schema.routines; drop view v1; + +# +# Bug#37527: mysqlcheck fails to report entire database +# when frm file corruption +# +CREATE TABLE t1(a INT); +CREATE TABLE t2(a INT); +# backup then null t1.frm +--copy_file $MYSQLTEST_VARDIR/master-data/test/t1.frm $MYSQLTEST_VARDIR/master-data/test/t1.frm.bak +--remove_file $MYSQLTEST_VARDIR/master-data/test/t1.frm +--write_file $MYSQLTEST_VARDIR/master-data/test/t1.frm +EOF +--exec $MYSQL_CHECK test +# restore t1.frm +--remove_file $MYSQLTEST_VARDIR/master-data/test/t1.frm +--copy_file $MYSQLTEST_VARDIR/master-data/test/t1.frm.bak $MYSQLTEST_VARDIR/master-data/test/t1.frm +--remove_file $MYSQLTEST_VARDIR/master-data/test/t1.frm.bak +DROP TABLE t1, t2; + + --echo End of 5.0 tests From dbc062bf2c5fe8a38151e72eb7a3c110da6d856b Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 14 Nov 2008 11:42:29 +0400 Subject: [PATCH 05/13] Test case for bug #34774: key prefix on text field in federated tables can cause server to crash! The bug will be fixed by patch for #34779: "crash in checksum table on federated tables with blobs containing nulls" Only a test case commited. mysql-test/r/federated.result: Test case for bug #34774: key prefix on text field in federated tables can cause server to crash! - test result. mysql-test/t/federated.test: Test case for bug #34774: key prefix on text field in federated tables can cause server to crash! - test case. --- mysql-test/r/federated.result | 9 +++++++++ mysql-test/t/federated.test | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result index 45b615864ac..f0de3e9b04a 100644 --- a/mysql-test/r/federated.result +++ b/mysql-test/r/federated.result @@ -2085,6 +2085,15 @@ Table Checksum test.t1 2465757603 DROP TABLE t1; DROP TABLE t1; +CREATE TABLE t1 (a TEXT, b TEXT, KEY(b(1))); +INSERT INTO t1 VALUES (NULL, NULL), (NULL, NULL), (NULL, NULL), (NULL, NULL); +CREATE TABLE t1 +(a TEXT, b TEXT, KEY(b(1))) ENGINE=FEDERATED +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1'; +SELECT t1.a FROM t1, t1 as t2 WHERE t2.b NOT LIKE t1.b; +a +DROP TABLE t1; +DROP TABLE t1; End of 5.0 tests SET @@GLOBAL.CONCURRENT_INSERT= @OLD_MASTER_CONCURRENT_INSERT; SET @@GLOBAL.CONCURRENT_INSERT= @OLD_SLAVE_CONCURRENT_INSERT; diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test index 8bbb87ccd9c..c977cb65fa0 100644 --- a/mysql-test/t/federated.test +++ b/mysql-test/t/federated.test @@ -1824,6 +1824,25 @@ DROP TABLE t1; connection master; DROP TABLE t1; + +# +# Bug #34774 key prefix on text field in federated tables can cause +# server to crash! +# +connection slave; +CREATE TABLE t1 (a TEXT, b TEXT, KEY(b(1))); +INSERT INTO t1 VALUES (NULL, NULL), (NULL, NULL), (NULL, NULL), (NULL, NULL); +connection master; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 + (a TEXT, b TEXT, KEY(b(1))) ENGINE=FEDERATED + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; +SELECT t1.a FROM t1, t1 as t2 WHERE t2.b NOT LIKE t1.b; +connection slave; +DROP TABLE t1; +connection master; +DROP TABLE t1; + connection default; --echo End of 5.0 tests From 56b9586fd1d94ebd70662417a1d2ac1921da4ad2 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Fri, 14 Nov 2008 21:25:57 +0400 Subject: [PATCH 06/13] Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade Obsolete arc/ directory and view .frm file backup support has been removed by the patch for bug 17823. However, that bugfix caused a problem with "live downgrades" of the server: if we rename some view 4 times under 5.1.29/5.0.72 and then try to rename it under 5.1.28/5.0.70 on the same database, the server fails with a error: query 'RENAME TABLE ... TO ...' failed: 6: Error on delete of '....frm-0001' (Errcode: 2) Also .frm file of that view may be lost (renamed to .frm~). The server failed because it tried to rename latest 3 backup .frm files renaming the view: the server used an integer value of the "revision" field of .frm file to extract those file names. After the fix for bug 17823 those files were not created/maintained any more, however the "revision" field was incremented as usual. So, the server failed renaming non existent files. This fix solves the problem by removing the support for "revision" .frm file field: 1. New server silently ignores existent "revision" fields in old .frm files and never write it down; 2. Old server assumes, that missing "revision" field in new .frm files means default value of 0. 3. Accordingly to the fix for bug 17823 the new server drops arc/ directory on alter/rename view, so after "live downgrade" old server begins maintenance of the arc/ directory from scratch without conflicts with .frm files. sql/parse_file.cc: Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade 1. static write_parameter(): the old_version parameter and the section for FILE_OPTIONS_REV have been re moved. 2. write_parameter(): the max_versions parameter has been removed; 3. sql_create_definition_file(): removal of dead code; 4. rename_in_schema_file(): revision and num_view_backups parameters and dead code have been removed; 5. File_parser::parse(): FILE_OPTIONS_REV section has been removed. sql/parse_file.h: Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade 1. The FILE_OPTIONS_REV constant has been removed. 2. sql_create_definition_file and rename_in_schema_file functions: obsolete versions, revision and num_view_backups parameters have been removed. sql/sql_db.cc: Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade Commentary update. sql/sql_trigger.cc: Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade sql_create_definition_file() calls have been updates to new parameter lists. sql/sql_view.cc: Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade 1. The mysql_create_view function code is used for both CREATE VIEW and ALTER queries, but query cache is necessary for ALTER command only. Check for a non first view revision has been replaced with a direct check for ALTER query. 2. The num_view_backups global constant has been removed. 3. view_parameters: the "revision" .frm field support has been removed. 4. sql_create_definition_file and rename_in_schema_file function calls have been updates to new parameter lists. sql/table.h: Bug #40021: Renaming view fails, archived .frm for view is missing after downgrade TABLE_LIST: the revision field has been removed. --- sql/parse_file.cc | 93 ++-------------------------------------------- sql/parse_file.h | 6 +-- sql/sql_db.cc | 2 - sql/sql_trigger.cc | 8 ++-- sql/sql_view.cc | 33 ++++------------ sql/table.h | 1 - 6 files changed, 17 insertions(+), 126 deletions(-) diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 2b947fcac4f..ade0709cf0d 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -88,7 +88,6 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s) file pointer to IO_CACHE structure for writing base pointer to data structure parameter pointer to parameter descriptor - old_version for returning back old version number value RETURN FALSE - OK @@ -96,8 +95,7 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s) */ static my_bool -write_parameter(IO_CACHE *file, gptr base, File_option *parameter, - ulonglong *old_version) +write_parameter(IO_CACHE *file, gptr base, File_option *parameter) { char num_buf[20]; // buffer for numeric operations // string for numeric operations @@ -125,15 +123,6 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter, DBUG_RETURN(TRUE); break; } - case FILE_OPTIONS_REV: - { - ulonglong *val_i= (ulonglong *)(base + parameter->offset); - *old_version= (*val_i)++; - num.set(*val_i, &my_charset_bin); - if (my_b_append(file, (const byte *)num.ptr(), num.length())) - DBUG_RETURN(TRUE); - break; - } case FILE_OPTIONS_TIMESTAMP: { /* string have to be allocated already */ @@ -205,7 +194,6 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter, base base address for parameter reading (structure like TABLE) parameters parameters description - max_versions number of versions to save RETURN FALSE - OK @@ -215,13 +203,11 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter, my_bool sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, const LEX_STRING *type, - gptr base, File_option *parameters, - uint max_versions) + gptr base, File_option *parameters) { File handler; IO_CACHE file; char path[FN_REFLEN+1]; // +1 to put temporary file name for sure - ulonglong old_version= ULONGLONG_MAX; int path_end; File_option *param; DBUG_ENTER("sql_create_definition_file"); @@ -255,7 +241,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, if (my_b_append(&file, (const byte *)param->name.str, param->name.length) || my_b_append(&file, (const byte *)STRING_WITH_LEN("=")) || - write_parameter(&file, base, param, &old_version) || + write_parameter(&file, base, param) || my_b_append(&file, (const byte *)STRING_WITH_LEN("\n"))) goto err_w_cache; } @@ -269,55 +255,6 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, } path[path_end]='\0'; -#ifdef FRM_ARCHIVE - // archive copies management: disabled unused feature (see bug #17823). - if (!access(path, F_OK)) - { - if (old_version != ULONGLONG_MAX && max_versions != 0) - { - // save backup - char path_arc[FN_REFLEN]; - // backup old version - char path_to[FN_REFLEN]; - - // check archive directory existence - fn_format(path_arc, "arc", dir->str, "", MY_UNPACK_FILENAME); - if (access(path_arc, F_OK)) - { - if (my_mkdir(path_arc, 0777, MYF(MY_WME))) - { - DBUG_RETURN(TRUE); - } - } - - my_snprintf(path_to, FN_REFLEN, "%s/%s-%04lu", - path_arc, file_name->str, (ulong) old_version); - if (my_rename(path, path_to, MYF(MY_WME))) - { - DBUG_RETURN(TRUE); - } - - // remove very old version - if (old_version > max_versions) - { - my_snprintf(path_to, FN_REFLEN, "%s/%s-%04lu", - path_arc, file_name->str, - (ulong)(old_version - max_versions)); - if (!access(path_arc, F_OK) && my_delete(path_to, MYF(MY_WME))) - { - DBUG_RETURN(TRUE); - } - } - } - else - { - if (my_delete(path, MYF(MY_WME))) // no backups - { - DBUG_RETURN(TRUE); - } - } - } -#endif//FRM_ARCHIVE { // rename temporary file @@ -346,8 +283,6 @@ err_w_file: schema name of given schema old_name original file name new_name new file name - revision revision number - num_view_backups number of backups RETURN 0 - OK @@ -356,8 +291,7 @@ err_w_file: */ my_bool rename_in_schema_file(THD *thd, const char *schema, const char *old_name, - const char *new_name, ulonglong revision, - uint num_view_backups) + const char *new_name) { char old_path[FN_REFLEN], new_path[FN_REFLEN], arc_path[FN_REFLEN]; @@ -376,23 +310,6 @@ my_bool rename_in_schema_file(THD *thd, strxnmov(arc_path, FN_REFLEN, mysql_data_home, "/", schema, "/arc", NullS); (void) unpack_filename(arc_path, arc_path); -#ifdef FRM_ARCHIVE - if (revision > 0 && !access(arc_path, F_OK)) - { - ulonglong limit= ((revision > num_view_backups) ? - revision - num_view_backups : 0); - for (; revision > limit ; revision--) - { - my_snprintf(old_path, FN_REFLEN, "%s/%s%s-%04lu", - arc_path, old_name, reg_ext, (ulong)revision); - (void) unpack_filename(old_path, old_path); - my_snprintf(new_path, FN_REFLEN, "%s/%s%s-%04lu", - arc_path, new_name, reg_ext, (ulong)revision); - (void) unpack_filename(new_path, new_path); - my_rename(old_path, new_path, MYF(0)); - } - } -#else//FRM_ARCHIVE { // remove obsolete 'arc' directory and files if any MY_DIR *new_dirp; if ((new_dirp = my_dir(arc_path, MYF(MY_DONT_SORT)))) @@ -401,7 +318,6 @@ my_bool rename_in_schema_file(THD *thd, (void) mysql_rm_arc_files(thd, new_dirp, arc_path); } } -#endif//FRM_ARCHIVE return 0; } @@ -838,7 +754,6 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, break; } case FILE_OPTIONS_ULONGLONG: - case FILE_OPTIONS_REV: if (!(eol= strchr(ptr, '\n'))) { my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), diff --git a/sql/parse_file.h b/sql/parse_file.h index ec920b58667..ad7d1629e0a 100644 --- a/sql/parse_file.h +++ b/sql/parse_file.h @@ -23,7 +23,6 @@ enum file_opt_type { FILE_OPTIONS_STRING, /* String (LEX_STRING) */ FILE_OPTIONS_ESTRING, /* Escaped string (LEX_STRING) */ FILE_OPTIONS_ULONGLONG, /* ulonglong parameter (ulonglong) */ - FILE_OPTIONS_REV, /* Revision version number (ulonglong) */ FILE_OPTIONS_TIMESTAMP, /* timestamp (LEX_STRING have to be allocated with length 20 (19+1) */ FILE_OPTIONS_STRLIST, /* list of escaped strings @@ -81,11 +80,10 @@ File_parser *sql_parse_prepare(const LEX_STRING *file_name, my_bool sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, const LEX_STRING *type, - gptr base, File_option *parameters, uint versions); + gptr base, File_option *parameters); my_bool rename_in_schema_file(THD *thd, const char *schema, const char *old_name, - const char *new_name, ulonglong revision, - uint num_view_backups); + const char *new_name); class File_parser: public Sql_alloc { diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 8fbb407555a..c3cf7429222 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -909,7 +909,6 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, /* .frm archive: Those archives are obsolete, but following code should exist to remove existent "arc" directories. - See #ifdef FRM_ARCHIVE directives for obsolete code. */ char newpath[FN_REFLEN]; MY_DIR *new_dirp; @@ -1069,7 +1068,6 @@ static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error) NOTE A support of "arc" directories is obsolete, however this function should exist to remove existent "arc" directories. - See #ifdef FRM_ARCHIVE directives for obsolete code. */ long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path) { diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index bead50e1da8..d3b5289cd68 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -479,7 +479,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, trigname.trigger_table.length= tables->table_name_length; if (sql_create_definition_file(&dir, &trigname_file, &trigname_file_type, - (gptr)&trigname, trigname_file_parameters, 0)) + (gptr)&trigname, trigname_file_parameters)) return 1; /* @@ -569,7 +569,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, /* Create trigger definition file. */ if (!sql_create_definition_file(&dir, &file, &triggers_file_type, - (gptr)this, triggers_file_parameters, 0)) + (gptr)this, triggers_file_parameters)) return 0; err_with_cleanup: @@ -656,7 +656,7 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db, file.str= file_buff; return sql_create_definition_file(&dir, &file, &triggers_file_type, - (gptr)triggers, triggers_file_parameters, 0); + (gptr)triggers, triggers_file_parameters); } @@ -1427,7 +1427,7 @@ Table_triggers_list::change_table_name_in_trignames(const char *db_name, trigname.trigger_table= *new_table_name; if (sql_create_definition_file(&dir, &trigname_file, &trigname_file_type, - (gptr)&trigname, trigname_file_parameters, 0)) + (gptr)&trigname, trigname_file_parameters)) return trigger; } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 8e6d3ed583a..f65a62bed75 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -660,7 +660,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, } VOID(pthread_mutex_unlock(&LOCK_open)); - if (view->revision != 1) + if (mode != VIEW_CREATE_NEW) query_cache_invalidate3(thd, view, 0); start_waiting_global_read_lock(thd); if (res) @@ -678,12 +678,8 @@ err: } -/* index of revision number in following table */ -static const int revision_number_position= 8; -/* index of last required parameter for making view */ -static const int required_view_parameters= 10; -/* number of backups */ -static const int num_view_backups= 3; +/* number of required parameters for making view */ +static const int required_view_parameters= 9; /* table of VIEW .frm field descriptors @@ -716,9 +712,6 @@ static File_option view_parameters[]= {{(char*) STRING_WITH_LEN("with_check_option")}, my_offsetof(TABLE_LIST, with_check), FILE_OPTIONS_ULONGLONG}, - {{(char*) STRING_WITH_LEN("revision")}, - my_offsetof(TABLE_LIST, revision), - FILE_OPTIONS_REV}, {{(char*) STRING_WITH_LEN("timestamp")}, my_offsetof(TABLE_LIST, timestamp), FILE_OPTIONS_TIMESTAMP}, @@ -880,18 +873,9 @@ loop_out: } /* - read revision number - TODO: read dependence list, too, to process cascade/restrict TODO: special cascade/restrict procedure for alter? */ - if (parser->parse((gptr)view, thd->mem_root, - view_parameters + revision_number_position, 1, - &file_parser_dummy_hook)) - { - error= thd->net.report_error? -1 : 0; - goto err; - } } else { @@ -933,7 +917,7 @@ loop_out: } if (sql_create_definition_file(&dir, &file, view_file_type, - (gptr)view, view_parameters, num_view_backups)) + (gptr)view, view_parameters)) { error= thd->net.report_error? -1 : 1; goto err; @@ -1868,8 +1852,7 @@ mysql_rename_view(THD *thd, goto err; /* rename view and it's backups */ - if (rename_in_schema_file(thd, view->db, view->table_name, new_name, - view_def.revision - 1, num_view_backups)) + if (rename_in_schema_file(thd, view->db, view->table_name, new_name)) goto err; strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", view->db, "/", NullS); @@ -1883,12 +1866,10 @@ mysql_rename_view(THD *thd, - file_buff); if (sql_create_definition_file(&pathstr, &file, view_file_type, - (gptr)&view_def, view_parameters, - num_view_backups)) + (gptr)&view_def, view_parameters)) { /* restore renamed view in case of error */ - rename_in_schema_file(thd, view->db, new_name, view->table_name, - view_def.revision - 1, num_view_backups); + rename_in_schema_file(thd, view->db, new_name, view->table_name); goto err; } } else diff --git a/sql/table.h b/sql/table.h index 08326e2fbe0..0884f5ba3d2 100644 --- a/sql/table.h +++ b/sql/table.h @@ -657,7 +657,6 @@ struct TABLE_LIST st_lex_user definer; /* definer of view */ ulonglong file_version; /* version of file's field set */ ulonglong updatable_view; /* VIEW can be updated */ - ulonglong revision; /* revision control number */ ulonglong algorithm; /* 0 any, 1 tmp tables , 2 merging */ ulonglong view_suid; /* view is suid (TRUE dy default) */ ulonglong with_check; /* WITH CHECK OPTION */ From 88a88636271aee2b89000a99c18d551813f0dcc5 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Mon, 17 Nov 2008 19:41:09 +0400 Subject: [PATCH 07/13] Bug#31616 div_precision_increment description looks wrong Item_func_div didn't calculate the precision of the result properly. The result of 5/0.0001 is 5000 so we have to add decimals of the divisor to the planned precision. per-file comments: mysql-test/r/type_newdecimal.result Bug#31616 div_precision_increment description looks wrong test result fixed mysql-test/t/type_newdecimal.test Bug#31616 div_precision_increment description looks wrong test case sql/item_func.cc Bug#31616 div_precision_increment description looks wrong precision must be increased with args[1]->decimals parameter --- mysql-test/r/type_newdecimal.result | 15 +++++++++++++++ mysql-test/t/type_newdecimal.test | 10 ++++++++++ sql/item_func.cc | 6 ++++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index 1bb07534a7f..90b6f524692 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -1524,4 +1524,19 @@ select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 * (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 * 1.01500000 * 1.01500000 * 0.99500000) 0.812988073953673124592306939480 +create table t1 as select 5.05 / 0.014; +Warnings: +Note 1265 Data truncated for column '5.05 / 0.014' at row 1 +show warnings; +Level Code Message +Note 1265 Data truncated for column '5.05 / 0.014' at row 1 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `5.05 / 0.014` decimal(10,6) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select * from t1; +5.05 / 0.014 +360.714286 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index c44abdb144e..a5331582df6 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -1225,4 +1225,14 @@ DROP TABLE t1; select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 * 1.01500000 * 1.01500000 * 0.99500000); +# +# Bug #31616 div_precision_increment description looks wrong +# + +create table t1 as select 5.05 / 0.014; +show warnings; +show create table t1; +select * from t1; +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index e663e1fcf83..dfe1082fd73 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1316,8 +1316,10 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value) void Item_func_div::result_precision() { - uint arg_prec= args[0]->decimal_precision() + prec_increment; - uint precision=min(arg_prec, DECIMAL_MAX_PRECISION); + uint precision=min(args[0]->decimal_precision() + + args[1]->decimals + prec_increment, + DECIMAL_MAX_PRECISION); + /* Integer operations keep unsigned_flag if one of arguments is unsigned */ if (result_type() == INT_RESULT) unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag; From 1cd8b9f700a3d20e0af43896b366cef6ef0e7d4c Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Thu, 20 Nov 2008 14:08:36 +0400 Subject: [PATCH 08/13] Fix for bug#40875: Memory leak in FEDERATED handler Problem: memory leak occurs when we open a federated table that has its share in the hash. Fix: free not used memory. Note: the fix should NOT be merged to 5.1 (the code changed). sql/ha_federated.cc: Fix for bug#40875: Memory leak in FEDERATED handler - free memory (tmp_share.scheme) allocated in the parse_url() if it isn't used anymore. --- sql/ha_federated.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index b4788dd9c87..d4144a41a2a 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -1320,6 +1320,14 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table) thr_lock_init(&share->lock); pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST); } + else + { + /* + Free tmp_share.scheme allocated in the parse_url() + as we found share in the hash and tmp_share isn't needed anymore. + */ + my_free((gptr) tmp_share.scheme, MYF(MY_ALLOW_ZERO_PTR)); + } share->use_count++; pthread_mutex_unlock(&federated_mutex); From 39efef853ba172b07c3df3869e98d4b894192acc Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 21 Nov 2008 13:48:22 +0400 Subject: [PATCH 09/13] Fix for bug#36772: When using UTF8, CONVERT with GROUP BY returns truncated results Problem: performig conversion from {INT, DECIMAL, REAL} to CHAR we incorrectly set its max length in some cases that may lead to truncated results returned. Fix: properly set CONVERT({INT, DECIMAL, REAL}, CHAR) result's max length. mysql-test/r/ctype_utf8.result: Fix for bug#36772: When using UTF8, CONVERT with GROUP BY returns truncated results - test result. mysql-test/t/ctype_utf8.test: Fix for bug#36772: When using UTF8, CONVERT with GROUP BY returns truncated results - test case. sql/item_timefunc.cc: Fix for bug#36772: When using UTF8, CONVERT with GROUP BY returns truncated results - calculating Item_char_typecast::max_length use initial argument's charset mbmaxlen instead of from_cs->mbmaxlen, as from_cs may differ in some case (see comment above). --- mysql-test/r/ctype_utf8.result | 32 ++++++++++++++++++++++++++++++++ mysql-test/t/ctype_utf8.test | 17 +++++++++++++++++ sql/item_timefunc.cc | 13 ++++++++----- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 5ca1d578d2a..a4d7ca2558f 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1813,3 +1813,35 @@ select hex(_utf8 B'001111111111'); ERROR HY000: Invalid utf8 character string: 'FF' select (_utf8 X'616263FF'); ERROR HY000: Invalid utf8 character string: 'FF' +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL); +INSERT INTO t1 VALUES (70000, 1092), (70001, 1085), (70002, 1065); +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b; +CONVERT(a, CHAR) CONVERT(b, CHAR) +70002 1065 +70001 1085 +70000 1092 +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1; +CONVERT(a, CHAR) CONVERT(b, CHAR) +70000 1092 +70001 1085 +70002 1065 +ALTER TABLE t1 ADD UNIQUE (b); +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b; +CONVERT(a, CHAR) CONVERT(b, CHAR) +70002 1065 +70001 1085 +70000 1092 +DROP INDEX b ON t1; +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b; +CONVERT(a, CHAR) CONVERT(b, CHAR) +70002 1065 +70001 1085 +70000 1092 +ALTER TABLE t1 ADD INDEX (b); +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) from t1 GROUP BY b; +CONVERT(a, CHAR) CONVERT(b, CHAR) +70002 1065 +70001 1085 +70000 1092 +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index d184200ad5a..5111660bcbe 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1437,3 +1437,20 @@ select hex(_utf8 X'616263FF'); select hex(_utf8 B'001111111111'); --error ER_INVALID_CHARACTER_STRING select (_utf8 X'616263FF'); + +# +# Bug #36772: When using UTF8, CONVERT with GROUP BY returns truncated results +# +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL); +INSERT INTO t1 VALUES (70000, 1092), (70001, 1085), (70002, 1065); +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b; +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1; +ALTER TABLE t1 ADD UNIQUE (b); +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b; +DROP INDEX b ON t1; +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b; +ALTER TABLE t1 ADD INDEX (b); +SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) from t1 GROUP BY b; +DROP TABLE t1; + +--echo End of 5.0 tests diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 0cb3c963dad..e9e92952908 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2550,6 +2550,8 @@ void Item_char_typecast::fix_length_and_dec() and thus avoid unnecessary character set conversion. - If the argument is not a number, then from_cs is set to the argument's charset. + + Note (TODO): we could use repertoire technique here. */ from_cs= (args[0]->result_type() == INT_RESULT || args[0]->result_type() == DECIMAL_RESULT || @@ -2557,12 +2559,13 @@ void Item_char_typecast::fix_length_and_dec() (cast_cs->mbminlen == 1 ? cast_cs : &my_charset_latin1) : args[0]->collation.collation; charset_conversion= (cast_cs->mbmaxlen > 1) || - !my_charset_same(from_cs, cast_cs) && - from_cs != &my_charset_bin && - cast_cs != &my_charset_bin; + (!my_charset_same(from_cs, cast_cs) && + from_cs != &my_charset_bin && + cast_cs != &my_charset_bin); collation.set(cast_cs, DERIVATION_IMPLICIT); - char_length= (cast_length >= 0) ? cast_length : - args[0]->max_length/from_cs->mbmaxlen; + char_length= (cast_length >= 0) ? + cast_length : + args[0]->max_length / args[0]->collation.collation->mbmaxlen; max_length= char_length * cast_cs->mbmaxlen; } From bd6376f1d17240956c1b1f243aaadde2611fcb56 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 21 Nov 2008 16:39:59 +0400 Subject: [PATCH 10/13] Bug#34760 Character set autodetection appears to fail the problem is the same as reported in bug#20835, so the fix is backport of bug#20835 patch. mysql-test/r/subselect.result: test result mysql-test/t/subselect.test: test case --- mysql-test/r/subselect.result | 15 +++++++++++++++ mysql-test/t/subselect.test | 19 ++++++++++++++++++- sql/item_cmpfunc.cc | 3 ++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index c5bae840214..6eeb652e3c1 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4407,4 +4407,19 @@ pk a 3 30 2 20 DROP TABLE t1,t2; +CREATE TABLE t1 (s1 char(1)); +INSERT INTO t1 VALUES ('a'); +SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1); +s1 +a +DROP TABLE t1; +CREATE TABLE t1(id BIGINT); +CREATE TABLE t2(id1 BIGINT, id2 BIGINT); +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (2,1),(3,1); +SELECT * FROM t1 i WHERE 1 IN (SELECT l.id2 FROM t2 l WHERE i.id=l.id1); +id +2 +3 +DROP TABLE t1, t2; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 2dfad2c58dd..d28e31fb545 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3307,5 +3307,22 @@ SELECT * FROM t1 WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b); DROP TABLE t1,t2; ---echo End of 5.0 tests. +# +# Bug#20835 (literal string with =any values) +# +CREATE TABLE t1 (s1 char(1)); +INSERT INTO t1 VALUES ('a'); +SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1); +DROP TABLE t1; +# +# Bug#40519 Subselect query using bigint fails +# +CREATE TABLE t1(id BIGINT); +CREATE TABLE t2(id1 BIGINT, id2 BIGINT); +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (2,1),(3,1); +SELECT * FROM t1 i WHERE 1 IN (SELECT l.id2 FROM t2 l WHERE i.id=l.id1); +DROP TABLE t1, t2; + +--echo End of 5.0 tests. diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 0410c781590..4bfae376acc 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1434,7 +1434,8 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref) } not_null_tables_cache= args[0]->not_null_tables(); with_sum_func= args[0]->with_sum_func; - const_item_cache= args[0]->const_item(); + if ((const_item_cache= args[0]->const_item())) + cache->store(args[0]); return 0; } From d795963cba42fefd57a788eb1112bfc4cc13f6d3 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 24 Nov 2008 17:30:47 +0200 Subject: [PATCH 11/13] Bug #39656: Behaviour different for agg functions with & without where - ONLY_FULL_GROUP_BY The check for non-aggregated columns in queries with aggregate function, but without GROUP BY was treating all the parts of the query as if they are in the SELECT list. Fixed by ignoring the non-aggregated fields in the WHERE clause. mysql-test/r/func_group.result: Bug #39656: test case mysql-test/t/func_group.test: Bug #39656: test case sql/sql_select.cc: Bug #39656: ignore the new non-aggregated column refs in a WHERE by saving the state so far and then adding only the new values of the other parts of the bitmask. --- mysql-test/r/func_group.result | 23 +++++++++++++++++++++++ mysql-test/t/func_group.test | 29 +++++++++++++++++++++++++++++ sql/sql_select.cc | 10 ++++++++++ 3 files changed, 62 insertions(+) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 772e432355b..a7f4c58f4af 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1425,4 +1425,27 @@ SELECT AVG(a), CAST(AVG(a) AS DECIMAL) FROM t1; AVG(a) CAST(AVG(a) AS DECIMAL) 15 15 DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,1), (1,2), (1,3); +SET SQL_MODE='ONLY_FULL_GROUP_BY'; +SELECT COUNT(*) FROM t1; +COUNT(*) +3 +SELECT COUNT(*) FROM t1 where a=1; +COUNT(*) +3 +SELECT COUNT(*),a FROM t1; +ERROR 42000: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause +SELECT COUNT(*) FROM t1 a JOIN t1 b ON a.a= b.a; +COUNT(*) +9 +SELECT COUNT(*), (SELECT count(*) FROM t1 inr WHERE inr.a = outr.a) +FROM t1 outr; +ERROR 42000: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause +SELECT COUNT(*) FROM t1 a JOIN t1 outr +ON a.a= (SELECT count(*) FROM t1 inr WHERE inr.a = outr.a); +COUNT(*) +0 +SET SQL_MODE=default; +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index dbe6d3113d5..38779ac1a2f 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -926,5 +926,34 @@ SELECT AVG(a), CAST(AVG(a) AS DECIMAL) FROM t1; DROP TABLE t1; +# +# Bug #39656: Behaviour different for agg functions with & without where - +# ONLY_FULL_GROUP_BY +# + +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,1), (1,2), (1,3); + +SET SQL_MODE='ONLY_FULL_GROUP_BY'; + +SELECT COUNT(*) FROM t1; +SELECT COUNT(*) FROM t1 where a=1; + +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS +SELECT COUNT(*),a FROM t1; + +SELECT COUNT(*) FROM t1 a JOIN t1 b ON a.a= b.a; + +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS +SELECT COUNT(*), (SELECT count(*) FROM t1 inr WHERE inr.a = outr.a) + FROM t1 outr; + +SELECT COUNT(*) FROM t1 a JOIN t1 outr + ON a.a= (SELECT count(*) FROM t1 inr WHERE inr.a = outr.a); + +SET SQL_MODE=default; +DROP TABLE t1; + + ### --echo End of 5.0 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 428d1709f94..2ac33c4e07f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -390,11 +390,21 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array, { int res; nesting_map save_allow_sum_func=thd->lex->allow_sum_func ; + /* + Need to save the value, so we can turn off only the new NON_AGG_FIELD + additions coming from the WHERE + */ + uint8 saved_flag= thd->lex->current_select->full_group_by_flag; DBUG_ENTER("setup_without_group"); thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level); res= setup_conds(thd, tables, leaves, conds); + /* it's not wrong to have non-aggregated columns in a WHERE */ + if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) + thd->lex->current_select->full_group_by_flag= saved_flag | + (thd->lex->current_select->full_group_by_flag & ~NON_AGG_FIELD_USED); + thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level; res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields, order); From 2578609322e891f78c9d2807a9533e68c36cef52 Mon Sep 17 00:00:00 2001 From: Patrick Crews Date: Mon, 24 Nov 2008 16:53:32 -0500 Subject: [PATCH 12/13] Bug#40866: mysql-test-run's check of tests provides false failures due to timestamp Altering how MTR checks global variable status to exclude timestamp Changed SQL statements to update style. --- mysql-test/include/check-testcase.test | 38 +++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test index 30cb7391f30..a9885f7b0ec 100644 --- a/mysql-test/include/check-testcase.test +++ b/mysql-test/include/check-testcase.test @@ -11,12 +11,12 @@ # # Dump all global variables # -show global variables; +SHOW GLOBAL VARIABLES WHERE variable_name != 'timestamp'; # # Dump all databases # -show databases; +SHOW DATABASES; # # Dump the "test" database, all it's tables and their data @@ -29,23 +29,23 @@ show databases; # --exec $MYSQL_DUMP --skip-comments --no-data mysql use mysql; -select * from columns_priv; -select * from db order by host, db, user; -select * from func; -select * from help_category; -select * from help_keyword; -select * from help_relation; -select * from help_relation; -select * from host; -select * from proc; -select * from procs_priv; -select * from tables_priv; -select * from time_zone; -select * from time_zone_leap_second; -select * from time_zone_name; -select * from time_zone_transition; -select * from time_zone_transition_type; -select * from user; +SELECT * FROM columns_priv; +SELECT * FROM db ORDER BY host, db, user; +SELECT * FROM func; +SELECT * FROM help_category; +SELECT * FROM help_keyword; +SELECT * FROM help_relation; +SELECT * FROM help_relation; +SELECT * FROM host; +SELECT * FROM proc; +SELECT * FROM procs_priv; +SELECT * FROM tables_priv; +SELECT * FROM time_zone; +SELECT * FROM time_zone_leap_second; +SELECT * FROM time_zone_name; +SELECT * FROM time_zone_transition; +SELECT * FROM time_zone_transition_type; +SELECT * FROM user; From df8a5474f8a904b4e254e446fd6ea61a94c98e2a Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Tue, 25 Nov 2008 10:22:02 +0400 Subject: [PATCH 13/13] Fix for bug#40984: backport fix from 39585 into 5.0 Problem: in 5.0 'check table for upgrade' doesn't detect incompatible collation changes made in 5.0.48. Fix: backport #39585 fix to 5.0 sql/handler.cc: Fix for bug#40984: backport fix from 39585 into 5.0 - backport of #39585 fix sql/handler.h: Fix for bug#40984: backport fix from 39585 into 5.0 - backport of #39585 fix --- sql/handler.cc | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ sql/handler.h | 1 + 2 files changed, 50 insertions(+) diff --git a/sql/handler.cc b/sql/handler.cc index 67ec5f3e759..71d184ad84b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1957,8 +1957,53 @@ bool handler::get_error_message(int error, String* buf) } +/** + Check for incompatible collation changes. + + @retval + HA_ADMIN_NEEDS_UPGRADE Table may have data requiring upgrade. + @retval + 0 No upgrade required. +*/ + +int handler::check_collation_compatibility() +{ + ulong mysql_version= table->s->mysql_version; + + if (mysql_version < 50048) + { + KEY *key= table->key_info; + KEY *key_end= key + table->s->keys; + for (; key < key_end; key++) + { + KEY_PART_INFO *key_part= key->key_part; + KEY_PART_INFO *key_part_end= key_part + key->key_parts; + for (; key_part < key_part_end; key_part++) + { + if (!key_part->fieldnr) + continue; + Field *field= table->field[key_part->fieldnr - 1]; + uint cs_number= field->charset()->number; + if (mysql_version < 50048 && + (cs_number == 11 || /* ascii_general_ci - bug #29499, bug #27562 */ + cs_number == 41 || /* latin7_general_ci - bug #29461 */ + cs_number == 42 || /* latin7_general_cs - bug #29461 */ + cs_number == 20 || /* latin7_estonian_cs - bug #29461 */ + cs_number == 21 || /* latin2_hungarian_ci - bug #29461 */ + cs_number == 22 || /* koi8u_general_ci - bug #29461 */ + cs_number == 23 || /* cp1251_ukrainian_ci - bug #29461 */ + cs_number == 26)) /* cp1250_general_ci - bug #29461 */ + return HA_ADMIN_NEEDS_UPGRADE; + } + } + } + return 0; +} + + int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt) { + int error; KEY *keyinfo, *keyend; KEY_PART_INFO *keypart, *keypartend; @@ -1987,6 +2032,10 @@ int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt) } if (table->s->frm_version != FRM_VER_TRUE_VARCHAR) return HA_ADMIN_NEEDS_ALTER; + + if ((error= check_collation_compatibility())) + return error; + return check_for_upgrade(check_opt); } diff --git a/sql/handler.h b/sql/handler.h index aa3377c3868..8706aae5fce 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -787,6 +787,7 @@ protected: virtual int check_for_upgrade(HA_CHECK_OPT *check_opt) { return 0; } public: + int check_collation_compatibility(); int ha_check_for_upgrade(HA_CHECK_OPT *check_opt); int check_old_types(); /* to be actually called to get 'check()' functionality*/