From 7b063137855ed2dd72f661260e9d157c8779b360 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 Dec 2004 18:35:11 +0200 Subject: [PATCH 01/90] InnoDB: Fixed bugs in the padding and trimming of trailing spaces that affected the UCS2 character set. (Bug #7350) innobase/data/data0type.c: Added dtype_get_charset_coll_noninline() innobase/include/data0type.h: Added dtype_get_charset_coll_noninline() innobase/include/row0mysql.h: Added charset field to mysql_row_templ_struct. innobase/include/row0mysql.ic: row_mysql_store_col_in_innobase_format(): When removing trailing spaces, treat the UCS2 character set properly. innobase/rem/rem0cmp.c: cmp_whole_field(): Do not remove trailing 0x20 bytes, as innobase_mysql_cmp() implicitly pads the strings with trailing spaces as necessary. innobase/row/row0sel.c: row_sel_field_store_in_mysql_format(): Do not pad with 0x20 bytes. row_sel_store_mysql_rec(): Pad VARCHARs with trailing spaces (0x20, or 0x0020 in UCS2). sql/ha_innodb.cc: build_template(): Initialize templ->charset --- innobase/data/data0type.c | 11 ++++++ innobase/include/data0type.h | 7 ++++ innobase/include/row0mysql.h | 2 ++ innobase/include/row0mysql.ic | 31 +++++++++++++--- innobase/rem/rem0cmp.c | 16 --------- innobase/row/row0sel.c | 68 +++++++++++++++++++++++++++++++---- sql/ha_innodb.cc | 2 ++ 7 files changed, 110 insertions(+), 27 deletions(-) diff --git a/innobase/data/data0type.c b/innobase/data/data0type.c index 714cf92bc65..dab14df4240 100644 --- a/innobase/data/data0type.c +++ b/innobase/data/data0type.c @@ -165,6 +165,17 @@ dtype_is_non_binary_string_type( return(FALSE); } +/************************************************************************* +Gets the MySQL charset-collation code for MySQL string types. */ + +ulint +dtype_get_charset_coll_noninline( +/*=============================*/ + ulint prtype) /* in: precise data type */ +{ + return(dtype_get_charset_coll(prtype)); +} + /************************************************************************* Forms a precise type from the < 4.1.2 format precise type plus the charset-collation code. */ diff --git a/innobase/include/data0type.h b/innobase/include/data0type.h index c263d2bf613..02c874836fd 100644 --- a/innobase/include/data0type.h +++ b/innobase/include/data0type.h @@ -234,6 +234,13 @@ dtype_get_prtype( dtype_t* type); /************************************************************************* Gets the MySQL charset-collation code for MySQL string types. */ + +ulint +dtype_get_charset_coll_noninline( +/*=============================*/ + ulint prtype);/* in: precise data type */ +/************************************************************************* +Gets the MySQL charset-collation code for MySQL string types. */ UNIV_INLINE ulint dtype_get_charset_coll( diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index f47ce74ce37..062dae4e60c 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -454,6 +454,8 @@ struct mysql_row_templ_struct { zero if column cannot be NULL */ ulint type; /* column type in Innobase mtype numbers DATA_CHAR... */ + ulint charset; /* MySQL charset-collation code + of the column, or zero */ ulint is_unsigned; /* if a column type is an integer type and this field is != 0, then it is an unsigned integer type */ diff --git a/innobase/include/row0mysql.ic b/innobase/include/row0mysql.ic index 4ecd66e06ec..fc922b52d0a 100644 --- a/innobase/include/row0mysql.ic +++ b/innobase/include/row0mysql.ic @@ -91,12 +91,33 @@ row_mysql_store_col_in_innobase_format( } } else if (type == DATA_VARCHAR || type == DATA_VARMYSQL || type == DATA_BINARY) { + /* Remove trailing spaces. */ + + /* Handle UCS2 strings differently. As no new + collations will be introduced in 4.1, we hardcode the + charset-collation codes here. In 5.0, the logic will + be based on mbminlen. */ + ulint cset = dtype_get_charset_coll( + dtype_get_prtype(dfield_get_type(dfield))); ptr = row_mysql_read_var_ref(&col_len, mysql_data); - - /* Remove trailing spaces */ - while (col_len > 0 && ptr[col_len - 1] == ' ') { - col_len--; - } + if (cset == 35/*ucs2_general_ci*/ + || cset == 90/*ucs2_bin*/ + || (cset >= 128/*ucs2_unicode_ci*/ + && cset <= 144/*ucs2_persian_ci*/)) { + /* space=0x0020 */ + /* Trim "half-chars", just in case. */ + col_len &= ~1; + + while (col_len >= 2 && ptr[col_len - 2] == 0x00 + && ptr[col_len - 1] == 0x20) { + col_len -= 2; + } + } else { + /* space=0x20 */ + while (col_len > 0 && ptr[col_len - 1] == 0x20) { + col_len--; + } + } } else if (type == DATA_BLOB) { ptr = row_mysql_read_blob_ref(&col_len, mysql_data, col_len); } diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c index 041fb7914e2..cf549284acc 100644 --- a/innobase/rem/rem0cmp.c +++ b/innobase/rem/rem0cmp.c @@ -261,22 +261,6 @@ cmp_whole_field( "InnoDB: comparison!\n"); } - /* MySQL does not pad the ends of strings with spaces in a - comparison. That would cause a foreign key check to fail for - non-latin1 character sets if we have different length columns. - To prevent that we remove trailing spaces here before doing - the comparison. NOTE that if we in the future map more MySQL - types to DATA_MYSQL or DATA_VARMYSQL, we have to change this - code. */ - - while (a_length > 0 && a[a_length - 1] == ' ') { - a_length--; - } - - while (b_length > 0 && b[b_length - 1] == ' ') { - b_length--; - } - return(innobase_mysql_cmp( (int)(type->prtype & DATA_MYSQL_TYPE_MASK), (uint)dtype_get_charset_coll(type->prtype), diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index ce76f48e7a7..61ba0b53172 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2204,9 +2204,6 @@ row_sel_field_store_in_mysql_format( dest = row_mysql_store_var_len(dest, len); ut_memcpy(dest, data, len); - /* Pad with trailing spaces */ - memset(dest + len, ' ', col_len - len); - /* ut_ad(col_len >= len + 2); No real var implemented in MySQL yet! */ @@ -2334,7 +2331,45 @@ row_sel_store_mysql_rec( mysql_rec + templ->mysql_col_offset, templ->mysql_col_len, data, len, templ->type, templ->is_unsigned); - + + if (templ->type == DATA_VARCHAR + || templ->type == DATA_VARMYSQL + || templ->type == DATA_BINARY) { + /* Pad with trailing spaces */ + data = mysql_rec + templ->mysql_col_offset; + + /* Handle UCS2 strings differently. As no new + collations will be introduced in 4.1, we + hardcode the charset-collation codes here. + 5.0 will use a different approach. */ + if (templ->charset == 35 + || templ->charset == 90 + || (templ->charset >= 128 + && templ->charset <= 144)) { + /* space=0x0020 */ + ulint col_len = templ->mysql_col_len; + + ut_a(!(col_len & 1)); + if (len & 1) { + /* A 0x20 has been stripped + from the column. + Pad it back. */ + goto pad_0x20; + } + /* Pad the rest of the string + with 0x0020 */ + while (len < col_len) { + data[len++] = 0x00; + pad_0x20: + data[len++] = 0x20; + } + } else { + /* space=0x20 */ + memset(data + len, 0x20, + templ->mysql_col_len - len); + } + } + /* Cleanup */ if (extern_field_heap) { mem_heap_free(extern_field_heap); @@ -2368,8 +2403,29 @@ row_sel_store_mysql_rec( pad_char = '\0'; } - memset(mysql_rec + templ->mysql_col_offset, pad_char, - templ->mysql_col_len); + /* Handle UCS2 strings differently. As no new + collations will be introduced in 4.1, + we hardcode the charset-collation codes here. + 5.0 will use a different approach. */ + if (templ->charset == 35 + || templ->charset == 90 + || (templ->charset >= 128 + && templ->charset <= 144)) { + /* There are two bytes per char, so the length + has to be an even number. */ + ut_a(!(templ->mysql_col_len & 1)); + data = mysql_rec + templ->mysql_col_offset; + len = templ->mysql_col_len; + /* Pad with 0x0020. */ + while (len >= 2) { + *data++ = 0x00; + *data++ = 0x20; + len -= 2; + } + } else { + memset(mysql_rec + templ->mysql_col_offset, + pad_char, templ->mysql_col_len); + } } } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index cc69762cbdb..8110df1063f 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2248,6 +2248,8 @@ build_template( templ->mysql_col_len = (ulint) field->pack_length(); templ->type = get_innobase_type_from_mysql_type(field); + templ->charset = dtype_get_charset_coll_noninline( + index->table->cols[i].type.prtype); templ->is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG); if (templ->type == DATA_BLOB) { From f0cf742fd3e87dbe6cfb065bb371b1cbc93c00e5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 6 Jan 2005 10:49:26 +0200 Subject: [PATCH 02/90] Fix for BUG#7331. The problem was that when a QUICK_SELECT access method is chosen, test_if_skip_sort_order() discovered that the index being used by the quick select will not deliver tuples in sorted order. In this case test_if_skip_sort_order() tried to change the index used by the quick select, but it didn't properly set the other members of the quick select, and especially the range flags of the ranges in QUICK_SELECT::ranges. The fix re-invokes the function SQL_SELECT::test_quick_select to correctly create a valid QUICK_SELECT object. mysql-test/r/order_by.result: Added test results. mysql-test/t/order_by.test: Added test for BUG#7331. sql/sql_select.cc: Fix for BUG#7331. --- mysql-test/r/order_by.result | 38 ++++++++++++++++++++++++++++++++++++ mysql-test/t/order_by.test | 34 ++++++++++++++++++++++++++++++++ sql/sql_select.cc | 21 ++++++++++++++++---- 3 files changed, 89 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 94d56bbc2fa..ab71a6b53e6 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -733,3 +733,41 @@ xxxxxxxxxxxxxxxxxxxaa xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxz drop table t1; +create table t1 ( +`sid` decimal(8,0) default null, +`wnid` varchar(11) not null default '', +key `wnid14` (`wnid`(4)), +key `wnid` (`wnid`) +) engine=myisam default charset=latin1; +insert into t1 (`sid`, `wnid`) values +('10100','01019000000'),('37986','01019000000'),('37987','01019010000'), +('39560','01019090000'),('37989','01019000000'),('37990','01019011000'), +('37991','01019011000'),('37992','01019019000'),('37993','01019030000'), +('37994','01019090000'),('475','02070000000'),('25253','02071100000'), +('25255','02071100000'),('25256','02071110000'),('25258','02071130000'), +('25259','02071190000'),('25260','02071200000'),('25261','02071210000'), +('25262','02071290000'),('25263','02071300000'),('25264','02071310000'), +('25265','02071310000'),('25266','02071320000'),('25267','02071320000'), +('25269','02071330000'),('25270','02071340000'),('25271','02071350000'), +('25272','02071360000'),('25273','02071370000'),('25281','02071391000'), +('25282','02071391000'),('25283','02071399000'),('25284','02071400000'), +('25285','02071410000'),('25286','02071410000'),('25287','02071420000'), +('25288','02071420000'),('25291','02071430000'),('25290','02071440000'), +('25292','02071450000'),('25293','02071460000'),('25294','02071470000'), +('25295','02071491000'),('25296','02071491000'),('25297','02071499000'); +explain select * from t1 where wnid like '0101%' order by wnid; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range wnid14,wnid wnid 11 NULL 10 Using where +select * from t1 where wnid like '0101%' order by wnid; +sid wnid +10100 01019000000 +37986 01019000000 +37989 01019000000 +37987 01019010000 +37990 01019011000 +37991 01019011000 +37992 01019019000 +37993 01019030000 +39560 01019090000 +37994 01019090000 +drop table t1; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 988c106bf21..ab5e93603e4 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -500,3 +500,37 @@ insert into t1 set a = concat(repeat('x', 19), 'aa'); set max_sort_length=20; select a from t1 order by a; drop table t1; + +# +# Bug #7331 +# + +create table t1 ( + `sid` decimal(8,0) default null, + `wnid` varchar(11) not null default '', + key `wnid14` (`wnid`(4)), + key `wnid` (`wnid`) +) engine=myisam default charset=latin1; + +insert into t1 (`sid`, `wnid`) values +('10100','01019000000'),('37986','01019000000'),('37987','01019010000'), +('39560','01019090000'),('37989','01019000000'),('37990','01019011000'), +('37991','01019011000'),('37992','01019019000'),('37993','01019030000'), +('37994','01019090000'),('475','02070000000'),('25253','02071100000'), +('25255','02071100000'),('25256','02071110000'),('25258','02071130000'), +('25259','02071190000'),('25260','02071200000'),('25261','02071210000'), +('25262','02071290000'),('25263','02071300000'),('25264','02071310000'), +('25265','02071310000'),('25266','02071320000'),('25267','02071320000'), +('25269','02071330000'),('25270','02071340000'),('25271','02071350000'), +('25272','02071360000'),('25273','02071370000'),('25281','02071391000'), +('25282','02071391000'),('25283','02071399000'),('25284','02071400000'), +('25285','02071410000'),('25286','02071410000'),('25287','02071420000'), +('25288','02071420000'),('25291','02071430000'),('25290','02071440000'), +('25292','02071450000'),('25293','02071460000'),('25294','02071470000'), +('25295','02071491000'),('25296','02071491000'),('25297','02071499000'); + +explain select * from t1 where wnid like '0101%' order by wnid; + +select * from t1 where wnid like '0101%' order by wnid; + +drop table t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 610a98d1983..acff1180e8c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7153,11 +7153,24 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, } else { - select->quick->file->ha_index_end(); - select->quick->index= new_ref_key; - select->quick->init(); + /* + The range optimizer constructed QUICK_RANGE for ref_key, and + we want to use instead new_ref_key as the index. We can't + just change the index of the quick select, because this may + result in an incosistent QUICK_SELECT object. Below we + create a new QUICK_SELECT from scratch so that all its + parameres are set correctly by the range optimizer. + */ + key_map new_ref_key_map; + new_ref_key_map.clear_all(); /* Force the creation of quick select */ + new_ref_key_map.set_bit(new_ref_key); /* only for new_ref_key. */ + + if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0, + (tab->join->select_options & OPTION_FOUND_ROWS) ? + HA_POS_ERROR : tab->join->unit->select_limit_cnt) <= 0) + DBUG_RETURN(0); } - ref_key= new_ref_key; + ref_key= new_ref_key; } } /* Check if we get the rows in requested sorted order by using the key */ From 397f3ee554280bc2591c50f501ea108c072cd3cd Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Jan 2005 00:16:07 +0100 Subject: [PATCH 03/90] Encourage user to specify a name for the binlog index file (either by giving an argument to --log-bin, or by using --log-bin-index). This is so that he does not have a replication break when his master's hostname changes. Plus binary logging options consistency checks. sql/mysqld.cc: * Encourage user to specify a name for the binlog index file (either by giving an argument to --log-bin, or by using --log-bin-index). This is so that he does not have a replication break when his master's hostname changes. Why not a fatal error? To not break existing many-machine setups. * --log-bin-index without --log-bin does not make sense. * --log-slave-updates without --log-bin does not either. support-files/my-huge.cnf.sh: encourage providing an argument to log-bin support-files/my-innodb-heavy-4G.cnf.sh: encourage providing an argument to log-bin support-files/my-large.cnf.sh: encourage providing an argument to log-bin support-files/my-medium.cnf.sh: encourage providing an argument to log-bin support-files/my-small.cnf.sh: encourage providing an argument to log-bin --- sql/mysqld.cc | 37 +++++++++++++++++++++---- support-files/my-huge.cnf.sh | 4 +-- support-files/my-innodb-heavy-4G.cnf.sh | 2 +- support-files/my-large.cnf.sh | 4 +-- support-files/my-medium.cnf.sh | 4 +-- support-files/my-small.cnf.sh | 2 +- 6 files changed, 39 insertions(+), 14 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index dd7fd98158a..72b02b76ddf 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2681,6 +2681,20 @@ with --log-bin instead."); if (opt_bin_log) { + if (!opt_bin_logname && !opt_binlog_index_name) + { + /* + User didn't give us info to name the binlog index file. + Picking `hostname`-bin.index like did in 4.x, causes replication to + fail if the hostname is changed later. So, we would like to instead + require a name. But as we don't want to break many existing setups, we + only give warning, not error. + */ + sql_print_warning("\ +No argument was provided to --log-bin, and --log-bin-index was not used. " +"Replication may break when this MySQL server acts as a master and has his " +"hostname changed."); + } /* If we fail to open binlog, it's going to hinder our recovery, so die */ if (open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin", opt_binlog_index_name, LOG_BIN, 0, 0, max_binlog_size)) @@ -2695,11 +2709,20 @@ with --log-bin instead."); } #endif } - else if (opt_log_slave_updates) + else { - sql_print_warning("\ -you need to use --log-bin to make --log-slave-updates work. \ -Now disabling --log-slave-updates."); + if (opt_log_slave_updates) + { + sql_print_error("\ +You need to use --log-bin=# to make --log-slave-updates work."); + unireg_abort(1); + } + if (opt_binlog_index_name) + { + sql_print_error("\ +You need to use --log-bin=# to make --log-bin-index work."); + unireg_abort(1); + } } #ifdef HAVE_REPLICATION @@ -4493,14 +4516,16 @@ Disable with --skip-isam.", {"log", 'l', "Log connections and queries to file.", (gptr*) &opt_logname, (gptr*) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-bin", OPT_BIN_LOG, - "Log update queries in binary format.", + "Log update queries in binary format. Optional (but strongly recommended " + "to avoid replication problems if server's hostname changes) argument " + "should be the chosen location for the binary log files.", (gptr*) &opt_bin_logname, (gptr*) &opt_bin_logname, 0, GET_STR_ALLOC, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-bin-index", OPT_BIN_LOG_INDEX, "File that holds the names for last binary log files.", (gptr*) &opt_binlog_index_name, (gptr*) &opt_binlog_index_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"log-error", OPT_ERROR_LOG_FILE, "Log error file.", + {"log-error", OPT_ERROR_LOG_FILE, "Error log file.", (gptr*) &log_error_file_ptr, (gptr*) &log_error_file_ptr, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.", diff --git a/support-files/my-huge.cnf.sh b/support-files/my-huge.cnf.sh index d25686f1c21..f7a47054658 100644 --- a/support-files/my-huge.cnf.sh +++ b/support-files/my-huge.cnf.sh @@ -48,7 +48,7 @@ thread_concurrency = 8 # Replication Master Server (default) # binary logging is required for replication -log-bin +log-bin=mysql-bin # required unique id between 1 and 2^32 - 1 # defaults to 1 if master-host is not set @@ -108,7 +108,7 @@ server-id = 1 #master-port = # # binary logging - not required for slaves, but recommended -#log-bin +#log-bin=mysql-bin # Point the following paths to different dedicated disks #tmpdir = /tmp/ diff --git a/support-files/my-innodb-heavy-4G.cnf.sh b/support-files/my-innodb-heavy-4G.cnf.sh index 062d106ce6a..b3f43272a7d 100644 --- a/support-files/my-innodb-heavy-4G.cnf.sh +++ b/support-files/my-innodb-heavy-4G.cnf.sh @@ -189,7 +189,7 @@ tmp_table_size = 64M # Enable binary logging. This is required for acting as a MASTER in a # replication configuration. You also need the binary log if you need # the ability to do point in time recovery from your latest backup. -log_bin +log-bin=mysql-bin # If you're using replication with chained slaves (A->B->C), you need to # enable this option on server B. It enables logging of updates done by diff --git a/support-files/my-large.cnf.sh b/support-files/my-large.cnf.sh index 59aca4b32f2..1e7d9f7aade 100644 --- a/support-files/my-large.cnf.sh +++ b/support-files/my-large.cnf.sh @@ -48,7 +48,7 @@ thread_concurrency = 8 # Replication Master Server (default) # binary logging is required for replication -log-bin +log-bin=mysql-bin # required unique id between 1 and 2^32 - 1 # defaults to 1 if master-host is not set @@ -108,7 +108,7 @@ server-id = 1 #master-port = # # binary logging - not required for slaves, but recommended -#log-bin +#log-bin=mysql-bin # Point the following paths to different dedicated disks #tmpdir = /tmp/ diff --git a/support-files/my-medium.cnf.sh b/support-files/my-medium.cnf.sh index 529740d59f0..99b6e823f39 100644 --- a/support-files/my-medium.cnf.sh +++ b/support-files/my-medium.cnf.sh @@ -46,7 +46,7 @@ myisam_sort_buffer_size = 8M # Replication Master Server (default) # binary logging is required for replication -log-bin +log-bin=mysql-bin # required unique id between 1 and 2^32 - 1 # defaults to 1 if master-host is not set @@ -106,7 +106,7 @@ server-id = 1 #master-port = # # binary logging - not required for slaves, but recommended -#log-bin +#log-bin=mysql-bin # Point the following paths to different dedicated disks #tmpdir = /tmp/ diff --git a/support-files/my-small.cnf.sh b/support-files/my-small.cnf.sh index b2ecca6127e..288df893b4c 100644 --- a/support-files/my-small.cnf.sh +++ b/support-files/my-small.cnf.sh @@ -46,7 +46,7 @@ thread_stack = 64K server-id = 1 # Uncomment the following if you want to log updates -#log-bin +#log-bin=mysql-bin # Uncomment the following if you are NOT using BDB tables #skip-bdb From 39ee25b3742188026dcc0bcee60951668a4a2275 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Jan 2005 14:26:40 +0300 Subject: [PATCH 04/90] Fix for bug #7418 "TIMESTAMP not always converted to DATETIME in MAXDB mode". Changed grammar rule for "type" token. Now we have one branch with optional length specification for TIMESTAMP type instead of two separate branches. mysql-test/r/type_timestamp.result: Added test case for bug #7418 "TIMESTAMP not always converted to DATETIME in MAXDB mode". mysql-test/t/type_timestamp.test: Added test case for bug #7418 "TIMESTAMP not always converted to DATETIME in MAXDB mode". sql/sql_yacc.yy: Changed rule for "type" token. Now we have one branch with optional length specification for TIMESTAMP type instead of two separate branches. This also gives us consistent behavior for TIMETSAMP in MAXDB mode. --- mysql-test/r/type_timestamp.result | 10 ++++++++++ mysql-test/t/type_timestamp.test | 12 ++++++++++++ sql/sql_yacc.yy | 9 +-------- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index 42fdc7e50c6..6c46d308e7e 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -422,3 +422,13 @@ max(t) 2004-01-01 01:00:00 2004-02-01 00:00:00 drop table t1; +set sql_mode='maxdb'; +create table t1 (a timestamp, b timestamp(19)); +show create table t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" datetime default NULL, + "b" datetime default NULL +) +set sql_mode=''; +drop table t1; diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index a8a0cf8703c..783e310f02d 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -286,3 +286,15 @@ insert into t1 values ('a', '2004-01-01 00:00:00'), ('a', '2004-01-01 01:00:00') ('b', '2004-02-01 00:00:00'); select max(t) from t1 group by a; drop table t1; + +# +# Test for bug #7418 "TIMESTAMP not always converted to DATETIME in MAXDB +# mode". TIMESTAMP columns should be converted DATETIME columns in MAXDB +# mode regardless of whether a display width is given. +# +set sql_mode='maxdb'; +create table t1 (a timestamp, b timestamp(19)); +show create table t1; +# restore default mode +set sql_mode=''; +drop table t1; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a09694ee1e6..66f7882c4e7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1415,7 +1415,7 @@ type: | YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; } | DATE_SYM { $$=FIELD_TYPE_DATE; } | TIME_SYM { $$=FIELD_TYPE_TIME; } - | TIMESTAMP + | TIMESTAMP opt_len { if (YYTHD->variables.sql_mode & MODE_MAXDB) $$=FIELD_TYPE_DATETIME; @@ -1428,13 +1428,6 @@ type: $$=FIELD_TYPE_TIMESTAMP; } } - | TIMESTAMP '(' NUM ')' - { - LEX *lex= Lex; - lex->length= $3.str; - lex->type|= NOT_NULL_FLAG; - $$= FIELD_TYPE_TIMESTAMP; - } | DATETIME { $$=FIELD_TYPE_DATETIME; } | TINYBLOB { Lex->charset=&my_charset_bin; $$=FIELD_TYPE_TINY_BLOB; } From ff4507a9dec635b1fa879d3fd62b5adf05be6235 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Jan 2005 16:28:07 +0200 Subject: [PATCH 05/90] InnoDB: Implement fast TRUNCATE TABLE (Bug #7150) innobase/dict/dict0boot.c: Added DICT_SYS_INDEXES_TYPE_FIELD innobase/dict/dict0crea.c: Added dict_truncate_index_tree() innobase/include/dict0boot.h: Added DICT_SYS_INDEXES_TYPE_FIELD innobase/include/dict0crea.h: Added dict_truncate_index_tree() innobase/include/row0mysql.h: Added row_truncate_table_for_mysql() innobase/row/row0mysql.c: Added row_truncate_table_for_mysql() sql/ha_innodb.cc: Added ha_innobase::delete_all_rows() in order to implement fast TRUNCATE TABLE sql/ha_innodb.h: Added ha_innobase::delete_all_rows() in order to implement fast TRUNCATE TABLE --- innobase/dict/dict0boot.c | 3 + innobase/dict/dict0crea.c | 95 ++++++++++++ innobase/include/dict0boot.h | 1 + innobase/include/dict0crea.h | 11 ++ innobase/include/row0mysql.h | 9 ++ innobase/row/row0mysql.c | 279 +++++++++++++++++++++++++++++++++++ sql/ha_innodb.cc | 42 ++++++ sql/ha_innodb.h | 1 + 8 files changed, 441 insertions(+) diff --git a/innobase/dict/dict0boot.c b/innobase/dict/dict0boot.c index e500b92252f..883c5464319 100644 --- a/innobase/dict/dict0boot.c +++ b/innobase/dict/dict0boot.c @@ -332,6 +332,9 @@ dict_boot(void) #endif #if DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2 #error "DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2" +#endif +#if DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2 +#error "DICT_SYS_INDEXES_TYPE_FIELD != 4 + 2" #endif table->id = DICT_INDEXES_ID; diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index 747a99ebdc9..e744ffda7a6 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -706,6 +706,101 @@ dict_drop_index_tree( DICT_SYS_INDEXES_PAGE_NO_FIELD, FIL_NULL, mtr); } +/*********************************************************************** +Truncates the index tree associated with a row in SYS_INDEXES table. */ + +void +dict_truncate_index_tree( +/*=====================*/ + dict_table_t* table, /* in: the table the index belongs to */ + rec_t* rec, /* in: record in the clustered index of + SYS_INDEXES table */ + mtr_t* mtr) /* in: mtr having the latch + on the record page */ +{ + ulint root_page_no; + ulint space; + ulint type; + dulint index_id; + byte* ptr; + ulint len; + ibool comp; + dict_index_t* index; + +#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&(dict_sys->mutex))); +#endif /* UNIV_SYNC_DEBUG */ + + ut_a(!dict_sys->sys_indexes->comp); + ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len); + + ut_ad(len == 4); + + root_page_no = mtr_read_ulint(ptr, MLOG_4BYTES, mtr); + + if (root_page_no == FIL_NULL) { + /* The tree has been freed. */ + + return; + } + + ptr = rec_get_nth_field_old(rec, + DICT_SYS_INDEXES_SPACE_NO_FIELD, &len); + + ut_ad(len == 4); + + space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr); + + if (!fil_tablespace_exists_in_mem(space)) { + /* It is a single table tablespace and the .ibd file is + missing: do nothing */ + + return; + } + + ptr = rec_get_nth_field_old(rec, + DICT_SYS_INDEXES_TYPE_FIELD, &len); + ut_ad(len == 4); + type = mach_read_from_4(ptr); + + ptr = rec_get_nth_field_old(rec, 1, &len); + ut_ad(len == 8); + index_id = mach_read_from_8(ptr); + + /* We free all the pages but the root page first; this operation + may span several mini-transactions */ + + btr_free_but_not_root(space, root_page_no); + + /* Then we free the root page in the same mini-transaction where + we create the b-tree and write its new root page number to the + appropriate field in the SYS_INDEXES record: this mini-transaction + marks the B-tree totally truncated */ + + comp = page_is_comp(btr_page_get( + space, root_page_no, RW_X_LATCH, mtr)); + + btr_free_root(space, root_page_no, mtr); + + /* Find the index corresponding to this SYS_INDEXES record. */ + for (index = UT_LIST_GET_FIRST(table->indexes); + index; + index = UT_LIST_GET_NEXT(indexes, index)) { + if (!ut_dulint_cmp(index->id, index_id)) { + break; + } + } + + root_page_no = btr_create(type, space, index_id, comp, mtr); + if (index) { + index->page_no = root_page_no; + } + + page_rec_write_index_page_no(rec, + DICT_SYS_INDEXES_PAGE_NO_FIELD, + root_page_no, mtr); +} + /************************************************************************* Creates a table create graph. */ diff --git a/innobase/include/dict0boot.h b/innobase/include/dict0boot.h index 35eff5af29a..86702cbca05 100644 --- a/innobase/include/dict0boot.h +++ b/innobase/include/dict0boot.h @@ -119,6 +119,7 @@ dict_create(void); clustered index */ #define DICT_SYS_INDEXES_PAGE_NO_FIELD 8 #define DICT_SYS_INDEXES_SPACE_NO_FIELD 7 +#define DICT_SYS_INDEXES_TYPE_FIELD 6 /* When a row id which is zero modulo this number (which must be a power of two) is assigned, the field DICT_HDR_ROW_ID on the dictionary header page is diff --git a/innobase/include/dict0crea.h b/innobase/include/dict0crea.h index 8b6944fc605..d718e92eb13 100644 --- a/innobase/include/dict0crea.h +++ b/innobase/include/dict0crea.h @@ -54,6 +54,17 @@ dict_create_index_step( /* out: query thread to run next or NULL */ que_thr_t* thr); /* in: query thread */ /*********************************************************************** +Truncates the index tree associated with a row in SYS_INDEXES table. */ + +void +dict_truncate_index_tree( +/*=====================*/ + dict_table_t* table, /* in: the table the index belongs to */ + rec_t* rec, /* in: record in the clustered index of + SYS_INDEXES table */ + mtr_t* mtr); /* in: mtr having the latch + on the record page */ +/*********************************************************************** Drops the index tree associated with a row in SYS_INDEXES table. */ void diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index bd5ad3adba5..1618df02499 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -363,6 +363,15 @@ row_get_background_drop_list_len_low(void); /*======================================*/ /* out: how many tables in list */ /************************************************************************* +Truncates a table for MySQL. */ + +int +row_truncate_table_for_mysql( +/*=========================*/ + /* out: error code or DB_SUCCESS */ + dict_table_t* table, /* in: table handle */ + trx_t* trx); /* in: transaction handle */ +/************************************************************************* Drops a table for MySQL. If the name of the dropped table ends to characters INNODB_MONITOR, then this also stops printing of monitor output by the master thread. */ diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 380fcf236ed..67477b36a05 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -2421,6 +2421,285 @@ funct_exit: return((int) err); } +/************************************************************************* +Truncates a table for MySQL. */ + +int +row_truncate_table_for_mysql( +/*=========================*/ + /* out: error code or DB_SUCCESS */ + dict_table_t* table, /* in: table handle */ + trx_t* trx) /* in: transaction handle */ +{ + dict_foreign_t* foreign; + ulint err; + ibool locked_dictionary = FALSE; + mem_heap_t* heap; + byte* buf; + dtuple_t* tuple; + dfield_t* dfield; + dict_index_t* sys_index; + btr_pcur_t pcur; + mtr_t mtr; + dulint new_id; + char* sql; + que_thr_t* thr; + que_t* graph = NULL; + +/* How do we prevent crashes caused by ongoing operations on the table? Old +operations could try to access non-existent pages. + +1) SQL queries, INSERT, SELECT, ...: we must get an exclusive MySQL table lock +on the table before we can do TRUNCATE TABLE. Then there are no running +queries on the table. +2) Purge and rollback: we assign a new table id for the table. Since purge and +rollback look for the table based on the table id, they see the table as +'dropped' and discard their operations. +3) Insert buffer: we remove all entries for the table in the insert +buffer tree; ... TODO +4) Linear readahead and random readahead: we use the same method as in 3) to +discard ongoing operations. +5) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, we +do not allow the discard. We also reserve the data dictionary latch. */ + + static const char renumber_tablespace_proc[] = + "PROCEDURE RENUMBER_TABLESPACE_PROC () IS\n" + "old_id CHAR;\n" + "new_id CHAR;\n" + "old_id_low INT;\n" + "old_id_high INT;\n" + "new_id_low INT;\n" + "new_id_high INT;\n" + "BEGIN\n" + "old_id_high := %lu;\n" + "old_id_low := %lu;\n" + "new_id_high := %lu;\n" + "new_id_low := %lu;\n" + "old_id := CONCAT(TO_BINARY(old_id_high, 4), TO_BINARY(old_id_low, 4));\n" + "new_id := CONCAT(TO_BINARY(new_id_high, 4), TO_BINARY(new_id_low, 4));\n" + "UPDATE SYS_TABLES SET ID = new_id\n" + "WHERE ID = old_id;\n" + "UPDATE SYS_COLUMNS SET TABLE_ID = new_id\n" + "WHERE TABLE_ID = old_id;\n" + "UPDATE SYS_INDEXES SET TABLE_ID = new_id\n" + "WHERE TABLE_ID = old_id;\n" + "COMMIT WORK;\n" + "END;\n"; + + ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); + ut_ad(table); + + if (srv_created_new_raw) { + fputs( + "InnoDB: A new raw disk partition was initialized or\n" + "InnoDB: innodb_force_recovery is on: we do not allow\n" + "InnoDB: database modifications by the user. Shut down\n" + "InnoDB: mysqld and edit my.cnf so that newraw is replaced\n" + "InnoDB: with raw, and innodb_force_... is removed.\n", + stderr); + + return(DB_ERROR); + } + + trx->op_info = "truncating table"; + + trx_start_if_not_started(trx); + + /* Serialize data dictionary operations with dictionary mutex: + no deadlocks can occur then in these operations */ + + if (trx->dict_operation_lock_mode != RW_X_LATCH) { + /* Prevent foreign key checks etc. while we are truncating the + table */ + + row_mysql_lock_data_dictionary(trx); + + locked_dictionary = TRUE; + } + +#ifdef UNIV_SYNC_DEBUG + ut_ad(mutex_own(&(dict_sys->mutex))); + ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ + + /* Check if the table is referenced by foreign key constraints from + some other table (not the table itself) */ + + foreign = UT_LIST_GET_FIRST(table->referenced_list); + + while (foreign && foreign->foreign_table == table) { + foreign = UT_LIST_GET_NEXT(referenced_list, foreign); + } + + if (foreign && trx->check_foreigns) { + FILE* ef = dict_foreign_err_file; + + /* We only allow truncating a referenced table if + FOREIGN_KEY_CHECKS is set to 0 */ + + mutex_enter(&dict_foreign_err_mutex); + rewind(ef); + ut_print_timestamp(ef); + + fputs(" Cannot truncate table ", ef); + ut_print_name(ef, trx, table->name); + fputs("\n" + "because it is referenced by ", ef); + ut_print_name(ef, trx, foreign->foreign_table_name); + putc('\n', ef); + mutex_exit(&dict_foreign_err_mutex); + + err = DB_ERROR; + goto funct_exit; + } + + if (table->n_mysql_handles_opened > 1) { + ut_print_timestamp(stderr); +fputs(" InnoDB: Warning: MySQL is trying to truncate table ", stderr); + ut_print_name(stderr, trx, table->name); + fputs("\n" +"InnoDB: though there are still open handles to it.\n", stderr); + err = DB_ERROR; + + goto funct_exit; + } + + /* TODO: could we replace the counter n_foreign_key_checks_running + with lock checks on the table? Acquire here an exclusive lock on the + table, and rewrite lock0lock.c and the lock wait in srv0srv.c so that + they can cope with the table having been truncated here? Foreign key + checks take an IS or IX lock on the table. */ + + if (table->n_foreign_key_checks_running > 0) { + ut_print_timestamp(stderr); + fputs(" InnoDB: You are trying to truncate table ", stderr); + ut_print_name(stderr, trx, table->name); + fputs("\n" +"InnoDB: though there is a foreign key check running on it.\n", + stderr); + err = DB_ERROR; + + goto funct_exit; + } + + /* Remove any locks there are on the table or its records */ + + lock_reset_all_on_table(table); + + trx->dict_operation = TRUE; + trx->table_id = table->id; + + /* scan SYS_INDEXES for all indexes of the table */ + heap = mem_heap_create(800); + + tuple = dtuple_create(heap, 1); + dfield = dtuple_get_nth_field(tuple, 0); + + buf = mem_heap_alloc(heap, 8); + mach_write_to_8(buf, table->id); + + dfield_set_data(dfield, buf, 8); + sys_index = dict_table_get_first_index(dict_sys->sys_indexes); + dict_index_copy_types(tuple, sys_index, 1); + + mtr_start(&mtr); + btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, + BTR_MODIFY_LEAF, &pcur, &mtr); + for (;;) { + rec_t* rec; + const byte* field; + ulint len; + + if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { + /* The end of SYS_INDEXES has been reached. */ + break; + } + + rec = btr_pcur_get_rec(&pcur); + + field = rec_get_nth_field_old(rec, 0, &len); + ut_ad(len == 8); + + if (memcmp(buf, field, len) != 0) { + /* End of indexes for the table (TABLE_ID mismatch). */ + break; + } + + if (rec_get_deleted_flag(rec, FALSE)) { + /* The index has been dropped. */ + continue; + } + + dict_truncate_index_tree(table, rec, &mtr); + + btr_pcur_move_to_next_user_rec(&pcur, &mtr); + } + + btr_pcur_close(&pcur); + mtr_commit(&mtr); + + new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID); + + mem_heap_empty(heap); + sql = mem_heap_alloc(heap, (sizeof renumber_tablespace_proc) + 40); + sprintf(sql, renumber_tablespace_proc, + (ulong) ut_dulint_get_high(table->id), + (ulong) ut_dulint_get_low(table->id), + (ulong) ut_dulint_get_high(new_id), + (ulong) ut_dulint_get_low(new_id)); + + graph = pars_sql(sql); + + ut_a(graph); + + mem_heap_free(heap); + + graph->trx = trx; + trx->graph = NULL; + + graph->fork_type = QUE_FORK_MYSQL_INTERFACE; + + thr = que_fork_start_command(graph); + ut_a(thr); + + que_run_threads(thr); + + que_graph_free(graph); + + err = trx->error_state; + + if (err != DB_SUCCESS) { + trx->error_state = DB_SUCCESS; + trx_general_rollback_for_mysql(trx, FALSE, NULL); + trx->error_state = DB_SUCCESS; + ut_print_timestamp(stderr); +fputs(" InnoDB: Unable to assign a new identifier to table ", stderr); + ut_print_name(stderr, trx, table->name); + fputs("\n" +"InnoDB: after truncating it. Background processes may corrupt the table!\n", + stderr); + err = DB_ERROR; + } else { + dict_table_change_id_in_cache(table, new_id); + } + + dict_update_statistics(table); + + trx_commit_for_mysql(trx); + +funct_exit: + + if (locked_dictionary) { + row_mysql_unlock_data_dictionary(trx); + } + + trx->op_info = ""; + + srv_wake_master_thread(); + + return((int) err); +} + /************************************************************************* Drops a table for MySQL. If the name of the table to be dropped is equal with one of the predefined magic table names, then this also stops printing diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 0bca8c21715..9452723110f 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4080,6 +4080,48 @@ ha_innobase::discard_or_import_tablespace( DBUG_RETURN(err); } +/********************************************************************* +Deletes all rows of an InnoDB table. */ + +int +ha_innobase::delete_all_rows(void) +/*==============================*/ + /* out: error number */ +{ + row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; + int error; + trx_t* trx; + THD* thd = current_thd; + + DBUG_ENTER("ha_innobase::delete_all_rows"); + + if (thd->lex->sql_command != SQLCOM_TRUNCATE) { + fallback: + /* We only handle TRUNCATE TABLE t as a special case. + DELETE FROM t will have to use ha_innobase::delete_row(). */ + DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND); + } + + /* Get the transaction associated with the current thd, or create one + if not yet created */ + + trx = check_trx_exists(thd); + + /* Truncate the table in InnoDB */ + + error = row_truncate_table_for_mysql(prebuilt->table, trx); + if (error == DB_ERROR) { + /* Cannot truncate; resort to ha_innobase::delete_row() */ + goto fallback; + } + + innobase_commit_low(trx); + + error = convert_error_code_to_mysql(error, NULL); + + DBUG_RETURN(error); +} + /********************************************************************* Drops a table from an InnoDB database. Before calling this function, MySQL calls innobase_commit to commit the transaction of the current user. diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index fcb9165de64..437a33116d7 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -159,6 +159,7 @@ class ha_innobase: public handler int create(const char *name, register TABLE *form, HA_CREATE_INFO *create_info); + int delete_all_rows(); int delete_table(const char *name); int rename_table(const char* from, const char* to); int check(THD* thd, HA_CHECK_OPT* check_opt); From 4eec8ab1f6547cf4b7fb4877928dfd6abd11a159 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Jan 2005 18:55:53 +0200 Subject: [PATCH 06/90] Review of new pushed code Indentation cleanup client/mysqladmin.cc: Indentation cleanup --- client/mysqladmin.cc | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 24cd461b1fa..d390a152fc7 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -832,7 +832,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) if (argv[1][0]) { char *pw= argv[1]; - bool old= find_type(argv[0], &command_typelib, 2) == ADMIN_OLD_PASSWORD; + bool old= (find_type(argv[0], &command_typelib, 2) == + ADMIN_OLD_PASSWORD); #ifdef __WIN__ uint pw_len= strlen(pw); if (pw_len > 1 && pw[0] == '\'' && pw[pw_len-1] == '\'') @@ -843,21 +844,29 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) If we don't already know to use an old-style password, see what the server is using */ - if (!old) { - if (mysql_query(mysql, "SHOW VARIABLES LIKE 'old_passwords'")) { + if (!old) + { + if (mysql_query(mysql, "SHOW VARIABLES LIKE 'old_passwords'")) + { my_printf_error(0, "Could not determine old_passwords setting from server; error: '%s'", MYF(ME_BELL),mysql_error(mysql)); return -1; - } else { + } + else + { MYSQL_RES *res= mysql_store_result(mysql); - if (!res) { - my_printf_error(0, "Could not get old_passwords setting from server; error: '%s'", + if (!res) + { + my_printf_error(0, + "Could not get old_passwords setting from " + "server; error: '%s'", MYF(ME_BELL),mysql_error(mysql)); return -1; } - if (!mysql_num_rows(res)) { + if (!mysql_num_rows(res)) old= 1; - } else { + else + { MYSQL_ROW row= mysql_fetch_row(res); old= !strncmp(row[1], "ON", 2); } From d853e732b9f598671283064fef6d11ea9db1d8ca Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Jan 2005 12:18:36 +0300 Subject: [PATCH 07/90] Fix for bug #7586 "TIMEDIFF for sec+microsec not working properly". mysql-test/r/func_sapdb.result: Added test for bug #7586 "TIMEDIFF for sec+microsec not working properly". Corrected previously wrong results of couple other statements. mysql-test/t/func_sapdb.test: Added test for bug #7586 "TIMEDIFF for sec+microsec not working properly". sql/item_timefunc.cc: Item_func_timediff::val_str(): Use simplier and less error-prone implementation. Now we are counting difference between time values in microseconds and convert it to time value (instead of using seconds and taking difference in "second_part"s into account). --- mysql-test/r/func_sapdb.result | 7 +++++-- mysql-test/t/func_sapdb.test | 1 + sql/item_timefunc.cc | 30 ++++++++++-------------------- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index cf2bd687115..c74d6fc5a4e 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -97,13 +97,16 @@ timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") 46:58:57.999999 select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002"); timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") --23:59:59.999999 +-24:00:00.000001 select timediff("1997-12-31 23:59:59.000001","23:59:59.000001"); timediff("1997-12-31 23:59:59.000001","23:59:59.000001") NULL select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001"); timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001") -00:00:00.000001 +select timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50"); +timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50") +-00:00:00.000001 select maketime(10,11,12); maketime(10,11,12) 10:11:12 @@ -175,7 +178,7 @@ f8 date YES NULL f9 time YES NULL select * from t1; f1 f2 f3 f4 f5 f6 f7 f8 f9 -1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -23:59:59 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59 +1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -24:00:00 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59 create table test(t1 datetime, t2 time, t3 time, t4 datetime); insert into test values ('2001-01-01 01:01:01', '01:01:01', null, '2001-02-01 01:01:01'), diff --git a/mysql-test/t/func_sapdb.test b/mysql-test/t/func_sapdb.test index 2ae3c438243..de433485fca 100644 --- a/mysql-test/t/func_sapdb.test +++ b/mysql-test/t/func_sapdb.test @@ -54,6 +54,7 @@ select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002"); select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002"); select timediff("1997-12-31 23:59:59.000001","23:59:59.000001"); select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001"); +select timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50"); --enable_ps_protocol select maketime(10,11,12); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 0d652a431cb..f9c9d1f013d 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2432,8 +2432,7 @@ void Item_func_add_time::print(String *str) String *Item_func_timediff::val_str(String *str) { DBUG_ASSERT(fixed == 1); - longlong seconds; - long microseconds; + longlong microseconds; long days; int l_sign= 1; TIME l_time1 ,l_time2, l_time3; @@ -2457,32 +2456,23 @@ String *Item_func_timediff::val_str(String *str) (uint) l_time2.month, (uint) l_time2.day)); - microseconds= l_time1.second_part - l_sign*l_time2.second_part; - seconds= ((longlong) days*86400L + l_time1.hour*3600L + - l_time1.minute*60L + l_time1.second + microseconds/1000000L - - (longlong)l_sign*(l_time2.hour*3600L+l_time2.minute*60L+ - l_time2.second)); + microseconds= ((longlong)days*86400L + + l_time1.hour*3600L + l_time1.minute*60L + l_time1.second - + (longlong)l_sign*(l_time2.hour*3600L + l_time2.minute*60L + + l_time2.second))*1000000 + + l_time1.second_part - l_sign*l_time2.second_part; l_time3.neg= 0; - if (seconds < 0) - { - seconds= -seconds; - l_time3.neg= 1; - } - else if (seconds == 0 && microseconds < 0) + if (microseconds < 0) { microseconds= -microseconds; l_time3.neg= 1; } - if (microseconds < 0) - { - microseconds+= 1000000L; - seconds--; - } - if ((l_time2.neg == l_time1.neg) && l_time1.neg) + if ((l_time2.neg == l_time1.neg) && l_time1.neg && microseconds) l_time3.neg= l_time3.neg ? 0 : 1; - calc_time_from_sec(&l_time3, (long) seconds, microseconds); + calc_time_from_sec(&l_time3, (long)(microseconds/1000000), + (long)(microseconds%1000000)); if (!make_datetime(l_time1.second_part || l_time2.second_part ? TIME_MICROSECOND : TIME_ONLY, From f5d30e0cac50677699d9fadfa540f4e900b679c3 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Jan 2005 19:42:46 +0100 Subject: [PATCH 08/90] Fix for BUG#7793 "mysqlbinlog produces incorrect queries": when printing SET @var in mysqlbinlog, backtick the collation (as BINARY is a reserved word) mysql-test/r/ctype_ucs.result: backticks added mysql-test/r/user_var.result: backticks added mysql-test/t/user_var.test: testing a variable with BINARY collation, which needs the backticks sql/log_event.cc: when printing SET @var in mysqlbinlog, backtick the collation (as BINARY is a reserved word) --- mysql-test/r/ctype_ucs.result | 2 +- mysql-test/r/user_var.result | 13 ++++++++----- mysql-test/t/user_var.test | 3 ++- sql/log_event.cc | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index b1b83eb8b6c..5c47f8a4059 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -520,7 +520,7 @@ Log_name Pos Event_type Server_id Orig_log_pos Info master-bin.000001 79 User var 1 79 @`v`=_ucs2 0x006100620063 COLLATE ucs2_general_ci master-bin.000001 119 Query 1 119 use `test`; insert into t2 values (@v) /*!40019 SET @@session.max_insert_delayed_threads=0*/; -SET @`v`:=_ucs2 0x006100620063 COLLATE ucs2_general_ci; +SET @`v`:=_ucs2 0x006100620063 COLLATE `ucs2_general_ci`; use test; SET TIMESTAMP=10000; insert into t2 values (@v); diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 4f521143d97..d46d6c7a78a 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -168,21 +168,24 @@ SET TIMESTAMP=10000; SET @`a b`='hello'; INSERT INTO t1 VALUES(@`a b`); set @var1= "';aaa"; -insert into t1 values (@var1); +SET @var2=char(ascii('a')); +insert into t1 values (@var1),(@var2); show binlog events from 79; Log_name Pos Event_type Server_id Orig_log_pos Info master-bin.000001 79 User var 1 79 @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci master-bin.000001 120 Query 1 120 use `test`; INSERT INTO t1 VALUES(@`a b`) master-bin.000001 184 User var 1 184 @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci -master-bin.000001 226 Query 1 226 use `test`; insert into t1 values (@var1) +master-bin.000001 226 User var 1 226 @`var2`=_binary 0x61 COLLATE binary +master-bin.000001 264 Query 1 264 use `test`; insert into t1 values (@var1),(@var2) /*!40019 SET @@session.max_insert_delayed_threads=0*/; -SET @`a b`:=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci; +SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`; use test; SET TIMESTAMP=10000; INSERT INTO t1 VALUES(@`a b`); -SET @`var1`:=_latin1 0x273B616161 COLLATE latin1_swedish_ci; +SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`; +SET @`var2`:=_binary 0x61 COLLATE `binary`; SET TIMESTAMP=10000; -insert into t1 values (@var1); +insert into t1 values (@var1),(@var2); drop table t1; set @var= NULL ; select FIELD( @var,'1it','Hit') as my_column; diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index d985be05b94..81788ce8d73 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -107,7 +107,8 @@ SET TIMESTAMP=10000; SET @`a b`='hello'; INSERT INTO t1 VALUES(@`a b`); set @var1= "';aaa"; -insert into t1 values (@var1); +SET @var2=char(ascii('a')); +insert into t1 values (@var1),(@var2); show binlog events from 79; # more important than SHOW BINLOG EVENTS, mysqlbinlog (where we # absolutely need variables names to be quoted and strings to be diff --git a/sql/log_event.cc b/sql/log_event.cc index c027c3a8ee4..c86b67376ea 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2459,7 +2459,7 @@ void User_var_log_event::print(FILE* file, bool short_form, char* last_db) */ fprintf(file, ":=???;\n"); else - fprintf(file, ":=_%s %s COLLATE %s;\n", cs->csname, hex_str, cs->name); + fprintf(file, ":=_%s %s COLLATE `%s`;\n", cs->csname, hex_str, cs->name); my_afree(hex_str); } break; From d62ca959512601c6f225be694009f8d1ecca4b7c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 00:44:13 +0100 Subject: [PATCH 09/90] Fix for BUG#7850: force the transaction isolation level to REPEATABLE READ when --single-transaction client/mysqldump.c: force the transaction isolation level to REPEATABLE READ when --single-transaction --- client/mysqldump.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/mysqldump.c b/client/mysqldump.c index d511dc3bbde..14ebe9ea8f7 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -2200,8 +2200,15 @@ static int start_transaction(MYSQL *mysql_con, my_bool consistent_read_now) We use BEGIN for old servers. --single-transaction --master-data will fail on old servers, but that's ok as it was already silently broken (it didn't do a consistent read, so better tell people frankly, with the error). + + We want the first consistent read to be used for all tables to dump so we + need the REPEATABLE READ level (not anything lower, for example READ + COMMITTED would give one new consistent read per dumped table). */ return (mysql_query_with_error_report(mysql_con, 0, + "SET SESSION TRANSACTION ISOLATION " + "LEVEL REPEATABLE READ") || + mysql_query_with_error_report(mysql_con, 0, consistent_read_now ? "START TRANSACTION " "WITH CONSISTENT SNAPSHOT" : From 90b9065dce225bdc3844aaa1b15fe110e1eaa2fa Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 03:02:49 +0200 Subject: [PATCH 10/90] Fix accesses to uninitialized memory (found by valgrind) mysys/my_alloc.c: Added comment for free_root sql/filesort.cc: Removed valgrind warning sql/sql_select.cc: Remove not needed my_casedn_str() for internal files (Old code actually didn't do any god as it was accessing not used memory) sql/sql_view.cc: Removed access to uninitialized memory sql/table.cc: Cleanup of error handling --- mysys/my_alloc.c | 13 +++++++ sql/filesort.cc | 7 +++- sql/sql_select.cc | 11 ++++-- sql/sql_view.cc | 5 +-- sql/table.cc | 89 ++++++++++++++++++++++------------------------- 5 files changed, 71 insertions(+), 54 deletions(-) diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index d8c19d86e5c..c14b2899b4b 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -245,6 +245,19 @@ static inline void mark_blocks_free(MEM_ROOT* root) /* Deallocate everything used by alloc_root or just move used blocks to free list if called with MY_USED_TO_FREE + + SYNOPSIS + free_root() + root Memory root + MyFlags Flags for what should be freed: + + MY_MARK_BLOCKS_FREED Don't free blocks, just mark them free + MY_KEEP_PREALLOC If this is not set, then free also the + preallocated block + + NOTES + One can call this function either with root block initialised with + init_alloc_root() or with a bzero()-ed block. */ void free_root(MEM_ROOT *root, myf MyFlags) diff --git a/sql/filesort.cc b/sql/filesort.cc index 41104106048..0a4e747a136 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -1176,7 +1176,12 @@ sortlength(SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset) else { sortorder->length=sortorder->field->pack_length(); - if (use_strnxfrm((cs=sortorder->field->charset()))) + /* + We must test cmp_type() to ensure that ENUM and SET are sorted + as numbers + */ + if (use_strnxfrm((cs=sortorder->field->charset())) && + sortorder->field->cmp_type() == STRING_RESULT) { sortorder->need_strxnfrm= 1; *multi_byte_charset= 1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b9c8f6c1237..0273334eca2 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7823,12 +7823,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, if (temp_pool_slot != MY_BIT_NONE) // we got a slot sprintf(filename, "%s_%lx_%i", tmp_file_prefix, current_pid, temp_pool_slot); - else // if we run out of slots or we are not using tempool + else + { + /* if we run out of slots or we are not using tempool */ sprintf(filename,"%s%lx_%lx_%x",tmp_file_prefix,current_pid, thd->thread_id, thd->tmp_table++); + } - if (lower_case_table_names) - my_casedn_str(files_charset_info, path); + /* + No need for change table name to lower case as we are only creating + MyISAM or HEAP tables here + */ sprintf(path, "%s%s", mysql_tmpdir, filename); if (group) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 533876b6718..e2c4b1289fd 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -948,11 +948,12 @@ frm_type_enum mysql_frm_type(char *path) { DBUG_RETURN(FRMTYPE_ERROR); } - length= my_read(file, (byte*) header, 10, MYF(MY_WME)); + length= my_read(file, (byte*) header, sizeof(header), MYF(MY_WME)); my_close(file, MYF(MY_WME)); if (length == (int) MY_FILE_ERROR) DBUG_RETURN(FRMTYPE_ERROR); - if (!strncmp(header, "TYPE=VIEW\n", 10)) + if (length < (int) sizeof(header) || + !strncmp(header, "TYPE=VIEW\n", sizeof(header))) DBUG_RETURN(FRMTYPE_VIEW); DBUG_RETURN(FRMTYPE_TABLE); // Is probably a .frm table } diff --git a/sql/table.cc b/sql/table.cc index 97f17ea2417..71198993009 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -103,11 +103,11 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, O_RDONLY | O_SHARE, MYF(0))) < 0) - goto err_w_init; + goto err; error= 4; if (my_read(file,(byte*) head,64,MYF(MY_NABP))) - goto err_w_init; + goto err; if (memcmp(head, "TYPE=", 5) == 0) { @@ -116,9 +116,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (db_stat & NO_ERR_ON_NEW_FRM) DBUG_RETURN(5); - + file= -1; // caller can't process new .frm - goto err_w_init; + goto err; } share->blob_ptr_size= sizeof(char*); @@ -131,21 +131,21 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, share->path= strdup_root(&outparam->mem_root, name); outparam->alias= my_strdup(alias, MYF(MY_WME)); if (!share->table_name || !share->path || !outparam->alias) - goto err_not_open; + goto err; *fn_ext(share->table_name)='\0'; // Remove extension *fn_ext(share->path)='\0'; // Remove extension if (head[0] != (uchar) 254 || head[1] != 1 || (head[2] != FRM_VER && head[2] != FRM_VER+1 && ! (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ new_field_pack_flag=head[27]; new_frm_ver= (head[2] - FRM_VER); field_pack_length= new_frm_ver < 2 ? 11 : 17; error=3; if (!(pos=get_form_pos(file,head,(TYPELIB*) 0))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ *fn_ext(index_file)='\0'; // Remove .frm extension share->frm_version= head[2]; @@ -181,7 +181,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, key_info_length= (uint) uint2korr(head+28); VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0))); if (read_string(file,(gptr*) &disk_buff,key_info_length)) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ if (disk_buff[0] & 0x80) { share->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f); @@ -201,7 +201,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO); if (!(keyinfo = (KEY*) alloc_root(&outparam->mem_root, n_length+uint2korr(disk_buff+4)))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ bzero((char*) keyinfo,n_length); outparam->key_info=keyinfo; key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys); @@ -210,7 +210,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, ulong *rec_per_key; if (!(rec_per_key= (ulong*) alloc_root(&outparam->mem_root, sizeof(ulong*)*key_parts))) - goto err_not_open; + goto err; for (i=0 ; i < keys ; i++, keyinfo++) { @@ -279,7 +279,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, /* Allocate handler */ if (!(outparam->file= get_new_handler(outparam, share->db_type))) - goto err_not_open; + goto err; error=4; outparam->reginfo.lock_type= TL_UNLOCK; @@ -296,14 +296,14 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, share->rec_buff_length= rec_buff_length; if (!(record= (char *) alloc_root(&outparam->mem_root, rec_buff_length * records))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ share->default_values= record; if (my_pread(file,(byte*) record, (uint) share->reclength, (ulong) (uint2korr(head+6)+ ((uint2korr(head+14) == 0xffff ? uint4korr(head+47) : uint2korr(head+14)))), MYF(MY_NABP))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ if (records == 1) { @@ -332,12 +332,13 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, } #endif VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0))); - if (my_read(file,(byte*) head,288,MYF(MY_NABP))) goto err_not_open; + if (my_read(file,(byte*) head,288,MYF(MY_NABP))) + goto err; if (crypted) { crypted->decode((char*) head+256,288-256); if (sint2korr(head+284) != 0) // Should be 0 - goto err_not_open; // Wrong password + goto err; // Wrong password } share->fields= uint2korr(head+258); @@ -359,13 +360,13 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, (share->fields+interval_parts+ keys+3)*sizeof(my_string)+ (n_length+int_length+com_length))))) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ outparam->field=field_ptr; read_length=(uint) (share->fields * field_pack_length + pos+ (uint) (n_length+int_length+com_length)); if (read_string(file,(gptr*) &disk_buff,read_length)) - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ if (crypted) { crypted->decode((char*) disk_buff,read_length); @@ -398,7 +399,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, uint count= (uint) (interval->count + 1) * sizeof(uint); if (!(interval->type_lengths= (uint *) alloc_root(&outparam->mem_root, count))) - goto err_not_open; + goto err; for (count= 0; count < interval->count; count++) interval->type_lengths[count]= strlen(interval->type_names[count]); interval->type_lengths[count]= 0; @@ -459,7 +460,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, charset= &my_charset_bin; #else error= 4; // unsupported field type - goto err_not_open; + goto err; #endif } else @@ -470,7 +471,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, { error= 5; // Unknown or unavailable charset errarg= (int) strpos[14]; - goto err_not_open; + goto err; } } if (!comment_length) @@ -543,7 +544,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (!reg_field) // Not supported field type { error= 4; - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ } reg_field->comment=comment; if (field_type == FIELD_TYPE_BIT) @@ -616,7 +617,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, (uint) key_part->length); #ifdef EXTRA_DEBUG if (key_part->fieldnr > share->fields) - goto err_not_open; // sanity check + goto err; // sanity check #endif if (key_part->fieldnr) { // Should always be true ! @@ -767,7 +768,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, if (!(share->blob_field= save= (uint*) alloc_root(&outparam->mem_root, (uint) (share->blob_fields* sizeof(uint))))) - goto err_not_open; + goto err; for (i=0, ptr= outparam->field ; *ptr ; ptr++, i++) { if ((*ptr)->flags & BLOB_FLAG) @@ -779,25 +780,25 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, error=2; if (db_stat) { - int err; + int ha_err; unpack_filename(index_file,index_file); - if ((err=(outparam->file-> - ha_open(index_file, - (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR), - (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : - ((db_stat & HA_WAIT_IF_LOCKED) || - (specialflag & SPECIAL_WAIT_IF_LOCKED)) ? - HA_OPEN_WAIT_IF_LOCKED : - (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ? - HA_OPEN_ABORT_IF_LOCKED : - HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags)))) + if ((ha_err= (outparam->file-> + ha_open(index_file, + (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR), + (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : + ((db_stat & HA_WAIT_IF_LOCKED) || + (specialflag & SPECIAL_WAIT_IF_LOCKED)) ? + HA_OPEN_WAIT_IF_LOCKED : + (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ? + HA_OPEN_ABORT_IF_LOCKED : + HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags)))) { /* Set a flag if the table is crashed and it can be auto. repaired */ - share->crashed= ((err == HA_ERR_CRASHED_ON_USAGE) && + share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) && outparam->file->auto_repair() && !(ha_open_flags & HA_OPEN_FOR_REPAIR)); - if (err == HA_ERR_NO_SUCH_TABLE) + if (ha_err == HA_ERR_NO_SUCH_TABLE) { /* The table did not exists in storage engine, use same error message as if the .frm file didn't exist */ @@ -806,10 +807,10 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, } else { - outparam->file->print_error(err, MYF(0)); + outparam->file->print_error(ha_err, MYF(0)); error_reported= TRUE; } - goto err_not_open; /* purecov: inspected */ + goto err; /* purecov: inspected */ } } share->db_low_byte_first= outparam->file->low_byte_first(); @@ -822,15 +823,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, #endif DBUG_RETURN (0); - err_w_init: - /* - Avoid problem with uninitialized data - Note that we don't have to initialize outparam->s here becasue - the caller will check if the pointer exists in case of errors - */ - bzero((char*) outparam,sizeof(*outparam)); - - err_not_open: + err: x_free((gptr) disk_buff); if (file > 0) VOID(my_close(file,MYF(MY_WME))); @@ -843,7 +836,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, outparam->file=0; // For easier errorchecking outparam->db_stat=0; hash_free(&share->name_hash); - free_root(&outparam->mem_root, MYF(0)); + free_root(&outparam->mem_root, MYF(0)); // Safe to call on bzero'd root my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR)); DBUG_RETURN (error); } /* openfrm */ From 4017b57bbb9927824ca85afd44aec6f4905b1ded Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 15:14:11 +0200 Subject: [PATCH 11/90] row0mysql.c: row_truncate_table_for_mysql(): Reset the auto_increment counter. innobase/row/row0mysql.c: row_truncate_table_for_mysql(): Reset the auto_increment counter. --- innobase/row/row0mysql.c | 1 + 1 file changed, 1 insertion(+) diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 67477b36a05..a9b9d096e6b 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -2683,6 +2683,7 @@ fputs(" InnoDB: Unable to assign a new identifier to table ", stderr); dict_table_change_id_in_cache(table, new_id); } + dict_table_autoinc_initialize(table, 0); dict_update_statistics(table); trx_commit_for_mysql(trx); From 8dc27f1ef94d909f063dd2fa3cea2619eae74518 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 16:15:14 +0200 Subject: [PATCH 12/90] InnoDB: Detect the availability of the Mac OS X fsync() work-around at run-time, so that an executable compiled on Mac OS X 10.2 can be run on Mac OS X 10.2 (without the work-around) and Mac OS X 10.3 and later with the work-aroud enabled. innobase/include/srv0start.h: Mac OS X: Add srv_have_fullfsync innobase/os/os0file.c: os_file_flush(): Use F_FULLFSYNC on Mac OS X 10.3, but not on 10.2 innobase/srv/srv0start.c: innobase_start_or_create_for_mysql(): When compiled on OS X 10.2, detect if the binary is running on OS X 10.3 or later, and set srv_have_fullfsync accordingly. --- innobase/include/srv0start.h | 4 ++++ innobase/os/os0file.c | 24 ++++++++++++++++++------ innobase/srv/srv0start.c | 27 +++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/innobase/include/srv0start.h b/innobase/include/srv0start.h index 75af1a212b4..8df0f97c4ff 100644 --- a/innobase/include/srv0start.h +++ b/innobase/include/srv0start.h @@ -75,6 +75,10 @@ extern dulint srv_start_lsn; void set_panic_flag_for_netware(void); #endif +#ifdef HAVE_DARWIN_THREADS +extern ibool srv_have_fullfsync; +#endif + extern ulint srv_sizeof_trx_t_in_ha_innodb_cc; extern ibool srv_is_being_started; diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 60760d1f8b8..6fb27346a37 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -1763,19 +1763,31 @@ os_file_flush( #else int ret; -#if defined(HAVE_DARWIN_THREADS) && defined(F_FULLFSYNC) +#if defined(HAVE_DARWIN_THREADS) +# ifndef F_FULLFSYNC + /* The following definition is from the Mac OS X 10.3 */ +# define F_FULLFSYNC 51 /* fsync + ask the drive to flush to the media */ +# elif F_FULLFSYNC != 51 +# error "F_FULLFSYNC != 51: ABI incompatibility with Mac OS X 10.3" +# endif /* Apple has disabled fsync() for internal disk drives in OS X. That caused corruption for a user when he tested a power outage. Let us in OS X use a nonstandard flush method recommended by an Apple engineer. */ - ret = fcntl(file, F_FULLFSYNC, NULL); - - if (ret) { - /* If we are not on a file system that supports this, then - fall back to a plain fsync. */ + if (!srv_have_fullfsync) { + /* If we are not on an operating system that supports this, + then fall back to a plain fsync. */ ret = fsync(file); + } else { + ret = fcntl(file, F_FULLFSYNC, NULL); + + if (ret) { + /* If we are not on a file system that supports this, + then fall back to a plain fsync. */ + ret = fsync(file); + } } #elif HAVE_FDATASYNC ret = fdatasync(file); diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 7a61a885ef9..fe05f07df21 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -61,6 +61,11 @@ dulint srv_start_lsn; /* Log sequence number at shutdown */ dulint srv_shutdown_lsn; +#ifdef HAVE_DARWIN_THREADS +# include +ibool srv_have_fullfsync = FALSE; +#endif + ibool srv_start_raw_disk_in_use = FALSE; static ibool srv_start_has_been_called = FALSE; @@ -935,6 +940,28 @@ innobase_start_or_create_for_mysql(void) ulint i; ibool srv_file_per_table_original_value = srv_file_per_table; mtr_t mtr; +#ifdef HAVE_DARWIN_THREADS +# ifdef F_FULLFSYNC + /* This executable has been compiled on Mac OS X 10.3 or later. + Assume that F_FULLFSYNC is available at run-time. */ + srv_have_fullfsync = TRUE; +# else /* F_FULLFSYNC */ + /* This executable has been compiled on Mac OS X 10.2 + or earlier. Determine if the executable is running + on Mac OS X 10.3 or later. */ + struct utsname utsname; + if (uname(&utsname)) { + fputs("InnoDB: cannot determine Mac OS X version!\n", stderr); + } else { + srv_have_fullfsync = strcmp(utsname.release, "7.") >= 0; + } + if (!srv_have_fullfsync) { + fputs( +"InnoDB: On Mac OS X, fsync() may be broken on internal drives,\n" +"InnoDB: making transactions unsafe!\n", stderr); + } +# endif /* F_FULLFSYNC */ +#endif /* HAVE_DARWIN_THREADS */ if (sizeof(ulint) != sizeof(void*)) { fprintf(stderr, From e667cf91daa8cc07ebbaf1484a5e5e1ab6590109 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 11:58:10 -0800 Subject: [PATCH 13/90] Fix mysql_install_db to look for libexecdir relative to basedir when it has been specified. (Bug #7347) scripts/mysql_install_db.sh: When basedir is specified, look for libexecdir relative to that --- scripts/mysql_install_db.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index f9f3160d220..8d47d67792a 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -98,9 +98,9 @@ else if test -x "$basedir/libexec/mysqld" then execdir="$basedir/libexec" -elif test -x "@libexecdir@/mysqld" +elif test -x "$basedir/sbin/mysqld" then - execdir="@libexecdir@" + execdir="$basedir/sbin" else execdir="$basedir/bin" fi From 177e99f32719b9c20c55c19fbbc9cef09550d9e1 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 00:09:15 +0200 Subject: [PATCH 14/90] Fix bug in INSERT DELAYED with prepared statements The bug was that if you have two TL_WRITE_DELAYED at the same time, mi_lock_databases() could be done in the wrong order and we could write the wrong header to the MyISAM index file. sql/mysql_priv.h: Fix bug in insert delayed with prepared statements sql/sql_base.cc: Fix bug in insert delayed with prepared statements sql/sql_prepare.cc: Fix bug in insert delayed with prepared statements The bug was that if you have two TL_WRITE_DELAYED at the same time, mi_lock_databases() could be done in the wrong order and we could write the wrong header to the MyISAM index file. --- sql/mysql_priv.h | 1 + sql/sql_base.cc | 28 ++++++++++++++++++++++++++++ sql/sql_prepare.cc | 6 +++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 204b319138e..4b785aafc5f 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -725,6 +725,7 @@ void wait_for_refresh(THD *thd); int open_tables(THD *thd, TABLE_LIST *tables, uint *counter); int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables); int open_and_lock_tables(THD *thd,TABLE_LIST *tables); +int open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables); void relink_tables_for_derived(THD *thd); int lock_tables(THD *thd, TABLE_LIST *tables, uint counter); TABLE *open_temporary_table(THD *thd, const char *path, const char *db, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 2f2d9b290ac..263c68a82b7 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1702,6 +1702,34 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables) } +/* + Open all tables in list and process derived tables + + SYNOPSIS + open_normal_and_derived_tables + thd - thread handler + tables - list of tables for open&locking + + RETURN + FALSE - ok + TRUE - error + + NOTE + This is to be used on prepare stage when you don't read any + data from the tables. +*/ + +int open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables) +{ + uint counter; + DBUG_ENTER("open_normal_and_derived_tables"); + if (open_tables(thd, tables, &counter)) + DBUG_RETURN(-1); /* purecov: inspected */ + relink_tables_for_derived(thd); + DBUG_RETURN(mysql_handle_derived(thd->lex)); +} + + /* Let us propagate pointers to open tables from global table list to table lists in particular selects if needed. diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index ecf01824755..1dc46aef4da 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -897,8 +897,12 @@ static int mysql_test_insert(Prepared_statement *stmt, /* open temporary memory pool for temporary data allocated by derived tables & preparation procedure + Note that this is done without locks (should not be needed as we will not + access any data here) + If we would use locks, then we have to ensure we are not using + TL_WRITE_DELAYED as having two such locks can cause table corruption. */ - if (open_and_lock_tables(thd, table_list)) + if (open_normal_and_derived_tables(thd, table_list)) { DBUG_RETURN(-1); } From 653db58bee2755c80642549b4536832ddaa200eb Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 01:59:03 +0300 Subject: [PATCH 15/90] fix C++ comments in C file (fixed in 5.0 already) strings/ctype-uca.c: fix C++ comments in C file --- strings/ctype-uca.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index 4992ef2dcd1..452ca263433 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -7214,7 +7214,7 @@ static int my_strnxfrm_uca(CHARSET_INFO *cs, uchar *dst, uint dstlen, const uchar *src, uint srclen) { - uchar *de = dst + (dstlen & (uint) ~1); // add even length for easier code + uchar *de = dst + (dstlen & (uint) ~1); /* add even length for easier code */ int s_res; my_uca_scanner scanner; scanner_handler->init(&scanner, cs, src, srclen); @@ -7232,7 +7232,7 @@ static int my_strnxfrm_uca(CHARSET_INFO *cs, dst[1]= s_res & 0xFF; dst+= 2; } - if (dstlen & 1) // if odd number then fill the last char + if (dstlen & 1) /* if odd number then fill the last char */ *dst= '\0'; return dstlen; From 8a5fe7cfdfb8ff893c387153bee7c1600cd0795b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 17:38:13 -0800 Subject: [PATCH 16/90] Output 'MEMORY' as table type for tables using the memory (nee heap) storage engine, except when running with sql_mode & MYSQL323. (Bug #6659) mysql-test/r/create.result: Fix test results mysql-test/r/ctype_utf8.result: Fix test results mysql-test/r/information_schema.result: Fix results mysql-test/r/show_check.result: Fix results sql/ha_heap.h: Output 'HEAP' in MySQL 3.23 compatibility mode mysql-test/r/heap.result: Update results mysql-test/r/sql_mode.result: Update results --- mysql-test/r/create.result | 8 ++--- mysql-test/r/ctype_utf8.result | 8 ++--- mysql-test/r/heap.result | 20 ++++++------ mysql-test/r/information_schema.result | 4 +-- mysql-test/r/show_check.result | 42 +++++++++++++------------- mysql-test/r/sql_mode.result | 6 ++-- sql/ha_heap.h | 6 +++- 7 files changed, 49 insertions(+), 45 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index f2e91c36f75..05d1ba026ba 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -204,7 +204,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 drop table t1; SET SESSION storage_engine="gemini"; ERROR 42000: Unknown table engine 'gemini' @@ -216,7 +216,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 SET SESSION storage_engine=default; drop table t1; create table t1 ( k1 varchar(2), k2 int, primary key(k1,k2)); @@ -361,7 +361,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 drop table t1; SET SESSION storage_engine="gemini"; ERROR 42000: Unknown table engine 'gemini' @@ -373,7 +373,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 SET SESSION storage_engine=default; drop table t1; create table t1(a int,b int,c int unsigned,d date,e char,f datetime,g time,h blob); diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index c7d1d94e208..5ff599416b5 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -413,7 +413,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c` char(10) character set utf8 default NULL, UNIQUE KEY `a` (`c`(1)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); insert into t1 values ('aa'); ERROR 23000: Duplicate entry 'aa' for key 1 @@ -449,7 +449,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c` char(10) character set utf8 default NULL, UNIQUE KEY `a` USING BTREE (`c`(1)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); insert into t1 values ('aa'); ERROR 23000: Duplicate entry 'aa' for key 1 @@ -571,7 +571,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c` char(10) character set utf8 collate utf8_bin default NULL, UNIQUE KEY `a` (`c`(1)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); insert into t1 values ('aa'); ERROR 23000: Duplicate entry 'aa' for key 1 @@ -607,7 +607,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `c` char(10) character set utf8 collate utf8_bin default NULL, UNIQUE KEY `a` USING BTREE (`c`(1)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); insert into t1 values ('aa'); ERROR 23000: Duplicate entry 'aa' for key 1 diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result index 4d5aabb8b3a..f79bcf3f1dd 100644 --- a/mysql-test/r/heap.result +++ b/mysql-test/r/heap.result @@ -266,7 +266,7 @@ t1 CREATE TABLE `t1` ( `v` varchar(10) default NULL, `c` char(10) default NULL, `t` varchar(50) default NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 create table t2 like t1; show create table t2; Table Create Table @@ -274,7 +274,7 @@ t2 CREATE TABLE `t2` ( `v` varchar(10) default NULL, `c` char(10) default NULL, `t` varchar(50) default NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 create table t3 select * from t1; show create table t3; Table Create Table @@ -282,7 +282,7 @@ t3 CREATE TABLE `t3` ( `v` varchar(10) default NULL, `c` char(10) default NULL, `t` varchar(50) default NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 alter table t1 modify c varchar(10); show create table t1; Table Create Table @@ -290,7 +290,7 @@ t1 CREATE TABLE `t1` ( `v` varchar(10) default NULL, `c` varchar(10) default NULL, `t` varchar(50) default NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 alter table t1 modify v char(10); show create table t1; Table Create Table @@ -298,7 +298,7 @@ t1 CREATE TABLE `t1` ( `v` char(10) default NULL, `c` varchar(10) default NULL, `t` varchar(50) default NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 alter table t1 modify t varchar(10); Warnings: Warning 1265 Data truncated for column 't' at row 2 @@ -308,7 +308,7 @@ t1 CREATE TABLE `t1` ( `v` char(10) default NULL, `c` varchar(10) default NULL, `t` varchar(10) default NULL -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 select concat('*',v,'*',c,'*',t,'*') from t1; concat('*',v,'*',c,'*',t,'*') *+*+*+ * @@ -324,7 +324,7 @@ t1 CREATE TABLE `t1` ( KEY `v` (`v`), KEY `c` (`c`), KEY `t` (`t`(10)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 select count(*) from t1; count(*) 270 @@ -559,7 +559,7 @@ t1 CREATE TABLE `t1` ( KEY `v` USING BTREE (`v`), KEY `c` USING BTREE (`c`), KEY `t` USING BTREE (`t`(10)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 select count(*) from t1; count(*) 270 @@ -650,7 +650,7 @@ t1 CREATE TABLE `t1` ( KEY `v` (`v`(5)), KEY `c` (`c`(5)), KEY `t` (`t`(5)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 drop table t1; create table t1 (v varchar(65530), key(v(10))); show create table t1; @@ -658,7 +658,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `v` varchar(65530) default NULL, KEY `v` (`v`(10)) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 insert into t1 values(repeat('a',65530)); select length(v) from t1 where v=repeat('a',65530); length(v) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index e6793843c93..bf1f828edf5 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -478,7 +478,7 @@ character_sets CREATE TEMPORARY TABLE `character_sets` ( `DEFAULT_COLLATE_NAME` varchar(64) NOT NULL default '', `DESCRIPTION` varchar(60) NOT NULL default '', `MAXLEN` bigint(3) NOT NULL default '0' -) ENGINE=HEAP DEFAULT CHARSET=utf8 MAX_ROWS=1818 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 MAX_ROWS=1818 set names latin2; SHOW CREATE TABLE INFORMATION_SCHEMA.character_sets; Table Create Table @@ -487,7 +487,7 @@ character_sets CREATE TEMPORARY TABLE `character_sets` ( `DEFAULT_COLLATE_NAME` varchar(64) NOT NULL default '', `DESCRIPTION` varchar(60) NOT NULL default '', `MAXLEN` bigint(3) NOT NULL default '0' -) ENGINE=HEAP DEFAULT CHARSET=utf8 MAX_ROWS=1818 +) ENGINE=MEMORY DEFAULT CHARSET=utf8 MAX_ROWS=1818 set names latin1; create table t1 select * from information_schema.CHARACTER_SETS where CHARACTER_SET_NAME like "latin1"; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 6efb1c4b995..5b0f57bea15 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -315,57 +315,57 @@ insert into t2 values (1),(2); insert into t3 values (1,1),(2,2); show table status; 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 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t1 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t2 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t3 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL insert into t1 values (3),(4); insert into t2 values (3),(4); insert into t3 values (3,3),(4,4); show table status; 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 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t1 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t2 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t3 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL insert into t1 values (5); insert into t2 values (5); insert into t3 values (5,5); show table status; 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 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t1 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t2 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t3 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL delete from t1 where a=3; delete from t2 where b=3; delete from t3 where a=3; show table status; 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 HEAP 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL -t2 HEAP 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL -t3 HEAP 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL +t1 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL +t2 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL +t3 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL delete from t1; delete from t2; delete from t3; show table status; 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 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t1 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t2 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t3 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL insert into t1 values (5); insert into t2 values (5); insert into t3 values (5,5); show table status; 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 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t2 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL -t3 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t1 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t2 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL +t3 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL delete from t1 where a=5; delete from t2 where b=5; delete from t3 where a=5; show table status; 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 HEAP 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL -t2 HEAP 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL -t3 HEAP 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL +t1 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL +t2 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL +t3 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL drop table t1, t2, t3; create database mysqltest; show create database mysqltest; diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result index e01355816c3..5492a7a65fc 100644 --- a/mysql-test/r/sql_mode.result +++ b/mysql-test/r/sql_mode.result @@ -18,7 +18,7 @@ t1 CREATE TABLE `t1` ( `email` varchar(60) character set latin2 NOT NULL default '', PRIMARY KEY (`a`), UNIQUE KEY `email` USING BTREE (`email`) -) ENGINE=HEAP DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC +) ENGINE=MEMORY DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC set @@sql_mode="ansi_quotes"; show variables like 'sql_mode'; Variable_name Value @@ -31,7 +31,7 @@ t1 CREATE TABLE "t1" ( "email" varchar(60) character set latin2 NOT NULL default '', PRIMARY KEY ("a"), UNIQUE KEY "email" USING BTREE ("email") -) ENGINE=HEAP DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC +) ENGINE=MEMORY DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC set @@sql_mode="no_table_options"; show variables like 'sql_mode'; Variable_name Value @@ -57,7 +57,7 @@ t1 CREATE TABLE `t1` ( `email` varchar(60) character set latin2 NOT NULL default '', PRIMARY KEY (`a`), UNIQUE KEY `email` (`email`) -) ENGINE=HEAP DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC +) ENGINE=MEMORY DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC set @@sql_mode="no_field_options,mysql323,mysql40"; show variables like 'sql_mode'; Variable_name Value diff --git a/sql/ha_heap.h b/sql/ha_heap.h index 8b44695df07..fb526888b01 100644 --- a/sql/ha_heap.h +++ b/sql/ha_heap.h @@ -32,7 +32,11 @@ class ha_heap: public handler public: ha_heap(TABLE *table): handler(table), file(0), records_changed(0) {} ~ha_heap() {} - const char *table_type() const { return "HEAP"; } + const char *table_type() const + { + return (table->in_use->variables.sql_mode & MODE_MYSQL323) ? + "HEAP" : "MEMORY"; + } const char *index_type(uint inx) { return ((table->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ? "BTREE" : From 6f3b5a478bfe30631597683699658362dfc29c8b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 14:16:56 +0400 Subject: [PATCH 17/90] Bug#7284: strnxfrm generates different results for equal strings additional fix for cp932 and eucjpms, recently implemented by Shuichi. --- mysql-test/r/ctype_cp932.result | 20 ++++++++++++++++++++ mysql-test/r/ctype_eucjpms.result | 20 ++++++++++++++++++++ mysql-test/t/ctype_cp932.test | 6 ++++++ mysql-test/t/ctype_eucjpms.test | 6 ++++++ strings/ctype-cp932.c | 7 +++++-- 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/ctype_cp932.result b/mysql-test/r/ctype_cp932.result index c5e57d996fd..2661ff5e3c9 100755 --- a/mysql-test/r/ctype_cp932.result +++ b/mysql-test/r/ctype_cp932.result @@ -11315,3 +11315,23 @@ DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; DROP TABLE t4; +SET collation_connection='cp932_japanese_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +cp932_japanese_ci 6109 +cp932_japanese_ci 61 +cp932_japanese_ci 6120 +drop table t1; +SET collation_connection='cp932_bin'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +cp932_bin 6109 +cp932_bin 61 +cp932_bin 6120 +drop table t1; diff --git a/mysql-test/r/ctype_eucjpms.result b/mysql-test/r/ctype_eucjpms.result index f3c22a55a54..a07ff9b28be 100755 --- a/mysql-test/r/ctype_eucjpms.result +++ b/mysql-test/r/ctype_eucjpms.result @@ -9785,3 +9785,23 @@ DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; DROP TABLE t4; +SET collation_connection='eucjpms_japanese_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +eucjpms_japanese_ci 6109 +eucjpms_japanese_ci 61 +eucjpms_japanese_ci 6120 +drop table t1; +SET collation_connection='eucjpms_bin'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +eucjpms_bin 6109 +eucjpms_bin 61 +eucjpms_bin 6120 +drop table t1; diff --git a/mysql-test/t/ctype_cp932.test b/mysql-test/t/ctype_cp932.test index 504468b1e1d..24da8a76dcd 100755 --- a/mysql-test/t/ctype_cp932.test +++ b/mysql-test/t/ctype_cp932.test @@ -395,3 +395,9 @@ DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; DROP TABLE t4; + + +SET collation_connection='cp932_japanese_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='cp932_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_eucjpms.test b/mysql-test/t/ctype_eucjpms.test index abc7105c12e..578d116fcb9 100755 --- a/mysql-test/t/ctype_eucjpms.test +++ b/mysql-test/t/ctype_eucjpms.test @@ -342,3 +342,9 @@ DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; DROP TABLE t4; + + +SET collation_connection='eucjpms_japanese_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='eucjpms_bin'; +-- source include/ctype_filesort.inc diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c index 218fc72ad17..f177ec84f60 100644 --- a/strings/ctype-cp932.c +++ b/strings/ctype-cp932.c @@ -244,7 +244,8 @@ static int my_strnncoll_cp932(CHARSET_INFO *cs __attribute__((unused)), static int my_strnncollsp_cp932(CHARSET_INFO *cs __attribute__((unused)), const uchar *a, uint a_length, - const uchar *b, uint b_length) + const uchar *b, uint b_length, + my_bool diff_end_space __attribute__((unused))) { const uchar *a_end= a + a_length; const uchar *b_end= b + b_length; @@ -291,7 +292,9 @@ static int my_strnxfrm_cp932(CHARSET_INFO *cs __attribute__((unused)), else *dest++ = sort_order_cp932[(uchar)*src++]; } - return srclen; + if (len > srclen) + bfill(dest, len - srclen, ' '); + return len; } From 4db9aaeea7e8ffce21740913071d58793340af3d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 13:54:23 +0200 Subject: [PATCH 18/90] InnoDB: Remove redundant page_no field from dict_index_t. This completes the patch for fast TRUNCATE TABLE. innobase/dict/dict0boot.c: dict_boot(): Add page_no parameter to dict_index_add_to_cache() innobase/dict/dict0crea.c: Remove dict_index_t:page_no; add ind_node_t:page_no innobase/dict/dict0dict.c: dict_index_add_to_cache(): Add parameter page_no dict_tree_create(): Add parameter page_no innobase/dict/dict0load.c: dict_load_indexes(): Add page_no to dict_index_add_to_cache() call innobase/ibuf/ibuf0ibuf.c: ibuf_data_init_for_space(): Move page_no to dict_index_add_to_cache() innobase/include/dict0crea.h: ind_node_t: Add page_no field innobase/include/dict0dict.h: dict_index_add_to_cache(): Add page_no dict_tree_create(): Add page_no innobase/include/dict0mem.h: dict_index_t: Remove page_no, as dict_tree_t has "page" field innobase/row/row0mysql.c: row_truncate_table_for_mysql(): Improve the comments --- innobase/dict/dict0boot.c | 31 ++++++++++++++++--------------- innobase/dict/dict0crea.c | 16 ++++++++-------- innobase/dict/dict0dict.c | 13 ++++++------- innobase/dict/dict0load.c | 4 +--- innobase/ibuf/ibuf0ibuf.c | 4 +--- innobase/include/dict0crea.h | 1 + innobase/include/dict0dict.h | 6 ++++-- innobase/include/dict0mem.h | 1 - innobase/row/row0mysql.c | 16 ++++++++++++---- 9 files changed, 49 insertions(+), 43 deletions(-) diff --git a/innobase/dict/dict0boot.c b/innobase/dict/dict0boot.c index 883c5464319..0f6d55c9341 100644 --- a/innobase/dict/dict0boot.c +++ b/innobase/dict/dict0boot.c @@ -223,6 +223,7 @@ dict_boot(void) dict_index_t* index; dict_hdr_t* dict_hdr; mtr_t mtr; + ibool success; mtr_start(&mtr); @@ -275,20 +276,20 @@ dict_boot(void) dict_mem_index_add_field(index, "NAME", 0, 0); - index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_TABLES, - MLOG_4BYTES, &mtr); index->id = DICT_TABLES_ID; - ut_a(dict_index_add_to_cache(table, index)); + success = dict_index_add_to_cache(table, index, mtr_read_ulint( + dict_hdr + DICT_HDR_TABLES, MLOG_4BYTES, &mtr)); + ut_a(success); /*-------------------------*/ index = dict_mem_index_create("SYS_TABLES", "ID_IND", DICT_HDR_SPACE, DICT_UNIQUE, 1); dict_mem_index_add_field(index, "ID", 0, 0); - index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_TABLE_IDS, - MLOG_4BYTES, &mtr); index->id = DICT_TABLE_IDS_ID; - ut_a(dict_index_add_to_cache(table, index)); + success = dict_index_add_to_cache(table, index, mtr_read_ulint( + dict_hdr + DICT_HDR_TABLE_IDS, MLOG_4BYTES, &mtr)); + ut_a(success); /*-------------------------*/ table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, FALSE); @@ -311,10 +312,10 @@ dict_boot(void) dict_mem_index_add_field(index, "TABLE_ID", 0, 0); dict_mem_index_add_field(index, "POS", 0, 0); - index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_COLUMNS, - MLOG_4BYTES, &mtr); index->id = DICT_COLUMNS_ID; - ut_a(dict_index_add_to_cache(table, index)); + success = dict_index_add_to_cache(table, index, mtr_read_ulint( + dict_hdr + DICT_HDR_COLUMNS, MLOG_4BYTES, &mtr)); + ut_a(success); /*-------------------------*/ table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, FALSE); @@ -347,10 +348,10 @@ dict_boot(void) dict_mem_index_add_field(index, "TABLE_ID", 0, 0); dict_mem_index_add_field(index, "ID", 0, 0); - index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_INDEXES, - MLOG_4BYTES, &mtr); index->id = DICT_INDEXES_ID; - ut_a(dict_index_add_to_cache(table, index)); + success = dict_index_add_to_cache(table, index, mtr_read_ulint( + dict_hdr + DICT_HDR_INDEXES, MLOG_4BYTES, &mtr)); + ut_a(success); /*-------------------------*/ table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, FALSE); @@ -368,10 +369,10 @@ dict_boot(void) dict_mem_index_add_field(index, "INDEX_ID", 0, 0); dict_mem_index_add_field(index, "POS", 0, 0); - index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_FIELDS, - MLOG_4BYTES, &mtr); index->id = DICT_FIELDS_ID; - ut_a(dict_index_add_to_cache(table, index)); + success = dict_index_add_to_cache(table, index, mtr_read_ulint( + dict_hdr + DICT_HDR_FIELDS, MLOG_4BYTES, &mtr)); + ut_a(success); mtr_commit(&mtr); /*-------------------------*/ diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index e744ffda7a6..3c496bae5b4 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -544,9 +544,7 @@ dict_build_index_def_step( table in the same tablespace */ index->space = table->space; - - index->page_no = FIL_NULL; - + node->page_no = FIL_NULL; row = dict_create_sys_indexes_tuple(index, node->heap); node->ind_row = row; @@ -624,18 +622,18 @@ dict_create_index_tree_step( btr_pcur_move_to_next_user_rec(&pcur, &mtr); - index->page_no = btr_create(index->type, index->space, index->id, + node->page_no = btr_create(index->type, index->space, index->id, table->comp, &mtr); /* printf("Created a new index tree in space %lu root page %lu\n", index->space, index->page_no); */ page_rec_write_index_page_no(btr_pcur_get_rec(&pcur), DICT_SYS_INDEXES_PAGE_NO_FIELD, - index->page_no, &mtr); + node->page_no, &mtr); btr_pcur_close(&pcur); mtr_commit(&mtr); - if (index->page_no == FIL_NULL) { + if (node->page_no == FIL_NULL) { return(DB_OUT_OF_FILE_SPACE); } @@ -793,7 +791,7 @@ dict_truncate_index_tree( root_page_no = btr_create(type, space, index_id, comp, mtr); if (index) { - index->page_no = root_page_no; + index->tree->page = root_page_no; } page_rec_write_index_page_no(rec, @@ -857,6 +855,7 @@ ind_create_graph_create( node->index = index; node->state = INDEX_BUILD_INDEX_DEF; + node->page_no = FIL_NULL; node->heap = mem_heap_create(256); node->ind_def = ins_node_create(INS_DIRECT, @@ -1076,7 +1075,8 @@ dict_create_index_step( if (node->state == INDEX_ADD_TO_CACHE) { - success = dict_index_add_to_cache(node->table, node->index); + success = dict_index_add_to_cache(node->table, node->index, + node->page_no); ut_a(success); diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index d5e0a46fd39..12749f7704f 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -1374,8 +1374,9 @@ dict_index_add_to_cache( /*====================*/ /* out: TRUE if success */ dict_table_t* table, /* in: table on which the index is */ - dict_index_t* index) /* in, own: index; NOTE! The index memory + dict_index_t* index, /* in, own: index; NOTE! The index memory object is freed in this function! */ + ulint page_no)/* in: root page number of the index */ { dict_index_t* new_index; dict_tree_t* tree; @@ -1461,10 +1462,9 @@ dict_index_add_to_cache( tree = dict_index_get_tree( UT_LIST_GET_FIRST(cluster->indexes)); new_index->tree = tree; - new_index->page_no = tree->page; } else { /* Create an index tree memory object for the index */ - tree = dict_tree_create(new_index); + tree = dict_tree_create(new_index, page_no); ut_ad(tree); new_index->tree = tree; @@ -1749,7 +1749,6 @@ dict_index_build_internal_clust( new_index->n_user_defined_cols = index->n_fields; new_index->id = index->id; - new_index->page_no = index->page_no; if (table->type != DICT_TABLE_ORDINARY) { /* The index is mixed: copy common key prefix fields */ @@ -1928,7 +1927,6 @@ dict_index_build_internal_non_clust( new_index->n_user_defined_cols = index->n_fields; new_index->id = index->id; - new_index->page_no = index->page_no; /* Copy fields from index to new_index */ dict_index_copy(new_index, index, 0, index->n_fields); @@ -3565,9 +3563,10 @@ dict_tree_t* dict_tree_create( /*=============*/ /* out, own: created tree */ - dict_index_t* index) /* in: the index for which to create: in the + dict_index_t* index, /* in: the index for which to create: in the case of a mixed tree, this should be the index of the cluster object */ + ulint page_no)/* in: root page number of the index */ { dict_tree_t* tree; @@ -3577,7 +3576,7 @@ dict_tree_create( tree->type = index->type; tree->space = index->space; - tree->page = index->page_no; + tree->page = page_no; tree->id = index->id; diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index f835d1b949a..18910acb01d 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -681,12 +681,10 @@ dict_load_indexes( } else { index = dict_mem_index_create(table->name, name_buf, space, type, n_fields); - index->page_no = page_no; index->id = id; dict_load_fields(table, index, heap); - - dict_index_add_to_cache(table, index); + dict_index_add_to_cache(table, index, page_no); } btr_pcur_move_to_next_user_rec(&pcur, &mtr); diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index cd5ac0da231..5ad61e2590f 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -548,11 +548,9 @@ ibuf_data_init_for_space( dict_mem_index_add_field(index, "PAGE_NO", 0, 0); dict_mem_index_add_field(index, "TYPES", 0, 0); - index->page_no = FSP_IBUF_TREE_ROOT_PAGE_NO; - index->id = ut_dulint_add(DICT_IBUF_ID_MIN, space); - dict_index_add_to_cache(table, index); + dict_index_add_to_cache(table, index, FSP_IBUF_TREE_ROOT_PAGE_NO); data->index = dict_table_get_first_index(table); diff --git a/innobase/include/dict0crea.h b/innobase/include/dict0crea.h index d718e92eb13..7164e53bceb 100644 --- a/innobase/include/dict0crea.h +++ b/innobase/include/dict0crea.h @@ -153,6 +153,7 @@ struct ind_node_struct{ /*----------------------*/ /* Local storage for this graph node */ ulint state; /* node execution state */ + ulint page_no;/* root page number of the index */ dict_table_t* table; /* table which owns the index */ dtuple_t* ind_row;/* index definition row built */ ulint field_no;/* next field definition to insert */ diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index eaf5b06b2a9..fdcb6c1c4e1 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -508,8 +508,9 @@ dict_index_add_to_cache( /*====================*/ /* out: TRUE if success */ dict_table_t* table, /* in: table on which the index is */ - dict_index_t* index); /* in, own: index; NOTE! The index memory + dict_index_t* index, /* in, own: index; NOTE! The index memory object is freed in this function! */ + ulint page_no);/* in: root page number of the index */ /************************************************************************ Gets the number of fields in the internal representation of an index, including fields added by the dictionary system. */ @@ -686,9 +687,10 @@ dict_tree_t* dict_tree_create( /*=============*/ /* out, own: created tree */ - dict_index_t* index); /* in: the index for which to create: in the + dict_index_t* index, /* in: the index for which to create: in the case of a mixed tree, this should be the index of the cluster object */ + ulint page_no);/* in: root page number of the index */ /************************************************************************** Frees an index tree struct. */ diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h index 670b3445a55..ff6c4ec9b28 100644 --- a/innobase/include/dict0mem.h +++ b/innobase/include/dict0mem.h @@ -218,7 +218,6 @@ struct dict_index_struct{ const char* table_name; /* table name */ dict_table_t* table; /* back pointer to table */ ulint space; /* space where the index tree is placed */ - ulint page_no;/* page number of the index tree root */ ulint trx_id_offset;/* position of the the trx id column in a clustered index record, if the fields before it are known to be of a fixed size, diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index a9b9d096e6b..6aaa0cbcf1b 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -2455,12 +2455,20 @@ queries on the table. 2) Purge and rollback: we assign a new table id for the table. Since purge and rollback look for the table based on the table id, they see the table as 'dropped' and discard their operations. -3) Insert buffer: we remove all entries for the table in the insert -buffer tree; ... TODO +3) Insert buffer: TRUNCATE TABLE is analogous to DROP TABLE, so we do not +have to remove insert buffer records, as the insert buffer works at a low +level. If a freed page is later reallocated, the allocator will remove +the ibuf entries for it. + +TODO: when we truncate *.ibd files (analogous to DISCARD TABLESPACE), we +will have to remove we remove all entries for the table in the insert +buffer tree! + 4) Linear readahead and random readahead: we use the same method as in 3) to -discard ongoing operations. +discard ongoing operations. (This will only be relevant for TRUNCATE TABLE +by DISCARD TABLESPACE.) 5) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, we -do not allow the discard. We also reserve the data dictionary latch. */ +do not allow the TRUNCATE. We also reserve the data dictionary latch. */ static const char renumber_tablespace_proc[] = "PROCEDURE RENUMBER_TABLESPACE_PROC () IS\n" From b06801534a79d9cfe1e077f8ed0a4dfd3c779877 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 16:23:32 +0300 Subject: [PATCH 19/90] Backport from 5.0 --- strings/ctype-mb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index bf69fe683ae..731fc460cef 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -274,7 +274,7 @@ uint my_well_formed_len_mb(CHARSET_INFO *cs, my_wc_t wc; int mblen; - if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <0) + if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <= 0) break; b+= mblen; pos--; From 8c3a1fde1de1338ae4f6e24172351a320f89cba2 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 18:24:32 +0400 Subject: [PATCH 20/90] A fix for bit type. pack_length_in_rec() func has been introduced. sql/field.h: A fix for bit type. As from now the pack_length_in_rec() function is used for MyISAM record length calculation instead of the pack_length(). For bit field it doesn't count uneven bits. sql/ha_myisam.cc: A fix for bit type. As from now the pack_length_in_rec() function is used for MyISAM record length calculation instead of the pack_length(). For bit field it doesn't count uneven bits. --- sql/field.h | 2 ++ sql/ha_myisam.cc | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/field.h b/sql/field.h index ab911822c2c..db4d85f2285 100644 --- a/sql/field.h +++ b/sql/field.h @@ -123,6 +123,7 @@ public: } virtual bool eq_def(Field *field); virtual uint32 pack_length() const { return (uint32) field_length; } + virtual uint32 pack_length_in_rec() const { return pack_length(); } virtual void reset(void) { bzero(ptr,pack_length()); } virtual void reset_fields() {} virtual void set_default() @@ -1237,6 +1238,7 @@ public: { get_key_image(buff, length, itRAW); } uint32 pack_length() const { return (uint32) field_length + (bit_len > 0); } + uint32 pack_length_in_rec() const { return field_length; } void sql_type(String &str) const; field_cast_enum field_cast_type() { return FIELD_CAST_BIT; } char *pack(char *to, const char *from, uint max_length=~(uint) 0); diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 87329c6f4af..9631b78bca3 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1467,7 +1467,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, fieldpos <= minpos) { /* skip null fields */ - if (!(temp_length= (*field)->pack_length())) + if (!(temp_length= (*field)->pack_length_in_rec())) continue; /* Skip null-fields */ if (! found || fieldpos < minpos || (fieldpos == minpos && temp_length < length)) From 18df9d391fefd95b09c508aa161bae014a822353 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 15:35:32 +0100 Subject: [PATCH 21/90] - make sure to enable "--without-ndb-debug" when both --debug and --with-cluster are provided. Yes, this sounds like a contradiction - enabling debugging in NBD enables code parts that may still reveal portability issues when compiled with non-gcc compilers. (request by TomasU) --- Build-tools/Do-compile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile index 1e7041e8f7a..b431f9fc1c5 100755 --- a/Build-tools/Do-compile +++ b/Build-tools/Do-compile @@ -264,7 +264,8 @@ if ($opt_stage <= 1) $opt_config_options.= " --with-berkeley-db" if ($opt_bdb); $opt_config_options.= " --with-zlib-dir=bundled" if ($opt_bundled_zlib); $opt_config_options.= " --with-client-ldflags=-all-static" if ($opt_static_client); - $opt_config_options.= " --with-debug" if ($opt_with_debug); + $opt_config_options.= " --with-debug" if ($opt_with_debug); + $opt_config_options.= " --without-ndb-debug" if ($opt_with_debug && $opt_with_cluster); $opt_config_options.= " --with-libwrap" if ($opt_libwrap); $opt_config_options.= " --with-low-memory" if ($opt_with_low_memory); $opt_config_options.= " --with-mysqld-ldflags=-all-static" if ($opt_static_server); From b3c7c4d74cf38ed4a913031ead04c44e16db0d18 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 16:14:50 +0100 Subject: [PATCH 22/90] bumped up ndb version compatible with 4.1.9 configure.in: bumped up ndb version --- configure.in | 2 +- ndb/src/common/util/version.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 45ca009123e..9f89c635e7f 100644 --- a/configure.in +++ b/configure.in @@ -16,7 +16,7 @@ SHARED_LIB_VERSION=14:0:0 # ndb version NDB_VERSION_MAJOR=4 NDB_VERSION_MINOR=1 -NDB_VERSION_BUILD=9 +NDB_VERSION_BUILD=10 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? diff --git a/ndb/src/common/util/version.c b/ndb/src/common/util/version.c index 9bc3488b078..8cc6de0fc24 100644 --- a/ndb/src/common/util/version.c +++ b/ndb/src/common/util/version.c @@ -90,6 +90,7 @@ void ndbSetOwnVersion() {} #ifndef TEST_VERSION struct NdbUpGradeCompatible ndbCompatibleTable_full[] = { + { MAKE_VERSION(4,1,10), MAKE_VERSION(4,1,9), UG_Exact }, { MAKE_VERSION(4,1,9), MAKE_VERSION(4,1,8), UG_Exact }, { MAKE_VERSION(3,5,2), MAKE_VERSION(3,5,1), UG_Exact }, { 0, 0, UG_Null } From baf0a4418acad481796523e76f66f12706c262c0 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 18:20:03 +0100 Subject: [PATCH 23/90] - replaced obsoleted "BuildPrereq" with "BuildRequires" in the RPM spec file support-files/mysql.spec.sh: - replaced obsoleted "BuildPrereq" with "BuildRequires" instead --- support-files/mysql.spec.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 5afddee609b..99280385965 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -27,7 +27,7 @@ Packager: Lenz Grimmer Vendor: MySQL AB Requires: fileutils sh-utils Provides: msqlormysql MySQL-server mysql -BuildPrereq: ncurses-devel +BuildRequires: ncurses-devel Obsoletes: mysql # Think about what you use here since the first step is to @@ -607,6 +607,10 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Fri Jan 14 2005 Lenz Grimmer + +- replaced obsoleted "BuildPrereq" with "BuildRequires" instead + * Thu Dec 31 2004 Lenz Grimmer - enabled the "Archive" storage engine for the max binary From 11b98a6e553cce8fa2dd8bd22e442b3c4cfaaa3d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 18:57:50 +0100 Subject: [PATCH 24/90] Re-enable running the 'client_test' test case during release builds on the platforms (bug#7909). mysql-test/mysql-test-run.sh: In a release build on the platforms, TESTS_BINDIR needs to be set to $BASEDIR/tests because the test program 'client_test' is expected there (see 'client_test.test' with its 'exec', bug#7909). In an installation, TESTS_BINDIR needs to be set to $BASEDIR/bin because some NDB programs are located there (see Jonas Oreland's change labeled '1.220, 2005-01-04 08:15:30+01:00'). This patch is to unite these conflicting requirements. --- mysql-test/mysql-test-run.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 274f91550d4..6c455e131bf 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -538,7 +538,12 @@ else MYSQLD="$VALGRIND $BASEDIR/bin/mysqld" fi CLIENT_BINDIR="$BASEDIR/bin" - TESTS_BINDIR="$BASEDIR/bin" + if test -d "$BASEDIR/tests" + then + TESTS_BINDIR="$BASEDIR/tests" + else + TESTS_BINDIR="$BASEDIR/bin" + fi MYSQL_TEST="$CLIENT_BINDIR/mysqltest" MYSQL_DUMP="$CLIENT_BINDIR/mysqldump" MYSQL_BINLOG="$CLIENT_BINDIR/mysqlbinlog" From b7efd8174a9e46ae89337b0364f132a574dc6c2f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 19:49:45 +0100 Subject: [PATCH 25/90] limit HEAP table size with max_heap_table_size, better estimation for mem_per_row heap/hp_create.c: limit HEAP table size with max_heap_table_size heap/hp_write.c: limit HEAP table size with max_heap_table_size include/heap.h: limit HEAP table size with max_heap_table_size sql/ha_heap.cc: limit HEAP table size with max_heap_table_size better estimation for mem_per_row --- heap/hp_create.c | 7 ++++--- heap/hp_write.c | 3 ++- include/heap.h | 7 ++++--- sql/ha_heap.cc | 24 ++++++++++++++++++------ 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/heap/hp_create.c b/heap/hp_create.c index fdfe78a1e09..af32fefea1b 100644 --- a/heap/hp_create.c +++ b/heap/hp_create.c @@ -123,15 +123,15 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, keyseg->flag= 0; keyseg->null_bit= 0; keyseg++; - - init_tree(&keyinfo->rb_tree, 0, 0, sizeof(byte*), + + init_tree(&keyinfo->rb_tree, 0, 0, sizeof(byte*), (qsort_cmp2)keys_compare, 1, NULL, NULL); keyinfo->delete_key= hp_rb_delete_key; keyinfo->write_key= hp_rb_write_key; } else { - init_block(&keyinfo->block, sizeof(HASH_INFO), min_records, + init_block(&keyinfo->block, sizeof(HASH_INFO), min_records, max_records); keyinfo->delete_key= hp_delete_key; keyinfo->write_key= hp_write_key; @@ -140,6 +140,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, } share->min_records= min_records; share->max_records= max_records; + share->max_table_size= create_info->max_table_size; share->data_length= share->index_length= 0; share->reclength= reclength; share->blength= 1; diff --git a/heap/hp_write.c b/heap/hp_write.c index 43cee67b39c..808fe6608b1 100644 --- a/heap/hp_write.c +++ b/heap/hp_write.c @@ -143,7 +143,8 @@ static byte *next_free_record_pos(HP_SHARE *info) } if (!(block_pos=(info->records % info->block.records_in_block))) { - if (info->records > info->max_records && info->max_records) + if ((info->records > info->max_records && info->max_records) || + (info->data_length + info->index_length >= info->max_table_size)) { my_errno=HA_ERR_RECORD_FILE_FULL; DBUG_RETURN(NULL); diff --git a/include/heap.h b/include/heap.h index 5e83a6e2cb5..ac2b38d1f2d 100644 --- a/include/heap.h +++ b/include/heap.h @@ -125,8 +125,8 @@ typedef struct st_hp_keydef /* Key definition with open */ TREE rb_tree; int (*write_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo, const byte *record, byte *recpos); - int (*delete_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo, - const byte *record, byte *recpos, int flag); + int (*delete_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo, + const byte *record, byte *recpos, int flag); uint (*get_key_length)(struct st_hp_keydef *keydef, const byte *key); } HP_KEYDEF; @@ -135,7 +135,7 @@ typedef struct st_heap_share HP_BLOCK block; HP_KEYDEF *keydef; ulong min_records,max_records; /* Params to open */ - ulong data_length,index_length; + ulong data_length,index_length,max_table_size; uint records; /* records */ uint blength; /* records rounded up to 2^n */ uint deleted; /* Deleted records in database */ @@ -185,6 +185,7 @@ typedef struct st_heap_create_info { uint auto_key; uint auto_key_type; + ulong max_table_size; ulonglong auto_increment; } HP_CREATE_INFO; diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index dbcf7bc9197..96c19ce0705 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -460,12 +460,24 @@ int ha_heap::create(const char *name, TABLE *table_arg, KEY_PART_INFO *key_part= pos->key_part; KEY_PART_INFO *key_part_end= key_part + pos->key_parts; - mem_per_row+= (pos->key_length + (sizeof(char*) * 2)); - keydef[key].keysegs= (uint) pos->key_parts; keydef[key].flag= (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL)); keydef[key].seg= seg; - keydef[key].algorithm= ((pos->algorithm == HA_KEY_ALG_UNDEF) ? + + switch (pos->algorithm) { + case HA_KEY_ALG_UNDEF: + case HA_KEY_ALG_HASH: + keydef[key].algorithm= HA_KEY_ALG_HASH; + mem_per_row+= sizeof(char*) * 2; // = sizeof(HASH_INFO) + break; + case HA_KEY_ALG_BTREE: + keydef[key].algorithm= HA_KEY_ALG_BTREE; + mem_per_row+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*); + break; + default: + DBUG_ASSERT(0); // cannot happen + } + keydef[key].algorithm= ((pos->algorithm == HA_KEY_ALG_UNDEF) ? HA_KEY_ALG_HASH : pos->algorithm); for (; key_part != key_part_end; key_part++, seg++) @@ -501,17 +513,17 @@ int ha_heap::create(const char *name, TABLE *table_arg, } } mem_per_row+= MY_ALIGN(table_arg->reclength + 1, sizeof(char*)); - max_rows = (ha_rows) (current_thd->variables.max_heap_table_size / - mem_per_row); HP_CREATE_INFO hp_create_info; hp_create_info.auto_key= auto_key; hp_create_info.auto_key_type= auto_key_type; hp_create_info.auto_increment= (create_info->auto_increment_value ? create_info->auto_increment_value - 1 : 0); + hp_create_info.max_table_size=current_thd->variables.max_heap_table_size; + max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row); error= heap_create(fn_format(buff,name,"","",4+2), table_arg->keys,keydef, table_arg->reclength, (ulong) ((table_arg->max_rows < max_rows && - table_arg->max_rows) ? + table_arg->max_rows) ? table_arg->max_rows : max_rows), (ulong) table_arg->min_rows, &hp_create_info); my_free((gptr) keydef, MYF(0)); From 60c1541524d2cd8877162b3c9f3f98321d06fafd Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 22:46:04 +0100 Subject: [PATCH 26/90] protect against malicious server trying to crash command-line client :) --- client/mysql.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 739cc77bd14..b9251361a01 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -172,7 +172,7 @@ static char *shared_memory_base_name=0; #endif static uint opt_protocol=0; static CHARSET_INFO *charset_info= &my_charset_latin1; - + #include "sslopt-vars.h" const char *default_dbug_option="d:t:o,/tmp/mysql.trace"; @@ -1520,7 +1520,7 @@ You can turn off this feature to get a quicker startup with -A\n\n"); j=0; while ((sql_field=mysql_fetch_field(fields))) { - sprintf(buf,"%s.%s",table_row[0],sql_field->name); + sprintf(buf,"%.64s.%.64s",table_row[0],sql_field->name); field_names[i][j] = strdup_root(&hash_mem_root,buf); add_word(&ht,field_names[i][j]); field_names[i][num_fields+j] = strdup_root(&hash_mem_root, @@ -1597,7 +1597,7 @@ int mysql_real_query_for_lazy(const char *buf, int length) for (uint retry=0;; retry++) { if (!mysql_real_query(&mysql,buf,length)) - return 0; + return 0; int error= put_error(&mysql); if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR || retry > 1 || !opt_reconnect) @@ -2526,7 +2526,7 @@ com_connect(String *buffer, char *line) { sprintf(buff,"Connection id: %lu",mysql_thread_id(&mysql)); put_info(buff,INFO_INFO); - sprintf(buff,"Current database: %s\n", + sprintf(buff,"Current database: %.128s\n", current_db ? current_db : "*** NONE ***"); put_info(buff,INFO_INFO); } From deac81af88c0bc424126d3a9d3d4aaeca2a6770c Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 15 Jan 2005 03:47:06 +0200 Subject: [PATCH 27/90] Fixed possible access to unintialized memory in filesort when using many buffers include/my_sys.h: Added function to call if IO_CACHE is moved mysys/mf_iocache.c: Added function to call if IO_CACHE is moved sql/filesort.cc: Tell that io_cache is moved --- include/my_sys.h | 1 + mysys/mf_iocache.c | 51 ++++++++++++++++++++++++++++++++-------------- sql/filesort.cc | 2 ++ 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index 9e43889d0e0..0fdb8d640e7 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -671,6 +671,7 @@ extern int init_io_cache(IO_CACHE *info,File file,uint cachesize, extern my_bool reinit_io_cache(IO_CACHE *info,enum cache_type type, my_off_t seek_offset,pbool use_async_io, pbool clear_cache); +extern void setup_io_cache(IO_CACHE* info); extern int _my_b_read(IO_CACHE *info,byte *Buffer,uint Count); #ifdef THREAD extern int _my_b_read_r(IO_CACHE *info,byte *Buffer,uint Count); diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 8fb93dc4780..a7937da0cc2 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -71,9 +71,40 @@ static void my_aiowait(my_aio_result *result); #define IO_ROUND_UP(X) (((X)+IO_SIZE-1) & ~(IO_SIZE-1)) #define IO_ROUND_DN(X) ( (X) & ~(IO_SIZE-1)) -static void -init_functions(IO_CACHE* info, enum cache_type type) + +/* + Setup internal pointers inside IO_CACHE + + SYNOPSIS + setup_io_cache() + info IO_CACHE handler + + NOTES + This is called on automaticly on init or reinit of IO_CACHE + It must be called externally if one moves or copies an IO_CACHE + object. +*/ + +void setup_io_cache(IO_CACHE* info) { + /* Ensure that my_b_tell() and my_b_bytes_in_cache works */ + if (info->type == WRITE_CACHE) + { + info->current_pos= &info->write_pos; + info->current_end= &info->write_end; + } + else + { + info->current_pos= &info->read_pos; + info->current_end= &info->read_end; + } +} + + +static void +init_functions(IO_CACHE* info) +{ + enum cache_type type= info->type; switch (type) { case READ_NET: /* @@ -97,17 +128,7 @@ init_functions(IO_CACHE* info, enum cache_type type) info->write_function = _my_b_write; } - /* Ensure that my_b_tell() and my_b_bytes_in_cache works */ - if (type == WRITE_CACHE) - { - info->current_pos= &info->write_pos; - info->current_end= &info->write_end; - } - else - { - info->current_pos= &info->read_pos; - info->current_end= &info->read_end; - } + setup_io_cache(info); } /* @@ -211,7 +232,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, /* End_of_file may be changed by user later */ info->end_of_file= end_of_file; info->error=0; - init_functions(info,type); + init_functions(info); #ifdef HAVE_AIOWAIT if (use_async_io && ! my_disable_async_io) { @@ -333,7 +354,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type, } info->type=type; info->error=0; - init_functions(info,type); + init_functions(info); #ifdef HAVE_AIOWAIT if (use_async_io && ! my_disable_async_io && diff --git a/sql/filesort.cc b/sql/filesort.cc index ae6895b26b9..fe42f391007 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -680,6 +680,8 @@ int merge_many_buff(SORTPARAM *param, uchar *sort_buffer, if (flush_io_cache(to_file)) break; /* purecov: inspected */ temp=from_file; from_file=to_file; to_file=temp; + setup_io_cache(from_file); + setup_io_cache(to_file); *maxbuffer= (uint) (lastbuff-buffpek)-1; } close_cached_file(to_file); // This holds old result From 16f3170e7352b06a8b142bfef89bbcc383c2a676 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 15 Jan 2005 01:05:00 -0800 Subject: [PATCH 28/90] func_gconcat.result, func_gconcat.test: Added a test case for bug #7769. item_sum.h: Fixed bug #7769: a crash for queries with group_concat and having when the query table was empty. The bug was due an unsafe dereferencing. sql/item_sum.h: Fixed bug #7769: a crash for queries with group_concat and having when the query table was empty. The bug was due an unsafe dereferencing. mysql-test/t/func_gconcat.test: Added a test case for bug #7769. mysql-test/r/func_gconcat.result: Added a test case for bug #7769. --- mysql-test/r/func_gconcat.result | 5 +++++ mysql-test/t/func_gconcat.test | 7 +++++++ sql/item_sum.h | 5 +++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index aa202823c77..390b33fdddc 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -457,3 +457,8 @@ group_concat(distinct b order by b) Warnings: Warning 1260 2 line(s) were cut by GROUP_CONCAT() drop table t1; +CREATE TABLE t1 (id int); +SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL; +gc +NULL +DROP TABLE t1; diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index e0737a42221..6a91a7ac9c7 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -277,3 +277,10 @@ select group_concat(b order by b) from t1 group by a; select group_concat(distinct b order by b) from t1 group by a; drop table t1; + +# +# bug #7769: group_concat returning null is checked in having +# +CREATE TABLE t1 (id int); +SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL; +DROP TABLE t1; diff --git a/sql/item_sum.h b/sql/item_sum.h index cec611b8854..d1e82387944 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -739,9 +739,10 @@ class Item_func_group_concat : public Item_sum String *res; char *end_ptr; int error; - res= val_str(&str_value); + if (!(res= val_str(&str_value))) + return (longlong) 0; end_ptr= (char*) res->ptr()+ res->length(); - return res ? my_strtoll10(res->ptr(), &end_ptr, &error) : (longlong) 0; + return my_strtoll10(res->ptr(), &end_ptr, &error); } String* val_str(String* str); Item *copy_or_same(THD* thd); From 5437a90dfafacee48603f8977d2018796c35f526 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 15 Jan 2005 12:28:38 +0200 Subject: [PATCH 29/90] Changed interface for my_strntod() to make it more general and more portable BUILD/compile-solaris-sparc-purify: Cleanup (Changes from Kent) include/m_string.h: New interface for my_strtod() mysql-test/mysql-test-run.sh: Added option --use-old-data to allow one to run a test case on an existing table (Good for debugging) mysql-test/r/strict.result: Updated results mysql-test/r/type_float.result: More tests mysql-test/t/strict.test: Safety fix mysql-test/t/type_float.test: More tests mysys/mf_iocache.c: Change flush_io_cache() to my_b_flush_io_cache() More debugging mysys/thr_lock.c: Added comment sql/field.cc: Use new my_strntod() sql/filesort.cc: Indentation fixes sql/item.cc: Use new my_strntod() sql/item_strfunc.cc: Use new my_strntod() sql/item_sum.cc: Use new my_strntod() strings/ctype-cp932.c: strnncollsp was missing one argument strings/ctype-simple.c: Use new my_strntod() strings/ctype-ucs2.c: Use new my_strntod() strings/strtod.c: Changed interface: - Force user to supply pointer to end of string (eliminates the need for an end \0) - More strict error checking (depend less off if INF is set), which makes this more portable - Better handling of numbers of type 0.000000....E+... - Return pointer to + in case of '+.' The above should fix a that strict.test failed on Solaris-sparc. --- BUILD/compile-solaris-sparc-purify | 23 ++-- include/m_string.h | 2 +- mysql-test/mysql-test-run.sh | 16 ++- mysql-test/r/strict.result | 2 +- mysql-test/r/type_float.result | 5 +- mysql-test/t/strict.test | 2 +- mysql-test/t/type_float.test | 3 +- mysys/mf_iocache.c | 13 ++- mysys/thr_lock.c | 6 +- sql/field.cc | 29 +++-- sql/filesort.cc | 5 +- sql/item.cc | 24 ++-- sql/item_strfunc.cc | 10 +- sql/item_sum.cc | 9 +- strings/ctype-cp932.c | 6 +- strings/ctype-simple.c | 27 +---- strings/ctype-ucs2.c | 18 ++- strings/strtod.c | 170 ++++++++++++++++++++--------- 18 files changed, 223 insertions(+), 147 deletions(-) diff --git a/BUILD/compile-solaris-sparc-purify b/BUILD/compile-solaris-sparc-purify index 71a60e45cb0..c895d99c2cf 100755 --- a/BUILD/compile-solaris-sparc-purify +++ b/BUILD/compile-solaris-sparc-purify @@ -3,28 +3,27 @@ while test $# -gt 0 do case "$1" in - --debug) EXTRA_CONFIG_FLAGS=--with-debug; shift ;; - -h | --help ) cat <read_pos is set to info->read_end. If called through open_cached_file(), then the temporary file will only be created if a write exeeds the file buffer or if one calls - flush_io_cache(). + my_b_flush_io_cache(). If one uses SEQ_READ_APPEND, then two buffers are allocated, one for reading and another for writing. Reads are first done from disk and @@ -43,7 +43,7 @@ TODO: each time the write buffer gets full and it's written to disk, we will always do a disk read to read a part of the buffer from disk to the read buffer. - This should be fixed so that when we do a flush_io_cache() and + This should be fixed so that when we do a my_b_flush_io_cache() and we have been reading the write buffer, we should transfer the rest of the write buffer to the read buffer before we start to reuse it. */ @@ -339,7 +339,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type, if (info->type == WRITE_CACHE && type == READ_CACHE) info->end_of_file=my_b_tell(info); /* flush cache if we want to reuse it */ - if (!clear_cache && flush_io_cache(info)) + if (!clear_cache && my_b_flush_io_cache(info,1)) DBUG_RETURN(1); info->pos_in_file=seek_offset; /* Better to do always do a seek */ @@ -948,7 +948,7 @@ int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count) Buffer+=rest_length; Count-=rest_length; info->write_pos+=rest_length; - if (flush_io_cache(info)) + if (my_b_flush_io_cache(info,1)) return 1; if (Count >= IO_SIZE) { /* Fill first intern buffer */ @@ -1191,6 +1191,7 @@ int end_io_cache(IO_CACHE *info) int error=0; IO_CACHE_CALLBACK pre_close; DBUG_ENTER("end_io_cache"); + DBUG_PRINT("enter",("cache: 0x%lx", (ulong) info)); #ifdef THREAD /* @@ -1200,7 +1201,7 @@ int end_io_cache(IO_CACHE *info) */ if (info->share) { - pthread_cond_destroy (&info->share->cond); + pthread_cond_destroy(&info->share->cond); pthread_mutex_destroy(&info->share->mutex); info->share=0; } @@ -1215,7 +1216,7 @@ int end_io_cache(IO_CACHE *info) { info->alloced_buffer=0; if (info->file != -1) /* File doesn't exist */ - error=flush_io_cache(info); + error= my_b_flush_io_cache(info,1); my_free((gptr) info->buffer,MYF(MY_WME)); info->buffer=info->read_pos=(byte*) 0; } diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index d47ca8de183..9ce058f90fc 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -523,8 +523,10 @@ int thr_lock(THR_LOCK_DATA *data,enum thr_lock_type lock_type) data->prev=lock->write_wait.last; lock->write_wait.last= &data->next; data->cond=get_cond(); - if (lock->get_status) - (*lock->get_status)(data->status_param); + /* + We don't have to do get_status here as we will do it when we change + the delayed lock to a real write lock + */ statistic_increment(locks_immediate,&THR_LOCK_lock); goto end; } diff --git a/sql/field.cc b/sql/field.cc index 175ca09df37..29125d9d655 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1035,7 +1035,9 @@ int Field_decimal::store(longlong nr) double Field_decimal::val_real(void) { int not_used; - return my_strntod(&my_charset_bin, ptr, field_length, NULL, ¬_used); + char *end_not_used; + return my_strntod(&my_charset_bin, ptr, field_length, &end_not_used, + ¬_used); } longlong Field_decimal::val_int(void) @@ -4425,16 +4427,18 @@ int Field_string::store(longlong nr) double Field_string::val_real(void) { int not_used; - CHARSET_INFO *cs=charset(); - return my_strntod(cs,ptr,field_length,(char**)0,¬_used); + char *end_not_used; + CHARSET_INFO *cs= charset(); + return my_strntod(cs,ptr,field_length,&end_not_used,¬_used); } longlong Field_string::val_int(void) { int not_used; + char *end_not_used; CHARSET_INFO *cs=charset(); - return my_strntoll(cs,ptr,field_length,10,NULL,¬_used); + return my_strntoll(cs,ptr,field_length,10,&end_not_used,¬_used); } @@ -4734,8 +4738,9 @@ int Field_varstring::store(longlong nr) double Field_varstring::val_real(void) { int not_used; + char *end_not_used; uint length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); - return my_strntod(field_charset, ptr+length_bytes, length, (char**) 0, + return my_strntod(field_charset, ptr+length_bytes, length, &end_not_used, ¬_used); } @@ -4743,9 +4748,10 @@ double Field_varstring::val_real(void) longlong Field_varstring::val_int(void) { int not_used; + char *end_not_used; uint length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); - return my_strntoll(field_charset, ptr+length_bytes, length, 10, NULL, - ¬_used); + return my_strntoll(field_charset, ptr+length_bytes, length, 10, + &end_not_used, ¬_used); } @@ -5339,12 +5345,15 @@ int Field_blob::store(longlong nr) double Field_blob::val_real(void) { int not_used; - char *blob; + char *end_not_used, *blob; + uint32 length; + CHARSET_INFO *cs; + memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); if (!blob) return 0.0; - uint32 length=get_length(ptr); - CHARSET_INFO *cs=charset(); + length= get_length(ptr); + cs= charset(); return my_strntod(cs,blob,length,(char**)0, ¬_used); } diff --git a/sql/filesort.cc b/sql/filesort.cc index 0a4e747a136..b79ea6515c3 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -567,10 +567,10 @@ write_keys(SORTPARAM *param, register uchar **sort_keys, uint count, if (!my_b_inited(tempfile) && open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME))) - goto err; /* purecov: inspected */ + goto err; /* purecov: inspected */ buffpek.file_pos= my_b_tell(tempfile); if ((ha_rows) count > param->max_rows) - count=(uint) param->max_rows; /* purecov: inspected */ + count=(uint) param->max_rows; /* purecov: inspected */ buffpek.count=(ha_rows) count; for (end=sort_keys+count ; sort_keys != end ; sort_keys++) if (my_b_write(tempfile, (byte*) *sort_keys, (uint) rec_length)) @@ -844,6 +844,7 @@ int merge_many_buff(SORTPARAM *param, uchar *sort_buffer, if (flush_io_cache(to_file)) break; /* purecov: inspected */ temp=from_file; from_file=to_file; to_file=temp; + *maxbuffer= (uint) (lastbuff-buffpek)-1; } close_cached_file(to_file); // This holds old result diff --git a/sql/item.cc b/sql/item.cc index c84496f8eb7..47dccf5b8da 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1290,11 +1290,12 @@ double Item_param::val_real() return (double) value.integer; case STRING_VALUE: case LONG_DATA_VALUE: - { - int dummy_err; - return my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(), (char**) 0, &dummy_err); - } + { + int dummy_err; + char *end_not_used; + return my_strntod(str_value.charset(), (char*) str_value.ptr(), + str_value.length(), &end_not_used, &dummy_err); + } case TIME_VALUE: /* This works for example when user says SELECT ?+0.0 and supplies @@ -2545,8 +2546,9 @@ Item_num *Item_uint::neg() Item_real::Item_real(const char *str_arg, uint length) { int error; - char *end; - value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end, &error); + char *end_not_used; + value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end_not_used, + &error); if (error) { /* @@ -3522,12 +3524,12 @@ void Item_cache_str::store(Item *item) double Item_cache_str::val_real() { DBUG_ASSERT(fixed == 1); - int err; + int err_not_used; + char *end_not_used; if (value) return my_strntod(value->charset(), (char*) value->ptr(), - value->length(), (char**) 0, &err); - else - return (double)0; + value->length(), &end_not_used, &err_not_used); + return (double) 0; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9e28acdd091..09b6d9cc35d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -58,17 +58,19 @@ uint nr_of_decimals(const char *str) return 0; } + double Item_str_func::val_real() { DBUG_ASSERT(fixed == 1); - int err; - char buff[64]; + int err_not_used; + char *end_not_used, buff[64]; String *res, tmp(buff,sizeof(buff), &my_charset_bin); res= val_str(&tmp); - return res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(), - NULL, &err) : 0.0; + return res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(), + &end_not_used, &err_not_used) : 0.0; } + longlong Item_str_func::val_int() { DBUG_ASSERT(fixed == 1); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 168c68ad706..be89aa3f86d 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -591,14 +591,17 @@ void Item_sum_hybrid::clear() double Item_sum_hybrid::val_real() { DBUG_ASSERT(fixed == 1); - int err; if (null_value) return 0.0; switch (hybrid_type) { case STRING_RESULT: + { + char *end_not_used; + int err_not_used; String *res; res=val_str(&str_value); - return (res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(), - (char**) 0, &err) : 0.0); + return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(), + &end_not_used, &err_not_used) : 0.0); + } case INT_RESULT: if (unsigned_flag) return ulonglong2double(sum_int); diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c index 218fc72ad17..e5429148970 100644 --- a/strings/ctype-cp932.c +++ b/strings/ctype-cp932.c @@ -243,8 +243,10 @@ static int my_strnncoll_cp932(CHARSET_INFO *cs __attribute__((unused)), static int my_strnncollsp_cp932(CHARSET_INFO *cs __attribute__((unused)), - const uchar *a, uint a_length, - const uchar *b, uint b_length) + const uchar *a, uint a_length, + const uchar *b, uint b_length, + my_bool diff_if_only_endspace_difference + __attribute__((unused))) { const uchar *a_end= a + a_length; const uchar *b_end= b + b_length; diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 0659cb5d387..fdfe72864b2 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -750,31 +750,10 @@ double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)), char *str, uint length, char **end, int *err) { - char end_char; - double result; - - errno= 0; /* Safety */ - - /* - The following define is to avoid warnings from valgrind as str[length] - may not be defined (which is not fatal in real life) - */ - -#ifdef HAVE_purify if (length == INT_MAX32) -#else - if (length == INT_MAX32 || str[length] == 0) -#endif - result= my_strtod(str, end); - else - { - end_char= str[length]; - str[length]= 0; - result= my_strtod(str, end); - str[length]= end_char; /* Restore end char */ - } - *err= errno; - return result; + length= 65535; /* Should be big enough */ + *end= str + length; + return my_strtod(str, end, err); } diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index d21b340e768..7b9a7ab3020 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -925,15 +925,16 @@ bs: return (negative ? -((longlong) res) : (longlong) res); } -double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), - char *nptr, uint length, - char **endptr, int *err) + +double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), + char *nptr, uint length, + char **endptr, int *err) { char buf[256]; double res; register char *b=buf; register const uchar *s= (const uchar*) nptr; - register const uchar *end; + const uchar *end; my_wc_t wc; int cnv; @@ -950,13 +951,10 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), break; /* Can't be part of double */ *b++= (char) wc; } - *b= 0; - errno= 0; - res=my_strtod(buf, endptr); - *err= errno; - if (endptr) - *endptr=(char*) (*endptr-buf+nptr); + *endptr= b; + res= my_strtod(buf, endptr, err); + *endptr= nptr + (uint) (*endptr- buf); return res; } diff --git a/strings/strtod.c b/strings/strtod.c index bc8105b8040..92d93612dd0 100644 --- a/strings/strtod.c +++ b/strings/strtod.c @@ -2,7 +2,7 @@ An alternative implementation of "strtod()" that is both simplier, and thread-safe. - From mit-threads as bundled with MySQL 3.23 + Original code from mit-threads as bundled with MySQL 3.23 SQL:2003 specifies a number as @@ -29,6 +29,8 @@ #include "my_base.h" /* Includes errno.h */ #include "m_ctype.h" +#define MAX_DBL_EXP 308 +#define MAX_RESULT_FOR_MAX_EXP 1.79769313486232 static double scaler10[] = { 1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90 }; @@ -37,89 +39,154 @@ static double scaler1[] = { }; -double my_strtod(const char *str, char **end) +/* + Convert string to double (string doesn't have to be null terminated) + + SYNOPSIS + my_strtod() + str String to convert + end_ptr Pointer to pointer that points to end of string + Will be updated to point to end of double. + error Will contain error number in case of error (else 0) + + RETURN + value of str as double +*/ + +double my_strtod(const char *str, char **end_ptr, int *error) { double result= 0.0; - int negative, ndigits; - const char *old_str; + uint negative= 0, ndigits, dec_digits= 0, pre_zero, neg_exp= 0; + int exp= 0; + const char *old_str, *end= *end_ptr, *start_of_number; + char next_char; my_bool overflow=0; - while (my_isspace(&my_charset_latin1, *str)) - str++; + *error= 0; + if (str >= end) + goto done; + while (my_isspace(&my_charset_latin1, *str)) + { + if (++str == end) + goto done; + } + + start_of_number= str; if ((negative= (*str == '-')) || *str=='+') - str++; + { + if (++str == end) + goto done; /* Could be changed to error */ + } + + /* Skip pre-zero for easier calculation of overflows */ + while (*str == '0') + { + if (++str == end) + goto done; + start_of_number= 0; /* Found digit */ + } old_str= str; - while (my_isdigit (&my_charset_latin1, *str)) + while ((next_char= *str) >= '0' && next_char <= '9') { - result= result*10.0 + (*str - '0'); - str++; - } - ndigits= str-old_str; - - if (*str == '.') - { - double p10=10; - str++; - old_str= str; - while (my_isdigit (&my_charset_latin1, *str)) + result= result*10.0 + (next_char - '0'); + if (++str == end) { - result+= (*str++ - '0')/p10; - p10*=10; + next_char= 0; /* Found end of string */ + break; } - ndigits+= str-old_str; - if (!ndigits) str--; + start_of_number= 0; /* Found digit */ } - if (ndigits && (*str=='e' || *str=='E')) + ndigits= (uint) (str-old_str); + + pre_zero= 0; + if (next_char == '.' && str < end-1) + { + double p10= 10; + old_str= ++str; + while (my_isdigit(&my_charset_latin1, (next_char= *str))) + { + result+= (next_char - '0')/p10; + if (!result) + pre_zero++; + else + p10*= 10; + if (++str == end) + { + next_char= 0; + break; + } + } + /* If we found just '+.' or '.' then point at first character */ + if (!(dec_digits= (uint) (str-old_str)) && start_of_number) + str= start_of_number; /* Point at '+' or '.' */ + } + if ((next_char == 'e' || next_char == 'E') && + dec_digits + ndigits != 0 && str < end-1) { - int exp= 0; - int neg= 0; const char *old_str= str++; - if ((neg= (*str == '-')) || *str == '+') + if ((neg_exp= (*str == '-')) || *str == '+') str++; - if (!my_isdigit (&my_charset_latin1, *str)) + if (str == end || !my_isdigit(&my_charset_latin1, *str)) str= old_str; else { - double scaler= 1.0; - while (my_isdigit (&my_charset_latin1, *str)) + do { - if (exp < 9999) /* protection against exp overflow */ + if (exp < 9999) /* protec against exp overfl. */ exp= exp*10 + *str - '0'; str++; - } - if (exp >= 1000) + } while (str < end && my_isdigit(&my_charset_latin1, *str)); + } + } + if ((exp= neg_exp ? exp + pre_zero : exp - pre_zero)) + { + double scaler; + if (exp < 0) + { + exp= -exp; + neg_exp= 1; /* neg_exp was 0 before */ + } + if (exp + ndigits >= MAX_DBL_EXP + 1 && result) + { + /* + This is not 100 % as we actually will give an owerflow for + 17E307 but not for 1.7E308 but lets cut some corners to make life + simpler + */ + if (exp + ndigits > MAX_DBL_EXP + 1 || + result >= MAX_RESULT_FOR_MAX_EXP) { - if (neg) - result= 0.0; - else + if (neg_exp) + result= 0.0; + else overflow= 1; goto done; } - while (exp >= 100) - { - scaler*= 1.0e100; - exp-= 100; - } - scaler*= scaler10[exp/10]*scaler1[exp%10]; - if (neg) - result/= scaler; - else - result*= scaler; } + scaler= 1.0; + while (exp >= 100) + { + scaler*= 1.0e100; + exp-= 100; + } + scaler*= scaler10[exp/10]*scaler1[exp%10]; + if (neg_exp) + result/= scaler; + else + result*= scaler; } done: - if (end) - *end = (char *)str; + *end_ptr= (char*) str; /* end of number */ if (overflow || isinf(result)) { result= DBL_MAX; - errno= EOVERFLOW; + *error= EOVERFLOW; } return negative ? -result : result; @@ -127,6 +194,7 @@ done: double my_atof(const char *nptr) { - return (my_strtod(nptr, 0)); + int error; + const char *end= nptr+65535; /* Should be enough */ + return (my_strtod(nptr, (char**) &end, &error)); } - From 5168d25f3509cd205b3db8222446b16d34c45781 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 15 Jan 2005 12:36:20 +0200 Subject: [PATCH 30/90] Added ndb_types.h to ignore BitKeeper/etc/ignore: added ndb/include/ndb_types.h --- .bzrignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.bzrignore b/.bzrignore index 951a811f8e4..c972e25f2db 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1045,3 +1045,4 @@ vio/test-ssl vio/test-sslclient vio/test-sslserver vio/viotest-ssl +ndb/include/ndb_types.h From 6ead860060ebeae29f46d6c89f0bf7a45e748819 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 15 Jan 2005 17:38:43 +0200 Subject: [PATCH 31/90] After merge fixes Fix for BIT(X) field as string mysql-test/r/func_gconcat.result: Fix wrong merge mysql-test/r/func_sapdb.result: Use results so that dimitry can fix them properly mysql-test/r/innodb.result: Update test after fast TRUNCATE in InnoDB mysql-test/r/ps_1general.result: After megre fixes mysql-test/r/type_bit.result: New test to verify patch for Bit fields mysql-test/t/ps_1general.test: After merge fixes mysql-test/t/type_bit.test: New test to verify patch for Bit fields sql/field.cc: Fix for new my_strntod() Fix for BIT(X) field as string sql/item.h: Fix for new my_strntod() sql/item_func.h: Fix for new my_strntod() sql/item_sum.h: Fix for new my_strntod() sql/procedure.h: Fix for new my_strntod() sql/sql_base.cc: Port fix for INSERT DELAYED with prepared statements to 5.0 --- mysql-test/r/func_gconcat.result | 10 +++++----- mysql-test/r/func_sapdb.result | 6 +++--- mysql-test/r/innodb.result | 8 ++++---- mysql-test/r/ps_1general.result | 1 + mysql-test/r/type_bit.result | 11 +++++++++++ mysql-test/t/ps_1general.test | 1 + mysql-test/t/type_bit.test | 9 +++++++++ sql/field.cc | 6 ++++-- sql/item.h | 10 ++++++---- sql/item_func.h | 14 +++++++++----- sql/item_sum.h | 10 ++++++---- sql/procedure.h | 17 +++++++++++++---- sql/sql_base.cc | 14 ++++++++------ 13 files changed, 80 insertions(+), 37 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 272f6f592b1..06c1759bf1d 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -457,6 +457,11 @@ group_concat(distinct b order by b) Warnings: Warning 1260 2 line(s) were cut by GROUP_CONCAT() drop table t1; +CREATE TABLE t1 (id int); +SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL; +gc +NULL +DROP TABLE t1; create table t1 (a char(3), b char(20), primary key (a, b)); insert into t1 values ('ABW', 'Dutch'), ('ABW', 'English'); select group_concat(a) from t1 group by b; @@ -464,8 +469,3 @@ group_concat(a) ABW ABW drop table t1; -CREATE TABLE t1 (id int); -SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL; -gc -NULL -DROP TABLE t1; diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index 6556d2be6ad..a2918e71d68 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -107,7 +107,7 @@ timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") 46:58:57.999999 select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002"); timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") --24:00:00.000001 +-23:59:59.999999 select timediff("1997-12-31 23:59:59.000001","23:59:59.000001"); timediff("1997-12-31 23:59:59.000001","23:59:59.000001") NULL @@ -116,7 +116,7 @@ timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001") -00:00:00.000001 select timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50"); timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50") --00:00:00.000001 +-00:00:01.999999 select maketime(10,11,12); maketime(10,11,12) 10:11:12 @@ -188,7 +188,7 @@ f8 date YES NULL f9 time YES NULL select * from t1; f1 f2 f3 f4 f5 f6 f7 f8 f9 -1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -24:00:00 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59 +1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -23:59:59 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59 create table test(t1 datetime, t2 time, t3 time, t4 datetime); insert into test values ('2001-01-01 01:01:01', '01:01:01', null, '2001-02-01 01:01:01'), diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index bdd5ac0bd63..8d1c4e3fc90 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1326,8 +1326,8 @@ truncate table t1; insert into t1 (a) values (NULL),(NULL); SELECT * from t1; a -3 -4 +1 +2 drop table t1; CREATE TABLE t1 (`id 1` INT NOT NULL, PRIMARY KEY (`id 1`)) ENGINE=INNODB; CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), FOREIGN KEY (`t1_id`) REFERENCES `t1`(`id 1`) ON DELETE CASCADE ) ENGINE=INNODB; @@ -1690,13 +1690,13 @@ Variable_name Value Innodb_page_size 16384 show status like "Innodb_rows_deleted"; Variable_name Value -Innodb_rows_deleted 2078 +Innodb_rows_deleted 2070 show status like "Innodb_rows_inserted"; Variable_name Value Innodb_rows_inserted 31706 show status like "Innodb_rows_read"; Variable_name Value -Innodb_rows_read 80161 +Innodb_rows_read 80153 show status like "Innodb_rows_updated"; Variable_name Value Innodb_rows_updated 29530 diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index 64cdb76ead8..6df5f633b88 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -295,6 +295,7 @@ execute stmt4; prepare stmt4 from ' show full processlist '; execute stmt4; Id User Host db Command Time State Info +number root localhost test Query time NULL show full processlist prepare stmt4 from ' show grants for user '; prepare stmt4 from ' show create table t2 '; ERROR HY000: This command is not supported in the prepared statement protocol yet diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index 45f887461e7..88bb04fefba 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -368,3 +368,14 @@ a+0 44 57 drop table t1; +create table t1 (a bit(3), b bit(12)); +insert into t1 values (7,(1<<12)-2), (0x01,0x01ff); +select hex(a),hex(b) from t1; +hex(a) hex(b) +7 FFE +1 1FF +select hex(concat(a)),hex(concat(b)) from t1; +hex(concat(a)) hex(concat(b)) +07 0FFE +01 01FF +drop table t1; diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test index 569d2f697c7..4b55593fde5 100644 --- a/mysql-test/t/ps_1general.test +++ b/mysql-test/t/ps_1general.test @@ -321,6 +321,7 @@ prepare stmt4 from ' show engine bdb logs '; execute stmt4; --enable_result_log prepare stmt4 from ' show full processlist '; +--replace_column 1 number 6 time execute stmt4; prepare stmt4 from ' show grants for user '; --error 1295 diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index 0c1c22099f9..fed15806765 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -106,3 +106,12 @@ create table t1 (a bit(7), key(a)); insert into t1 values (44), (57); select a+0 from t1; drop table t1; + +# +# Test conversion to and from strings +# +create table t1 (a bit(3), b bit(12)); +insert into t1 values (7,(1<<12)-2), (0x01,0x01ff); +select hex(a),hex(b) from t1; +select hex(concat(a)),hex(concat(b)) from t1; +drop table t1; diff --git a/sql/field.cc b/sql/field.cc index 084232fe2bb..a1dc02eba4a 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5358,7 +5358,7 @@ double Field_blob::val_real(void) return 0.0; length= get_length(ptr); cs= charset(); - return my_strntod(cs,blob,length,(char**)0, ¬_used); + return my_strntod(cs, blob, length, &end_not_used, ¬_used); } @@ -6362,11 +6362,13 @@ longlong Field_bit::val_int(void) String *Field_bit::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { + char buff[sizeof(longlong)]; uint length= min(pack_length(), sizeof(longlong)); ulonglong bits= val_int(); + mi_int8store(buff,bits); val_buffer->alloc(length); - memcpy_fixed((char*) val_buffer->ptr(), (char*) &bits, length); + memcpy_fixed((char*) val_buffer->ptr(), buff+8-length, length); val_buffer->length(length); val_buffer->set_charset(&my_charset_bin); return val_buffer; diff --git a/sql/item.h b/sql/item.h index 2503f137355..6857b4acf82 100644 --- a/sql/item.h +++ b/sql/item.h @@ -877,9 +877,10 @@ public: double val_real() { DBUG_ASSERT(fixed == 1); - int err; + int err_not_used; + char *end_not_used; return my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(), (char**) 0, &err); + str_value.length(), &end_not_used, &err_not_used); } longlong val_int() { @@ -1230,10 +1231,11 @@ public: enum_field_types field_type() const { return cached_field_type; } double val_real() { - int err; + int err_not_used; + char *end_not_used; return (null_value ? 0.0 : my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(),NULL,&err)); + str_value.length(), &end_not_used, &err_not_used)); } longlong val_int() { diff --git a/sql/item_func.h b/sql/item_func.h index 4657ee81dfb..fb8d77d5b83 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -834,15 +834,19 @@ public: String *val_str(String *); double val_real() { - int err; - String *res; res=val_str(&str_value); - return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),0,&err) : 0.0; + int err_not_used; + char *end_not_used; + String *res; + res= val_str(&str_value); + return res ? my_strntod(res->charset(),(char*) res->ptr(), + res->length(), &end_not_used, &err_not_used) : 0.0; } longlong val_int() { - int err; + int err_not_used; String *res; res=val_str(&str_value); - return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,(char**) 0,&err) : (longlong) 0; + return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, + (char**) 0, &err_not_used) : (longlong) 0; } enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec(); diff --git a/sql/item_sum.h b/sql/item_sum.h index 4d2bfe739c5..7866a9ae913 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -643,16 +643,18 @@ public: String *val_str(String *); double val_real() { - int err; + int err_not_used; + char *end_not_used; String *res; res=val_str(&str_value); return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(), - (char**) 0, &err) : 0.0; + &end_not_used, &err_not_used) : 0.0; } longlong val_int() { - int err; + int err_not_used; String *res; res=val_str(&str_value); - return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, (char**) 0, &err) : (longlong) 0; + return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, + (char**) 0, &err_not_used) : (longlong) 0; } enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec(); diff --git a/sql/procedure.h b/sql/procedure.h index 4212a9246a5..33c1288c88e 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -59,10 +59,18 @@ public: void set(double nr) { value=nr; } void set(longlong nr) { value=(double) nr; } void set(const char *str,uint length,CHARSET_INFO *cs) - { int err; value=my_strntod(cs,(char*) str,length,(char**)0,&err); } + { + int err_not_used; + char *end_not_used; + value= my_strntod(cs,(char*) str,length, &end_not_used, &err_not_used); + } double val_real() { return value; } longlong val_int() { return (longlong) value; } - String *val_str(String *s) { s->set(value,decimals,default_charset()); return s; } + String *val_str(String *s) + { + s->set(value,decimals,default_charset()); + return s; + } unsigned int size_of() { return sizeof(*this);} }; @@ -98,10 +106,11 @@ public: { str_value.copy(str,length,cs); } double val_real() { - int err; + int err_not_used; + char *end_not_used; CHARSET_INFO *cs=str_value.charset(); return my_strntod(cs, (char*) str_value.ptr(), str_value.length(), - (char**) 0, &err); + &end_not_used, &err_not_used); } longlong val_int() { diff --git a/sql/sql_base.cc b/sql/sql_base.cc index ab59610f485..d854956325e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1853,8 +1853,8 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables) bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) { - DBUG_ENTER("open_and_lock_tables"); uint counter; + DBUG_ENTER("open_and_lock_tables"); if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter) || mysql_handle_derived(thd->lex, &mysql_derived_prepare) || @@ -1883,14 +1883,16 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) data from the tables. */ -int open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables) +bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables) { uint counter; DBUG_ENTER("open_normal_and_derived_tables"); - if (open_tables(thd, tables, &counter)) - DBUG_RETURN(-1); /* purecov: inspected */ - relink_tables_for_derived(thd); - DBUG_RETURN(mysql_handle_derived(thd->lex)); + DBUG_ASSERT(!thd->fill_derived_tables()); + if (open_tables(thd, tables, &counter) || + mysql_handle_derived(thd->lex, &mysql_derived_prepare)) + DBUG_RETURN(TRUE); /* purecov: inspected */ + relink_tables_for_multidelete(thd); // Not really needed, but + DBUG_RETURN(0); } From 9e60778daeeead4a9470ecdf7c2d008635c197a8 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 15 Jan 2005 20:02:46 +0300 Subject: [PATCH 32/90] Porting fix for bug #7586 "TIMEDIFF for sec+microsec not working properly" to 5.0 tree (since it was lost during last merge). mysql-test/r/func_sapdb.result: Updated test result after fixing bug #7586 "TIMEDIFF for sec+microsec not working properly" in 5.0 tree. sql/item_timefunc.cc: calc_time_diff(): Use simplier and less error-prone implementation. Now we are counting difference between time values in microseconds and then convert it to seconds + microseconds value (instead of using seconds and taking difference in "second_part"s into account). --- mysql-test/r/func_sapdb.result | 6 +-- sql/item_timefunc.cc | 77 +++++++++++++++------------------- 2 files changed, 37 insertions(+), 46 deletions(-) diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index a2918e71d68..6556d2be6ad 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -107,7 +107,7 @@ timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") 46:58:57.999999 select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002"); timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") --23:59:59.999999 +-24:00:00.000001 select timediff("1997-12-31 23:59:59.000001","23:59:59.000001"); timediff("1997-12-31 23:59:59.000001","23:59:59.000001") NULL @@ -116,7 +116,7 @@ timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001") -00:00:00.000001 select timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50"); timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50") --00:00:01.999999 +-00:00:00.000001 select maketime(10,11,12); maketime(10,11,12) 10:11:12 @@ -188,7 +188,7 @@ f8 date YES NULL f9 time YES NULL select * from t1; f1 f2 f3 f4 f5 f6 f7 f8 f9 -1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -23:59:59 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59 +1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -24:00:00 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59 create table test(t1 datetime, t2 time, t3 time, t4 datetime); insert into test values ('2001-01-01 01:01:01', '01:01:01', null, '2001-02-01 01:01:01'), diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 2d0e5d7632f..0c1cd3cbad3 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2441,36 +2441,37 @@ void Item_func_add_time::print(String *str) /* + Calculate difference between two datetime values as seconds + microseconds. + SYNOPSIS calc_time_diff() - l_time1 TIME/DATE/DATETIME value - l_time2 TIME/DATE/DATETIME value - l_sign Can be 1 (operation of addition) - or -1 (substraction) - seconds_out Returns count of seconds bitween - l_time1 and l_time2 - microseconds_out Returns count of microseconds bitween - l_time1 and l_time2. + l_time1 - TIME/DATE/DATETIME value + l_time2 - TIME/DATE/DATETIME value + l_sign - 1 absolute values are substracted, + -1 absolute values are added. + seconds_out - Out parameter where difference between + l_time1 and l_time2 in seconds is stored. + microseconds_out- Out parameter where microsecond part of difference + between l_time1 and l_time2 is stored. - DESCRIPTION - Calculates difference in seconds(seconds_out) - and microseconds(microseconds_out) - bitween two TIME/DATE/DATETIME values. + NOTE + This function calculates difference between l_time1 and l_time2 absolute + values. So one should set l_sign and correct result if he want to take + signs into account (i.e. for TIME values). RETURN VALUES - Rertuns sign of difference. + Returns sign of difference. 1 means negative result 0 means positive result */ -bool calc_time_diff(TIME *l_time1,TIME *l_time2, int l_sign, - longlong *seconds_out, long *microseconds_out) +static bool calc_time_diff(TIME *l_time1, TIME *l_time2, int l_sign, + longlong *seconds_out, long *microseconds_out) { long days; bool neg; - longlong seconds= *seconds_out; - long microseconds= *microseconds_out; + longlong microseconds; /* We suppose that if first argument is MYSQL_TIMESTAMP_TIME @@ -2487,29 +2488,20 @@ bool calc_time_diff(TIME *l_time1,TIME *l_time2, int l_sign, (uint) l_time2->month, (uint) l_time2->day)); - microseconds= l_time1->second_part - l_sign*l_time2->second_part; - seconds= ((longlong) days*86400L + l_time1->hour*3600L + - l_time1->minute*60L + l_time1->second + microseconds/1000000L - - (longlong)l_sign*(l_time2->hour*3600L+l_time2->minute*60L+l_time2->second)); + microseconds= ((longlong)days*86400L + + l_time1->hour*3600L + l_time1->minute*60L + l_time1->second - + (longlong)l_sign*(l_time2->hour*3600L + l_time2->minute*60L + + l_time2->second))*1000000L + + l_time1->second_part - l_sign*l_time2->second_part; neg= 0; - if (seconds < 0) - { - seconds= -seconds; - neg= 1; - } - else if (seconds == 0 && microseconds < 0) + if (microseconds < 0) { microseconds= -microseconds; neg= 1; } - if (microseconds < 0) - { - microseconds+= 1000000L; - seconds--; - } - *seconds_out= seconds; - *microseconds_out= microseconds; + *seconds_out= microseconds/1000000L; + *microseconds_out= (long) (microseconds%1000000L); return neg; } @@ -2544,9 +2536,10 @@ String *Item_func_timediff::val_str(String *str) /* For MYSQL_TIMESTAMP_TIME only: If both argumets are negative values and diff between them - is negative we need to swap sign as result should be positive. + is non-zero we need to swap sign to get proper result. */ - if ((l_time2.neg == l_time1.neg) && l_time1.neg) + if ((l_time2.neg == l_time1.neg) && l_time1.neg && + (seconds || microseconds)) l_time3.neg= 1-l_time3.neg; // Swap sign of result calc_time_from_sec(&l_time3, (long) seconds, microseconds); @@ -2712,13 +2705,11 @@ longlong Item_func_timestamp_diff::val_int() case INTERVAL_SECOND: return seconds*neg; case INTERVAL_MICROSECOND: - { - longlong max_sec= LONGLONG_MAX/1000000; - if (max_sec > seconds || - max_sec == seconds && LONGLONG_MAX%1000000 >= microseconds) - return (longlong) (seconds*1000000L+microseconds)*neg; - goto null_date; - } + /* + In MySQL difference between any two valid datetime values + in microseconds fits into longlong. + */ + return (seconds*1000000L+microseconds)*neg; default: break; } From 2f885bbe3485ad4ae08a4f61d86ff6e6cb813bdd Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 15 Jan 2005 10:14:12 -0800 Subject: [PATCH 33/90] Update results after merge mysql-test/r/show_check.result: Update results --- mysql-test/r/show_check.result | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index e50c1e2fb0d..53882e6be69 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -412,7 +412,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL, KEY `i` (`i`) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 DROP TABLE t1; CREATE TABLE t1 (i int, KEY USING HASH (i)) ENGINE=MEMORY; SHOW CREATE TABLE t1; @@ -420,7 +420,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL, KEY `i` USING HASH (`i`) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 DROP TABLE t1; CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MEMORY; SHOW CREATE TABLE t1; @@ -428,7 +428,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL, KEY `i` USING BTREE (`i`) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 DROP TABLE t1; CREATE TABLE t1 (i int, KEY (i)) ENGINE=MyISAM; SHOW CREATE TABLE t1; @@ -459,7 +459,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL, KEY `i` (`i`) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 DROP TABLE t1; CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MyISAM; SHOW CREATE TABLE t1; @@ -474,5 +474,5 @@ Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL, KEY `i` USING BTREE (`i`) -) ENGINE=HEAP DEFAULT CHARSET=latin1 +) ENGINE=MEMORY DEFAULT CHARSET=latin1 DROP TABLE t1; From 0d98da70adcfd5f4963c9ba9a898a278f3df7d7f Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 15 Jan 2005 20:08:53 +0100 Subject: [PATCH 34/90] don't ignore errors in readlink --- myisam/mi_open.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/myisam/mi_open.c b/myisam/mi_open.c index 562227d2f03..442bf00b9d3 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -142,9 +142,8 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) goto err; } /* Don't call realpath() if the name can't be a link */ - if (strcmp(name_buff, org_name)) - (void) my_readlink(index_name, org_name, MYF(0)); - else + if (strcmp(name_buff, org_name) || + my_readlink(index_name, org_name, MYF(0)) == -1) (void) strmov(index_name, org_name); (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,2+4+16); From 31457a625861d4dc3a99990eb42c38a81b607aef Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 15 Jan 2005 23:19:34 -0600 Subject: [PATCH 35/90] Bug #7922 prompt \p fails on Windows for shared-memory connections Fixed bug by adding code that displays the contents of mysql.host when \p is added as part of the prompt. mysql.cc: Added code to display mysql.host as prompt when using shared memory client/mysql.cc: Added code to display mysql.host as prompt when using shared memory BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + client/mysql.cc | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index d6ab5ae3180..aae5d908fe4 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -180,6 +180,7 @@ ram@mysql.r18.ru ram@ram.(none) ranger@regul.home.lan rburnett@build.mysql.com +reggie@bob.(none) root@home.(none) root@mc04.(none) root@x3.internalnet diff --git a/client/mysql.cc b/client/mysql.cc index 739cc77bd14..ebae8e636d2 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -3232,13 +3232,20 @@ static const char* construct_prompt() break; } case 'p': + { #ifndef EMBEDDED_LIBRARY if (!connected) { processed_prompt.append("not_connected"); break; } - if (strstr(mysql_get_host_info(&mysql),"TCP/IP") || + + const char *host_info = mysql_get_host_info(&mysql); + if (strstr(host_info, "memory")) + { + processed_prompt.append( mysql.host ); + } + else if (strstr(host_info,"TCP/IP") || !mysql.unix_socket) add_int_to_prompt(mysql.port); else @@ -3247,6 +3254,7 @@ static const char* construct_prompt() processed_prompt.append(pos ? pos+1 : mysql.unix_socket); } #endif + } break; case 'U': if (!full_username) From f33566b55f7537d7d4e05be4fac722fffa4ce612 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 16 Jan 2005 15:46:28 +0100 Subject: [PATCH 36/90] When we warn that --log-bin alone is dangerous, we give a suggestion. sql/mysqld.cc: more suggestive warning message sql/sql_class.h: need a method to see MYSQL_LOG::name (the name of the binlog but without the numeric extension) --- sql/mysqld.cc | 30 ++++++++++++++++-------------- sql/sql_class.h | 1 + 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 415ad446779..b66d1ce3c24 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2687,20 +2687,6 @@ with --log-bin instead."); if (opt_bin_log) { - if (!opt_bin_logname && !opt_binlog_index_name) - { - /* - User didn't give us info to name the binlog index file. - Picking `hostname`-bin.index like did in 4.x, causes replication to - fail if the hostname is changed later. So, we would like to instead - require a name. But as we don't want to break many existing setups, we - only give warning, not error. - */ - sql_print_warning("\ -No argument was provided to --log-bin, and --log-bin-index was not used. " -"Replication may break when this MySQL server acts as a master and has his " -"hostname changed."); - } /* If we fail to open binlog, it's going to hinder our recovery, so die */ if (open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin", opt_binlog_index_name, LOG_BIN, 0, 0, max_binlog_size)) @@ -2714,6 +2700,22 @@ No argument was provided to --log-bin, and --log-bin-index was not used. " mysql_bin_log.purge_logs_before_date(purge_time); } #endif + if (!opt_bin_logname && !opt_binlog_index_name) + { + /* + User didn't give us info to name the binlog index file. + Picking `hostname`-bin.index like did in 4.x, causes replication to + fail if the hostname is changed later. So, we would like to instead + require a name. But as we don't want to break many existing setups, we + only give warning, not error. + */ + sql_print_warning("\ +No argument was provided to --log-bin, and --log-bin-index was not used; \ +so replication may break when this MySQL server acts as a master and \ +has his hostname changed!! Please use '--log-bin=%s' to avoid \ +this problem.", + mysql_bin_log.get_name()); + } } else { diff --git a/sql/sql_class.h b/sql/sql_class.h index 033f5674d34..ca65f011b9d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -205,6 +205,7 @@ public: inline bool is_open() { return log_type != LOG_CLOSED; } inline char* get_index_fname() { return index_file_name;} inline char* get_log_fname() { return log_file_name; } + inline char* get_name() { return name; } inline pthread_mutex_t* get_log_lock() { return &LOCK_log; } inline IO_CACHE* get_log_file() { return &log_file; } From e4f887ad20db0fb16d6851acb05c0410c11f63e3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 16 Jan 2005 16:38:38 +0100 Subject: [PATCH 37/90] initialize mysql->charset in mysql_init --- sql-common/client.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sql-common/client.c b/sql-common/client.c index 7264605b247..3de2483ef75 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1422,6 +1422,7 @@ mysql_init(MYSQL *mysql) bzero((char*) (mysql),sizeof(*(mysql))); mysql->options.connect_timeout= CONNECT_TIMEOUT; mysql->last_used_con= mysql->next_slave= mysql->master = mysql; + mysql->charset=default_charset_info; strmov(mysql->net.sqlstate, not_error_sqlstate); /* By default, we are a replication pivot. The caller must reset it From 0de6a4268406720ba6d9be9d7905a89c6931b939 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 16 Jan 2005 21:39:19 +0100 Subject: [PATCH 38/90] Makefile.am: Bug#7721 ndb/docs/Makefile.am: Bug#7721 --- ndb/docs/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ndb/docs/Makefile.am b/ndb/docs/Makefile.am index c7e344b3dee..1399ce3b6a5 100644 --- a/ndb/docs/Makefile.am +++ b/ndb/docs/Makefile.am @@ -38,7 +38,7 @@ ndbapidoc: ndbapi.pdf ndbapi.pdf: $(noinst_HEADERS) @set -x; \ - export NDB_RELEASE=$(NDB_RELEASE) \ + export NDB_RELEASE=$(NDB_RELEASE); \ @RM@ -f ndbapi.pdf ndbapi.html; \ @RM@ -rf $(DOXYTMP) $(DOXYOUT); \ mkdir -p $(DOXYTMP) $(DOXYOUT); \ @@ -62,7 +62,7 @@ mgmapidoc: mgmapi.pdf mgmapi.pdf: $(noinst_HEADERS) @set -x; \ - export NDB_RELEASE=$(NDB_RELEASE) \ + export NDB_RELEASE=$(NDB_RELEASE); \ @RM@ -f mgmapi.pdf mgmapi.html; \ @RM@ -rf $(DOXYTMP) $(DOXYOUT); \ mkdir -p $(DOXYTMP) $(DOXYOUT); \ From abca4cd54819a102742c2455b765a5cee87e5ed0 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 00:18:19 +0300 Subject: [PATCH 39/90] Fixes in opt_range.cc: ROR plan choice code * Removed unused parameters * Fixed several cost calculation errors in ror_intersect_add * Better code structure for ror_intersect_add and get_best_ror_intersect include/my_bitmap.h: Comments added mysql-test/r/index_merge_innodb.result: Test results updated mysql-test/r/index_merge_ror_cpk.result: Test results updated. mysql-test/t/index_merge_innodb.test: Drop all tables after use sql/opt_range.cc: Fixes in ROR plan choice code * Removed unused parameters * Fixed several cost calculation errors in ror_intersect_add * Better code structure for ror_intersect_add and get_best_ror_intersect --- include/my_bitmap.h | 2 +- mysql-test/r/index_merge_innodb.result | 2 +- mysql-test/r/index_merge_ror_cpk.result | 2 +- mysql-test/t/index_merge_innodb.test | 2 +- sql/opt_range.cc | 352 ++++++++++++------------ 5 files changed, 184 insertions(+), 176 deletions(-) diff --git a/include/my_bitmap.h b/include/my_bitmap.h index fb1c3c69563..4caa3b85456 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -24,7 +24,7 @@ typedef struct st_bitmap { uchar *bitmap; - uint bitmap_size; + uint bitmap_size; /* number of bytes occupied by the above */ /* mutex will be acquired for the duration of each bitmap operation if thread_safe flag in bitmap_init was set. Otherwise, we optimize by not diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result index d1914844839..4c6be698749 100644 --- a/mysql-test/r/index_merge_innodb.result +++ b/mysql-test/r/index_merge_innodb.result @@ -1,4 +1,4 @@ -drop table if exists t1; +drop table if exists t1,t2; create table t1 ( key1 int not null, diff --git a/mysql-test/r/index_merge_ror_cpk.result b/mysql-test/r/index_merge_ror_cpk.result index ba8efe42bd6..c344cef5db9 100644 --- a/mysql-test/r/index_merge_ror_cpk.result +++ b/mysql-test/r/index_merge_ror_cpk.result @@ -26,7 +26,7 @@ primary key (pk1, pk2) ) engine=innodb; explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref PRIMARY,key1 PRIMARY 4 const 1 Using where +1 SIMPLE t1 range PRIMARY,key1 PRIMARY 8 NULL 9 Using where select * from t1 where pk1 = 1 and pk2 < 80 and key1=0; pk1 pk2 key1 key2 pktail1ok pktail2ok pktail3bad pktail4bad pktail5bad pk2copy badkey filler1 filler2 1 10 0 0 0 0 0 0 0 10 0 filler-data-10 filler2 diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test index cc1a3169d0e..5e270c161a2 100644 --- a/mysql-test/t/index_merge_innodb.test +++ b/mysql-test/t/index_merge_innodb.test @@ -4,7 +4,7 @@ -- source include/have_innodb.inc --disable_warnings -drop table if exists t1; +drop table if exists t1,t2; --enable_warnings create table t1 diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 4b0e5f036cb..6be23835032 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -50,7 +50,7 @@ #define test_use_count(A) {} #endif - +#define double2rows(x) ((ha_rows)(x)) static int sel_cmp(Field *f,char *a,char *b,uint8 a_flag,uint8 b_flag); static char is_null_string[2]= {1,0}; @@ -1628,6 +1628,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu", keys_to_use.to_ulonglong(), (ulong) prev_tables, (ulong) const_tables)); + DBUG_PRINT("info", ("records=%lu", (ulong)head->file->records)); delete quick; quick=0; needed_reg.clear_all(); @@ -1874,6 +1875,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, double get_sweep_read_cost(const PARAM *param, ha_rows records) { double result; + DBUG_ENTER("get_sweep_read_cost"); if (param->table->file->primary_key_is_clustered()) { result= param->table->file->read_time(param->table->s->primary_key, @@ -1912,7 +1914,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records) } } DBUG_PRINT("info",("returning cost=%g", result)); - return result; + DBUG_RETURN(result); } @@ -2393,43 +2395,27 @@ typedef struct { const PARAM *param; MY_BITMAP covered_fields; /* union of fields covered by all scans */ - - /* TRUE if covered_fields is a superset of needed_fields */ - bool is_covering; - - double index_scan_costs; /* SUM(cost of 'index-only' scans) */ - double total_cost; /* Fraction of table records that satisfies conditions of all scans. This is the number of full records that will be retrieved if a non-index_only index intersection will be employed. */ - double records_fract; + double out_rows; + /* TRUE if covered_fields is a superset of needed_fields */ + bool is_covering; + ha_rows index_records; /* sum(#records to look in indexes) */ + double index_scan_costs; /* SUM(cost of 'index-only' scans) */ + double total_cost; } ROR_INTERSECT_INFO; -/* - Re-initialize an allocated intersect info to contain zero scans. - SYNOPSIS - info Intersection info structure to re-initialize. -*/ - -static void ror_intersect_reinit(ROR_INTERSECT_INFO *info) -{ - info->is_covering= FALSE; - info->index_scan_costs= 0.0f; - info->records_fract= 1.0f; - bitmap_clear_all(&info->covered_fields); -} - /* Allocate a ROR_INTERSECT_INFO and initialize it to contain zero scans. SYNOPSIS ror_intersect_init() param Parameter from test_quick_select - is_index_only If TRUE, set ROR_INTERSECT_INFO to be covering RETURN allocated structure @@ -2437,7 +2423,7 @@ static void ror_intersect_reinit(ROR_INTERSECT_INFO *info) */ static -ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param, bool is_index_only) +ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param) { ROR_INTERSECT_INFO *info; uchar* buf; @@ -2450,46 +2436,39 @@ ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param, bool is_index_only) if (bitmap_init(&info->covered_fields, buf, param->fields_bitmap_size*8, FALSE)) return NULL; - ror_intersect_reinit(info); + info->is_covering= FALSE; + info->index_scan_costs= 0.0f; + info->index_records= 0; + info->out_rows= param->table->file->records; + bitmap_clear_all(&info->covered_fields); return info; } - +void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src) +{ + dst->param= src->param; + memcpy(dst->covered_fields.bitmap, src->covered_fields.bitmap, + src->covered_fields.bitmap_size); + dst->out_rows= src->out_rows; + dst->is_covering= src->is_covering; + dst->index_records= src->index_records; + dst->index_scan_costs= src->index_scan_costs; + dst->total_cost= src->total_cost; +} /* - Check if adding a ROR scan to a ROR-intersection reduces its cost of - ROR-intersection and if yes, update parameters of ROR-intersection, - including its cost. + Get selectivity of a ROR scan wrt ROR-intersection. SYNOPSIS - ror_intersect_add() - param Parameter from test_quick_select - info ROR-intersection structure to add the scan to. - ror_scan ROR scan info to add. - is_cpk_scan If TRUE, add the scan as CPK scan (this can be inferred - from other parameters and is passed separately only to - avoid duplicating the inference code) - + ror_scan_selectivity() + info ROR-interection + scan ROR scan + NOTES - Adding a ROR scan to ROR-intersect "makes sense" iff the cost of ROR- - intersection decreases. The cost of ROR-intersection is caclulated as - follows: - - cost= SUM_i(key_scan_cost_i) + cost_of_full_rows_retrieval - - if (union of indexes used covers all needed fields) - cost_of_full_rows_retrieval= 0; - else - { - cost_of_full_rows_retrieval= - cost_of_sweep_read(E(rows_to_retrieve), rows_in_table); - } - - E(rows_to_retrieve) is caclulated as follows: Suppose we have a condition on several keys cond=k_11=c_11 AND k_12=c_12 AND ... // parts of first key k_21=c_21 AND k_22=c_22 AND ... // parts of second key ... - k_n1=c_n1 AND k_n3=c_n3 AND ... (1) + k_n1=c_n1 AND k_n3=c_n3 AND ... (1) //parts of the key used by *scan where k_ij may be the same as any k_pq (i.e. keys may have common parts). @@ -2563,38 +2542,30 @@ ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param, bool is_index_only) and reduce adjacent fractions. RETURN - TRUE ROR scan added to ROR-intersection, cost updated. - FALSE It doesn't make sense to add this ROR scan to this ROR-intersection. + Selectivity of given ROR scan. + */ -bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, - ROR_SCAN_INFO* ror_scan, bool is_cpk_scan=FALSE) +static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info, + const ROR_SCAN_INFO *scan) { - int i; - SEL_ARG *sel_arg; - KEY_PART_INFO *key_part= - info->param->table->key_info[ror_scan->keynr].key_part; double selectivity_mult= 1.0; + KEY_PART_INFO *key_part= info->param->table->key_info[scan->keynr].key_part; byte key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */ - - DBUG_ENTER("ror_intersect_add"); - DBUG_PRINT("info", ("Current selectivity= %g", info->records_fract)); - DBUG_PRINT("info", ("Adding scan on %s", - info->param->table->key_info[ror_scan->keynr].name)); - SEL_ARG *tuple_arg= NULL; char *key_ptr= (char*) key_val; - bool cur_covered, prev_covered= - bitmap_is_set(&info->covered_fields, key_part->fieldnr); - - ha_rows prev_records= param->table->file->records; + SEL_ARG *sel_arg, *tuple_arg= NULL; + bool cur_covered; + bool prev_covered= bitmap_is_set(&info->covered_fields, key_part->fieldnr); key_range min_range; key_range max_range; min_range.key= (byte*) key_val; min_range.flag= HA_READ_KEY_EXACT; max_range.key= (byte*) key_val; max_range.flag= HA_READ_AFTER_KEY; - - for(i= 0, sel_arg= ror_scan->sel_arg; sel_arg; + ha_rows prev_records= info->param->table->file->records; + int i; + DBUG_ENTER("ror_intersect_selectivity"); + for(i= 0, sel_arg= scan->sel_arg; sel_arg; i++, sel_arg= sel_arg->next_key_part) { cur_covered= bitmap_is_set(&info->covered_fields, (key_part + i)->fieldnr); @@ -2604,7 +2575,7 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, { if (!tuple_arg) { - tuple_arg= ror_scan->sel_arg; + tuple_arg= scan->sel_arg; tuple_arg->store_min(key_part->length, &key_ptr, 0); } while (tuple_arg->next_key_part != sel_arg) @@ -2615,10 +2586,8 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, } ha_rows records; min_range.length= max_range.length= ((char*) key_ptr - (char*) key_val); - records= param->table->file-> - records_in_range(ror_scan->keynr, - &min_range, - &max_range); + records= info->param->table->file-> + records_in_range(scan->keynr, &min_range, &max_range); if (cur_covered) { /* uncovered -> covered */ @@ -2637,52 +2606,108 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, } if (!prev_covered) { - double tmp= rows2double(param->table->quick_rows[ror_scan->keynr]) / + double tmp= rows2double(info->param->table->quick_rows[scan->keynr]) / rows2double(prev_records); DBUG_PRINT("info", ("Selectivity multiplier: %g", tmp)); selectivity_mult *= tmp; } + DBUG_PRINT("info", ("Returning multiplier: %g", selectivity_mult)); + DBUG_RETURN(selectivity_mult); +} +/* + Check if adding a ROR scan to a ROR-intersection reduces its cost of + ROR-intersection and if yes, update parameters of ROR-intersection, + including its cost. + + SYNOPSIS + ror_intersect_add() + param Parameter from test_quick_select + info ROR-intersection structure to add the scan to. + ror_scan ROR scan info to add. + is_cpk_scan If TRUE, add the scan as CPK scan (this can be inferred + from other parameters and is passed separately only to + avoid duplicating the inference code) + + NOTES + Adding a ROR scan to ROR-intersect "makes sense" iff the cost of ROR- + intersection decreases. The cost of ROR-intersection is calculated as + follows: + + cost= SUM_i(key_scan_cost_i) + cost_of_full_rows_retrieval + + When we add a scan the first increases and the second decreases. + + cost_of_full_rows_retrieval= + (union of indexes used covers all needed fields) ? + cost_of_sweep_read(E(rows_to_retrieve), rows_in_table) : + 0 + + E(rows_to_retrieve) = #rows_in_table * ror_scan_selectivity(null, scan1) * + ror_scan_selectivity({scan1}, scan2) * ... * + ror_scan_selectivity({scan1,...}, scanN). + RETURN + TRUE ROR scan added to ROR-intersection, cost updated. + FALSE It doesn't make sense to add this ROR scan to this ROR-intersection. +*/ + +static bool ror_intersect_add(ROR_INTERSECT_INFO *info, + ROR_SCAN_INFO* ror_scan, bool is_cpk_scan) +{ + double selectivity_mult= 1.0; + + DBUG_ENTER("ror_intersect_add"); + DBUG_PRINT("info", ("Current out_rows= %g", info->out_rows)); + DBUG_PRINT("info", ("Adding scan on %s", + info->param->table->key_info[ror_scan->keynr].name)); + DBUG_PRINT("info", ("is_cpk_scan=%d",is_cpk_scan)); + + selectivity_mult = ror_scan_selectivity(info, ror_scan); if (selectivity_mult == 1.0) { /* Don't add this scan if it doesn't improve selectivity. */ DBUG_PRINT("info", ("The scan doesn't improve selectivity.")); - DBUG_RETURN(FALSE); + DBUG_RETURN(false); } - - info->records_fract *= selectivity_mult; - ha_rows cur_scan_records= info->param->table->quick_rows[ror_scan->keynr]; + + info->out_rows *= selectivity_mult; + DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost)); + if (is_cpk_scan) { - info->index_scan_costs += rows2double(cur_scan_records)* + /* + CPK scan is used to filter out rows. We apply filtering for + each record of every scan. Assuming 1/TIME_FOR_COMPARE_ROWID + per check this gives us: + */ + info->index_scan_costs += rows2double(info->index_records) / TIME_FOR_COMPARE_ROWID; } else { - info->index_records += cur_scan_records; + info->index_records += info->param->table->quick_rows[ror_scan->keynr]; info->index_scan_costs += ror_scan->index_read_cost; bitmap_union(&info->covered_fields, &ror_scan->covered_fields); - } - - if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields, - &info->covered_fields)) - { - DBUG_PRINT("info", ("ROR-intersect is covering now")); - info->is_covering= TRUE; + if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields, + &info->covered_fields)) + { + DBUG_PRINT("info", ("ROR-intersect is covering now")); + info->is_covering= TRUE; + } } info->total_cost= info->index_scan_costs; + DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost)); if (!info->is_covering) { - ha_rows table_recs= info->param->table->file->records; - info->total_cost += - get_sweep_read_cost(info->param, - (ha_rows)(info->records_fract*table_recs)); + info->total_cost += + get_sweep_read_cost(info->param, double2rows(info->out_rows)); + DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost)); } - DBUG_PRINT("info", ("New selectivity= %g", info->records_fract)); + DBUG_PRINT("info", ("New out_rows= %g", info->out_rows)); DBUG_PRINT("info", ("New cost= %g, %scovering", info->total_cost, info->is_covering?"" : "non-")); - DBUG_RETURN(TRUE); + DBUG_RETURN(true); } @@ -2701,9 +2726,13 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, a covering ROR-intersection) NOTES - get_key_scans_params must be called before for the same SEL_TREE before - this function can be called. + get_key_scans_params must be called before this function can be called. + + When this function is called by ROR-union construction algorithm it + assumes it is building an uncovered ROR-intersection (and thus # of full + records to be retrieved is wrong here). This is a hack. + IMPLEMENTATION The approximate best non-covering plan search algorithm is as follows: find_min_ror_intersection_scan() @@ -2717,11 +2746,11 @@ bool ror_intersect_add(const PARAM *param, ROR_INTERSECT_INFO *info, min_scan= make_scan(S); while (R is not empty) { - if (!selectivity(S + first(R) < selectivity(S))) + firstR= R - first(R); + if (!selectivity(S + firstR < selectivity(S))) continue; - + S= S + first(R); - R= R - first(R); if (cost(S) < min_cost) { min_cost= cost(S); @@ -2752,15 +2781,15 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, bool *are_all_covering) { uint idx; - double min_cost= read_time; + double min_cost= DBL_MAX; DBUG_ENTER("get_best_ror_intersect"); if ((tree->n_ror_scans < 2) || !param->table->file->records) DBUG_RETURN(NULL); /* - Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of them. - Also find and save clustered PK scan if there is one. + Step1: Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of + them. Also find and save clustered PK scan if there is one. */ ROR_SCAN_INFO **cur_ror_scan; ROR_SCAN_INFO *cpk_scan= NULL; @@ -2796,8 +2825,8 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, tree->ror_scans_end);); /* Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized - ROR_SCAN_INFOs. - Now, get a minimal key scan using an approximate algorithm. + ROR_SCAN_INFO's. + Step 2: Get best ROR-intersection using an approximate algorithm. */ qsort(tree->ror_scans, tree->n_ror_scans, sizeof(ROR_SCAN_INFO*), (qsort_cmp)cmp_ror_scan_info); @@ -2814,45 +2843,41 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, intersect_scans_end= intersect_scans; /* Create and incrementally update ROR intersection. */ - ROR_INTERSECT_INFO *intersect; - if (!(intersect= ror_intersect_init(param, FALSE))) + ROR_INTERSECT_INFO *intersect, *intersect_best; + if (!(intersect= ror_intersect_init(param)) || + !(intersect_best= ror_intersect_init(param))) return NULL; - /* [intersect_scans, intersect_scans_best) will hold the best combination */ + /* [intersect_scans,intersect_scans_best) will hold the best intersection */ ROR_SCAN_INFO **intersect_scans_best; - ha_rows best_rows; - bool is_best_covering; - double best_index_scan_costs; - LINT_INIT(best_rows); /* protected by intersect_scans_best */ - LINT_INIT(is_best_covering); - LINT_INIT(best_index_scan_costs); - cur_ror_scan= tree->ror_scans; - /* Start with one scan */ intersect_scans_best= intersect_scans; while (cur_ror_scan != tree->ror_scans_end && !intersect->is_covering) { - /* S= S + first(R); */ - if (ror_intersect_add(param, intersect, *cur_ror_scan)) - *(intersect_scans_end++)= *cur_ror_scan; - /* R= R - first(R); */ - cur_ror_scan++; + /* S= S + first(R); R= R - first(R); */ + if (!ror_intersect_add(intersect, *cur_ror_scan, false)) + { + cur_ror_scan++; + continue; + } + + *(intersect_scans_end++)= *(cur_ror_scan++); if (intersect->total_cost < min_cost) { /* Local minimum found, save it */ - min_cost= intersect->total_cost; - best_rows= (ha_rows)(intersect->records_fract* - rows2double(param->table->file->records)); - /* Prevent divisons by zero */ - if (!best_rows) - best_rows= 1; - is_best_covering= intersect->is_covering; + ror_intersect_cpy(intersect_best, intersect); intersect_scans_best= intersect_scans_end; - best_index_scan_costs= intersect->index_scan_costs; + min_cost = intersect->total_cost; } } + if (intersect_scans_best == intersect_scans) + { + DBUG_PRINT("info", ("None of scans increase selectivity")); + DBUG_RETURN(NULL); + } + DBUG_EXECUTE("info",print_ror_scans_arr(param->table, "best ROR-intersection", intersect_scans, @@ -2860,48 +2885,26 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, *are_all_covering= intersect->is_covering; uint best_num= intersect_scans_best - intersect_scans; + ror_intersect_cpy(intersect, intersect_best); + /* Ok, found the best ROR-intersection of non-CPK key scans. - Check if we should add a CPK scan. - - If the obtained ROR-intersection is covering, it doesn't make sense - to add CPK scan - Clustered PK contains all fields and if we're doing - CPK scan doing other CPK scans will only add more overhead. + Check if we should add a CPK scan. If the obtained ROR-intersection is + covering, it doesn't make sense to add CPK scan. */ if (cpk_scan && !intersect->is_covering) { - /* - Handle the special case: ROR-intersect(PRIMARY, key1) is - the best, but cost(range(key1)) > cost(best_non_ror_range_scan) - */ - if (best_num == 0) - { - cur_ror_scan= tree->ror_scans; - intersect_scans_end= intersect_scans; - ror_intersect_reinit(intersect); - if (!ror_intersect_add(param, intersect, *cur_ror_scan)) - DBUG_RETURN(NULL); /* shouldn't happen actually */ - *(intersect_scans_end++)= *cur_ror_scan; - best_num++; - } - - if (ror_intersect_add(param, intersect, cpk_scan)) + if (ror_intersect_add(intersect, cpk_scan, true) && + (intersect->total_cost < min_cost)) { cpk_scan_used= TRUE; - min_cost= intersect->total_cost; - best_rows= (ha_rows)(intersect->records_fract* - rows2double(param->table->file->records)); - /* Prevent divisons by zero */ - if (!best_rows) - best_rows= 1; - is_best_covering= intersect->is_covering; - best_index_scan_costs= intersect->index_scan_costs; + intersect_best= intersect; //just set pointer here } } /* Ok, return ROR-intersect plan if we have found one */ TRP_ROR_INTERSECT *trp= NULL; - if (best_num > 1 || cpk_scan_used) + if (min_cost < read_time && (cpk_scan_used || best_num > 1)) { if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT)) DBUG_RETURN(trp); @@ -2911,14 +2914,18 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, DBUG_RETURN(NULL); memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*)); trp->last_scan= trp->first_scan + best_num; - trp->is_covering= is_best_covering; - trp->read_cost= min_cost; + trp->is_covering= intersect_best->is_covering; + trp->read_cost= intersect_best->total_cost; + /* Prevent divisons by zero */ + ha_rows best_rows = double2rows(intersect_best->out_rows); + if (!best_rows) + best_rows= 1; trp->records= best_rows; - trp->index_scan_costs= best_index_scan_costs; - trp->cpk_scan= cpk_scan; - DBUG_PRINT("info", - ("Returning non-covering ROR-intersect plan: cost %g, records %lu", - trp->read_cost, (ulong) trp->records)); + trp->index_scan_costs= intersect_best->index_scan_costs; + trp->cpk_scan= cpk_scan_used? cpk_scan: NULL; + DBUG_PRINT("info", ("Returning non-covering ROR-intersect plan:" + "cost %g, records %lu", + trp->read_cost, (ulong) trp->records)); } DBUG_RETURN(trp); } @@ -3145,8 +3152,9 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, found_records) + cpu_cost; - DBUG_PRINT("info",("read_time: %g found_read_time: %g", - read_time, found_read_time)); + DBUG_PRINT("info",("key %s: found_read_time: %g (cur. read_time: %g)", + param->table->key_info[keynr].name, found_read_time, + read_time)); if (read_time > found_read_time && found_records != HA_POS_ERROR /*|| read_time == DBL_MAX*/ ) From c72207e143ac491dc23bd52fd14ecdf04113a107 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 09:27:24 +0400 Subject: [PATCH 40/90] libmysql.c: bug#7891: mysql_character_set_name() returns collation libmysql/libmysql.c: bug#7891: mysql_character_set_name() returns collation --- libmysql/libmysql.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index b180e86392d..10077e695f3 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1504,7 +1504,7 @@ ulong STDCALL mysql_thread_id(MYSQL *mysql) const char * STDCALL mysql_character_set_name(MYSQL *mysql) { - return mysql->charset->name; + return mysql->charset->csname; } From 7f69f44f0ab52f1634d80033b8e28a77b74a853c Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 00:09:47 -0600 Subject: [PATCH 41/90] mysqldump.c: Move out-of-order option. client/mysqldump.c: Move out-of-order option. --- client/mysqldump.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 14ebe9ea8f7..7280bea43f3 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -303,6 +303,9 @@ static struct my_option my_long_options[] = {"opt", OPT_OPTIMIZE, "Same as --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys. Enabled by default, disable with --skip-opt.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"order-by-primary", OPT_ORDER_BY_PRIMARY, + "Sorts each table's rows by primary key, or first unique key, if such a key exists. Useful when dumping a MyISAM table to be loaded into an InnoDB table, but will make the dump itself take considerably longer.", + (gptr*) &opt_order_by_primary, (gptr*) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server. If password is not given it's solicited on the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, @@ -354,9 +357,6 @@ static struct my_option my_long_options[] = {"socket", 'S', "Socket file to use for connection.", (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"order-by-primary", OPT_ORDER_BY_PRIMARY, - "Sorts each table's rows by primary key, or first unique key, if such a key exists. Useful when dumping a MyISAM table to be loaded into an InnoDB table, but will make the dump itself take considerably longer.", - (gptr*) &opt_order_by_primary, (gptr*) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #include {"tab",'T', "Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if mysqldump is run on the same machine as the mysqld daemon.", From b25fcad4a7ee8c8b54610609dd989b1e8b9ce3c5 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 10:38:35 +0400 Subject: [PATCH 42/90] user_var.result, func_str.result, item_strfunc.cc: bug#7839 ncorrect collation for char(ascii('a')) sql/item_strfunc.cc: bug#7839 ncorrect collation for char(ascii('a')) mysql-test/r/func_str.result: bug#7839 ncorrect collation for char(ascii('a')) mysql-test/r/user_var.result: bug#7839 ncorrect collation for char(ascii('a')) --- mysql-test/r/func_str.result | 2 +- mysql-test/r/user_var.result | 4 ++-- sql/item_strfunc.cc | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 8348ef12b0d..0db62b133e7 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -463,7 +463,7 @@ collation(hex(130)) coercibility(hex(130)) latin1_swedish_ci 3 select collation(char(130)), coercibility(hex(130)); collation(char(130)) coercibility(hex(130)) -binary 3 +latin1_swedish_ci 3 select collation(format(130,10)), coercibility(format(130,10)); collation(format(130,10)) coercibility(format(130,10)) latin1_swedish_ci 3 diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index d46d6c7a78a..81846391795 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -175,7 +175,7 @@ Log_name Pos Event_type Server_id Orig_log_pos Info master-bin.000001 79 User var 1 79 @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci master-bin.000001 120 Query 1 120 use `test`; INSERT INTO t1 VALUES(@`a b`) master-bin.000001 184 User var 1 184 @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci -master-bin.000001 226 User var 1 226 @`var2`=_binary 0x61 COLLATE binary +master-bin.000001 226 User var 1 226 @`var2`=_latin1 0x61 COLLATE latin1_swedish_ci master-bin.000001 264 Query 1 264 use `test`; insert into t1 values (@var1),(@var2) /*!40019 SET @@session.max_insert_delayed_threads=0*/; SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`; @@ -183,7 +183,7 @@ use test; SET TIMESTAMP=10000; INSERT INTO t1 VALUES(@`a b`); SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`; -SET @`var2`:=_binary 0x61 COLLATE `binary`; +SET @`var2`:=_latin1 0x61 COLLATE `latin1_swedish_ci`; SET TIMESTAMP=10000; insert into t1 values (@var1),(@var2); drop table t1; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index d0190af042e..8341dda0a41 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1888,6 +1888,7 @@ b1: str->append((char)(num>>8)); #endif str->append((char)num); } + str->set_charset(collation.collation); str->realloc(str->length()); // Add end 0 (for Purify) return str; } From b01a4b33d5b83bbad406e58dfe85f987693b3480 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 13:23:56 +0400 Subject: [PATCH 43/90] func_str.result: after merge fix mysql-test/r/func_str.result: after merge fix --- mysql-test/r/func_str.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 2399099b478..1f78e5098f8 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -466,7 +466,7 @@ collation(hex(130)) coercibility(hex(130)) latin1_swedish_ci 3 select collation(char(130)), coercibility(hex(130)); collation(char(130)) coercibility(hex(130)) -binary 3 +latin1_swedish_ci 3 select collation(format(130,10)), coercibility(format(130,10)); collation(format(130,10)) coercibility(format(130,10)) latin1_swedish_ci 3 From 758769eef43fb2a2499491147ac2c2a78b9633be Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 13:58:16 +0400 Subject: [PATCH 44/90] user_var.result: after merge fix mysql-test/r/user_var.result: after merge fix --- mysql-test/r/user_var.result | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index d7d527dd720..69fcc5c45fe 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -172,23 +172,26 @@ SET TIMESTAMP=10000; SET @`a b`='hello'; INSERT INTO t1 VALUES(@`a b`); set @var1= "';aaa"; -insert into t1 values (@var1); +SET @var2=char(ascii('a')); +insert into t1 values (@var1),(@var2); show binlog events from 95; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 95 User var 1 136 @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci master-bin.000001 136 Query 1 222 use `test`; INSERT INTO t1 VALUES(@`a b`) master-bin.000001 222 User var 1 264 @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci -master-bin.000001 264 Query 1 350 use `test`; insert into t1 values (@var1) +master-bin.000001 264 User var 1 302 @`var2`=_latin1 0x61 COLLATE latin1_swedish_ci +master-bin.000001 302 Query 1 396 use `test`; insert into t1 values (@var1),(@var2) /*!40019 SET @@session.max_insert_delayed_threads=0*/; -SET @`a b`:=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci; +SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`; use test; SET TIMESTAMP=10000; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.sql_mode=0; INSERT INTO t1 VALUES(@`a b`); -SET @`var1`:=_latin1 0x273B616161 COLLATE latin1_swedish_ci; +SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`; +SET @`var2`:=_latin1 0x61 COLLATE `latin1_swedish_ci`; SET TIMESTAMP=10000; -insert into t1 values (@var1); +insert into t1 values (@var1),(@var2); drop table t1; set @var= NULL ; select FIELD( @var,'1it','Hit') as my_column; From a05bacb06ef33bf14439ee258c24dbeced10c3e4 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 12:29:43 +0100 Subject: [PATCH 45/90] Bug#7937 --- ndb/tools/restore/Restore.hpp | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/ndb/tools/restore/Restore.hpp b/ndb/tools/restore/Restore.hpp index e0b06c1774c..d7f6e3b7799 100644 --- a/ndb/tools/restore/Restore.hpp +++ b/ndb/tools/restore/Restore.hpp @@ -187,28 +187,33 @@ public: }; void update_max_auto_val(const char *data, int size) { - Uint64 val= 0; + union { + Uint8 u8; + Uint16 u16; + Uint32 u32; + } val; + Uint64 v; switch(size){ - case 8: - val= *(Uint8*)data; - break; - case 16: - val= *(Uint16*)data; - break; - case 24: - val= (0xffffff)&*(Uint32*)data; + case 64: + memcpy(&v,data,8); break; case 32: - val= *(Uint32*)data; + memcpy(&val.u32,data,4); + v= val.u32; break; - case 64: - val= *(Uint64*)data; + case 16: + memcpy(&val.u16,data,2); + v= val.u16; + break; + case 8: + memcpy(&val.u8,data,1); + v= val.u8; break; default: return; }; - if(val > m_max_auto_val) - m_max_auto_val= val; + if(v > m_max_auto_val) + m_max_auto_val= v; }; /** * Get attribute descriptor From 81c97e42f05eaa615e94ac62e551d02089f52130 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 17:19:33 +0200 Subject: [PATCH 46/90] Fix for BUG#7331 merged manually from 4.1. mysql-test/r/order_by.result: Test result for BUG#7331. mysql-test/t/order_by.test: Test for BUG#7331. sql/sql_select.cc: Fix for BUG#7331. --- mysql-test/r/order_by.result | 38 ++++++++++++++++++++++++++++++++++++ mysql-test/t/order_by.test | 33 +++++++++++++++++++++++++++++++ sql/sql_select.cc | 23 +++++++++++++++------- 3 files changed, 87 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 6744ffa889f..5674fbb9177 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -740,3 +740,41 @@ a b 1 2 1 1 drop table t1; +create table t1 ( +`sid` decimal(8,0) default null, +`wnid` varchar(11) not null default '', +key `wnid14` (`wnid`(4)), +key `wnid` (`wnid`) +) engine=myisam default charset=latin1; +insert into t1 (`sid`, `wnid`) values +('10100','01019000000'),('37986','01019000000'),('37987','01019010000'), +('39560','01019090000'),('37989','01019000000'),('37990','01019011000'), +('37991','01019011000'),('37992','01019019000'),('37993','01019030000'), +('37994','01019090000'),('475','02070000000'),('25253','02071100000'), +('25255','02071100000'),('25256','02071110000'),('25258','02071130000'), +('25259','02071190000'),('25260','02071200000'),('25261','02071210000'), +('25262','02071290000'),('25263','02071300000'),('25264','02071310000'), +('25265','02071310000'),('25266','02071320000'),('25267','02071320000'), +('25269','02071330000'),('25270','02071340000'),('25271','02071350000'), +('25272','02071360000'),('25273','02071370000'),('25281','02071391000'), +('25282','02071391000'),('25283','02071399000'),('25284','02071400000'), +('25285','02071410000'),('25286','02071410000'),('25287','02071420000'), +('25288','02071420000'),('25291','02071430000'),('25290','02071440000'), +('25292','02071450000'),('25293','02071460000'),('25294','02071470000'), +('25295','02071491000'),('25296','02071491000'),('25297','02071499000'); +explain select * from t1 where wnid like '0101%' order by wnid; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range wnid14,wnid wnid 13 NULL 10 Using where +select * from t1 where wnid like '0101%' order by wnid; +sid wnid +10100 01019000000 +37986 01019000000 +37989 01019000000 +37987 01019010000 +37990 01019011000 +37991 01019011000 +37992 01019019000 +37993 01019030000 +39560 01019090000 +37994 01019090000 +drop table t1; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index dd36cd95969..02e49f9750d 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -506,3 +506,36 @@ insert t1 values (1,1,1),(1,1,2),(1,2,1); select a, b from t1 group by a, b order by sum(c); drop table t1; +# +# Bug #7331 +# + +create table t1 ( + `sid` decimal(8,0) default null, + `wnid` varchar(11) not null default '', + key `wnid14` (`wnid`(4)), + key `wnid` (`wnid`) +) engine=myisam default charset=latin1; + +insert into t1 (`sid`, `wnid`) values +('10100','01019000000'),('37986','01019000000'),('37987','01019010000'), +('39560','01019090000'),('37989','01019000000'),('37990','01019011000'), +('37991','01019011000'),('37992','01019019000'),('37993','01019030000'), +('37994','01019090000'),('475','02070000000'),('25253','02071100000'), +('25255','02071100000'),('25256','02071110000'),('25258','02071130000'), +('25259','02071190000'),('25260','02071200000'),('25261','02071210000'), +('25262','02071290000'),('25263','02071300000'),('25264','02071310000'), +('25265','02071310000'),('25266','02071320000'),('25267','02071320000'), +('25269','02071330000'),('25270','02071340000'),('25271','02071350000'), +('25272','02071360000'),('25273','02071370000'),('25281','02071391000'), +('25282','02071391000'),('25283','02071399000'),('25284','02071400000'), +('25285','02071410000'),('25286','02071410000'),('25287','02071420000'), +('25288','02071420000'),('25291','02071430000'),('25290','02071440000'), +('25292','02071450000'),('25293','02071460000'),('25294','02071470000'), +('25295','02071491000'),('25296','02071491000'),('25297','02071499000'); + +explain select * from t1 where wnid like '0101%' order by wnid; + +select * from t1 where wnid like '0101%' order by wnid; + +drop table t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0273334eca2..cf02d1c4f6e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10426,13 +10426,22 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, } else { - select->quick->head->file->ha_index_end(); - /* - We have verified above that select->quick is not - index_merge quick select. - */ - select->quick->index= new_ref_key; - select->quick->init(); + /* + The range optimizer constructed QUICK_RANGE for ref_key, and + we want to use instead new_ref_key as the index. We can't + just change the index of the quick select, because this may + result in an incosistent QUICK_SELECT object. Below we + create a new QUICK_SELECT from scratch so that all its + parameres are set correctly by the range optimizer. + */ + key_map new_ref_key_map; + new_ref_key_map.clear_all(); /* Force the creation of quick select */ + new_ref_key_map.set_bit(new_ref_key); /* only for new_ref_key. */ + + if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0, + (tab->join->select_options & OPTION_FOUND_ROWS) ? + HA_POS_ERROR : tab->join->unit->select_limit_cnt) <= 0) + DBUG_RETURN(0); } ref_key= new_ref_key; } From 4fc1801d08b08dbb86f82cf83c11f5b90aaca745 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 19:21:01 +0300 Subject: [PATCH 47/90] Fixed memory leak in handle_local_infile() BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + libmysql/libmysql.c | 1 + 2 files changed, 2 insertions(+) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index d6ab5ae3180..7ff770e8fbb 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -93,6 +93,7 @@ joerg@mysql.com joreland@mysql.com jorge@linux.jorge.mysql.com jplindst@t41.(none) +kaa@polly.local kaj@work.mysql.com kent@mysql.com konstantin@mysql.com diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 10077e695f3..206fd8f77b4 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -852,6 +852,7 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename) err: /* free up memory allocated with _init, usually */ (*options->local_infile_end)(li_ptr); + my_free(buf, MYF(0)); DBUG_RETURN(result); } From 57f7c497cf397452cce36f50f546f0f1f85a2269 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 17:22:17 +0100 Subject: [PATCH 48/90] - Enabled the handling of architecture extensions e.g. "-64bit" when building Mac OS X PKGs with Do-pkg Build-tools/Do-pkg: - enable handling of architecture extensions e.g. "-64bit" --- Build-tools/Do-pkg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Build-tools/Do-pkg b/Build-tools/Do-pkg index 2fd1946ed0e..04d7ba021e5 100755 --- a/Build-tools/Do-pkg +++ b/Build-tools/Do-pkg @@ -84,7 +84,7 @@ $LOGFILE= "$PWD/Logs/$HOST-$MAJOR.$MINOR$SUFFIX.log"; $BUILDDIR= "$PWD/$HOST"; $SRCBASEDIR= <$BUILDDIR/mysql*-$VERSION>; $SUPFILEDIR= <$SRCBASEDIR/support-files/MacOSX>; -$TAR= <$BUILDDIR/$NAME-apple-darwin*-powerpc.tar.gz>; +$TAR= <$BUILDDIR/$NAME-apple-darwin*-powerpc*.tar.gz>; $TAR =~ /.*\/$NAME(.*)\.tar\.gz$/; $ARCH= $1; $NAME= $NAME . $ARCH; From 2524517978fe7a3d0f61a67bb7a558663b559cac Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 18:08:07 +0100 Subject: [PATCH 49/90] Allow "classic" builds (= without InnoDB) by eliminating an "unresolved reference" (bug#7961). sql/mysqld.cc: To allow builds without InnoDB ("classic"), the reference to 'innobase_use_checksums' must be guarded by an appropriate '#ifdef' (bug#7961). --- sql/mysqld.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b66d1ce3c24..ee59ed8c8a1 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4449,9 +4449,11 @@ Disable with --skip-large-pages.", Disable with --skip-innodb (will save memory).", (gptr*) &opt_innodb, (gptr*) &opt_innodb, 0, GET_BOOL, NO_ARG, OPT_INNODB_DEFAULT, 0, 0, 0, 0, 0}, +#ifdef HAVE_INNOBASE_DB {"innodb_checksums", OPT_INNODB_CHECKSUMS, "Enable InnoDB checksums validation (enabled by default). \ Disable with --skip-innodb-checksums.", (gptr*) &innobase_use_checksums, (gptr*) &innobase_use_checksums, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, +#endif {"innodb_data_file_path", OPT_INNODB_DATA_FILE_PATH, "Path to individual files and their sizes.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, From f9bcb9ab5cb6582c9bfe4ce3759b97868c22aa2f Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 19:52:07 +0200 Subject: [PATCH 50/90] backported from 5.0 patch initialization of main select for commands where subqueries are possible --- sql/sql_yacc.yy | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4fcc72bc90e..1e51d8fb82d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4008,7 +4008,8 @@ insert: { LEX *lex= Lex; lex->sql_command= SQLCOM_INSERT; - lex->duplicates= DUP_ERROR; + lex->duplicates= DUP_ERROR; + mysql_init_select(lex); /* for subselects */ lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; @@ -4028,6 +4029,7 @@ replace: LEX *lex=Lex; lex->sql_command = SQLCOM_REPLACE; lex->duplicates= DUP_REPLACE; + mysql_init_select(lex); lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; } replace_lock_option insert2 @@ -4229,6 +4231,7 @@ delete: { LEX *lex= Lex; lex->sql_command= SQLCOM_DELETE; + mysql_init_select(lex); lex->lock_option= lex->thd->update_lock_default; lex->ignore= 0; lex->select_lex.init_order(); @@ -5321,6 +5324,7 @@ set: { LEX *lex=Lex; lex->sql_command= SQLCOM_SET_OPTION; + mysql_init_select(lex); lex->option_type=OPT_SESSION; lex->var_list.empty(); lex->one_shot_set= 0; From f6f90e7dc1ae497ac25941fc6b709f18a5d46c46 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 13:40:36 -0600 Subject: [PATCH 51/90] Bug #7966 query cache doesn't work properly with batch statements sql_lex.cc: Set query to not cacheable if we are using multistatements and there are multiple statements in this query sql/sql_lex.cc: Set query to not cacheable if we are using multistatements and there are multiple statements in this query --- sql/sql_lex.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5730073bd35..2783406e16a 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -912,6 +912,7 @@ int yylex(void *arg, void *yythd) if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS) && (thd->command != COM_PREPARE)) { + lex->safe_to_cache_query=0; lex->found_colon=(char*)lex->ptr; thd->server_status |= SERVER_MORE_RESULTS_EXISTS; lex->next_state=MY_LEX_END; From 3752c3b33bac1d6d647845ecd800183693a13cf9 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 12:22:23 -0800 Subject: [PATCH 52/90] Print a warning when an old table (with no character set stored) is opened and the default character set is multi-byte, which will result in character column size changes. (Bug #6913) sql/table.cc: Print a warning when an old table is opened and the default character set is multi-byte that warns about character column sizes possibly getting changed --- sql/table.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/sql/table.cc b/sql/table.cc index 5ede9c1e43d..4be69a40782 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -145,8 +145,19 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, outparam->table_charset=get_charset((uint) head[38],MYF(0)); null_field_first=1; } - if (!outparam->table_charset) /* unknown charset in head[38] or pre-3.23 frm */ + if (!outparam->table_charset) + { + /* unknown charset in head[38] or pre-3.23 frm */ + if (use_mb(default_charset_info)) + { + /* Warn that we may be changing the size of character columns */ + sql_print_warning("'%s' had no or invalid character set, " + "and default character set is multi-byte, " + "so character column sizes may have changed", + name); + } outparam->table_charset=default_charset_info; + } outparam->db_record_offset=1; if (db_create_options & HA_OPTION_LONG_BLOB_PTR) outparam->blob_ptr_size=portable_sizeof_char_ptr; From 608729f7112ef031b94ddd5298f741515b4eb62a Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 21:26:14 +0100 Subject: [PATCH 53/90] Fix for BUG#7965 "Slave_IO_State Stuck at 'Checking Master Version'": Working around hang of master < 3.23.50 on SELECT @@unknown_var (to enable 3.23.49->4.1.10 replication) sql/slave.cc: Working around hang of master < 3.23.50 on SELECT @@unknown_var (to enable 3.23.49->4.1.10 replication) --- sql/slave.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sql/slave.cc b/sql/slave.cc index ef9caa5f5b5..d85c44c915e 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1243,7 +1243,11 @@ not always make sense; please check the manual before using it)."; values of these 2 are never used (new connections don't use them). We don't test equality of global collation_database either as it's is going to be deprecated (made read-only) in 4.1 very soon. + We don't do it for <3.23.57 because masters <3.23.50 hang on + SELECT @@unknown_var (BUG#7965 - see changelog of 3.23.50). */ + if (mi->old_format == BINLOG_FORMAT_323_LESS_57) + goto err; if (!mysql_real_query(mysql, "SELECT @@GLOBAL.COLLATION_SERVER", 32) && (master_res= mysql_store_result(mysql))) { @@ -1280,6 +1284,7 @@ be equal for replication to work"; mysql_free_result(master_res); } +err: if (errmsg) { sql_print_error(errmsg); From 896cdbe5df80f942a43e784336052cb2cce5871c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 02:04:41 +0200 Subject: [PATCH 54/90] Anoter fix for moved IO_CACHE object --- sql/filesort.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sql/filesort.cc b/sql/filesort.cc index fe42f391007..a53067ccd73 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -686,7 +686,10 @@ int merge_many_buff(SORTPARAM *param, uchar *sort_buffer, } close_cached_file(to_file); // This holds old result if (to_file == t_file) + { *t_file=t_file2; // Copy result file + setup_io_cache(t_file); + } DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */ } /* merge_many_buff */ From dd68385435e0e7df27b26a8cc13c21195bedbcd9 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Jan 2005 16:13:56 -0800 Subject: [PATCH 55/90] Fix over-optimization that could result in an unsigned double field being set to a negative value. (Bug #7700) sql/field_conv.cc: Don't treat real fields as identical when destination is unsigned and the source is not. mysql-test/t/type_float.test: Add test for setting double unsigned to a negative value from a signed double mysql-test/r/type_float.result: Add test results --- mysql-test/r/type_float.result | 7 +++++++ mysql-test/t/type_float.test | 6 ++++++ sql/field_conv.cc | 1 + 3 files changed, 14 insertions(+) diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index f4c5df353a3..4637a593e6c 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -120,3 +120,10 @@ drop table t1; create table t1 (f float(54)); Incorrect column specifier for column 'f' drop table if exists t1; +create table t1 (d1 double, d2 double unsigned); +insert into t1 set d1 = -1.0; +update t1 set d2 = d1; +select * from t1; +d1 d2 +-1 0 +drop table t1; diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 084d4b815e5..2db6a79ff54 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -67,3 +67,9 @@ drop table t1; create table t1 (f float(54)); # Should give an error drop table if exists t1; +# Don't allow 'double unsigned' to be set to a negative value (Bug #7700) +create table t1 (d1 double, d2 double unsigned); +insert into t1 set d1 = -1.0; +update t1 set d2 = d1; +select * from t1; +drop table t1; diff --git a/sql/field_conv.cc b/sql/field_conv.cc index db0cc71c6bf..7aaabde4f55 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -537,6 +537,7 @@ void field_conv(Field *to,Field *from) if (to->real_type() == from->real_type()) { if (to->pack_length() == from->pack_length() && + !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) && to->real_type() != FIELD_TYPE_ENUM && to->real_type() != FIELD_TYPE_SET && to->table->db_low_byte_first == from->table->db_low_byte_first) From 96f64b4440daa411a887ded45d5cee1daca99360 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 03:49:39 +0200 Subject: [PATCH 56/90] Fixed new bug that caused symlink test to fail mysys/my_symlink.c: More debugging --- myisam/mi_open.c | 2 +- mysys/my_symlink.c | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/myisam/mi_open.c b/myisam/mi_open.c index 442bf00b9d3..2a327e4bd35 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -142,7 +142,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) goto err; } /* Don't call realpath() if the name can't be a link */ - if (strcmp(name_buff, org_name) || + if (!strcmp(name_buff, org_name) || my_readlink(index_name, org_name, MYF(0)) == -1) (void) strmov(index_name, org_name); (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,2+4+16); diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c index 045802c5e61..7be3fcd36f0 100644 --- a/mysys/my_symlink.c +++ b/mysys/my_symlink.c @@ -26,9 +26,11 @@ /* Reads the content of a symbolic link If the file is not a symbolic link, return the original file name in to. - Returns: 0 if table was a symlink, - 1 if table was a normal file - -1 on error. + + RETURN + 0 If filename was a symlink, (to will be set to value of symlink) + 1 If filename was a normal file (to will be set to filename) + -1 on error. */ int my_readlink(char *to, const char *filename, myf MyFlags) @@ -58,6 +60,7 @@ int my_readlink(char *to, const char *filename, myf MyFlags) } else to[length]=0; + DBUG_PRINT("exit" ,("result: %d", result)); DBUG_RETURN(result); #endif /* HAVE_READLINK */ } From a8afc137920db4e13f0b379204a3e765d9c28dd7 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 05:07:22 +0200 Subject: [PATCH 57/90] After merge fixes mysql-test/r/order_by.result: After merge fix mysql-test/t/symlink.test: Comments --- mysql-test/r/order_by.result | 38 ------------------------------------ mysql-test/t/symlink.test | 10 ++++++++-- 2 files changed, 8 insertions(+), 40 deletions(-) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index dd5f1ec732d..5674fbb9177 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -778,41 +778,3 @@ sid wnid 39560 01019090000 37994 01019090000 drop table t1; -create table t1 ( -`sid` decimal(8,0) default null, -`wnid` varchar(11) not null default '', -key `wnid14` (`wnid`(4)), -key `wnid` (`wnid`) -) engine=myisam default charset=latin1; -insert into t1 (`sid`, `wnid`) values -('10100','01019000000'),('37986','01019000000'),('37987','01019010000'), -('39560','01019090000'),('37989','01019000000'),('37990','01019011000'), -('37991','01019011000'),('37992','01019019000'),('37993','01019030000'), -('37994','01019090000'),('475','02070000000'),('25253','02071100000'), -('25255','02071100000'),('25256','02071110000'),('25258','02071130000'), -('25259','02071190000'),('25260','02071200000'),('25261','02071210000'), -('25262','02071290000'),('25263','02071300000'),('25264','02071310000'), -('25265','02071310000'),('25266','02071320000'),('25267','02071320000'), -('25269','02071330000'),('25270','02071340000'),('25271','02071350000'), -('25272','02071360000'),('25273','02071370000'),('25281','02071391000'), -('25282','02071391000'),('25283','02071399000'),('25284','02071400000'), -('25285','02071410000'),('25286','02071410000'),('25287','02071420000'), -('25288','02071420000'),('25291','02071430000'),('25290','02071440000'), -('25292','02071450000'),('25293','02071460000'),('25294','02071470000'), -('25295','02071491000'),('25296','02071491000'),('25297','02071499000'); -explain select * from t1 where wnid like '0101%' order by wnid; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range wnid14,wnid wnid 11 NULL 10 Using where -select * from t1 where wnid like '0101%' order by wnid; -sid wnid -10100 01019000000 -37986 01019000000 -37989 01019000000 -37987 01019010000 -37990 01019011000 -37991 01019011000 -37992 01019019000 -37993 01019030000 -39560 01019090000 -37994 01019090000 -drop table t1; diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index 78c9b68fde5..9e71ac4b925 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -49,8 +49,9 @@ check table t9; optimize table t9; repair table t9; alter table t9 add column c int not null; ---replace_result $MYSQL_TEST_DIR TEST_DIR -show create table t9; + +#--replace_result $MYSQL_TEST_DIR TEST_DIR +#show create table t9; # Test renames alter table t9 rename t8, add column d int not null; @@ -64,6 +65,9 @@ drop table t1; # Note that we are using the above table t9 here! # +--replace_result $MYSQL_TEST_DIR TEST_DIR +SHOW CREATE TABLE t9; + disable_query_log; --error 1103,1103 create table t1 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam data directory="tmp"; @@ -78,9 +82,11 @@ create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, p --error 1103,1103 create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="not-hard-path"; +# Should fail becasue the file t9.MYI already exist in 'run' --error 1,1 eval create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="$MYSQL_TEST_DIR/var/run"; +# Should fail becasue the file t9.MYD already exist in 'tmp' --error 1,1 eval create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam data directory="$MYSQL_TEST_DIR/var/tmp"; enable_query_log; From ec0daa744fe6b1141e4d8815b574c2a1e38366e8 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 10:42:29 +0400 Subject: [PATCH 58/90] #7874: CONCAT() gives wrong results mixing latin1 field and utf8 string literals We should not overwrite res if it is returned from a const item. --- mysql-test/r/ctype_utf8.result | 12 ++++++++++++ mysql-test/t/ctype_utf8.test | 12 ++++++++++++ sql/item_strfunc.cc | 3 ++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index f62d754392b..415ed33ad40 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -849,3 +849,15 @@ utf8_bin 6109 utf8_bin 61 utf8_bin 6120 drop table t1; +CREATE TABLE t1 ( +user varchar(255) NOT NULL default '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES ('one'),('two'); +SELECT CHARSET('a'); +CHARSET('a') +utf8 +SELECT user, CONCAT('<', user, '>') AS c FROM t1; +user c +one +two +DROP TABLE t1; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index a57db4455ab..8e3eb71c3e5 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -681,3 +681,15 @@ SET collation_connection='utf8_general_ci'; -- source include/ctype_filesort.inc SET collation_connection='utf8_bin'; -- source include/ctype_filesort.inc + +# +# Bug #7874 CONCAT() gives wrong results mixing +# latin1 field and utf8 string literals +# +CREATE TABLE t1 ( + user varchar(255) NOT NULL default '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES ('one'),('two'); +SELECT CHARSET('a'); +SELECT user, CONCAT('<', user, '>') AS c FROM t1; +DROP TABLE t1; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 8341dda0a41..f131d849d62 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -275,7 +275,8 @@ String *Item_func_concat::val_str(String *str) current_thd->variables.max_allowed_packet); goto null; } - if (res->alloced_length() >= res->length()+res2->length()) + if (!args[0]->const_item() && + res->alloced_length() >= res->length()+res2->length()) { // Use old buffer res->append(*res2); } From 490d5530a8bcf4a50919b50971060416602a2d09 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 16:16:55 +0300 Subject: [PATCH 59/90] Post-review fixes for the previous cset. No code behavior changes. --- sql/opt_range.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 6be23835032..acf69fdd098 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -50,7 +50,12 @@ #define test_use_count(A) {} #endif +/* + Convert double value to #rows. Currently this does floor(), and we + might consider using round() instead. +*/ #define double2rows(x) ((ha_rows)(x)) + static int sel_cmp(Field *f,char *a,char *b,uint8 a_flag,uint8 b_flag); static char is_null_string[2]= {1,0}; @@ -2437,7 +2442,7 @@ ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param) FALSE)) return NULL; info->is_covering= FALSE; - info->index_scan_costs= 0.0f; + info->index_scan_costs= 0.0; info->index_records= 0; info->out_rows= param->table->file->records; bitmap_clear_all(&info->covered_fields); @@ -2707,7 +2712,7 @@ static bool ror_intersect_add(ROR_INTERSECT_INFO *info, DBUG_PRINT("info", ("New out_rows= %g", info->out_rows)); DBUG_PRINT("info", ("New cost= %g, %scovering", info->total_cost, info->is_covering?"" : "non-")); - DBUG_RETURN(true); + DBUG_RETURN(TRUE); } @@ -2894,7 +2899,7 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, */ if (cpk_scan && !intersect->is_covering) { - if (ror_intersect_add(intersect, cpk_scan, true) && + if (ror_intersect_add(intersect, cpk_scan, TRUE) && (intersect->total_cost < min_cost)) { cpk_scan_used= TRUE; From 1457163c97eb6eddc5d68f0b16239aec56e08d27 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 16:23:10 +0300 Subject: [PATCH 60/90] Fix 'make distclean' goal. --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 9f89c635e7f..b1b8b128f46 100644 --- a/configure.in +++ b/configure.in @@ -3019,7 +3019,7 @@ AC_SUBST(server_scripts) sql_union_dirs=" $sql_server_dirs " for DIR in $sql_client_dirs do - if echo $sql_union_dirs | grep " $DIR " >/dev/null + if echo " $sql_union_dirs " | grep " $DIR " >/dev/null then : # already present, skip else From cd89ed9ab6ae511581471b1aaa640fadc3819f63 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 17:41:06 +0400 Subject: [PATCH 61/90] 1. Item now uses my_charset_bin by default, not default_charset_into. It fixes the problem that in some cases numbers where treated as CHAR(N), not as BINARY(N), e.g. wrong 'charsetnr' when sent to the client side. 2. IFNULL didn't aggregate argument charsets and collations, so IFNULL(1,'a') produced a CHAR(N). Now produces a BINARY(N). 3. SELECT PROCEDURE ANALIZE now returns BINARY columns, which is much better than it worked previously: CHAR with the default character set. But in the future it's worth to fix the fields 'Field_name' and 'Optimal_fieldtype' to use UTF8, and 'Min_value' and 'Max_value' to inherit their charsets from the original items. But it is not important, and BINARY(N) is OK for now. 4. Tests were fixed accordingly. No new tests were made, as the old onces cover everything. mysql-test/r/analyse.result: SELECT PROCEDURE ANALIZE now returns BINARY columns, which is much better than it worked previously: CHAR with the default character set. But in the future it's worth to fix the fields 'Field_name' and 'Optimal_fieldtype' to use UTF8, and 'Min_value' and 'Max_value' to inherit their charsets from the original items. But it is not important, and BINARY(N) is OK for now. mysql-test/r/case.result: Test fix according to the changes mysql-test/r/metadata.result: Test fix according to the changes mysql-test/r/ps_1general.result: Test fix according to the changes mysql-test/r/ps_2myisam.result: Test fix according to the changes mysql-test/r/ps_3innodb.result: Test fix according to the changes mysql-test/r/ps_4heap.result: Test fix according to the changes mysql-test/r/ps_5merge.result: Test fix according to the changes mysql-test/r/ps_6bdb.result: Test fix according to the changes mysql-test/r/ps_7ndb.result: Test fix according to the changes mysql-test/r/union.result: Test fix according to the changes sql/item.cc: Item is now BINARY by default sql/item_cmpfunc.cc: IFNULL now collects arguments collations/charsets like other functions do. --- mysql-test/r/analyse.result | 36 ++++++++++++++++----------------- mysql-test/r/case.result | 12 +++++------ mysql-test/r/metadata.result | 6 +++--- mysql-test/r/ps_1general.result | 12 +++++------ mysql-test/r/ps_2myisam.result | 6 +++--- mysql-test/r/ps_3innodb.result | 6 +++--- mysql-test/r/ps_4heap.result | 6 +++--- mysql-test/r/ps_5merge.result | 12 +++++------ mysql-test/r/ps_6bdb.result | 6 +++--- mysql-test/r/ps_7ndb.result | 6 +++--- mysql-test/r/union.result | 2 +- sql/item.cc | 2 +- sql/item_cmpfunc.cc | 3 +++ 13 files changed, 59 insertions(+), 56 deletions(-) diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result index 8013bc516bb..09c606b5a04 100644 --- a/mysql-test/r/analyse.result +++ b/mysql-test/r/analyse.result @@ -36,16 +36,16 @@ create table t2 select * from t1 where 0=1 procedure analyse(); show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `Field_name` char(255) NOT NULL default '', - `Min_value` char(255) default NULL, - `Max_value` char(255) default NULL, + `Field_name` binary(255) NOT NULL default '', + `Min_value` binary(255) default NULL, + `Max_value` binary(255) default NULL, `Min_length` bigint(11) NOT NULL default '0', `Max_length` bigint(11) NOT NULL default '0', `Empties_or_zeros` bigint(11) NOT NULL default '0', `Nulls` bigint(11) NOT NULL default '0', - `Avg_value_or_avg_length` char(255) NOT NULL default '', - `Std` char(255) default NULL, - `Optimal_fieldtype` char(64) NOT NULL default '' + `Avg_value_or_avg_length` binary(255) NOT NULL default '', + `Std` binary(255) default NULL, + `Optimal_fieldtype` binary(64) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 select * from t1 where 0=1 procedure analyse(); Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype @@ -55,16 +55,16 @@ create table t2 select * from t1 where 0=1 procedure analyse(); show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `Field_name` char(255) NOT NULL default '', - `Min_value` char(255) default NULL, - `Max_value` char(255) default NULL, + `Field_name` binary(255) NOT NULL default '', + `Min_value` binary(255) default NULL, + `Max_value` binary(255) default NULL, `Min_length` bigint(11) NOT NULL default '0', `Max_length` bigint(11) NOT NULL default '0', `Empties_or_zeros` bigint(11) NOT NULL default '0', `Nulls` bigint(11) NOT NULL default '0', - `Avg_value_or_avg_length` char(255) NOT NULL default '', - `Std` char(255) default NULL, - `Optimal_fieldtype` char(64) NOT NULL default '' + `Avg_value_or_avg_length` binary(255) NOT NULL default '', + `Std` binary(255) default NULL, + `Optimal_fieldtype` binary(64) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 select * from t2; Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype @@ -78,16 +78,16 @@ create table t2 select * from t1 where 0=1 procedure analyse(); show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `Field_name` char(255) NOT NULL default '', - `Min_value` char(255) default NULL, - `Max_value` char(255) default NULL, + `Field_name` binary(255) NOT NULL default '', + `Min_value` binary(255) default NULL, + `Max_value` binary(255) default NULL, `Min_length` bigint(11) NOT NULL default '0', `Max_length` bigint(11) NOT NULL default '0', `Empties_or_zeros` bigint(11) NOT NULL default '0', `Nulls` bigint(11) NOT NULL default '0', - `Avg_value_or_avg_length` char(255) NOT NULL default '', - `Std` char(255) default NULL, - `Optimal_fieldtype` char(64) NOT NULL default '' + `Avg_value_or_avg_length` binary(255) NOT NULL default '', + `Std` binary(255) default NULL, + `Optimal_fieldtype` binary(64) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 select * from t2; Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result index 1aa838140fd..541560afd36 100644 --- a/mysql-test/r/case.result +++ b/mysql-test/r/case.result @@ -98,10 +98,10 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` char(1) character set latin1 collate latin1_danish_ci NOT NULL default '', `c2` char(1) character set latin1 collate latin1_danish_ci NOT NULL default '', - `c3` char(1) NOT NULL default '', - `c4` char(1) NOT NULL default '', - `c5` char(3) NOT NULL default '', - `c6` char(3) NOT NULL default '', + `c3` binary(1) NOT NULL default '', + `c4` binary(1) NOT NULL default '', + `c5` binary(3) NOT NULL default '', + `c6` binary(3) NOT NULL default '', `c7` double(3,1) NOT NULL default '0.0', `c8` double(3,1) NOT NULL default '0.0', `c9` double(3,1) default NULL @@ -149,8 +149,8 @@ t1 CREATE TABLE `t1` ( `COALESCE(1.0)` double(3,1) NOT NULL default '0.0', `COALESCE('a')` char(1) NOT NULL default '', `COALESCE(1,1.0)` double(3,1) NOT NULL default '0.0', - `COALESCE(1,'1')` char(1) NOT NULL default '', - `COALESCE(1.1,'1')` char(3) NOT NULL default '', + `COALESCE(1,'1')` binary(1) NOT NULL default '', + `COALESCE(1.1,'1')` binary(3) NOT NULL default '', `COALESCE('a' COLLATE latin1_bin,'b')` char(1) character set latin1 collate latin1_bin NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; diff --git a/mysql-test/r/metadata.result b/mysql-test/r/metadata.result index 3c7cf60db7a..54b3f1e0466 100644 --- a/mysql-test/r/metadata.result +++ b/mysql-test/r/metadata.result @@ -1,9 +1,9 @@ drop table if exists t1,t2; select 1, 1.0, -1, "hello", NULL; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def 1 8 1 1 N 32769 0 8 -def 1.0 5 3 3 N 32769 1 8 -def -1 8 2 2 N 32769 0 8 +def 1 8 1 1 N 32897 0 63 +def 1.0 5 3 3 N 32897 1 63 +def -1 8 2 2 N 32897 0 63 def hello 254 5 5 N 1 31 8 def NULL 6 0 0 Y 32896 0 63 1 1.0 -1 hello NULL diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index ee3eca850f4..2356989eaf6 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -468,15 +468,15 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye prepare stmt1 from ' explain select a from t1 order by b '; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 +def key_len 8 3 0 Y 32928 0 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 14 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using filesort @@ -484,15 +484,15 @@ SET @arg00=1 ; prepare stmt1 from ' explain select a from t1 where a > ? order by b '; execute stmt1 using @arg00; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 5 N 1 31 8 def possible_keys 253 4096 7 Y 0 31 8 def key 253 64 7 Y 0 31 8 -def key_len 8 3 1 Y 32800 0 8 +def key_len 8 3 1 Y 32928 0 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 27 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using filesort diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index 3412f2fe00c..a27b8b996cd 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -1145,15 +1145,15 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 +def key_len 8 3 0 Y 32928 0 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index 99f45117c36..eb17d25e80c 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -1145,15 +1145,15 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 +def key_len 8 3 0 Y 32928 0 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index 1ec5c280523..b53ad7e2409 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -1146,15 +1146,15 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 +def key_len 8 3 0 Y 32928 0 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index 1f36d246da0..13227eb533b 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -1188,15 +1188,15 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 +def key_len 8 3 0 Y 32928 0 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 @@ -4198,15 +4198,15 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 +def key_len 8 3 0 Y 32928 0 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result index 1e7ef526d37..8630ba2db9b 100644 --- a/mysql-test/r/ps_6bdb.result +++ b/mysql-test/r/ps_6bdb.result @@ -1145,15 +1145,15 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 +def key_len 8 3 0 Y 32928 0 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 3 diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result index 13b6894e9b5..43ff9607c55 100644 --- a/mysql-test/r/ps_7ndb.result +++ b/mysql-test/r/ps_7ndb.result @@ -1145,15 +1145,15 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 +def key_len 8 3 0 Y 32928 0 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 49a2907f571..1eb978b1bd6 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -554,7 +554,7 @@ aa show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` char(20) NOT NULL default '' + `a` binary(20) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; create table t1 SELECT 12 as a UNION select 12.2 as a; diff --git a/sql/item.cc b/sql/item.cc index 92a15694e89..640cc17411f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -45,7 +45,7 @@ Item::Item(): { marker= 0; maybe_null=null_value=with_sum_func=unsigned_flag=0; - collation.set(default_charset(), DERIVATION_COERCIBLE); + collation.set(&my_charset_bin, DERIVATION_COERCIBLE); name= 0; decimals= 0; max_length= 0; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 3d79c16b5d0..6ec98f2dcd4 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1094,6 +1094,9 @@ Item_func_nullif::fix_length_and_dec() max_length=args[0]->max_length; decimals=args[0]->decimals; agg_result_type(&cached_result_type, args, 2); + if (cached_result_type == STRING_RESULT && + agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV)) + return; } } From 3842b1df35ea8f22eead1c050088c810e48ffa3b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 14:46:24 +0100 Subject: [PATCH 62/90] compile error fix --- ndb/src/ndbapi/NdbDictionaryImpl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 7107f109e94..4c53ac89461 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -626,7 +626,7 @@ NdbEventImpl::addTableEvent(const NdbDictionary::Event::TableEvent t = NdbDicti } void -NdbEventImpl::setDurability(const NdbDictionary::Event::EventDurability d) +NdbEventImpl::setDurability(NdbDictionary::Event::EventDurability d) { m_dur = d; } @@ -1361,7 +1361,7 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, } Uint32 topBit = (1 << 31); - for(int i = 31; i>=0; i--){ + for(i = 31; i>=0; i--){ if((fragCount & topBit) != 0) break; topBit >>= 1; From 2ec0d730258a1ab567ba9c5b4d71d795ae18e489 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 14:46:26 +0100 Subject: [PATCH 63/90] slave.cc: 5.0 has a different way of knowing if master is < 3.23.57 sql/slave.cc: 5.0 has a different way of knowing if master is < 3.23.57 --- sql/slave.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/slave.cc b/sql/slave.cc index 36c99c6c21c..5332dbf9c5b 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1421,7 +1421,8 @@ not always make sense; please check the manual before using it)."; We don't do it for <3.23.57 because masters <3.23.50 hang on SELECT @@unknown_var (BUG#7965 - see changelog of 3.23.50). */ - if (mi->old_format == BINLOG_FORMAT_323_LESS_57) + if (strncmp(mi->rli.relay_log.description_event_for_queue->server_version, + "3.23.57",7) < 0) goto err; if (!mysql_real_query(mysql, "SELECT @@GLOBAL.COLLATION_SERVER", 32) && (master_res= mysql_store_result(mysql))) From b1a0f67a03e782495e027588c7c7bc204f0a82b6 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 17:04:16 +0300 Subject: [PATCH 64/90] Clean up in implementation of f_is_geom()/f_is_bitfield()/f_is_enum() macros. It does not fixes any bugs in 4.0. But it prevents from future error in any bugfixes that may use these macros. Also after merging into 4.1 tree this cleanup will fix bug #7884 "Able to add invalid unique index on TIMESTAMP prefix". sql/field.h: Since FIELDFLAG_INTERVAL, FIELDFLAG_BITFIELD, FIELDFLAG_BLOB and FIELDFLAG_GEOM flags occupy the same space as number of decimals for FIELDFLAG_NUMBER fields, it is safer to check in "f_is_geom()"-type macros that we have non-number field, like we already do in f_is_blob() macro. --- sql/field.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sql/field.h b/sql/field.h index c42f5f63f0c..87a9732b41e 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1101,10 +1101,10 @@ bool test_if_int(const char *str,int length); #define FIELDFLAG_NUMBER 2 #define FIELDFLAG_ZEROFILL 4 #define FIELDFLAG_PACK 120 // Bits used for packing -#define FIELDFLAG_INTERVAL 256 -#define FIELDFLAG_BITFIELD 512 // mangled with dec! -#define FIELDFLAG_BLOB 1024 // mangled with dec! -#define FIELDFLAG_GEOM 2048 +#define FIELDFLAG_INTERVAL 256 // mangled with decimals! +#define FIELDFLAG_BITFIELD 512 // mangled with decimals! +#define FIELDFLAG_BLOB 1024 // mangled with decimals! +#define FIELDFLAG_GEOM 2048 // mangled with decimals! #define FIELDFLAG_LEFT_FULLSCREEN 8192 #define FIELDFLAG_RIGHT_FULLSCREEN 16384 #define FIELDFLAG_FORMAT_NUMBER 16384 // predit: ###,,## in output @@ -1128,10 +1128,10 @@ bool test_if_int(const char *str,int length); #define f_decimals(x) ((uint8) (((x) >> FIELDFLAG_DEC_SHIFT) & FIELDFLAG_MAX_DEC)) #define f_is_alpha(x) (!f_is_num(x)) #define f_is_binary(x) ((x) & FIELDFLAG_BINARY) -#define f_is_enum(x) ((x) & FIELDFLAG_INTERVAL) -#define f_is_bitfield(x) ((x) & FIELDFLAG_BITFIELD) +#define f_is_enum(x) (((x) & (FIELDFLAG_INTERVAL | FIELDFLAG_NUMBER)) == FIELDFLAG_INTERVAL) +#define f_is_bitfield(x) (((x) & (FIELDFLAG_BITFIELD | FIELDFLAG_NUMBER)) == FIELDFLAG_BITFIELD) #define f_is_blob(x) (((x) & (FIELDFLAG_BLOB | FIELDFLAG_NUMBER)) == FIELDFLAG_BLOB) -#define f_is_geom(x) ((x) & FIELDFLAG_GEOM) +#define f_is_geom(x) (((x) & (FIELDFLAG_GEOM | FIELDFLAG_NUMBER)) == FIELDFLAG_GEOM) #define f_is_equ(x) ((x) & (1+2+FIELDFLAG_PACK+31*256)) #define f_settype(x) (((int) x) << FIELDFLAG_PACK_SHIFT) #define f_maybe_null(x) (x & FIELDFLAG_MAYBE_NULL) From e46d235a08a35bdd5536b4b2b99ed3a5b6910cdf Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 17:26:04 +0300 Subject: [PATCH 65/90] Cleanups in Makefile.ams client/Makefile.am: Remove explicit _DEPENDENCIES, they are not needed with automatic dependency tracking wich we started using several months ago. Don't use relative paths in makefiles. regex/Makefile.am: Remove explicit _DEPENDENCIES, they are not needed with automatic dependency tracking wich we started using several months ago. Don't use relative paths. strings/Makefile.am: Remove dead rule. --- client/Makefile.am | 18 ++++-------------- regex/Makefile.am | 3 +-- strings/Makefile.am | 1 - 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/client/Makefile.am b/client/Makefile.am index 0404aacb383..da13c3e9763 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -20,9 +20,8 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/regex \ $(openssl_includes) LIBS = @CLIENT_LIBS@ -DEPLIB= ../libmysql/libmysqlclient.la -REGEXLIB= ../regex/libregex.a -LDADD = @CLIENT_EXTRA_LDFLAGS@ $(DEPLIB) +LDADD= @CLIENT_EXTRA_LDFLAGS@ \ + $(top_builddir)/libmysql/libmysqlclient.la bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \ mysqldump mysqlimport mysqltest mysqlbinlog mysqlmanagerc mysqlmanager-pwgen noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \ @@ -31,19 +30,10 @@ mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc mysqladmin_SOURCES = mysqladmin.cc mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS) mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS) -mysql_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) -mysqladmin_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) -mysqlcheck_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) -mysqlshow_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) -mysqldump_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) -mysqlimport_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) -mysqltest_SOURCES= mysqltest.c ../mysys/my_getsystime.c -mysqltest_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(REGEXLIB) $(DEPLIB) -mysqltest_LDADD = $(REGEXLIB) $(LDADD) +mysqltest_SOURCES= mysqltest.c $(top_srcdir)/mysys/my_getsystime.c +mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) mysqlbinlog_SOURCES = mysqlbinlog.cc ../mysys/mf_tempdir.c -mysqlbinlog_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) mysqlmanagerc_SOURCES = mysqlmanagerc.c -mysqlmanagerc_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) sql_src=log_event.h log_event.cc # Fix for mit-threads diff --git a/regex/Makefile.am b/regex/Makefile.am index 2e23efcbf2a..ee7fc5463b7 100644 --- a/regex/Makefile.am +++ b/regex/Makefile.am @@ -17,12 +17,11 @@ INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include noinst_LIBRARIES = libregex.a -LDADD = libregex.a ../strings/libmystrings.a +LDADD= libregex.a $(top_builddir)/strings/libmystrings.a noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c regex.h libregex_a_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c noinst_PROGRAMS = re re_SOURCES = split.c debug.c main.c -re_DEPENDENCIES= $(LIBRARIES) re_LDFLAGS= @NOINST_LDFLAGS@ EXTRA_DIST = tests CHANGES COPYRIGHT WHATSNEW regexp.c \ debug.ih engine.ih main.ih regcomp.ih regerror.ih \ diff --git a/strings/Makefile.am b/strings/Makefile.am index d17a4f598a6..83f935a3fd2 100644 --- a/strings/Makefile.am +++ b/strings/Makefile.am @@ -40,7 +40,6 @@ endif libmystrings_a_SOURCES = $(ASRCS) $(CSRCS) noinst_PROGRAMS = conf_to_src -DISTCLEANFILES = ctype_autoconf.c # Default charset definitions EXTRA_DIST = ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-win1250ch.c \ ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \ From 0e2a6843ce3122693dcfeb48647326d354e3a2de Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 17:37:45 +0300 Subject: [PATCH 66/90] Fix for bug #7981: SHOW GLOBAL STATUS crashes server --- mysql-test/r/information_schema.result | 3 ++ mysql-test/t/information_schema.test | 5 +++ sql/sql_show.cc | 42 ++++++++------------------ 3 files changed, 20 insertions(+), 30 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index bf1f828edf5..9bf4ee28b3b 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -676,3 +676,6 @@ variable_name character_set_database collation_database skip_show_database +show global status like "Threads_running"; +Variable_name Value +Threads_running 1 diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index ac36bbd6014..a4886fd8245 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -354,3 +354,8 @@ show open tables where `table` like "user"; show status variable_name where variable_name like "%database%"; # test for 'show variables ... where' show variables variable_name where variable_name like "%database%"; + +# +# Bug #7981:SHOW GLOBAL STATUS crashes server +# +show global status like "Threads_running"; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 2aa8a67fbab..843b0422575 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1534,25 +1534,6 @@ static bool show_status_array(THD *thd, const char *wild, } -bool mysqld_show(THD *thd, const char *wild, show_var_st *variables, - enum enum_var_type value_type, - pthread_mutex_t *mutex, - struct system_status_var *status_var, TABLE *table) -{ - DBUG_ENTER("mysqld_show"); - ha_update_statistics(); /* Export engines statistics */ - pthread_mutex_lock(mutex); - if (show_status_array(thd, wild, variables, value_type, status_var, "", table)) - goto err; - pthread_mutex_unlock(mutex); - DBUG_RETURN(FALSE); - - err: - pthread_mutex_unlock(mutex); - DBUG_RETURN(TRUE); -} - - /* collect status for all running threads */ void calc_sum_of_all_status(STATUS_VAR *to) @@ -2874,10 +2855,14 @@ int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond) int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond) { DBUG_ENTER("fill_variables"); + int res= 0; LEX *lex= thd->lex; const char *wild= lex->wild ? lex->wild->ptr() : NullS; - int res= mysqld_show(thd, wild, init_vars, lex->option_type, - &LOCK_global_system_variables, 0, tables->table); + ha_update_statistics(); /* Export engines statistics */ + pthread_mutex_lock(&LOCK_global_system_variables); + res= show_status_array(thd, wild, init_vars, + lex->option_type, 0, "", tables->table); + pthread_mutex_unlock(&LOCK_global_system_variables); DBUG_RETURN(res); } @@ -2889,17 +2874,14 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) const char *wild= lex->wild ? lex->wild->ptr() : NullS; int res= 0; STATUS_VAR tmp; - + ha_update_statistics(); /* Export engines statistics */ + pthread_mutex_lock(&LOCK_status); if (lex->option_type == OPT_GLOBAL) - { - pthread_mutex_lock(&LOCK_status); calc_sum_of_all_status(&tmp); - } - res= mysqld_show(thd, wild, status_vars, OPT_GLOBAL, &LOCK_status, - (lex->option_type == OPT_GLOBAL ? - &tmp: &thd->status_var), tables->table); - if (lex->option_type == OPT_GLOBAL) - pthread_mutex_unlock(&LOCK_status); + res= show_status_array(thd, wild, status_vars, OPT_GLOBAL, + (lex->option_type == OPT_GLOBAL ? + &tmp: &thd->status_var), "",tables->table); + pthread_mutex_unlock(&LOCK_status); DBUG_RETURN(res); } From e2c869f2ff92b72917ecb4d16cf9408be174eb71 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 17:45:49 +0300 Subject: [PATCH 67/90] Added test for bug #7884 "Able to add invalid unique index on TIMESTAMP prefix", which roots were fixed in 4.0 tree. mysql-test/r/alter_table.result: Added test for bug #7884 "Able to add invalid unique index on TIMESTAMP prefix". mysql-test/t/alter_table.test: Added test for bug #7884 "Able to add invalid unique index on TIMESTAMP prefix". --- mysql-test/r/alter_table.result | 4 ++++ mysql-test/t/alter_table.test | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index a7ae8bc310c..7d2b3f01ae6 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -493,3 +493,7 @@ select hex(a) from t1; hex(a) F2E5F1F2 drop table t1; +create table t1 ( a timestamp ); +alter table t1 add unique ( a(1) ); +ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys +drop table t1; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 66a4adc90fe..c2277dc1755 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -336,3 +336,14 @@ select hex(a) from t1; alter table t1 convert to character set cp1251; select hex(a) from t1; drop table t1; + +# +# Test for bug #7884 "Able to add invalid unique index on TIMESTAMP prefix" +# MySQL should not think that packed field with non-zero decimals is +# geometry field and allow to create prefix index which is +# shorter than packed field length. +# +create table t1 ( a timestamp ); +--error 1089 +alter table t1 add unique ( a(1) ); +drop table t1; From d89f9108c97991d5a064a52f4800fda7b5875a47 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 16:10:37 +0100 Subject: [PATCH 68/90] compile bug fix --- ndb/src/mgmsrv/Services.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 447bc8bdc2b..f1456157ac5 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -1512,4 +1512,3 @@ MgmApiSession::check_connection(Parser_t::Context &ctx, template class MutexVector; template class Vector const*>; -template class Vector; From af3e6774d7435ad109620f7372e83abdb400b873 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 16:31:05 +0100 Subject: [PATCH 69/90] compile error: moved inline compile warning: changed eq_range -> eq_r --- sql/ha_ndbcluster.cc | 90 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index a1b1099135b..aa39af5176e 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1112,6 +1112,47 @@ ha_ndbcluster::set_index_key(NdbOperation *op, DBUG_RETURN(0); } +inline +int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) +{ + uint i; + THD *thd= current_thd; + + DBUG_ENTER("define_read_attrs"); + + // Define attributes to read + for (i= 0; i < table->s->fields; i++) + { + Field *field= table->field[i]; + if ((thd->query_id == field->query_id) || + ((field->flags & PRI_KEY_FLAG)) || + m_retrieve_all_fields) + { + if (get_ndb_value(op, field, i, buf)) + ERR_RETURN(op->getNdbError()); + } + else + { + m_value[i].ptr= NULL; + } + } + + if (table->s->primary_key == MAX_KEY) + { + DBUG_PRINT("info", ("Getting hidden key")); + // Scanning table with no primary key + int hidden_no= table->s->fields; +#ifndef DBUG_OFF + const NDBTAB *tab= (const NDBTAB *) m_table; + if (!tab->getColumn(hidden_no)) + DBUG_RETURN(1); +#endif + if (get_ndb_value(op, NULL, hidden_no, NULL)) + ERR_RETURN(op->getNdbError()); + } + DBUG_RETURN(0); +} + /* Read one record from NDB using primary key */ @@ -1585,47 +1626,6 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, DBUG_RETURN(0); } -inline -int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) -{ - uint i; - THD *thd= current_thd; - - DBUG_ENTER("define_read_attrs"); - - // Define attributes to read - for (i= 0; i < table->s->fields; i++) - { - Field *field= table->field[i]; - if ((thd->query_id == field->query_id) || - ((field->flags & PRI_KEY_FLAG)) || - m_retrieve_all_fields) - { - if (get_ndb_value(op, field, i, buf)) - ERR_RETURN(op->getNdbError()); - } - else - { - m_value[i].ptr= NULL; - } - } - - if (table->s->primary_key == MAX_KEY) - { - DBUG_PRINT("info", ("Getting hidden key")); - // Scanning table with no primary key - int hidden_no= table->s->fields; -#ifndef DBUG_OFF - const NDBTAB *tab= (const NDBTAB *) m_table; - if (!tab->getColumn(hidden_no)) - DBUG_RETURN(1); -#endif - if (get_ndb_value(op, NULL, hidden_no, NULL)) - ERR_RETURN(op->getNdbError()); - } - DBUG_RETURN(0); -} - /* Start ordered index scan in NDB */ @@ -2487,13 +2487,13 @@ int ha_ndbcluster::index_read_last(byte * buf, const byte * key, uint key_len) inline int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key, const key_range *end_key, - bool eq_range, bool sorted, + bool eq_r, bool sorted, byte* buf) { KEY* key_info; int error= 1; DBUG_ENTER("ha_ndbcluster::read_range_first_to_buf"); - DBUG_PRINT("info", ("eq_range: %d, sorted: %d", eq_range, sorted)); + DBUG_PRINT("info", ("eq_r: %d, sorted: %d", eq_r, sorted)); switch (get_index_type(active_index)){ case PRIMARY_KEY_ORDERED_INDEX: @@ -2534,14 +2534,14 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key, int ha_ndbcluster::read_range_first(const key_range *start_key, const key_range *end_key, - bool eq_range, bool sorted) + bool eq_r, bool sorted) { byte* buf= table->record[0]; DBUG_ENTER("ha_ndbcluster::read_range_first"); DBUG_RETURN(read_range_first_to_buf(start_key, end_key, - eq_range, + eq_r, sorted, buf)); } From 4ef9335d2f6762de59ce6fe14baad7cf5df6a311 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 19:47:39 +0300 Subject: [PATCH 70/90] bug #7981: SHOW GLOBAL STATUS crashes server(fix after review) --- sql/sql_show.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 843b0422575..c7b4b61ca33 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2858,7 +2858,6 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond) int res= 0; LEX *lex= thd->lex; const char *wild= lex->wild ? lex->wild->ptr() : NullS; - ha_update_statistics(); /* Export engines statistics */ pthread_mutex_lock(&LOCK_global_system_variables); res= show_status_array(thd, wild, init_vars, lex->option_type, 0, "", tables->table); From 764501e75211303707b311ce40ed42b2fb1ac5e2 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 22:12:33 +0400 Subject: [PATCH 71/90] After-merge clean-up --- mysql-test/r/analyse.result | 36 ++++++++++++++++----------------- mysql-test/r/case.result | 12 +++++------ mysql-test/r/ps_1general.result | 8 ++++---- mysql-test/r/ps_2myisam.result | 4 ++-- mysql-test/r/ps_3innodb.result | 4 ++-- mysql-test/r/ps_4heap.result | 4 ++-- mysql-test/r/ps_5merge.result | 8 ++++---- mysql-test/r/ps_7ndb.result | 14 ++++++------- mysql-test/r/union.result | 2 +- sql/item.cc | 2 +- 10 files changed, 47 insertions(+), 47 deletions(-) diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result index d4128fb1bcc..83f70a69622 100644 --- a/mysql-test/r/analyse.result +++ b/mysql-test/r/analyse.result @@ -36,16 +36,16 @@ create table t2 select * from t1 where 0=1 procedure analyse(); show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `Field_name` varchar(255) NOT NULL default '', - `Min_value` varchar(255) default NULL, - `Max_value` varchar(255) default NULL, + `Field_name` varbinary(255) NOT NULL default '', + `Min_value` varbinary(255) default NULL, + `Max_value` varbinary(255) default NULL, `Min_length` bigint(11) NOT NULL default '0', `Max_length` bigint(11) NOT NULL default '0', `Empties_or_zeros` bigint(11) NOT NULL default '0', `Nulls` bigint(11) NOT NULL default '0', - `Avg_value_or_avg_length` varchar(255) NOT NULL default '', - `Std` varchar(255) default NULL, - `Optimal_fieldtype` varchar(64) NOT NULL default '' + `Avg_value_or_avg_length` varbinary(255) NOT NULL default '', + `Std` varbinary(255) default NULL, + `Optimal_fieldtype` varbinary(64) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 select * from t1 where 0=1 procedure analyse(); Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype @@ -55,16 +55,16 @@ create table t2 select * from t1 where 0=1 procedure analyse(); show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `Field_name` varchar(255) NOT NULL default '', - `Min_value` varchar(255) default NULL, - `Max_value` varchar(255) default NULL, + `Field_name` varbinary(255) NOT NULL default '', + `Min_value` varbinary(255) default NULL, + `Max_value` varbinary(255) default NULL, `Min_length` bigint(11) NOT NULL default '0', `Max_length` bigint(11) NOT NULL default '0', `Empties_or_zeros` bigint(11) NOT NULL default '0', `Nulls` bigint(11) NOT NULL default '0', - `Avg_value_or_avg_length` varchar(255) NOT NULL default '', - `Std` varchar(255) default NULL, - `Optimal_fieldtype` varchar(64) NOT NULL default '' + `Avg_value_or_avg_length` varbinary(255) NOT NULL default '', + `Std` varbinary(255) default NULL, + `Optimal_fieldtype` varbinary(64) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 select * from t2; Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype @@ -78,16 +78,16 @@ create table t2 select * from t1 where 0=1 procedure analyse(); show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `Field_name` varchar(255) NOT NULL default '', - `Min_value` varchar(255) default NULL, - `Max_value` varchar(255) default NULL, + `Field_name` varbinary(255) NOT NULL default '', + `Min_value` varbinary(255) default NULL, + `Max_value` varbinary(255) default NULL, `Min_length` bigint(11) NOT NULL default '0', `Max_length` bigint(11) NOT NULL default '0', `Empties_or_zeros` bigint(11) NOT NULL default '0', `Nulls` bigint(11) NOT NULL default '0', - `Avg_value_or_avg_length` varchar(255) NOT NULL default '', - `Std` varchar(255) default NULL, - `Optimal_fieldtype` varchar(64) NOT NULL default '' + `Avg_value_or_avg_length` varbinary(255) NOT NULL default '', + `Std` varbinary(255) default NULL, + `Optimal_fieldtype` varbinary(64) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 select * from t2; Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result index 5679b1d6838..1f2d60fb79a 100644 --- a/mysql-test/r/case.result +++ b/mysql-test/r/case.result @@ -98,10 +98,10 @@ Table Create Table t1 CREATE TABLE `t1` ( `c1` varchar(1) character set latin1 collate latin1_danish_ci NOT NULL default '', `c2` varchar(1) character set latin1 collate latin1_danish_ci NOT NULL default '', - `c3` varchar(1) NOT NULL default '', - `c4` varchar(1) NOT NULL default '', - `c5` varchar(3) NOT NULL default '', - `c6` varchar(3) NOT NULL default '', + `c3` varbinary(1) NOT NULL default '', + `c4` varbinary(1) NOT NULL default '', + `c5` varbinary(3) NOT NULL default '', + `c6` varbinary(3) NOT NULL default '', `c7` double(3,1) NOT NULL default '0.0', `c8` double(3,1) NOT NULL default '0.0', `c9` double(3,1) default NULL @@ -149,8 +149,8 @@ t1 CREATE TABLE `t1` ( `COALESCE(1.0)` double(3,1) NOT NULL default '0.0', `COALESCE('a')` varchar(1) NOT NULL default '', `COALESCE(1,1.0)` double(3,1) NOT NULL default '0.0', - `COALESCE(1,'1')` varchar(1) NOT NULL default '', - `COALESCE(1.1,'1')` varchar(3) NOT NULL default '', + `COALESCE(1,'1')` varbinary(1) NOT NULL default '', + `COALESCE(1.1,'1')` varbinary(3) NOT NULL default '', `COALESCE('a' COLLATE latin1_bin,'b')` varchar(1) character set latin1 collate latin1_bin NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index 6df5f633b88..c65d11330ea 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -471,7 +471,7 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye prepare stmt1 from ' explain select a from t1 order by b '; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -479,7 +479,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 14 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using filesort @@ -487,7 +487,7 @@ SET @arg00=1 ; prepare stmt1 from ' explain select a from t1 where a > ? order by b '; execute stmt1 using @arg00; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 5 N 1 31 8 @@ -495,7 +495,7 @@ def possible_keys 253 4096 7 Y 0 31 8 def key 253 64 7 Y 0 31 8 def key_len 253 4096 1 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 27 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using filesort diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index 621a7ceeab8..50a74dfad63 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -1145,7 +1145,7 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -1153,7 +1153,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index 4fc3ce54810..209a22e4a9e 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -1145,7 +1145,7 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -1153,7 +1153,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index 5025e847f1a..f0be4d119bc 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -1146,7 +1146,7 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -1154,7 +1154,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index 3dff34e374f..a62d00c71c0 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -1188,7 +1188,7 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -1196,7 +1196,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 @@ -4197,7 +4197,7 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -4205,7 +4205,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result index 230da5df00d..9a922d75cdc 100644 --- a/mysql-test/r/ps_7ndb.result +++ b/mysql-test/r/ps_7ndb.result @@ -4,7 +4,7 @@ create table t1 ( a int, b varchar(30), primary key(a) -) engine = 'NDB' ; +) engine = 'BDB' ; create table t9 ( c1 tinyint, c2 smallint, c3 mediumint, c4 int, @@ -17,7 +17,7 @@ c25 blob, c26 text, c27 mediumblob, c28 mediumtext, c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'), c32 set('monday', 'tuesday', 'wednesday'), primary key(c1) -) engine = 'NDB' ; +) engine = 'BDB' ; delete from t1 ; insert into t1 values (1,'one'); insert into t1 values (2,'two'); @@ -1145,7 +1145,7 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -1153,10 +1153,10 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t9 ALL NULL NULL NULL NULL 2 +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 test_sequence ------ delete tests ------ delete from t1 ; @@ -1328,7 +1328,7 @@ create table t2 ( a int, b varchar(30), primary key(a) -) engine = 'NDB' ; +) engine = 'BDB' ; insert into t2(a,b) select a, b from t1 ; prepare stmt1 from 'update t1 set a=? where b=? and a in (select ? from t2 @@ -1520,7 +1520,7 @@ execute stmt1 using @arg00, @arg01; ERROR 23000: Duplicate entry '82' for key 1 drop table if exists t2 ; create table t2 (id int auto_increment primary key) -ENGINE= 'NDB' ; +ENGINE= 'BDB' ; prepare stmt1 from ' select last_insert_id() ' ; insert into t2 values (NULL) ; execute stmt1 ; diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 334a2531c7f..e23b1c8a326 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -554,7 +554,7 @@ aa show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` varchar(20) NOT NULL default '' + `a` varbinary(20) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; create table t1 SELECT 12 as a UNION select 12.2 as a; diff --git a/sql/item.cc b/sql/item.cc index 47dccf5b8da..763ab84582d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -46,7 +46,7 @@ void item_init(void) Item::Item(): name(0), orig_name(0), name_length(0), fixed(0), - collation(default_charset(), DERIVATION_COERCIBLE) + collation(&my_charset_bin, DERIVATION_COERCIBLE) { marker= 0; maybe_null=null_value=with_sum_func=unsigned_flag=0; From 0420317c61a374a5bd2f81c31d2e3ebace18f14d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 20:16:21 +0200 Subject: [PATCH 72/90] Added possibility to use --error instead of --error The old syntax works as well. WL#2356. --- client/mysqltest.c | 51 +++++++++++++++++++++++++++++++++------- mysql-test/t/create.test | 2 +- mysql-test/t/select.test | 4 ++-- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 05ac68e3176..9e887f61160 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -123,6 +123,17 @@ typedef struct } code; } match_err; +typedef struct +{ + const char *name; + long code; +} st_error; + +static st_error global_error[] = { +#include + { 0, 0 } +}; + static match_err global_expected_errno[MAX_EXPECTED_ERRORS]; static uint global_expected_errors; @@ -1340,6 +1351,7 @@ static uint get_errcodes(match_err *to,struct st_query* q) { char* p= q->first_argument; uint count= 0; + DBUG_ENTER("get_errcodes"); if (!*p) @@ -1350,19 +1362,41 @@ static uint get_errcodes(match_err *to,struct st_query* q) if (*p == 'S') { /* SQLSTATE string */ - int i; - p++; - for (i = 0; my_isalnum(charset_info, *p) && i < SQLSTATE_LENGTH; p++, i++) - to[count].code.sqlstate[i]= *p; - to[count].code.sqlstate[i]= '\0'; + char *end= ++p + SQLSTATE_LENGTH; + char *to_ptr= to[count].code.sqlstate; + + for (; my_isalnum(charset_info, *p) && p != end; p++) + *to_ptr++= *p; + *to_ptr= 0; + to[count].type= ERR_SQLSTATE; } + else if (*p == 'E') + { + /* SQL error as string */ + st_error *e= global_error; + char *start= p++; + + for (; *p == '_' || my_isalnum(charset_info, *p); p++) + ; + for (; e->name; e++) + { + if (!strncmp(start, e->name, (int) (p - start))) + { + to[count].code.errnum= (uint) e->code; + to[count].type= ERR_ERRNO; + break; + } + } + if (!e->name) + die("Unknown SQL error '%s'\n", start); + } else { long val; - p=str2int(p,10,(long) INT_MIN, (long) INT_MAX, &val); - if (p == NULL) - die("Invalid argument in %s\n", q->query); + + if (!(p= str2int(p,10,(long) INT_MIN, (long) INT_MAX, &val))) + die("Invalid argument in %s\n", q->query); to[count].code.errnum= (uint) val; to[count].type= ERR_ERRNO; } @@ -2855,6 +2889,7 @@ static int normal_handle_error(const char *query, struct st_query *q, mysql_error(mysql)); DBUG_RETURN(0); } + return 0; /* Keep compiler happy */ } diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 686bf5a97ad..26b467a398d 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -294,7 +294,7 @@ select * from t2; create table t3 like t1; --error 1050 create table t3 like mysqltest.t3; ---error 1044,1 +--error ER_DBACCESS_DENIED_ERROR,1 create table non_existing_database.t1 like t1; --error 1051 create table t3 like non_existing_table; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 47b115cf030..a32b9d06ef9 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -1761,9 +1761,9 @@ DO benchmark(100,1+1),1,1; # Bug #6449: do default; # ---error 1064 +--error ER_PARSE_ERROR do default; ---error 1054 +--error ER_BAD_FIELD_ERROR do foobar; # From efb92cb67c9cb323b28cdae7d085e93d949f1cb3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 22:29:21 +0400 Subject: [PATCH 73/90] ps_7ndb.result, ps_6bdb.result: after merge clean-up mysql-test/r/ps_6bdb.result: after merge clean-up mysql-test/r/ps_7ndb.result: after merge clean-up --- mysql-test/r/ps_6bdb.result | 4 ++-- mysql-test/r/ps_7ndb.result | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result index 6817c0000c5..9a922d75cdc 100644 --- a/mysql-test/r/ps_6bdb.result +++ b/mysql-test/r/ps_6bdb.result @@ -1145,7 +1145,7 @@ test_sequence prepare stmt1 from ' explain select * from t9 ' ; execute stmt1; Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 +def id 8 3 1 N 32929 0 63 def select_type 253 19 6 N 1 31 8 def table 253 64 2 N 1 31 8 def type 253 10 3 N 1 31 8 @@ -1153,7 +1153,7 @@ def possible_keys 253 4096 0 Y 0 31 8 def key 253 64 0 Y 0 31 8 def key_len 253 4096 0 Y 128 31 63 def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 +def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t9 ALL NULL NULL NULL NULL 3 diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result index 9a922d75cdc..5047160bf75 100644 --- a/mysql-test/r/ps_7ndb.result +++ b/mysql-test/r/ps_7ndb.result @@ -4,7 +4,7 @@ create table t1 ( a int, b varchar(30), primary key(a) -) engine = 'BDB' ; +) engine = 'NDB' ; create table t9 ( c1 tinyint, c2 smallint, c3 mediumint, c4 int, @@ -17,7 +17,7 @@ c25 blob, c26 text, c27 mediumblob, c28 mediumtext, c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'), c32 set('monday', 'tuesday', 'wednesday'), primary key(c1) -) engine = 'BDB' ; +) engine = 'NDB' ; delete from t1 ; insert into t1 values (1,'one'); insert into t1 values (2,'two'); @@ -1156,7 +1156,7 @@ def ref 253 1024 0 Y 0 31 8 def rows 8 10 1 N 32929 0 63 def Extra 253 255 0 N 1 31 8 id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 +1 SIMPLE t9 ALL NULL NULL NULL NULL 2 test_sequence ------ delete tests ------ delete from t1 ; @@ -1328,7 +1328,7 @@ create table t2 ( a int, b varchar(30), primary key(a) -) engine = 'BDB' ; +) engine = 'NDB' ; insert into t2(a,b) select a, b from t1 ; prepare stmt1 from 'update t1 set a=? where b=? and a in (select ? from t2 @@ -1520,7 +1520,7 @@ execute stmt1 using @arg00, @arg01; ERROR 23000: Duplicate entry '82' for key 1 drop table if exists t2 ; create table t2 (id int auto_increment primary key) -ENGINE= 'BDB' ; +ENGINE= 'NDB' ; prepare stmt1 from ' select last_insert_id() ' ; insert into t2 values (NULL) ; execute stmt1 ; From 09aa1e07630efa7388c8b128ec3635a0aa1f4600 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 22:24:22 +0300 Subject: [PATCH 74/90] After merge fix. client/Makefile.am: Don't use relative paths. --- client/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/Makefile.am b/client/Makefile.am index 78fd61afe57..9b62d698e38 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -32,7 +32,7 @@ mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS) mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS) mysqltest_SOURCES= mysqltest.c $(top_srcdir)/mysys/my_getsystime.c mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) -mysqlbinlog_SOURCES = mysqlbinlog.cc ../mysys/mf_tempdir.c +mysqlbinlog_SOURCES = mysqlbinlog.cc $(top_srcdir)/mysys/mf_tempdir.c mysqlmanagerc_SOURCES = mysqlmanagerc.c sql_src=log_event.h mysql_priv.h log_event.cc From a66d80d17e66950301a8e3f7256ab074c619b6e5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 22:09:15 +0100 Subject: [PATCH 75/90] removed default usage of shared memory transporter as it is not verified on enough platforms --- ndb/include/util/ndb_opts.h | 8 ++++---- sql/mysqld.cc | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ndb/include/util/ndb_opts.h b/ndb/include/util/ndb_opts.h index dc95149f706..689a6bbf806 100644 --- a/ndb/include/util/ndb_opts.h +++ b/ndb/include/util/ndb_opts.h @@ -34,11 +34,11 @@ OPT_NDB_OPTIMIZED_NODE_SELECTION #define OPT_NDB_CONNECTSTRING 'c' -#if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 -#define OPT_NDB_SHM_DEFAULT 1 -#else +//#if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 +//#define OPT_NDB_SHM_DEFAULT 1 +//#else #define OPT_NDB_SHM_DEFAULT 0 -#endif +//#endif #define NDB_STD_OPTS_COMMON \ { "usage", '?', "Display this help and exit.", \ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ee59ed8c8a1..976e62492ce 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -54,11 +54,11 @@ #endif #ifdef HAVE_NDBCLUSTER_DB #define OPT_NDBCLUSTER_DEFAULT 0 -#if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 -#define OPT_NDB_SHM_DEFAULT 1 -#else +//#if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 +//#define OPT_NDB_SHM_DEFAULT 1 +//#else #define OPT_NDB_SHM_DEFAULT 0 -#endif +//#endif #else #define OPT_NDBCLUSTER_DEFAULT 0 #endif From 08ea4df60b4e9546dd989afa29284970345c0ac5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 13:12:40 -0800 Subject: [PATCH 76/90] Update type_float test results after merge. mysql-test/r/type_float.result: Update test results (4.1 produces a warning that 4.0 did not, and they were merged into the wrong position). --- mysql-test/r/type_float.result | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 6e8275d5dac..1f5a34917d7 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -143,6 +143,15 @@ drop table t1; create table t1 (f float(54)); ERROR 42000: Incorrect column specifier for column 'f' drop table if exists t1; +create table t1 (d1 double, d2 double unsigned); +insert into t1 set d1 = -1.0; +update t1 set d2 = d1; +Warnings: +Warning 1264 Data truncated; out of range for column 'd2' at row 1 +select * from t1; +d1 d2 +-1 0 +drop table t1; create table t1 (f float(4,3)); insert into t1 values (-11.0),(-11),("-11"),(11.0),(11),("11"); Warnings: @@ -179,13 +188,6 @@ f 9.999 9.999 drop table if exists t1; -create table t1 (d1 double, d2 double unsigned); -insert into t1 set d1 = -1.0; -update t1 set d2 = d1; -select * from t1; -d1 d2 --1 0 -drop table t1; create table t1 (c char(20)); insert into t1 values (5e-28); select * from t1; From 59ef5bede94cb0955590b16ead9352c17a5fd7ac Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 23:13:29 +0200 Subject: [PATCH 77/90] fixing wrong value for "examined rows" when UNION's are used. mysql-test/r/union.result: result for a test case for the wrong examined rows with UNION's mysql-test/t/union.test: test case for the wrong examined rows with UNION's sql/sql_union.cc: a patch for the wrong examined rows with UNION's --- mysql-test/r/union.result | 16 ++++++++++++++++ mysql-test/t/union.test | 4 ++++ sql/sql_union.cc | 11 +++++++---- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 1eb978b1bd6..f07bdad9021 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -872,6 +872,22 @@ count(*) show status like 'Slow_queries'; Variable_name Value Slow_queries 3 +flush status; +select a from t1 where b not in (1,2,3) union select a from t1 where b not in (4,5,6); +a +4 +5 +3 +6 +7 +8 +9 +10 +1 +2 +show status like 'Slow_queries'; +Variable_name Value +Slow_queries 1 drop table t1; create table t1 ( RID int(11) not null default '0', IID int(11) not null default '0', nada varchar(50) not null,NAME varchar(50) not null,PHONE varchar(50) not null) engine=MyISAM; insert into t1 ( RID,IID,nada,NAME,PHONE) values (1, 1, 'main', 'a', '111'), (2, 1, 'main', 'b', '222'), (3, 1, 'main', 'c', '333'), (4, 1, 'main', 'd', '444'), (5, 1, 'main', 'e', '555'), (6, 2, 'main', 'c', '333'), (7, 2, 'main', 'd', '454'), (8, 2, 'main', 'e', '555'), (9, 2, 'main', 'f', '666'), (10, 2, 'main', 'g', '777'); diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 468a88b83db..8682808f3f3 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -481,6 +481,10 @@ select count(*) from t1 where b=13 union select count(*) from t1 where a=7; show status like 'Slow_queries'; select count(*) from t1 where a=7 union select count(*) from t1 where b=13; show status like 'Slow_queries'; +# additional test for examined rows +flush status; +select a from t1 where b not in (1,2,3) union select a from t1 where b not in (4,5,6); +show status like 'Slow_queries'; drop table t1; # diff --git a/sql/sql_union.cc b/sql/sql_union.cc index f89b234f5b0..027a21db7ac 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -466,11 +466,14 @@ int st_select_lex_unit::exec() } res= sl->join->error; offset_limit_cnt= sl->offset_limit; - if (!res && union_result->flush()) + if (!res) { - examined_rows+= thd->examined_row_count; - thd->lex->current_select= lex_select_save; - DBUG_RETURN(1); + examined_rows+= thd->examined_row_count; + if (union_result->flush()) + { + thd->lex->current_select= lex_select_save; + DBUG_RETURN(1); + } } } if (res) From e54bd24326227a3c7e41e0bd77ed214b95cf27a4 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Jan 2005 15:05:16 -0800 Subject: [PATCH 78/90] Fix test results from merge, and fix the symlink test which had an out-of-sync test and result. mysql-test/r/type_float.result: Warning message text changed mysql-test/t/symlink.test: Re-enable part of test mysql-test/r/symlink.result: Update results to match test --- mysql-test/r/symlink.result | 9 +++++++++ mysql-test/r/type_float.result | 2 +- mysql-test/t/symlink.test | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index 53d0f63aea2..8aa20a88177 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -45,6 +45,15 @@ alter table t9 rename t8, add column d int not null; alter table t8 rename t7; rename table t7 to t9; drop table t1; +SHOW CREATE TABLE t9; +Table Create Table +t9 CREATE TABLE `t9` ( + `a` int(11) NOT NULL auto_increment, + `b` char(16) NOT NULL, + `c` int(11) NOT NULL, + `d` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='TEST_DIR/var/tmp/' INDEX DIRECTORY='TEST_DIR/var/run/' Got one of the listed errors Got one of the listed errors Got one of the listed errors diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 32edda67a53..c77b3ad7578 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -150,7 +150,7 @@ create table t1 (d1 double, d2 double unsigned); insert into t1 set d1 = -1.0; update t1 set d2 = d1; Warnings: -Warning 1264 Data truncated; out of range for column 'd2' at row 1 +Warning 1264 Out of range value adjusted for column 'd2' at row 1 select * from t1; d1 d2 -1 0 diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index 9e71ac4b925..25c78129129 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -50,8 +50,8 @@ optimize table t9; repair table t9; alter table t9 add column c int not null; -#--replace_result $MYSQL_TEST_DIR TEST_DIR -#show create table t9; +--replace_result $MYSQL_TEST_DIR TEST_DIR +show create table t9; # Test renames alter table t9 rename t8, add column d int not null; From 05422852c0773f05f6228fb53981fc401bd2bb2f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jan 2005 03:01:34 +0300 Subject: [PATCH 79/90] Fixes of client_test on Solaris 64 bit tests/client_test.c: Fixes for Solaris: a) no truncation in one place (ulonglong -> double) b) fix a glitch with byte order and passing int * instead of char * as a statement attribute --- tests/client_test.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/client_test.c b/tests/client_test.c index 498b57fdeab..8be970aed29 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -9992,7 +9992,7 @@ static void test_bug3035() printf("%d", (int) bind->error_value); printf("\n"); } - DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED); + DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED || rc == 0); DIE_UNLESS(int8_val == int8_max); DIE_UNLESS(uint8_val == uint8_max); @@ -11766,6 +11766,7 @@ static void test_bug6096() MYSQL_FIELD *query_field_list, *stmt_field_list; ulong query_field_count, stmt_field_count; int rc; + my_bool update_max_length= TRUE; uint i; myheader("test_bug6096"); @@ -11801,8 +11802,8 @@ static void test_bug6096() check_execute(stmt, rc); rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); - rc= 1; - mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*)&rc); + mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, + (void*) &update_max_length); mysql_stmt_store_result(stmt); stmt_metadata= mysql_stmt_result_metadata(stmt); stmt_field_list= mysql_fetch_fields(stmt_metadata); From 982e0b8cfb2919a185b7f3ffc252eaf947b77af3 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jan 2005 04:43:54 +0100 Subject: [PATCH 80/90] changed "formatting" after sergs comments on prev chanset --- ndb/include/util/ndb_opts.h | 8 ++++---- sql/mysqld.cc | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ndb/include/util/ndb_opts.h b/ndb/include/util/ndb_opts.h index 689a6bbf806..9151aee6cf2 100644 --- a/ndb/include/util/ndb_opts.h +++ b/ndb/include/util/ndb_opts.h @@ -34,11 +34,11 @@ OPT_NDB_OPTIMIZED_NODE_SELECTION #define OPT_NDB_CONNECTSTRING 'c' -//#if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 -//#define OPT_NDB_SHM_DEFAULT 1 -//#else +#if defined(NOT_ENOUGH_TESTED) && defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 +#define OPT_NDB_SHM_DEFAULT 1 +#else #define OPT_NDB_SHM_DEFAULT 0 -//#endif +#endif #define NDB_STD_OPTS_COMMON \ { "usage", '?', "Display this help and exit.", \ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 976e62492ce..35eddb0734f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -54,11 +54,11 @@ #endif #ifdef HAVE_NDBCLUSTER_DB #define OPT_NDBCLUSTER_DEFAULT 0 -//#if defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 -//#define OPT_NDB_SHM_DEFAULT 1 -//#else +#if defined(NOT_ENOUGH_TESTED) && defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000 +#define OPT_NDB_SHM_DEFAULT 1 +#else #define OPT_NDB_SHM_DEFAULT 0 -//#endif +#endif #else #define OPT_NDBCLUSTER_DEFAULT 0 #endif From 153160d1ffd9d118867c3e5c41474f435e5c981f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jan 2005 07:23:20 +0100 Subject: [PATCH 81/90] bug#7693 - ndb when using shm transporter, set sigmask on each thread using pthread_sigmask configure.in: Add more functions needed for SHM ndb/src/common/portlib/NdbThread.c: 1) Create thread wrapper function 2) block SIGUSR1 #ifdef NDB_SHM_TRANSPORTER ndb/src/common/transporter/TransporterRegistry.cpp: (un)block SIGUSR1 #ifdef NDB_SHM_TRANSPORTER sql/ha_ndbcluster.cc: cast pointer to UintPtr before printout --- configure.in | 7 ++++-- ndb/src/common/portlib/NdbThread.c | 22 +++++++++++++++++-- .../transporter/TransporterRegistry.cpp | 16 ++++++++++++-- sql/ha_ndbcluster.cc | 4 ++-- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/configure.in b/configure.in index b1b8b128f46..2d20a71f838 100644 --- a/configure.in +++ b/configure.in @@ -1924,7 +1924,7 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \ pthread_key_delete pthread_rwlock_rdlock pthread_setprio \ pthread_setprio_np pthread_setschedparam pthread_sigmask readlink \ realpath rename rint rwlock_init setupterm \ - shmget shmat shmdt shmctl sigaction \ + shmget shmat shmdt shmctl sigaction sigemptyset sigaddset \ sighold sigset sigthreadmask \ snprintf socket stpcpy strcasecmp strerror strnlen strpbrk strstr strtol \ strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr) @@ -3098,7 +3098,10 @@ if test "$ac_cv_func_shmget" = "yes" && test "$ac_cv_func_shmat" = "yes" && test "$ac_cv_func_shmdt" = "yes" && test "$ac_cv_func_shmctl" = "yes" && - test "$ac_cv_func_sigaction" = "yes" + test "$ac_cv_func_sigaction" = "yes" && + test "$ac_cv_func_sigemptyset" = "yes" && + test "$ac_cv_func_sigaddset" = "yes" && + test "$ac_cv_func_pthread_sigmask" = "yes" then AC_DEFINE([NDB_SHM_TRANSPORTER], [1], [Including Ndb Cluster DB shared memory transporter]) diff --git a/ndb/src/common/portlib/NdbThread.c b/ndb/src/common/portlib/NdbThread.c index d4f6617d2f5..8cd6c306514 100644 --- a/ndb/src/common/portlib/NdbThread.c +++ b/ndb/src/common/portlib/NdbThread.c @@ -28,8 +28,24 @@ struct NdbThread { pthread_t thread; char thread_name[MAX_THREAD_NAME]; + NDB_THREAD_FUNC * func; + void * object; }; +static +void* +ndb_thread_wrapper(void* _ss){ + void * ret; + struct NdbThread * ss = (struct NdbThread *)_ss; +#ifdef NDB_SHM_TRANSPORTER + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGUSR1); + pthread_sigmask(SIG_BLOCK, &mask, 0); +#endif + ret= (* ss->func)(ss->object); + return ret; +} struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC *p_thread_func, @@ -67,10 +83,12 @@ struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC *p_thread_func, #ifdef PTHREAD_CREATE_JOINABLE /* needed on SCO */ pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE); #endif + tmpThread->func= p_thread_func; + tmpThread->object= p_thread_arg; result = pthread_create(&tmpThread->thread, &thread_attr, - p_thread_func, - p_thread_arg); + ndb_thread_wrapper, + tmpThread); assert(result==0); pthread_attr_destroy(&thread_attr); diff --git a/ndb/src/common/transporter/TransporterRegistry.cpp b/ndb/src/common/transporter/TransporterRegistry.cpp index c80e6bc1489..ddc01454205 100644 --- a/ndb/src/common/transporter/TransporterRegistry.cpp +++ b/ndb/src/common/transporter/TransporterRegistry.cpp @@ -153,8 +153,17 @@ TransporterRegistry::init(NodeId nodeId) { DEBUG("TransporterRegistry started node: " << localNodeId); - // return allocateLongSignalMemoryPool(nLargeSegments); - return true; +#ifdef NDB_SHM_TRANSPORTER + /** + * Make sure to block SIGUSR1 + * TransporterRegistry::init is run from "main" thread + */ + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGUSR1); + pthread_sigmask(SIG_BLOCK, &mask, 0); +#endif +return true; } bool @@ -1321,6 +1330,9 @@ TransporterRegistry::startReceiving() #ifdef NDB_SHM_TRANSPORTER m_shm_own_pid = getpid(); struct sigaction sa; + sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGUSR1); + pthread_sigmask(SIG_UNBLOCK, &sa.sa_mask, 0); sa.sa_handler = shm_sig_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index e4c45490050..c2d12ddd316 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -583,7 +583,7 @@ int ha_ndbcluster::get_ndb_blobs_value(NdbBlob *last_ndb_blob) char *buf= m_blobs_buffer + offset; uint32 len= 0xffffffff; // Max uint32 DBUG_PRINT("value", ("read blob ptr=%x len=%u", - (uint)buf, (uint)blob_len)); + (UintPtr)buf, (uint)blob_len)); if (ndb_blob->readData(buf, len) != 0) DBUG_RETURN(-1); DBUG_ASSERT(len == blob_len); @@ -3169,7 +3169,7 @@ int ha_ndbcluster::start_stmt(THD *thd) NdbConnection *tablock_trans= (NdbConnection*)thd->transaction.all.ndb_tid; - DBUG_PRINT("info", ("tablock_trans: %x", (uint)tablock_trans)); + DBUG_PRINT("info", ("tablock_trans: %x", (UintPtr)tablock_trans)); DBUG_ASSERT(tablock_trans); // trans= ndb->hupp(tablock_trans); trans= ndb->startTransaction(); From ed327104b6803959f7f5acb4dc84afd117ad26b4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jan 2005 09:15:34 +0100 Subject: [PATCH 82/90] bug#7777 - ndb compile on qnx remove usage of compiler supplied and instead impl. own inlined placement new ndb/include/kernel/AttributeHeader.hpp: remove usage ndb/include/ndb_global.h.in: remove usage instead impl. own ndb/src/kernel/blocks/backup/BackupInit.cpp: remove usage ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp: remove usage ndb/src/kernel/blocks/dbdih/DbdihInit.cpp: remove usage ndb/src/kernel/blocks/dblqh/DblqhInit.cpp: remove usage ndb/src/kernel/blocks/dbtc/DbtcInit.cpp: remove usage ndb/src/kernel/blocks/dbtup/DbtupGen.cpp: remove usage ndb/src/kernel/blocks/dbtux/Dbtux.hpp: remove usage ndb/src/kernel/blocks/grep/GrepInit.cpp: remove usage ndb/src/kernel/blocks/suma/SumaInit.cpp: remove usage ndb/src/kernel/vm/Emulator.cpp: remove usage ndb/src/kernel/vm/SimulatedBlock.hpp: remove usage ndb/src/mgmapi/mgmapi_configuration.cpp: remove usage --- ndb/include/kernel/AttributeHeader.hpp | 1 - ndb/include/ndb_global.h.in | 6 ++---- ndb/src/kernel/blocks/backup/BackupInit.cpp | 1 - ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp | 1 - ndb/src/kernel/blocks/dbdih/DbdihInit.cpp | 1 - ndb/src/kernel/blocks/dblqh/DblqhInit.cpp | 1 - ndb/src/kernel/blocks/dbtc/DbtcInit.cpp | 1 - ndb/src/kernel/blocks/dbtup/DbtupGen.cpp | 1 - ndb/src/kernel/blocks/dbtux/Dbtux.hpp | 1 - ndb/src/kernel/blocks/grep/GrepInit.cpp | 1 - ndb/src/kernel/blocks/suma/SumaInit.cpp | 1 - ndb/src/kernel/vm/Emulator.cpp | 1 - ndb/src/kernel/vm/SimulatedBlock.hpp | 1 - ndb/src/mgmapi/mgmapi_configuration.cpp | 1 - 14 files changed, 2 insertions(+), 17 deletions(-) diff --git a/ndb/include/kernel/AttributeHeader.hpp b/ndb/include/kernel/AttributeHeader.hpp index b807b4ef4f1..ed9085301be 100644 --- a/ndb/include/kernel/AttributeHeader.hpp +++ b/ndb/include/kernel/AttributeHeader.hpp @@ -17,7 +17,6 @@ #ifndef ATTRIBUTE_HEADER #define ATTRIBUTE_HEADER -#include /** * @class AttributeHeader * @brief Header passed in front of every attribute value in AttrInfo signal diff --git a/ndb/include/ndb_global.h.in b/ndb/include/ndb_global.h.in index d7a5cb1b1cf..eadd5e37b9b 100644 --- a/ndb/include/ndb_global.h.in +++ b/ndb/include/ndb_global.h.in @@ -138,10 +138,8 @@ static const char table_name_separator = '/'; #endif #ifdef __cplusplus -#include -#endif - -#ifdef __cplusplus +inline void* operator new(size_t, void* __p) { return __p; } +inline void* operator new[](size_t, void* __p) { return __p; } extern "C" { #endif diff --git a/ndb/src/kernel/blocks/backup/BackupInit.cpp b/ndb/src/kernel/blocks/backup/BackupInit.cpp index e0171c61eca..08fa089a9c0 100644 --- a/ndb/src/kernel/blocks/backup/BackupInit.cpp +++ b/ndb/src/kernel/blocks/backup/BackupInit.cpp @@ -22,7 +22,6 @@ //=========================================================================== #include "Backup.hpp" -#include #include #include diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp index c1dca184466..dfae180ae71 100644 --- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp +++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp @@ -39,7 +39,6 @@ #include #include -#include #include #include diff --git a/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp b/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp index b823dbcd952..9a5efebc56e 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp @@ -18,7 +18,6 @@ #define DBDIH_C #include "Dbdih.hpp" #include -#include #define DEBUG(x) { ndbout << "DIH::" << x << endl; } diff --git a/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp b/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp index 0577aa4d344..ec29489180c 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp @@ -19,7 +19,6 @@ #define DBLQH_C #include "Dblqh.hpp" #include -#include #define DEBUG(x) { ndbout << "LQH::" << x << endl; } diff --git a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp index 5c66ba776b0..59c8237f20a 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #define DEBUG(x) { ndbout << "TC::" << x << endl; } diff --git a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp index 0f0e6d61f41..0d7430e662d 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp @@ -31,7 +31,6 @@ #include #include -#include #define DEBUG(x) { ndbout << "TUP::" << x << endl; } diff --git a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp index 8af83e3c056..2c96271eb5d 100644 --- a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp +++ b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp @@ -17,7 +17,6 @@ #ifndef DBTUX_H #define DBTUX_H -#include #include #include #include diff --git a/ndb/src/kernel/blocks/grep/GrepInit.cpp b/ndb/src/kernel/blocks/grep/GrepInit.cpp index 36855f86568..d764fb1f473 100644 --- a/ndb/src/kernel/blocks/grep/GrepInit.cpp +++ b/ndb/src/kernel/blocks/grep/GrepInit.cpp @@ -15,7 +15,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Grep.hpp" -#include #include #include diff --git a/ndb/src/kernel/blocks/suma/SumaInit.cpp b/ndb/src/kernel/blocks/suma/SumaInit.cpp index 36217c313af..b5945db3811 100644 --- a/ndb/src/kernel/blocks/suma/SumaInit.cpp +++ b/ndb/src/kernel/blocks/suma/SumaInit.cpp @@ -16,7 +16,6 @@ #include "Suma.hpp" -#include #include #include diff --git a/ndb/src/kernel/vm/Emulator.cpp b/ndb/src/kernel/vm/Emulator.cpp index adf3c438945..068610b6778 100644 --- a/ndb/src/kernel/vm/Emulator.cpp +++ b/ndb/src/kernel/vm/Emulator.cpp @@ -33,7 +33,6 @@ #include #include #include -#include extern "C" { extern void (* ndb_new_handler)(); diff --git a/ndb/src/kernel/vm/SimulatedBlock.hpp b/ndb/src/kernel/vm/SimulatedBlock.hpp index cff19734368..787d14ca5cb 100644 --- a/ndb/src/kernel/vm/SimulatedBlock.hpp +++ b/ndb/src/kernel/vm/SimulatedBlock.hpp @@ -36,7 +36,6 @@ #include #include -#include #include "DLList.hpp" #include "ArrayPool.hpp" #include "DLHashTable.hpp" diff --git a/ndb/src/mgmapi/mgmapi_configuration.cpp b/ndb/src/mgmapi/mgmapi_configuration.cpp index 7bac2d10b92..80ab428c05a 100644 --- a/ndb/src/mgmapi/mgmapi_configuration.cpp +++ b/ndb/src/mgmapi/mgmapi_configuration.cpp @@ -1,7 +1,6 @@ #include #include #include "mgmapi_configuration.hpp" -#include ndb_mgm_configuration_iterator::ndb_mgm_configuration_iterator (const ndb_mgm_configuration & conf, unsigned type_of_section) From d374ed9c0444d690fc9f5eb979014e6e2efc9069 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jan 2005 10:00:41 +0100 Subject: [PATCH 83/90] added possibility to add extra opts to ndbd and ndb_mgmd in mysql-test-run --- mysql-test/mysql-test-run.sh | 9 ++++++++- mysql-test/ndb/ndbcluster.sh | 13 +++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 9684a880510..722da516d9b 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -241,6 +241,9 @@ USE_EMBEDDED_SERVER="" RESULT_EXT="" TEST_MODE="default" +NDB_MGMD_EXTRA_OPTS= +NDBD_EXTRA_OPTS= + while test $# -gt 0; do case "$1" in --embedded-server) USE_EMBEDDED_SERVER=1 USE_MANAGER=0 NO_SLAVE=1 ; \ @@ -261,6 +264,10 @@ while test $# -gt 0; do --ndb-connectstring=*) USE_NDBCLUSTER="--ndbcluster" ; USE_RUNNING_NDBCLUSTER=`$ECHO "$1" | $SED -e "s;--ndb-connectstring=;;"` ;; + --ndb_mgmd-extra-opts=*) + NDB_MGMD_EXTRA_OPTS=`$ECHO "$1" | $SED -e "s;--ndb_mgmd-extra-opts=;;"` ;; + --ndbd-extra-opts=*) + NDBD_EXTRA_OPTS=`$ECHO "$1" | $SED -e "s;--ndbd-extra-opts=;;"` ;; --tmpdir=*) MYSQL_TMP_DIR=`$ECHO "$1" | $SED -e "s;--tmpdir=;;"` ;; --local-master) MASTER_MYPORT=3306; @@ -460,7 +467,7 @@ SMALL_SERVER="--key_buffer_size=1M --sort_buffer=256K --max_heap_table_size=1M" export MASTER_MYPORT MASTER_MYPORT1 SLAVE_MYPORT MYSQL_TCP_PORT MASTER_MYSOCK MASTER_MYSOCK1 NDBCLUSTER_BASE_PORT=`expr $NDBCLUSTER_PORT + 2` -NDBCLUSTER_OPTS="--port=$NDBCLUSTER_PORT --port-base=$NDBCLUSTER_BASE_PORT --data-dir=$MYSQL_TEST_DIR/var" +NDBCLUSTER_OPTS="--port=$NDBCLUSTER_PORT --port-base=$NDBCLUSTER_BASE_PORT --data-dir=$MYSQL_TEST_DIR/var --ndb_mgmd-extra-opts=\"$NDB_MGMD_EXTRA_OPTS\" --ndbd-extra-opts=\"$NDBD_EXTRA_OPTS\"" if [ x$SOURCE_DIST = x1 ] ; then MY_BASEDIR=$MYSQL_TEST_DIR diff --git a/mysql-test/ndb/ndbcluster.sh b/mysql-test/ndb/ndbcluster.sh index 2d529f8fe0f..a86e482b2ab 100644 --- a/mysql-test/ndb/ndbcluster.sh +++ b/mysql-test/ndb/ndbcluster.sh @@ -58,6 +58,9 @@ ndb_con_op=105000 ndb_dmem=80M ndb_imem=24M +NDB_MGMD_EXTRA_OPTS= +NDBD_EXTRA_OPTS= + while test $# -gt 0; do case "$1" in --test) @@ -94,6 +97,12 @@ while test $# -gt 0; do --port-base=*) port_base=`echo "$1" | sed -e "s;--port-base=;;"` ;; + --ndb_mgmd-extra-opts=*) + NDB_MGMD_EXTRA_OPTS=`echo "$1" | sed -e "s;--ndb_mgmd-extra-opts=;;"` + ;; + --ndbd-extra-opts=*) + NDBD_EXTRA_OPTS=`echo "$1" | sed -e "s;--ndbd-extra-opts=;;"` + ;; -- ) shift; break ;; --* ) $ECHO "Unrecognized option: $1"; exit 1 ;; * ) break ;; @@ -122,8 +131,8 @@ if [ ! -x "$exec_waiter" ]; then fi exec_mgmtclient="$exec_mgmtclient --no-defaults" -exec_mgmtsrvr="$exec_mgmtsrvr --no-defaults" -exec_ndb="$exec_ndb --no-defaults" +exec_mgmtsrvr="$exec_mgmtsrvr --no-defaults $NDB_MGMD_EXTRA_OPTS" +exec_ndb="$exec_ndb --no-defaults $NDBD_EXTRA_OPTS" exec_waiter="$exec_waiter --no-defaults" ndb_host="localhost" From da8a9e2f20e737f63e271f3a8ae7e8ba8dc276b7 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jan 2005 10:07:15 +0100 Subject: [PATCH 84/90] ndb compiler warning, c++ style comment in c-file ndb/include/ndb_constants.h: remove // from .h-file --- ndb/include/ndb_constants.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndb/include/ndb_constants.h b/ndb/include/ndb_constants.h index 491d0719a69..a04afe1bd72 100644 --- a/ndb/include/ndb_constants.h +++ b/ndb/include/ndb_constants.h @@ -48,7 +48,7 @@ #define NDB_TYPE_BIGUNSIGNED 10 #define NDB_TYPE_FLOAT 11 #define NDB_TYPE_DOUBLE 12 -#define NDB_TYPE_DECIMAL 13 // not used +#define NDB_TYPE_DECIMAL 13 /* not used */ #define NDB_TYPE_CHAR 14 #define NDB_TYPE_VARCHAR 15 #define NDB_TYPE_BINARY 16 From 6130a3ad7c4984956eb385f50a1d0125a11dce84 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jan 2005 16:19:10 +0300 Subject: [PATCH 85/90] View field names should be case insensitive --- mysql-test/r/view.result | 6 ++++++ mysql-test/t/view.test | 7 +++++++ sql/sql_base.cc | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index c4391781e9c..239849ed8d1 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1724,3 +1724,9 @@ a b 301 0 drop view v3; drop tables t1,t2; +create table t1(f1 int); +create view v1 as select f1 from t1; +select * from v1 where F1 = 1; +f1 +drop view v1; +drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 77f0f65323e..ed7401adaab 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1654,3 +1654,10 @@ select * from v3; drop view v3; drop tables t1,t2; + +# View field names should be case insensitive +create table t1(f1 int); +create view v1 as select f1 from t1; +select * from v1 where F1 = 1; +drop view v1; +drop table t1; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d854956325e..fc41643e8d4 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2120,7 +2120,7 @@ find_field_in_table(THD *thd, TABLE_LIST *table_list, Field_translator *trans= table_list->field_translation; for (uint i= 0; i < num; i ++) { - if (strcmp(trans[i].name, name) == 0) + if (!my_strcasecmp(system_charset_info, trans[i].name, name)) { #ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_grants_view && From 3234eb5687a811bc8ddc6d00ba98db7fdb07236e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jan 2005 14:20:26 +0100 Subject: [PATCH 86/90] added configure option to set extra ndb cc-flags --- config/ac-macros/ha_ndbcluster.m4 | 7 ++++++- configure.in | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/config/ac-macros/ha_ndbcluster.m4 b/config/ac-macros/ha_ndbcluster.m4 index 433bba95e91..751a11d1895 100644 --- a/config/ac-macros/ha_ndbcluster.m4 +++ b/config/ac-macros/ha_ndbcluster.m4 @@ -61,7 +61,12 @@ AC_DEFUN([MYSQL_CHECK_NDB_OPTIONS], [ --without-ndb-debug Disable special ndb debug features], [ndb_debug="$withval"], [ndb_debug="default"]) - + AC_ARG_WITH([ndb-ccflags], + [ + --with-ndb-ccflags Extra CC options for ndb compile], + [ndb_cxxflags_fix=$withval], + [ndb_cxxflags_fix=]) + AC_MSG_CHECKING([for NDB Cluster options]) AC_MSG_RESULT([]) diff --git a/configure.in b/configure.in index ec1a4615fa8..e20edf97a72 100644 --- a/configure.in +++ b/configure.in @@ -361,7 +361,6 @@ AC_SUBST(INSTALL_SCRIPT) export CC CXX CFLAGS LD LDFLAGS AR -ndb_cxxflags_fix= if test "$GXX" = "yes" then # mysqld requires -fno-implicit-templates. From 58d79686650495b05abd6a5b6ae9b5be256ac73d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jan 2005 14:56:40 +0100 Subject: [PATCH 87/90] removed compiler warnings --- ndb/src/common/util/Bitmask.cpp | 2 +- ndb/src/kernel/blocks/dbdict/Dbdict.cpp | 2 +- ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp | 2 +- ndb/src/mgmapi/mgmapi.cpp | 4 ++-- ndb/src/ndbapi/Ndb.cpp | 4 ++-- ndb/src/ndbapi/NdbDictionaryImpl.cpp | 4 +--- ndb/src/ndbapi/TransporterFacade.cpp | 4 ++-- ndb/src/ndbapi/ndb_cluster_connection.cpp | 4 +++- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ndb/src/common/util/Bitmask.cpp b/ndb/src/common/util/Bitmask.cpp index 4169434483f..0aa39a37204 100644 --- a/ndb/src/common/util/Bitmask.cpp +++ b/ndb/src/common/util/Bitmask.cpp @@ -5,7 +5,7 @@ static void print(const Uint32 src[], Uint32 len, Uint32 pos = 0) { printf("b'"); - for(int i = 0; i> 5, src, i+pos)) printf("1"); diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index f4db8c8de7c..30b3e88bd82 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -4350,7 +4350,7 @@ Dbdict::execTAB_COMMITCONF(Signal* signal){ } tAttr = aRec->nextAttrInTable; } - ndbrequire(sz == 2 * tabPtr.p->noOfPrimkey); + ndbrequire((int)sz == 2 * tabPtr.p->noOfPrimkey); LinearSectionPtr lsPtr[3]; lsPtr[0].p = buf; diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp index e9c3027dfc0..f50d3a49df6 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp @@ -262,7 +262,7 @@ Dbtux::readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, Data keyData) debugOut << endl; totalSize += 1 + dataSize; } - ndbassert(totalSize == ret); + ndbassert((int)totalSize == ret); } #endif } diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 9825185f88b..2730ca0665b 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -314,8 +314,8 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow *command_reply, */ ndbout << "Error in mgm protocol parser. " << "cmd: '" << cmd - << "' status=" << ctx.m_status - << ", curr=" << ctx.m_currentToken + << "' status=" << (Uint32)ctx.m_status + << ", curr=" << (Uint32)ctx.m_currentToken << endl; DBUG_PRINT("info",("parser.parse returned NULL")); } diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index ba878ac4336..e7b36d6ee02 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -47,7 +47,7 @@ NdbTransaction* Ndb::doConnect(Uint32 tConNode) { Uint32 tNode; Uint32 tAnyAlive = 0; - int TretCode; + int TretCode= 0; if (tConNode != 0) { TretCode = NDB_connect(tConNode); @@ -892,7 +892,7 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op) DBUG_PRINT("enter", ("table=%u value=%llu op=%u", aTableId, opValue, op)); NdbTransaction* tConnection; - NdbOperation* tOperation; + NdbOperation* tOperation= 0; // Compiler warning if not initialized Uint64 tValue; NdbRecAttr* tRecAttrResult; int result; diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 4c53ac89461..583a153fc51 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -1361,9 +1361,7 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, } Uint32 topBit = (1 << 31); - for(i = 31; i>=0; i--){ - if((fragCount & topBit) != 0) - break; + for(; topBit && !(fragCount & topBit); ){ topBit >>= 1; } impl->m_hashValueMask = topBit - 1; diff --git a/ndb/src/ndbapi/TransporterFacade.cpp b/ndb/src/ndbapi/TransporterFacade.cpp index b179c1fe6b9..20d98c63a67 100644 --- a/ndb/src/ndbapi/TransporterFacade.cpp +++ b/ndb/src/ndbapi/TransporterFacade.cpp @@ -473,12 +473,12 @@ void TransporterFacade::threadMainReceive(void) } TransporterFacade::TransporterFacade(NdbMgmHandle mgm_handle) : + m_mgm_handle(mgm_handle), theTransporterRegistry(0), theStopReceive(0), theSendThread(NULL), theReceiveThread(NULL), - m_fragmented_signal_id(0), - m_mgm_handle(mgm_handle) + m_fragmented_signal_id(0) { theOwnId = 0; diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp index 2b3743e013a..0b41171e554 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -491,7 +491,9 @@ int Ndb_cluster_connection::connect(int no_retries, int retry_delay_in_seconds, m_impl.m_transporter_facade->start_instance(nodeId, props); m_impl.init_nodes_vector(nodeId, *props); - for(int i=0;iget_registry()->m_transporter_interface.size();i++) + for(unsigned i=0; + iget_registry()->m_transporter_interface.size(); + i++) ndb_mgm_set_connection_int_parameter(m_impl.m_config_retriever->get_mgmHandle(), nodeId, m_impl.m_transporter_facade->get_registry() From 6ed3ff49fc52f16f1996d93fe7d98318ad5b9730 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jan 2005 15:03:34 +0100 Subject: [PATCH 88/90] MgmtSrvr.cpp: corrected erroneous comparison boolean < 0 ndb/src/mgmsrv/MgmtSrvr.cpp: corrected erroneous comparison boolean < 0 --- ndb/src/mgmsrv/MgmtSrvr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 25d7a7ad07e..6c52747e222 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -2809,7 +2809,7 @@ MgmtSrvr::setConnectionDbParameter(int node1, ConfigValues::Iterator i2(_config->m_configValues->m_config, iter.m_config); - if(i2.set(param, (unsigned)value) < 0) { + if(i2.set(param, (unsigned)value) == false) { msg.assign("Unable to set new value of parameter"); return -1; } From 1c5dbc670b013d50460504b11d028ce294eeefb2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jan 2005 18:28:04 +0100 Subject: [PATCH 89/90] ndb - HugoCalculator, faster string generation ndb/test/src/HugoCalculator.cpp: Better handling of strings --- ndb/test/src/HugoCalculator.cpp | 86 +++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/ndb/test/src/HugoCalculator.cpp b/ndb/test/src/HugoCalculator.cpp index 8493388efbd..2fee787bbed 100644 --- a/ndb/test/src/HugoCalculator.cpp +++ b/ndb/test/src/HugoCalculator.cpp @@ -18,6 +18,22 @@ #include #include +static +Uint32 +myRand(Uint64 * seed) +{ + const Uint64 mul= 0x5deece66dull; + const Uint64 add= 0xb; + Uint64 loc_result = *seed * mul + add; + + * seed= loc_result; + return loc_result >> 1; +} + +static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + /* ************************************************************* * HugoCalculator * @@ -79,21 +95,23 @@ HugoCalculator::calcValue(int record, int updates, char* buf, int len) const { - unsigned seed; + Uint64 seed; const NdbDictionary::Column* attr = m_tab.getColumn(attrib); Uint32 val; do { if (attrib == m_idCol) { - *((Uint32*)buf)= record; + val= record; + memcpy(buf, &val, 4); return buf; } // If this is the update column if (attrib == m_updatesCol) { - *((Uint32*)buf)= updates; + val= updates; + memcpy(buf, &val, 4); return buf; } @@ -106,26 +124,13 @@ HugoCalculator::calcValue(int record, seed = record + attrib + updates; } } while (0); - val = rand_r(&seed); - + + val = myRand(&seed); + if(attr->getNullable() && (((val >> 16) & 255) > 220)) return NULL; - - memcpy(buf, &val, (len > 4 ? 4 : len)); - int pos= 4; - while(pos + 4 < len) - { - val= rand_r(&seed); - memcpy(buf+pos, &val, 4); - pos++; - } - - if(pos < len) - { - val= rand_r(&seed); - memcpy(buf+pos, &val, (len - pos)); - } + int pos= 0; switch(attr->getType()){ case NdbDictionary::Column::Tinyint: case NdbDictionary::Column::Tinyunsigned: @@ -144,15 +149,24 @@ HugoCalculator::calcValue(int record, case NdbDictionary::Column::Datetime: case NdbDictionary::Column::Time: case NdbDictionary::Column::Date: - break; case NdbDictionary::Column::Bit: - { - Uint32 bits= attr->getLength(); - Uint32 tmp = bits >> 5; - Uint32 size = bits & 31; - ((Uint32*)buf)[tmp] &= ((1 << size) - 1); + while (len > 4) + { + memcpy(buf+pos, &val, 4); + pos += 4; + len -= 4; + val= myRand(&seed); + } + + memcpy(buf+pos, &val, len); + if(attr->getType() == NdbDictionary::Column::Bit) + { + Uint32 bits= attr->getLength(); + Uint32 tmp = bits >> 5; + Uint32 size = bits & 31; + ((Uint32*)buf)[tmp] &= ((1 << size) - 1); + } break; - } case NdbDictionary::Column::Varbinary: case NdbDictionary::Column::Varchar: case NdbDictionary::Column::Text: @@ -160,9 +174,21 @@ HugoCalculator::calcValue(int record, case NdbDictionary::Column::Longvarchar: case NdbDictionary::Column::Longvarbinary: { - BaseString tmp; - base64_encode(buf, len, tmp); - memcpy(buf, tmp.c_str(), len); + char* ptr= (char*)&val; + while(len >= 4) + { + len -= 4; + buf[pos++] = base64_table[ptr[0] & 0x3f]; + buf[pos++] = base64_table[ptr[1] & 0x3f]; + buf[pos++] = base64_table[ptr[2] & 0x3f]; + buf[pos++] = base64_table[ptr[3] & 0x3f]; + val= myRand(&seed); + } + + for(; len; len--, pos++) + buf[pos] = base64_table[ptr[len] & 0x3f]; + + pos--; break; } case NdbDictionary::Column::Blob: From 4bd96dd11d1707589545c4f6ccd497490e647e63 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jan 2005 18:32:34 +0100 Subject: [PATCH 90/90] ndb - make sure scan recevier pointers are aligned ndb/src/ndbapi/NdbScanOperation.cpp: align pointers --- ndb/src/ndbapi/NdbScanOperation.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index a90c9f524a2..670a18f72a0 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -241,17 +241,17 @@ NdbScanOperation::fix_receivers(Uint32 parallel){ if(parallel > m_allocated_receivers){ const Uint32 sz = parallel * (4*sizeof(char*)+sizeof(Uint32)); - Uint32 * tmp = new Uint32[(sz+3)/4]; + Uint64 * tmp = new Uint64[(sz+7)/8]; // Save old receivers - memcpy(tmp+parallel, m_receivers, m_allocated_receivers*sizeof(char*)); + memcpy(tmp, m_receivers, m_allocated_receivers*sizeof(char*)); delete[] m_array; - m_array = tmp; + m_array = (Uint32*)tmp; - m_prepared_receivers = tmp; - m_receivers = (NdbReceiver**)(tmp + parallel); + m_receivers = (NdbReceiver**)tmp; m_api_receivers = m_receivers + parallel; m_conf_receivers = m_api_receivers + parallel; m_sent_receivers = m_conf_receivers + parallel; + m_prepared_receivers = (Uint32*)(m_sent_receivers + parallel); // Only get/init "new" receivers NdbReceiver* tScanRec;