From b2dc376afe3a3f37ab11bfa292c1bf041fd89db1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Aug 2005 18:05:33 +0400 Subject: [PATCH 1/4] Fix bug#12266 GROUP BY DATE(LEFT(column,8)) returns result strings with reduced length. When temporary field created for DATE(LEFT(column,8)) expression, max_length value is taken from Item_date_typecast, and it is getting it from underlaid Item_func_left and it's max_length is 8 in given expression. And all this results in stripping last 2 digits. To Item_date_typecast class added its own fix_length_and_dec() function that sets max_length value to 10, which is proper for DATE field. mysql-test/t/group_by.test: Test case for bug#12266 GROUP BY DATE(LEFT(column,8)) returns result strings with reduced length. mysql-test/r/group_by.result: Test case for bug#12266 GROUP BY DATE(LEFT(column,8)) returns result strings with reduced length. sql/item_timefunc.h: Fix bug#12266 GROUP BY DATE(LEFT(column,8)) returns result strings with reduced length. To Item_date_typecast class added its own fix_length_and_dec() which sets proper max_length value. --- mysql-test/r/group_by.result | 7 +++++++ mysql-test/t/group_by.test | 10 ++++++++++ sql/item_timefunc.h | 6 ++++++ 3 files changed, 23 insertions(+) diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index 295663fe1d3..8287a042d60 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -757,3 +757,10 @@ SELECT n+1 AS n FROM t1 GROUP BY n; n 2 DROP TABLE t1; +create table t1 (f1 date); +insert into t1 values('2005-06-06'); +insert into t1 values('2005-06-06'); +select date(left(f1+0,8)) from t1 group by 1; +date(left(f1+0,8)) +2005-06-06 +drop table t1; diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index c07d309005e..815da66c717 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -590,4 +590,14 @@ INSERT INTO t1 VALUES (1); SELECT n+1 AS n FROM t1 GROUP BY n; DROP TABLE t1; +# +# Bug #12266 GROUP BY expression on DATE column produces result with +# reduced length +# +create table t1 (f1 date); +insert into t1 values('2005-06-06'); +insert into t1 values('2005-06-06'); +select date(left(f1+0,8)) from t1 group by 1; +drop table t1; + # End of 4.1 tests diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 1a30b24b7ce..0df84d14bea 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -709,6 +709,12 @@ public: { return (new Field_date(maybe_null, name, t_arg, &my_charset_bin)); } + void fix_length_and_dec() + { + collation.set(&my_charset_bin); + max_length= 10; + maybe_null= 1; + } }; From 852dcb75973a612ef5c28645018551ed7bd0055c Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 6 Aug 2005 21:08:28 +0000 Subject: [PATCH 2/4] BUG#11869 (cont'd, eliminating "table type doesn't support FULLTEXT" error): When creating temporary table for UNION, pass TMP_TABLE_FORCE_MYISAM flag to create_tmp_table if we will be using fulltext function(s) when reading from the temp. table. mysql-test/r/fulltext_order_by.result: Testcase for BUG#11869 (cont'd, eliminating "table type doesn't support FULLTEXT" error) mysql-test/t/fulltext_order_by.test: Testcase for BUG#11869 (cont'd, eliminating "table type doesn't support FULLTEXT" error) sql/mysql_priv.h: BUG#11869 (cont'd, eliminating "table type doesn't support FULLTEXT" error): Added TMP_TABLE_FORCE_MYISAM flag sql/sql_select.cc: BUG#11869 (cont'd, eliminating "table type doesn't support FULLTEXT" error): In create_tmp_table(), honor the TMP_TABLE_FORCE_MYISAM flag --- mysql-test/r/fulltext_order_by.result | 10 ++++++++++ mysql-test/t/fulltext_order_by.test | 11 +++++++++++ sql/mysql_priv.h | 6 ++++++ sql/sql_select.cc | 2 +- sql/sql_union.cc | 16 ++++++++++++---- 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/fulltext_order_by.result b/mysql-test/r/fulltext_order_by.result index 130d096e00f..5f40e43f0c0 100644 --- a/mysql-test/r/fulltext_order_by.result +++ b/mysql-test/r/fulltext_order_by.result @@ -159,4 +159,14 @@ match(c.beitrag) against ('+abc' in boolean mode) order by match(betreff) against ('+abc' in boolean mode) desc; text id betreff +(select b.id, b.betreff from t3 b) union +(select b.id, b.betreff from t3 b) +order by match(betreff) against ('+abc' in boolean mode) desc; +id betreff +select distinct b.id, b.betreff from t3 b +order by match(betreff) against ('+abc' in boolean mode) desc; +id betreff +select b.id, b.betreff from t3 b group by b.id+1 +order by match(betreff) against ('+abc' in boolean mode) desc; +id betreff drop table t1,t2,t3; diff --git a/mysql-test/t/fulltext_order_by.test b/mysql-test/t/fulltext_order_by.test index 1a70ac3880b..fec74b5dc54 100644 --- a/mysql-test/t/fulltext_order_by.test +++ b/mysql-test/t/fulltext_order_by.test @@ -133,6 +133,17 @@ where order by match(betreff) against ('+abc' in boolean mode) desc; +# BUG#11869 part2: used table type doesn't support FULLTEXT indexes error +(select b.id, b.betreff from t3 b) union +(select b.id, b.betreff from t3 b) +order by match(betreff) against ('+abc' in boolean mode) desc; + +select distinct b.id, b.betreff from t3 b +order by match(betreff) against ('+abc' in boolean mode) desc; + +select b.id, b.betreff from t3 b group by b.id+1 +order by match(betreff) against ('+abc' in boolean mode) desc; + drop table t1,t2,t3; # End of 4.1 tests diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c8a4c4740ef..0af3ea3af63 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -215,6 +215,12 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; in the user query has requested */ #define SELECT_ALL (1L << 29) +/* + Force the used temporary table to be a MyISAM table (because we will use + fulltext functions when reading from it. +*/ +#define TMP_TABLE_FORCE_MYISAM (1L << 30) + /* If set to 0, then the thread will ignore all warnings with level notes. Set by executing SET SQL_NOTES=1 */ #define OPTION_SQL_NOTES (1L << 31) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1bde62276b8..54afe5bb7a6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5290,7 +5290,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, /* If result table is small; use a heap */ if (blob_count || using_unique_constraint || (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == - OPTION_BIG_TABLES) + OPTION_BIG_TABLES ||(select_options & TMP_TABLE_FORCE_MYISAM)) { table->file=get_new_handler(table,table->db_type=DB_TYPE_MYISAM); if (group && diff --git a/sql/sql_union.cc b/sql/sql_union.cc index a54fb613fd2..eeb8dfdfef5 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -296,15 +296,23 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, goto err; } } + + ulong create_options= first_select_in_union()->options | thd_arg->options | + TMP_TABLE_ALL_COLUMNS; + /* + Force the temporary table to be a MyISAM table if we're going to use + fullext functions (MATCH ... AGAINST .. IN BOOLEAN MODE) when reading + from it. + */ + if (global_parameters->ftfunc_list->elements) + create_options= create_options | TMP_TABLE_FORCE_MYISAM; union_result->tmp_table_param.field_count= types.elements; if (!(table= create_tmp_table(thd_arg, &union_result->tmp_table_param, types, (ORDER*) 0, (bool) union_distinct, 1, - (first_select_in_union()->options | - thd_arg->options | - TMP_TABLE_ALL_COLUMNS), - HA_POS_ERROR, (char *) tmp_table_alias))) + create_options, HA_POS_ERROR, + (char *) tmp_table_alias))) goto err; table->file->extra(HA_EXTRA_WRITE_CACHE); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); From b9e04cf1efa45a717832cd2500502edb4c318858 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 7 Aug 2005 21:03:45 +0000 Subject: [PATCH 3/4] BUG#11869: part2: post-review fixes: In init_prepare_fake_select_lex() don't empty ftfunc_list. UNION's ORDER BY clause may contain MATCH(...), for which fix_index() should be called. mysql-test/r/fulltext_order_by.result: BUG#11869 part2 : added another test case mysql-test/t/fulltext_order_by.test: BUG#11869 part2 : added another test case --- mysql-test/r/fulltext_order_by.result | 4 ++++ mysql-test/t/fulltext_order_by.test | 5 +++++ sql/sql_union.cc | 5 ++--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/fulltext_order_by.result b/mysql-test/r/fulltext_order_by.result index 5f40e43f0c0..0b77153248e 100644 --- a/mysql-test/r/fulltext_order_by.result +++ b/mysql-test/r/fulltext_order_by.result @@ -163,6 +163,10 @@ text id betreff (select b.id, b.betreff from t3 b) order by match(betreff) against ('+abc' in boolean mode) desc; id betreff +(select b.id, b.betreff from t3 b) union +(select b.id, b.betreff from t3 b) +order by match(betreff) against ('+abc') desc; +ERROR HY000: Can't find FULLTEXT index matching the column list select distinct b.id, b.betreff from t3 b order by match(betreff) against ('+abc' in boolean mode) desc; id betreff diff --git a/mysql-test/t/fulltext_order_by.test b/mysql-test/t/fulltext_order_by.test index fec74b5dc54..da05fd494c4 100644 --- a/mysql-test/t/fulltext_order_by.test +++ b/mysql-test/t/fulltext_order_by.test @@ -138,6 +138,11 @@ order by (select b.id, b.betreff from t3 b) order by match(betreff) against ('+abc' in boolean mode) desc; +--error 1191 +(select b.id, b.betreff from t3 b) union +(select b.id, b.betreff from t3 b) +order by match(betreff) against ('+abc') desc; + select distinct b.id, b.betreff from t3 b order by match(betreff) against ('+abc' in boolean mode) desc; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index eeb8dfdfef5..c33444fd73e 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -132,8 +132,6 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd) options_tmp&= ~OPTION_FOUND_ROWS; else if (found_rows_for_union && !thd->lex->describe) options_tmp|= OPTION_FOUND_ROWS; - fake_select_lex->ftfunc_list_alloc.empty(); - fake_select_lex->ftfunc_list= &fake_select_lex->ftfunc_list_alloc; fake_select_lex->table_list.link_in_list((byte *)&result_table_list, (byte **) &result_table_list.next); @@ -302,7 +300,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, /* Force the temporary table to be a MyISAM table if we're going to use fullext functions (MATCH ... AGAINST .. IN BOOLEAN MODE) when reading - from it. + from it (this should be removed in 5.2 when fulltext search is moved + out of MyISAM). */ if (global_parameters->ftfunc_list->elements) create_options= create_options | TMP_TABLE_FORCE_MYISAM; From d7086c4a0cc5d6240b1a0ad2b4eb83a935fadd1e Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 7 Aug 2005 21:21:30 +0000 Subject: [PATCH 4/4] BUG#11869:part 2: post-review fixes: merging into 5.0 We're out of bits in st_select_lex->options so make TMP_TABLE_FORCE_MYISAM == OPTION_FOUND_COMMENT (the latter is not used by create_tmp_table). mysql-test/r/create.result: Updated the test result mysql-test/r/fulltext_order_by.result: Drop all tables this test uses mysql-test/t/fulltext_order_by.test: Drop all tables this test uses --- mysql-test/r/create.result | 2 +- mysql-test/r/fulltext_order_by.result | 2 +- mysql-test/t/fulltext_order_by.test | 4 +--- sql/item_sum.cc | 6 ++++-- sql/mysql_priv.h | 12 +++++++----- sql/sql_derived.cc | 3 ++- sql/sql_select.cc | 5 +++-- sql/sql_show.cc | 3 ++- sql/sql_union.cc | 6 +++--- 9 files changed, 24 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 293be36e5ab..82a5ccc3e82 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -606,6 +606,6 @@ create database mysqltest; use mysqltest; create view v1 as select 'foo' from dual; create table t1 like v1; -ERROR HY000: 'mysqltest.v1' is not a table +ERROR HY000: 'mysqltest.v1' is not BASE TABLE drop view v1; drop database mysqltest; diff --git a/mysql-test/r/fulltext_order_by.result b/mysql-test/r/fulltext_order_by.result index 5f40e43f0c0..adcceea408e 100644 --- a/mysql-test/r/fulltext_order_by.result +++ b/mysql-test/r/fulltext_order_by.result @@ -1,4 +1,4 @@ -DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t1,t2,t3; CREATE TABLE t1 ( a INT AUTO_INCREMENT PRIMARY KEY, message CHAR(20), diff --git a/mysql-test/t/fulltext_order_by.test b/mysql-test/t/fulltext_order_by.test index 5bad8161a0a..dcda00fecba 100644 --- a/mysql-test/t/fulltext_order_by.test +++ b/mysql-test/t/fulltext_order_by.test @@ -1,5 +1,5 @@ --disable_warnings -DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t1,t2,t3; --enable_warnings CREATE TABLE t1 ( @@ -117,8 +117,6 @@ where order by match(b.betreff) against ('+abc' in boolean mode) desc; --- todo psergey: fix ---error 1214 select a.text, b.id, b.betreff from t2 a inner join t3 b on a.id = b.forum inner join diff --git a/sql/item_sum.cc b/sql/item_sum.cc index b669a8c426d..3ba9cd10831 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -2275,7 +2275,8 @@ bool Item_sum_count_distinct::setup(THD *thd) DBUG_ASSERT(table == 0); if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1, 0, - select_lex->options | thd->options, + (select_lex->options | thd->options) & + ~TMP_TABLE_FORCE_MYISAM, HA_POS_ERROR, (char*)""))) return TRUE; table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows @@ -3057,7 +3058,8 @@ bool Item_func_group_concat::setup(THD *thd) */ if (!(table= create_tmp_table(thd, tmp_table_param, all_fields, (ORDER*) 0, 0, TRUE, - select_lex->options | thd->options, + (select_lex->options | thd->options) & + ~TMP_TABLE_FORCE_MYISAM, HA_POS_ERROR, (char*) ""))) DBUG_RETURN(TRUE); table->file->extra(HA_EXTRA_NO_ROWS); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 20898a4b654..ef7d6a1da96 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -256,6 +256,13 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; #define OPTION_WARNINGS (1L << 13) // THD, user #define OPTION_AUTO_IS_NULL (1L << 14) // THD, user, binlog #define OPTION_FOUND_COMMENT (1L << 15) // SELECT, intern, parser +/* + Force the used temporary table to be a MyISAM table (because we will use + fulltext functions when reading from it. This uses the same constant as + OPTION_FOUND_COMMENT because we've run out of bits and these two values + are not used together. +*/ +#define TMP_TABLE_FORCE_MYISAM (1L << 15) #define OPTION_SAFE_UPDATES (1L << 16) // THD, user #define OPTION_BUFFER_RESULT (1L << 17) // SELECT, user #define OPTION_BIN_LOG (1L << 18) // THD, user @@ -284,11 +291,6 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; #define OPTION_SETUP_TABLES_DONE (1L << 30) // intern /* If not set then the thread will ignore all warnings with level notes. */ #define OPTION_SQL_NOTES (1L << 31) // THD, user -/* - Force the used temporary table to be a MyISAM table (because we will use - fulltext functions when reading from it. -*/ -#define TMP_TABLE_FORCE_MYISAM (1L << 30) /* Maximum length of time zone name that we support diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index fc9d15e94c4..afcf7dbd93f 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -142,7 +142,8 @@ int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list) unit->types, (ORDER*) 0, FALSE, 1, (first_select->options | thd->options | - TMP_TABLE_ALL_COLUMNS), + TMP_TABLE_ALL_COLUMNS) & + ~TMP_TABLE_FORCE_MYISAM, HA_POS_ERROR, orig_table_list->alias))) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3f2f72fb768..a5527d8684c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1016,7 +1016,7 @@ JOIN::optimize() group_list : (ORDER*) 0), group_list ? 0 : select_distinct, group_list && simple_group, - select_options, + select_options & ~TMP_TABLE_FORCE_MYISAM, (order == 0 || skip_sort_order) ? select_limit : HA_POS_ERROR, (char *) ""))) @@ -1396,7 +1396,8 @@ JOIN::exec() (ORDER*) 0, curr_join->select_distinct && !curr_join->group_list, - 1, curr_join->select_options, + 1, curr_join->select_options + & ~TMP_TABLE_FORCE_MYISAM, HA_POS_ERROR, (char *) ""))) DBUG_VOID_RETURN; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 56272b4fdaf..a63ef8d689c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3319,7 +3319,8 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) if (!(table= create_tmp_table(thd, tmp_table_param, field_list, (ORDER*) 0, 0, 0, (select_lex->options | thd->options | - TMP_TABLE_ALL_COLUMNS), + TMP_TABLE_ALL_COLUMNS) & + ~TMP_TABLE_FORCE_MYISAM, HA_POS_ERROR, table_list->alias))) DBUG_RETURN(0); table_list->schema_table_param= tmp_table_param; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 55c2524ca42..ed77de87fe4 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -296,8 +296,8 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, } } - ulong create_options= first_select_in_union()->options | thd_arg->options | - TMP_TABLE_ALL_COLUMNS; + ulong create_options= (first_select_in_union()->options | thd_arg->options | + TMP_TABLE_ALL_COLUMNS) & ~TMP_TABLE_FORCE_MYISAM; /* Force the temporary table to be a MyISAM table if we're going to use fullext functions (MATCH ... AGAINST .. IN BOOLEAN MODE) when reading @@ -310,7 +310,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, if (!(table= create_tmp_table(thd_arg, &union_result->tmp_table_param, types, (ORDER*) 0, (bool) union_distinct, 1, - create_options, HA_POS_ERROR, + create_options, HA_POS_ERROR, (char *) tmp_table_alias))) goto err; table->file->extra(HA_EXTRA_WRITE_CACHE);