diff options
85 files changed, 934 insertions, 344 deletions
diff --git a/.bzrignore b/.bzrignore index bfa4ef2058c..54a8c8fd03a 100644 --- a/.bzrignore +++ b/.bzrignore @@ -45,6 +45,19 @@ COPYING COPYING.LIB Docs/#manual.texi# Docs/INSTALL-BINARY +Docs/Images/myaccess-odbc.txt +Docs/Images/myaccess.txt +Docs/Images/myarchitecture.txt +Docs/Images/mydll-properties.txt +Docs/Images/mydsn-example.txt +Docs/Images/mydsn-icon.txt +Docs/Images/mydsn-options.txt +Docs/Images/mydsn-setup.txt +Docs/Images/mydsn-test-fail.txt +Docs/Images/mydsn-test-success.txt +Docs/Images/mydsn-trace.txt +Docs/Images/mydsn.txt +Docs/Images/myflowchart.txt Docs/include.texi Docs/internals.html Docs/internals.info @@ -88,7 +101,9 @@ Makefile.in Makefile.in' PENDING/* TAGS +ac_available_languages_fragment aclocal.m4 +analyse.test autom4te-2.53.cache/output.0 autom4te-2.53.cache/requests autom4te-2.53.cache/traces.0 @@ -241,6 +256,7 @@ client/mf_iocache.c client/mf_iocache.cc client/mysql client/mysqladmin +client/mysqladmin.c client/mysqlbinlog client/mysqlcheck client/mysqldump @@ -287,6 +303,7 @@ gmon.out hardcopy.0 heap/hp_test1 heap/hp_test2 +help help.c help.h include/my_config.h @@ -355,7 +372,9 @@ libmysqld/field_conv.cc libmysqld/filesort.cc libmysqld/get_password.c libmysqld/gstream.cc +libmysqld/ha_archive.cc libmysqld/ha_berkeley.cc +libmysqld/ha_example.cc libmysqld/ha_heap.cc libmysqld/ha_innobase.cc libmysqld/ha_innodb.cc @@ -363,6 +382,7 @@ libmysqld/ha_isam.cc libmysqld/ha_isammrg.cc libmysqld/ha_myisam.cc libmysqld/ha_myisammrg.cc +libmysqld/ha_tina.cc libmysqld/handler.cc libmysqld/hash_filo.cc libmysqld/hostname.cc @@ -492,15 +512,71 @@ myisam/test2.MYD myisam/test2.MYI mysql-4.0.2-alpha-pc-linux-gnu-i686.tar.gz mysql-4.0.2-alpha.tar.gz +mysql-4.1.8-win-src.zip mysql-max-4.0.2-alpha-pc-linux-gnu-i686.tar.gz mysql-test/gmon.out mysql-test/install_test_db mysql-test/mysql-test-run +mysql-test/mysql-test-run.log +mysql-test/mysql_test_run_new mysql-test/ndb/ndbcluster mysql-test/r/*.reject +mysql-test/r/alter_table.err +mysql-test/r/archive.err +mysql-test/r/bdb-alter-table-1.err +mysql-test/r/bdb-alter-table-2.err +mysql-test/r/bdb-crash.err +mysql-test/r/bdb-deadlock.err +mysql-test/r/bdb.err +mysql-test/r/bdb_cache.err +mysql-test/r/client_test.err +mysql-test/r/csv.err +mysql-test/r/ctype_ucs.err +mysql-test/r/derived.err +mysql-test/r/exampledb.err +mysql-test/r/func_encrypt.err +mysql-test/r/isam.err +mysql-test/r/lowercase_table2.err +mysql-test/r/multi_update.err +mysql-test/r/mysql_protocols.err +mysql-test/r/mysqlbinlog.err +mysql-test/r/mysqlbinlog2.err +mysql-test/r/mysqldump.err +mysql-test/r/mysqltest.err +mysql-test/r/ndb_alter_table.err +mysql-test/r/ndb_autodiscover.err +mysql-test/r/ndb_autodiscover2.err +mysql-test/r/ndb_basic.err +mysql-test/r/ndb_blob.err +mysql-test/r/ndb_cache.err +mysql-test/r/ndb_charset.err +mysql-test/r/ndb_index.err +mysql-test/r/ndb_index_ordered.err +mysql-test/r/ndb_index_unique.err +mysql-test/r/ndb_insert.err +mysql-test/r/ndb_limit.err +mysql-test/r/ndb_lock.err +mysql-test/r/ndb_minmax.err +mysql-test/r/ndb_replace.err +mysql-test/r/ndb_subquery.err +mysql-test/r/ndb_transaction.err +mysql-test/r/ndb_truncate.err +mysql-test/r/ndb_types.err +mysql-test/r/ndb_update.err +mysql-test/r/openssl_1.err +mysql-test/r/ps_1general.err +mysql-test/r/ps_6bdb.err +mysql-test/r/ps_7ndb.err +mysql-test/r/query_cache.err +mysql-test/r/query_cache_merge.err +mysql-test/r/raid.err +mysql-test/r/repair.err +mysql-test/r/replace.err +mysql-test/r/rpl000001.err mysql-test/r/rpl000001.eval mysql-test/r/rpl000002.eval mysql-test/r/rpl000014.eval +mysql-test/r/rpl000015.err mysql-test/r/rpl000015.eval mysql-test/r/rpl000016.eval mysql-test/r/rpl_log.eval @@ -641,6 +717,8 @@ ndb/examples/ndbapi_example2/ndbapi_example2 ndb/examples/ndbapi_example3/ndbapi_example3 ndb/examples/ndbapi_example5/ndbapi_example5 ndb/examples/select_all/select_all +ndb/include/ndb_global.h +ndb/include/ndb_version.h ndb/lib/libMGM_API.so ndb/lib/libNDB_API.so ndb/lib/libNDB_ODBC.so @@ -711,10 +789,25 @@ ndb/tools/ndb_delete_all ndb/tools/ndb_desc ndb/tools/ndb_drop_index ndb/tools/ndb_drop_table +ndb/tools/ndb_restore ndb/tools/ndb_select_all ndb/tools/ndb_select_count ndb/tools/ndb_show_tables +ndb/tools/ndb_test_platform ndb/tools/ndb_waiter +ndbcluster-1186 +ndbcluster-1186/SCCS +ndbcluster-1186/config.ini +ndbcluster-1186/ndb_1.pid +ndbcluster-1186/ndb_1_out.log +ndbcluster-1186/ndb_1_signal.log +ndbcluster-1186/ndb_2.pid +ndbcluster-1186/ndb_2_out.log +ndbcluster-1186/ndb_2_signal.log +ndbcluster-1186/ndb_3.pid +ndbcluster-1186/ndb_3_cluster.log +ndbcluster-1186/ndb_3_out.log +ndbcluster-1186/ndbcluster.pid pull.log regex/re repl-tests/test-repl-ts/repl-timestamp.master.reject @@ -909,96 +1002,3 @@ vio/test-ssl vio/test-sslclient vio/test-sslserver vio/viotest-ssl -Docs/Images/myaccess-odbc.txt -Docs/Images/myaccess.txt -Docs/Images/myarchitecture.txt -Docs/Images/mydll-properties.txt -Docs/Images/mydsn-example.txt -Docs/Images/mydsn-icon.txt -Docs/Images/mydsn-options.txt -Docs/Images/mydsn-setup.txt -Docs/Images/mydsn-test-fail.txt -Docs/Images/mydsn-test-success.txt -Docs/Images/mydsn-trace.txt -Docs/Images/mydsn.txt -Docs/Images/myflowchart.txt -mysql-test/mysql_test_run_new -ndb/tools/ndb_test_platform -help -ndbcluster-1186 -ndbcluster-1186/SCCS -ndbcluster-1186/config.ini -ndbcluster-1186/ndb_1.pid -ndbcluster-1186/ndb_1_out.log -ndbcluster-1186/ndb_1_signal.log -ndbcluster-1186/ndb_2.pid -ndbcluster-1186/ndb_2_out.log -ndbcluster-1186/ndb_2_signal.log -ndbcluster-1186/ndb_3.pid -ndbcluster-1186/ndb_3_cluster.log -ndbcluster-1186/ndb_3_out.log -ndbcluster-1186/ndbcluster.pid -ndb/tools/ndb_restore -ac_available_languages_fragment -libmysqld/ha_archive.cc -libmysqld/ha_example.cc -libmysqld/ha_tina.cc -analyse.test -client/mysqladmin.c -mysql-4.1.8-win-src.zip -ndb/include/ndb_version.h -ndb/include/ndb_global.h -mysql-test/mysql-test-run.log -mysql-test/r/alter_table.err -mysql-test/r/archive.err -mysql-test/r/bdb-alter-table-1.err -mysql-test/r/bdb-alter-table-2.err -mysql-test/r/bdb-crash.err -mysql-test/r/bdb-deadlock.err -mysql-test/r/bdb.err -mysql-test/r/bdb_cache.err -mysql-test/r/client_test.err -mysql-test/r/csv.err -mysql-test/r/ctype_ucs.err -mysql-test/r/derived.err -mysql-test/r/exampledb.err -mysql-test/r/func_encrypt.err -mysql-test/r/isam.err -mysql-test/r/lowercase_table2.err -mysql-test/r/multi_update.err -mysql-test/r/mysql_protocols.err -mysql-test/r/mysqlbinlog.err -mysql-test/r/mysqlbinlog2.err -mysql-test/r/mysqldump.err -mysql-test/r/mysqltest.err -mysql-test/r/ndb_alter_table.err -mysql-test/r/ndb_autodiscover.err -mysql-test/r/ndb_autodiscover2.err -mysql-test/r/ndb_basic.err -mysql-test/r/ndb_blob.err -mysql-test/r/ndb_cache.err -mysql-test/r/ndb_charset.err -mysql-test/r/ndb_index.err -mysql-test/r/ndb_index_ordered.err -mysql-test/r/ndb_index_unique.err -mysql-test/r/ndb_insert.err -mysql-test/r/ndb_limit.err -mysql-test/r/ndb_lock.err -mysql-test/r/ndb_minmax.err -mysql-test/r/ndb_replace.err -mysql-test/r/ndb_subquery.err -mysql-test/r/ndb_transaction.err -mysql-test/r/ndb_truncate.err -mysql-test/r/ndb_types.err -mysql-test/r/ndb_update.err -mysql-test/r/openssl_1.err -mysql-test/r/ps_1general.err -mysql-test/r/ps_6bdb.err -mysql-test/r/ps_7ndb.err -mysql-test/r/query_cache.err -mysql-test/r/query_cache_merge.err -mysql-test/r/raid.err -mysql-test/r/repair.err -mysql-test/r/replace.err -mysql-test/r/rpl000001.err -mysql-test/r/rpl000015.err 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); } diff --git a/configure.in b/configure.in index f2184ed7be5..45ca009123e 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 4.1.9) +AM_INIT_AUTOMAKE(mysql, 4.1.10) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 6fb27346a37..7090e8662f3 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -486,7 +486,7 @@ os_io_init_simple(void) } } -#ifndef UNIV_HOTBACKUP +#if !defined(UNIV_HOTBACKUP) && !defined(__NETWARE__) /************************************************************************* Creates a temporary file. This function is defined in ha_innodb.cc. */ @@ -494,7 +494,7 @@ int innobase_mysql_tmpfile(void); /*========================*/ /* out: temporary file descriptor, or < 0 on error */ -#endif /* !UNIV_HOTBACKUP */ +#endif /* !UNIV_HOTBACKUP && !__NETWARE__ */ /*************************************************************************** Creates a temporary file. */ @@ -504,9 +504,12 @@ os_file_create_tmpfile(void) /*========================*/ /* out: temporary file handle, or NULL on error */ { +#ifdef __NETWARE__ + FILE* file = tmpfile(); +#else /* __NETWARE__ */ FILE* file = NULL; int fd = -1; -#ifdef UNIV_HOTBACKUP +# ifdef UNIV_HOTBACKUP int tries; for (tries = 10; tries--; ) { char* name = tempnam(fil_path_to_mysql_datadir, "ib"); @@ -515,15 +518,15 @@ os_file_create_tmpfile(void) } fd = open(name, -# ifdef __WIN__ +# ifdef __WIN__ O_SEQUENTIAL | O_SHORT_LIVED | O_TEMPORARY | -# endif /* __WIN__ */ +# endif /* __WIN__ */ O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE); if (fd >= 0) { -# ifndef __WIN__ +# ifndef __WIN__ unlink(name); -# endif /* !__WIN__ */ +# endif /* !__WIN__ */ free(name); break; } @@ -534,22 +537,25 @@ os_file_create_tmpfile(void) name); free(name); } -#else /* UNIV_HOTBACKUP */ +# else /* UNIV_HOTBACKUP */ fd = innobase_mysql_tmpfile(); -#endif /* UNIV_HOTBACKUP */ +# endif /* UNIV_HOTBACKUP */ if (fd >= 0) { file = fdopen(fd, "w+b"); } +#endif /* __NETWARE__ */ if (!file) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Error: unable to create temporary file;" " errno: %d\n", errno); +#ifndef __NETWARE__ if (fd >= 0) { close(fd); } +#endif /* !__NETWARE__ */ } return(file); diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def index c9ff70f208d..c5579e9ec2b 100644 --- a/libmysql/libmysql.def +++ b/libmysql/libmysql.def @@ -146,3 +146,4 @@ EXPORTS mysql_rpl_query_type mysql_slave_query mysql_embedded + get_defaults_files diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def index 14c6725bcb5..ea3133594f5 100644 --- a/libmysqld/libmysqld.def +++ b/libmysqld/libmysqld.def @@ -157,3 +157,4 @@ EXPORTS mysql_stmt_attr_get mysql_stmt_attr_set mysql_stmt_field_count + get_defaults_files diff --git a/mysql-test/include/ctype_filesort.inc b/mysql-test/include/ctype_filesort.inc new file mode 100644 index 00000000000..2068463d4e2 --- /dev/null +++ b/mysql-test/include/ctype_filesort.inc @@ -0,0 +1,15 @@ +# +# Set desired charset_connection and collation_collation +# before including this file. +# + +# The next query creates a LONGTEXT column +# using the current character_set_connection +# and collation_connection. + +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; +drop table t1; diff --git a/mysql-test/r/ctype_big5.result b/mysql-test/r/ctype_big5.result index 9b9fcbccbe0..8f4ee3d0558 100644 --- a/mysql-test/r/ctype_big5.result +++ b/mysql-test/r/ctype_big5.result @@ -56,3 +56,24 @@ DROP DATABASE d1; USE test; SET character_set_server= @safe_character_set_server; SET collation_server= @safe_collation_server; +SET NAMES big5; +SET collation_connection='big5_chinese_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) +big5_chinese_ci 6109 +big5_chinese_ci 61 +big5_chinese_ci 6120 +drop table t1; +SET collation_connection='big5_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) +big5_bin 6109 +big5_bin 61 +big5_bin 6120 +drop table t1; diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result index 355f53b63a5..cd804939a75 100644 --- a/mysql-test/r/ctype_latin1.result +++ b/mysql-test/r/ctype_latin1.result @@ -305,3 +305,23 @@ select 'a' regexp 'A' collate latin1_general_cs; select 'a' regexp 'A' collate latin1_bin; 'a' regexp 'A' collate latin1_bin 0 +SET collation_connection='latin1_swedish_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) +latin1_swedish_ci 6109 +latin1_swedish_ci 61 +latin1_swedish_ci 6120 +drop table t1; +SET collation_connection='latin1_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) +latin1_bin 6109 +latin1_bin 61 +latin1_bin 6120 +drop table t1; diff --git a/mysql-test/r/ctype_latin1_de.result b/mysql-test/r/ctype_latin1_de.result index 50af5464f54..6df9d963498 100644 --- a/mysql-test/r/ctype_latin1_de.result +++ b/mysql-test/r/ctype_latin1_de.result @@ -317,3 +317,12 @@ FIELD('ue',s1) FIELD('Ü',s1) s1='ue' s1='Ü' 1 1 1 1 1 1 1 1 DROP TABLE t1; +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) +latin1_german2_ci 6109 +latin1_german2_ci 61 +latin1_german2_ci 6120 +drop table t1; diff --git a/mysql-test/r/ctype_sjis.result b/mysql-test/r/ctype_sjis.result index 944fa0602a9..1f414f89e20 100644 --- a/mysql-test/r/ctype_sjis.result +++ b/mysql-test/r/ctype_sjis.result @@ -71,3 +71,23 @@ B1 B2 B3 drop table t1; +SET collation_connection='sjis_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) +sjis_japanese_ci 6109 +sjis_japanese_ci 61 +sjis_japanese_ci 6120 +drop table t1; +SET collation_connection='sjis_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) +sjis_bin 6109 +sjis_bin 61 +sjis_bin 6120 +drop table t1; diff --git a/mysql-test/r/ctype_tis620.result b/mysql-test/r/ctype_tis620.result index fa99c2d1318..6d8bfe74c4b 100644 --- a/mysql-test/r/ctype_tis620.result +++ b/mysql-test/r/ctype_tis620.result @@ -2937,3 +2937,23 @@ Screensaver 2 2002-01-22 491 0 519 0 0 3 http://www.siamzone.com/download/download/000003-jasonx2(800x600).jpg Jaso n X Wallpapers 1 2002-05-31 579 0 1091 0 0 DROP TABLE t1; +SET collation_connection='tis620_thai_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) +tis620_thai_ci 6109 +tis620_thai_ci 61 +tis620_thai_ci 6120 +drop table t1; +SET collation_connection='tis620_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) +tis620_bin 6109 +tis620_bin 61 +tis620_bin 6120 +drop table t1; diff --git a/mysql-test/r/ctype_uca.result b/mysql-test/r/ctype_uca.result index 0573092e39b..dd5a7ebf6a4 100644 --- a/mysql-test/r/ctype_uca.result +++ b/mysql-test/r/ctype_uca.result @@ -2386,3 +2386,13 @@ a 1 b 0 c 0 drop table t1; +SET collation_connection='utf8_unicode_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) +utf8_unicode_ci 6109 +utf8_unicode_ci 61 +utf8_unicode_ci 6120 +drop table t1; diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index b1b83eb8b6c..47211e67905 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -592,3 +592,24 @@ a NULL b NULL c NULL drop table t1; +SET collation_connection='ucs2_general_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) +ucs2_general_ci 00610009 +ucs2_general_ci 0061 +ucs2_general_ci 00610020 +drop table t1; +SET NAMES latin1; +SET collation_connection='ucs2_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) +ucs2_bin 00610009 +ucs2_bin 0061 +ucs2_bin 00610020 +drop table t1; diff --git a/mysql-test/r/ctype_ujis.result b/mysql-test/r/ctype_ujis.result index aa4c347d54f..fd6c501499b 100644 --- a/mysql-test/r/ctype_ujis.result +++ b/mysql-test/r/ctype_ujis.result @@ -2207,3 +2207,23 @@ F4FC F4FD F4FE DROP TABLE t1; +SET collation_connection='ujis_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) +ujis_japanese_ci 6109 +ujis_japanese_ci 61 +ujis_japanese_ci 6120 +drop table t1; +SET collation_connection='ujis_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) +ujis_bin 6109 +ujis_bin 61 +ujis_bin 6120 +drop table t1; diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index ebaa329891c..f62d754392b 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -412,7 +412,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c` char(10) character set utf8 default NULL, - UNIQUE KEY `a` (`c`(1)) + UNIQUE KEY `a` TYPE HASH (`c`(1)) ) ENGINE=HEAP DEFAULT CHARSET=latin1 insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); insert into t1 values ('aa'); @@ -570,7 +570,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c` char(10) character set utf8 collate utf8_bin default NULL, - UNIQUE KEY `a` (`c`(1)) + UNIQUE KEY `a` TYPE HASH (`c`(1)) ) ENGINE=HEAP DEFAULT CHARSET=latin1 insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); insert into t1 values ('aa'); @@ -829,3 +829,23 @@ select * from t1 where soundex(a) = soundex('test'); id a 1 Test drop table t1; +SET collation_connection='utf8_general_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) +utf8_general_ci 6109 +utf8_general_ci 61 +utf8_general_ci 6120 +drop table t1; +SET collation_connection='utf8_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) +utf8_bin 6109 +utf8_bin 61 +utf8_bin 6120 +drop table t1; diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result index 8b919964163..223ceb003b3 100644 --- a/mysql-test/r/drop.result +++ b/mysql-test/r/drop.result @@ -1,5 +1,6 @@ drop table if exists t1; drop database if exists mysqltest; +drop database if exists client_test_db; drop table t1; ERROR 42S02: Unknown table 't1' create table t1(n int); 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/r/ps_1general.result b/mysql-test/r/ps_1general.result index 25b9e2dcda4..ee3eca850f4 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -291,7 +291,7 @@ execute stmt4; prepare stmt4 from ' show full processlist '; execute stmt4; Id User Host db Command Time State Info -number root localhost test Query 0 NULL show full processlist +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/show_check.result b/mysql-test/r/show_check.result index 0afe45eb5e5..37531f05f43 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -405,3 +405,73 @@ where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3'; delete from mysql.db where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3'; flush privileges; +CREATE TABLE t1 (i int, KEY (i)) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` (`i`) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING HASH (i)) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` TYPE HASH (`i`) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` TYPE BTREE (`i`) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` TYPE BTREE (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +ALTER TABLE t1 ENGINE=MEMORY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` (`i`) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` TYPE BTREE (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +ALTER TABLE t1 ENGINE=MEMORY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` TYPE BTREE (`i`) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 9dd92c13c98..530eb32f77d 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -179,3 +179,18 @@ f 9.999 9.999 drop table if exists t1; +create table t1 (c char(20)); +insert into t1 values (5e-28); +select * from t1; +c +5e-28 +drop table t1; +create table t1 (c char(6)); +insert into t1 values (2e5),(2e6),(2e-4),(2e-5); +select * from t1; +c +200000 +2e+06 +0.0002 +2e-05 +drop table t1; diff --git a/mysql-test/r/type_float.result.es b/mysql-test/r/type_float.result.es index 64d9be7e30f..b93539b6bea 100644 --- a/mysql-test/r/type_float.result.es +++ b/mysql-test/r/type_float.result.es @@ -179,3 +179,18 @@ f 9.999 9.999 drop table if exists t1; +create table t1 (c char(20)); +insert into t1 values (5e-28); +select * from t1; +c +5e-28 +drop table t1; +create table t1 (c char(6)); +insert into t1 values (2e5),(2e6),(2e-4),(2e-5); +select * from t1; +c +200000 +2e+06 +0.0002 +2e-05 +drop table t1; 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/analyse.test b/mysql-test/t/analyse.test index 34343c2b7bf..52e367769a2 100644 --- a/mysql-test/t/analyse.test +++ b/mysql-test/t/analyse.test @@ -38,6 +38,11 @@ select * from t2; insert into t2 select * from t1 procedure analyse(); select * from t2; drop table t1,t2; + +# +# Bug#2813 - analyse does not quote string values in enums from string +# + create table t1 (v varchar(128)); insert into t1 values ('abc'),('abc\'def\\hij\"klm\0opq'),('\''),('\"'),('\\'),('a\0'),('b\''),('c\"'),('d\\'),('\'b'),('\"c'),('\\d'),('a\0\0\0b'),('a\'\'\'\'b'),('a\"\"\"\"b'),('a\\\\\\\\b'),('\'\0\\\"'),('\'\''),('\"\"'),('\\\\'),('The\ZEnd'); select * from t1 procedure analyse(); diff --git a/mysql-test/t/ctype_big5.test b/mysql-test/t/ctype_big5.test index b1d71a6af15..8b75123ca32 100644 --- a/mysql-test/t/ctype_big5.test +++ b/mysql-test/t/ctype_big5.test @@ -10,3 +10,9 @@ drop table if exists t1; SET @test_character_set= 'big5'; SET @test_collation= 'big5_chinese_ci'; -- source include/ctype_common.inc + +SET NAMES big5; +SET collation_connection='big5_chinese_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='big5_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_latin1.test b/mysql-test/t/ctype_latin1.test index 677acd9faa9..cee0324d12f 100644 --- a/mysql-test/t/ctype_latin1.test +++ b/mysql-test/t/ctype_latin1.test @@ -60,3 +60,9 @@ DROP TABLE t1; select 'a' regexp 'A' collate latin1_general_ci; select 'a' regexp 'A' collate latin1_general_cs; select 'a' regexp 'A' collate latin1_bin; + + +SET collation_connection='latin1_swedish_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='latin1_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_latin1_de.test b/mysql-test/t/ctype_latin1_de.test index 1c9576c1c56..ce4fdc4e3c9 100644 --- a/mysql-test/t/ctype_latin1_de.test +++ b/mysql-test/t/ctype_latin1_de.test @@ -114,3 +114,5 @@ SELECT s1,COUNT(*) FROM t1 GROUP BY s1; SELECT COUNT(DISTINCT s1) FROM t1; SELECT FIELD('ue',s1), FIELD('Ü',s1), s1='ue', s1='Ü' FROM t1; DROP TABLE t1; + +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_sjis.test b/mysql-test/t/ctype_sjis.test index a3a44789975..58ca3c6a997 100644 --- a/mysql-test/t/ctype_sjis.test +++ b/mysql-test/t/ctype_sjis.test @@ -62,3 +62,9 @@ CREATE TABLE t1 ( insert into t1 values(0xb1),(0xb2),(0xb3); select hex(c) from t1; drop table t1; + + +SET collation_connection='sjis_japanese_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='sjis_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_tis620.test b/mysql-test/t/ctype_tis620.test index 21ec314dca7..87047db9b54 100644 --- a/mysql-test/t/ctype_tis620.test +++ b/mysql-test/t/ctype_tis620.test @@ -151,3 +151,9 @@ INSERT INTO t1 VALUES n X Wallpapers',1,'','2002-05-31','',579,0,'',1091,0,0,''); select * from t1 order by id; DROP TABLE t1; + + +SET collation_connection='tis620_thai_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='tis620_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_uca.test b/mysql-test/t/ctype_uca.test index 8bca2a4b3c2..dfca82fa70a 100644 --- a/mysql-test/t/ctype_uca.test +++ b/mysql-test/t/ctype_uca.test @@ -452,3 +452,6 @@ create table t1 (a varchar(1)) character set utf8 collate utf8_estonian_ci; insert into t1 values ('A'),('B'),('C'),('a'),('b'),('c'); select a, a regexp '[a]' from t1 order by binary a; drop table t1; + +SET collation_connection='utf8_unicode_ci'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index b9f77505446..1a0ba82d6ff 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -384,3 +384,9 @@ alter table t1 add b char(1); show warnings; select * from t1 order by a; drop table t1; + +SET collation_connection='ucs2_general_ci'; +-- source include/ctype_filesort.inc +SET NAMES latin1; +SET collation_connection='ucs2_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_ujis.test b/mysql-test/t/ctype_ujis.test index 3f0e9882179..407287be30a 100644 --- a/mysql-test/t/ctype_ujis.test +++ b/mysql-test/t/ctype_ujis.test @@ -1141,3 +1141,9 @@ INSERT INTO t1 VALUES(0xF4FD); INSERT INTO t1 VALUES(0xF4FE); SELECT HEX(c) FROM t1 ORDER BY BINARY c; DROP TABLE t1; + + +SET collation_connection='ujis_japanese_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='ujis_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 214c2712665..a57db4455ab 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -675,3 +675,9 @@ select * from t1 where soundex(a) = soundex('Test'); select * from t1 where soundex(a) = soundex('TEST'); select * from t1 where soundex(a) = soundex('test'); drop table t1; + + +SET collation_connection='utf8_general_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='utf8_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test index 88c47803f48..6f0e5b3f14c 100644 --- a/mysql-test/t/drop.test +++ b/mysql-test/t/drop.test @@ -2,6 +2,8 @@ --disable_warnings drop table if exists t1; drop database if exists mysqltest; +# If earlier test failed +drop database if exists client_test_db; --enable_warnings --error 1051; 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/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 4035099ec7e..4a7367a333c 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -5,9 +5,9 @@ --disable_warnings drop table if exists t1,t2,t3; drop database if exists mysqltest; ---error 0,1141 +--error 0,1141,1147 revoke all privileges on mysqltest.t1 from mysqltest_1@localhost; ---error 0,1141 +--error 0,1141,1147 revoke all privileges on mysqltest.* from mysqltest_1@localhost; delete from mysql.user where user=_binary'mysqltest_1'; --enable_warnings diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test index 08c1ad85fb1..d9cc9de6ff1 100644 --- a/mysql-test/t/ps_1general.test +++ b/mysql-test/t/ps_1general.test @@ -317,7 +317,7 @@ prepare stmt4 from ' show engine bdb logs '; execute stmt4; --enable_result_log prepare stmt4 from ' show full processlist '; ---replace_column 1 number +--replace_column 1 number 6 time execute stmt4; prepare stmt4 from ' show grants for user '; --error 1295 diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 7788215dd27..cd8d4dba6ab 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -321,3 +321,35 @@ flush privileges; #--replace_column 7 # 8 # 9 # #show table status from `ä` LIKE 'ä'; #drop database `ä`; + +# Test that USING <keytype> is always shown in SHOW CREATE TABLE when it was +# specified during table creation, but not otherwise. (Bug #7235) +CREATE TABLE t1 (i int, KEY (i)) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING HASH (i)) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +DROP TABLE t1; +# Test that when an index is created with the default key algorithm and +# altered to another storage engine, it gets the default key algorithm +# for that storage engine, but when it is specified, the specified type is +# preserved. +CREATE TABLE t1 (i int, KEY (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +ALTER TABLE t1 ENGINE=MEMORY; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +ALTER TABLE t1 ENGINE=MEMORY; +SHOW CREATE TABLE t1; +DROP TABLE t1; diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 3fe3afa3fac..69cdeaa32a9 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -103,3 +103,13 @@ create table t1 (f double(4,3)); insert into t1 values (-11.0),(-11),("-11"),(11.0),(11),("11"); select * from t1; drop table if exists t1; + +# Check conversion of floats to character field (Bug #7774) +create table t1 (c char(20)); +insert into t1 values (5e-28); +select * from t1; +drop table t1; +create table t1 (c char(6)); +insert into t1 values (2e5),(2e6),(2e-4),(2e-5); +select * from t1; +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/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp index 8e1cba24359..0f0e6d61f41 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp @@ -632,14 +632,11 @@ void Dbtup::execREAD_CONFIG_REQ(Signal* signal) ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_FRAG, &cnoOfFragrec)); ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_OP_RECS, &cnoOfOprec)); - - // MemorySpaceTuples is specified in 8k pages, divide by 4 for 32k pages - Uint32 tmp; - ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE, &tmp)); - Uint64 pages = (tmp * 2048 + (ZWORDS_ON_PAGE - 1))/ (Uint64)ZWORDS_ON_PAGE; - cnoOfPage = (Uint32)pages; + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE, &cnoOfPage)); Uint32 noOfTriggers= 0; + Uint32 tmp= 0; ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE_RANGE, &tmp)); initPageRangeSize(tmp); ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_TABLE, &cnoOfTablerec)); diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp index 29255fc9837..4ad7050ce63 100644 --- a/ndb/src/kernel/vm/Configuration.cpp +++ b/ndb/src/kernel/vm/Configuration.cpp @@ -521,7 +521,7 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); } - noOfDataPages = (dataMem / 8192); + noOfDataPages = (dataMem / 32768); noOfIndexPages = (indexMem / 8192); for(unsigned j = 0; j<LogLevel::LOGLEVEL_CATEGORIES; j++){ diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index 800ffe2e361..fa77bc14762 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -98,6 +98,7 @@ static bool fixDepricated(InitConfigFileParser::Context & ctx, const char *); static bool saveInConfigValues(InitConfigFileParser::Context & ctx, const char *); static bool fixFileSystemPath(InitConfigFileParser::Context & ctx, const char * data); static bool fixBackupDataDir(InitConfigFileParser::Context & ctx, const char * data); +static bool fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data); const ConfigInfo::SectionRule ConfigInfo::m_SectionRules[] = { @@ -111,6 +112,8 @@ ConfigInfo::m_SectionRules[] = { { "REP", transformNode, 0 }, { "EXTERNAL REP", transformExtNode, 0 }, + { MGM_TOKEN, fixShmUniqueId, 0 }, + { "TCP", checkConnectionSupport, 0 }, { "SHM", checkConnectionSupport, 0 }, { "SCI", checkConnectionSupport, 0 }, @@ -3155,19 +3158,39 @@ fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){ DBUG_RETURN(true); } +static bool +fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data) +{ + DBUG_ENTER("fixShmUniqueId"); + Uint32 nodes= 0; + ctx.m_userProperties.get(ctx.fname, &nodes); + if (nodes == 1) // first management server + { + Uint32 portno= atoi(NDB_PORT); + ctx.m_currentSection->get("PortNumber", &portno); + ctx.m_userProperties.put("ShmUniqueId", portno); + } + DBUG_RETURN(true); +} + static bool fixShmKey(InitConfigFileParser::Context & ctx, const char *) { + DBUG_ENTER("fixShmKey"); Uint32 id1= 0, id2= 0, key= 0; require(ctx.m_currentSection->get("NodeId1", &id1)); require(ctx.m_currentSection->get("NodeId2", &id2)); if(ctx.m_currentSection->get("ShmKey", &key)) - return true; + { + DBUG_RETURN(true); + } - key= (id1 > id2 ? id1 << 16 | id2 : id2 << 16 | id1); + require(ctx.m_userProperties.get("ShmUniqueId", &key)); + key= key << 16 | (id1 > id2 ? id1 << 8 | id2 : id2 << 8 | id1); ctx.m_currentSection->put("ShmKey", key); - return true; + DBUG_PRINT("info",("Added ShmKey=0x%x", key)); + DBUG_RETURN(true); } /** diff --git a/scripts/mysqlaccess.sh b/scripts/mysqlaccess.sh index 9fd1f63f67a..654b43a8a99 100644 --- a/scripts/mysqlaccess.sh +++ b/scripts/mysqlaccess.sh @@ -2,7 +2,7 @@ # **************************** package MySQLaccess; #use strict; -use POSIX qw(tmpnam); +use File::Temp qw(tempfile tmpnam); use Fcntl; BEGIN { @@ -32,7 +32,6 @@ BEGIN { $ACCESS_U_BCK = 'user_backup'; $ACCESS_D_BCK = 'db_backup'; $DIFF = '/usr/bin/diff'; - $TMP_PATH = '/tmp'; #path to writable tmp-directory $MYSQLDUMP = '@bindir@/mysqldump'; #path to mysqldump executable @@ -431,7 +430,7 @@ use IPC::Open3; # no caching on STDOUT $|=1; - $MYSQL_CNF = POSIX::tmpnam(); + $MYSQL_CNF = tmpnam(); %MYSQL_CNF = (client => { }, mysql => { }, mysqldump => { }, @@ -576,8 +575,6 @@ if (!defined($Param{'host'})) { $Param{'host'}='localhost'; } push(@MySQLaccess::Grant::Error,'not_found_mysql') if !(-x $MYSQL); push(@MySQLaccess::Grant::Error,'not_found_diff') if !(-x $DIFF); push(@MySQLaccess::Grant::Error,'not_found_mysqldump') if !(-x $MYSQLDUMP); -push(@MySQLaccess::Grant::Error,'not_found_tmp') if !(-d $TMP_PATH); -push(@MySQLaccess::Grant::Error,'write_err_tmp') if !(-w $TMP_PATH); if (@MySQLaccess::Grant::Error) { MySQLaccess::Report::Print_Error_Messages() ; exit 0; @@ -1776,17 +1773,15 @@ sub Diff_Privileges { @before = sort(@before); @after = sort(@after); - $before = "$MySQLaccess::TMP_PATH/$MySQLaccess::script.before.$$"; - $after = "$MySQLaccess::TMP_PATH/$MySQLaccess::script.after.$$"; - #$after = "/tmp/t0"; - open(BEFORE,"> $before") || - push(@MySQLaccess::Report::Errors,"Can't open temporary file $before for writing"); - open(AFTER,"> $after") || - push(@MySQLaccess::Report::Errors,"Can't open temporary file $after for writing"); - print BEFORE join("\n",@before); - print AFTER join("\n",@after); - close(BEFORE); - close(AFTER); + ($hb, $before) = tempfile("$MySQLaccess::script.XXXXXX") or + push(@MySQLaccess::Report::Errors,"Can't create temporary file: $!"); + ($ha, $after) = tempfile("$MySQLaccess::script.XXXXXX") or + push(@MySQLaccess::Report::Errors,"Can't create temporary file: $!"); + + print $hb join("\n",@before); + print $ha join("\n",@after); + close $hb; + close $ha; # ---------------------------------- # compute difference @@ -1799,8 +1794,8 @@ sub Diff_Privileges { # ---------------------------------- # cleanup temp. files - unlink(BEFORE); - unlink(AFTER); + unlink($before); + unlink($after); return \@diffs; } @@ -2315,14 +2310,6 @@ BEGIN { => "The diff program <$MySQLaccess::DIFF> could not be found.\n" ."+ Check your path, or\n" ."+ edit the source of this script to point \$DIFF to the diff program.\n" - ,'not_found_tmp' - => "The temporary directory <$MySQLaccess::TMP_PATH> could not be found.\n" - ."+ create this directory (writeable!), or\n" - ."+ edit the source of this script to point \$TMP_PATH to the right directory.\n" - ,'write_err_tmp' - => "The temporary directory <$MySQLaccess::TMP_PATH> is not writable.\n" - ."+ make this directory writeable!, or\n" - ."+ edit the source of this script to point \$TMP_PATH to another directory.\n" ,'Unrecognized_option' => "Sorry,\n" ."You are using an old version of the mysql-program,\n" diff --git a/sql/field.cc b/sql/field.cc index e2c11cc7372..7357bc06f11 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4301,13 +4301,20 @@ int Field_str::store(double nr) char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; uint length; bool use_scientific_notation= TRUE; - use_scientific_notation= TRUE; - if (field_length < 32 && fabs(nr) < log_10[field_length]-1) + /* + Check fabs(nr) against longest value that can be stored in field, + which depends on whether the value is < 1 or not, and negative or not + */ + double anr= fabs(nr); + int neg= (nr < 0.0) ? 1 : 0; + if (field_length > 4 && field_length < 32 && + (anr < 1.0 ? anr > 1/(log_10[max(0,field_length-neg-2)]) /* -2 for "0." */ + : anr < log_10[field_length-neg]-1)) use_scientific_notation= FALSE; length= (uint) my_sprintf(buff, (buff, "%-.*g", (use_scientific_notation ? - max(0, (int)field_length-5) : + max(0, (int)field_length-neg-5) : field_length), nr)); /* @@ -4393,8 +4400,7 @@ void Field_string::sort_string(char *to,uint length) uint tmp=my_strnxfrm(field_charset, (unsigned char *) to, length, (unsigned char *) ptr, field_length); - if (tmp < length) - field_charset->cset->fill(field_charset, to + tmp, length - tmp, ' '); + DBUG_ASSERT(tmp == length); } @@ -4596,9 +4602,7 @@ void Field_varstring::sort_string(char *to,uint length) (uchar*) to, length, (uchar*) ptr+HA_KEY_BLOB_LENGTH, tot_length); - if (tot_length < length) - field_charset->cset->fill(field_charset, to+tot_length,length-tot_length, - binary() ? (char) 0 : ' '); + DBUG_ASSERT(tot_length == length); } @@ -5116,10 +5120,7 @@ void Field_blob::sort_string(char *to,uint length) blob_length=my_strnxfrm(field_charset, (uchar*) to, length, (uchar*) blob, blob_length); - if (blob_length < length) - field_charset->cset->fill(field_charset, to+blob_length, - length-blob_length, - binary() ? (char) 0 : ' '); + DBUG_ASSERT(blob_length == length); } } diff --git a/sql/filesort.cc b/sql/filesort.cc index bd0de022fd4..cb377070aaa 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -622,10 +622,7 @@ static void make_sortkey(register SORTPARAM *param, } uint tmp_length=my_strnxfrm(cs,to,sort_field->length, (unsigned char *) from, length); - if (tmp_length < sort_field->length) - cs->cset->fill(cs, (char*) to+tmp_length, - sort_field->length-tmp_length, - fill_char); + DBUG_ASSERT(tmp_length == sort_field->length); } else { diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 2c7cce4bcd0..e33cd3fca1b 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -165,11 +165,13 @@ bool berkeley_init(void) { db_env->close(db_env,0); /* purecov: inspected */ db_env=0; /* purecov: inspected */ + goto err; } (void) hash_init(&bdb_open_tables,system_charset_info,32,0,0, (hash_get_key) bdb_get_key,0,0); pthread_mutex_init(&bdb_mutex,MY_MUTEX_INIT_FAST); +err: DBUG_RETURN(db_env == 0); } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index f82b9c03505..502f8eb92f3 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -5267,7 +5267,9 @@ ha_innobase::store_lock( if ((lock_type == TL_READ && thd->in_lock_tables) || (lock_type == TL_READ_HIGH_PRIORITY && thd->in_lock_tables) || lock_type == TL_READ_WITH_SHARED_LOCKS || - lock_type == TL_READ_NO_INSERT) { + lock_type == TL_READ_NO_INSERT || + thd->lex->sql_command != SQLCOM_SELECT) { + /* The OR cases above are in this order: 1) MySQL is doing LOCK TABLES ... READ LOCAL, or 2) (we do not know when TL_READ_HIGH_PRIORITY is used), or @@ -5275,7 +5277,10 @@ ha_innobase::store_lock( 4) we are doing a complex SQL statement like INSERT INTO ... SELECT ... and the logical logging (MySQL binlog) requires the use of a locking read, or - MySQL is doing LOCK TABLES ... READ. */ + MySQL is doing LOCK TABLES ... READ. + 5) we let InnoDB do locking reads for all SQL statements that + are not simple SELECTs; note that select_lock_type in this + case may get strengthened in ::external_lock() to LOCK_X. */ prebuilt->select_lock_type = LOCK_S; prebuilt->stored_select_lock_type = LOCK_S; 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, diff --git a/sql/log_event.cc b/sql/log_event.cc index c027c3a8ee4..04395f121fd 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1418,7 +1418,7 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex, const char *db_arg, const char *table_name_arg, List<Item> &fields_arg, enum enum_duplicates handle_dup, - bool using_trans) + bool ignore, bool using_trans) :Log_event(thd_arg, !thd_arg->tmp_table_used ? 0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans), thread_id(thd_arg->thread_id), @@ -1456,9 +1456,6 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex, sql_ex.empty_flags= 0; switch (handle_dup) { - case DUP_IGNORE: - sql_ex.opt_flags|= IGNORE_FLAG; - break; case DUP_REPLACE: sql_ex.opt_flags|= REPLACE_FLAG; break; @@ -1466,6 +1463,8 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex, case DUP_ERROR: break; } + if (ignore) + sql_ex.opt_flags|= IGNORE_FLAG; if (!ex->field_term->length()) sql_ex.empty_flags |= FIELD_TERM_EMPTY; @@ -1791,6 +1790,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, { char llbuff[22]; enum enum_duplicates handle_dup; + bool ignore= 0; /* Make a simplified LOAD DATA INFILE query, for the information of the user in SHOW PROCESSLIST. Note that db is known in the 'db' column. @@ -1807,21 +1807,24 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, if (sql_ex.opt_flags & REPLACE_FLAG) handle_dup= DUP_REPLACE; else if (sql_ex.opt_flags & IGNORE_FLAG) - handle_dup= DUP_IGNORE; + { + ignore= 1; + handle_dup= DUP_ERROR; + } else { /* When replication is running fine, if it was DUP_ERROR on the - master then we could choose DUP_IGNORE here, because if DUP_ERROR + master then we could choose IGNORE here, because if DUP_ERROR suceeded on master, and data is identical on the master and slave, - then there should be no uniqueness errors on slave, so DUP_IGNORE is + then there should be no uniqueness errors on slave, so IGNORE is the same as DUP_ERROR. But in the unlikely case of uniqueness errors (because the data on the master and slave happen to be different (user error or bug), we want LOAD DATA to print an error message on the slave to discover the problem. If reading from net (a 3.23 master), mysql_load() will change this - to DUP_IGNORE. + to IGNORE. */ handle_dup= DUP_ERROR; } @@ -1855,7 +1858,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, */ thd->net.pkt_nr = net->pkt_nr; } - if (mysql_load(thd, &ex, &tables, field_list, handle_dup, net != 0, + if (mysql_load(thd, &ex, &tables, field_list, handle_dup, ignore, net != 0, TL_WRITE)) thd->query_error = 1; if (thd->cuted_fields) @@ -2747,8 +2750,9 @@ Create_file_log_event:: Create_file_log_event(THD* thd_arg, sql_exchange* ex, const char* db_arg, const char* table_name_arg, List<Item>& fields_arg, enum enum_duplicates handle_dup, + bool ignore, char* block_arg, uint block_len_arg, bool using_trans) - :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, + :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore, using_trans), fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg), file_id(thd_arg->file_id = mysql_bin_log.next_file_id()) diff --git a/sql/log_event.h b/sql/log_event.h index 8a2334e8574..f848f2ae1b9 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -599,7 +599,7 @@ public: Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg, const char* table_name_arg, - List<Item>& fields_arg, enum enum_duplicates handle_dup, + List<Item>& fields_arg, enum enum_duplicates handle_dup, bool ignore, bool using_trans); void set_fields(const char* db, List<Item> &fields_arg); const char* get_db() { return db; } @@ -908,7 +908,7 @@ public: Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg, const char* table_name_arg, List<Item>& fields_arg, - enum enum_duplicates handle_dup, + enum enum_duplicates handle_dup, bool ignore, char* block_arg, uint block_len_arg, bool using_trans); #ifdef HAVE_REPLICATION diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c300ea2885e..4b785aafc5f 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -538,6 +538,7 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name, List<Key> &keys, uint order_num, ORDER *order, enum enum_duplicates handle_duplicates, + bool ignore, ALTER_INFO *alter_info, bool do_send_ok=1); int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok); int mysql_create_like_table(THD *thd, TABLE_LIST *table, @@ -557,11 +558,11 @@ int mysql_prepare_update(THD *thd, TABLE_LIST *table_list, int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields, List<Item> &values,COND *conds, uint order_num, ORDER *order, ha_rows limit, - enum enum_duplicates handle_duplicates); + enum enum_duplicates handle_duplicates, bool ignore); int mysql_multi_update(THD *thd, TABLE_LIST *table_list, List<Item> *fields, List<Item> *values, COND *conds, ulong options, - enum enum_duplicates handle_duplicates, + enum enum_duplicates handle_duplicates, bool ignore, SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex); int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE_LIST *insert_table_list, TABLE *table, @@ -570,7 +571,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, List<Item> &update_values, enum_duplicates duplic); int mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields, List<List_item> &values, List<Item> &update_fields, - List<Item> &update_values, enum_duplicates flag); + List<Item> &update_values, enum_duplicates flag, bool ignore); int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds); int mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, SQL_LIST *order, ha_rows rows, ulong options); @@ -724,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, @@ -759,6 +761,7 @@ bool eval_const_cond(COND *cond); /* sql_load.cc */ int mysql_load(THD *thd,sql_exchange *ex, TABLE_LIST *table_list, List<Item> &fields, enum enum_duplicates handle_duplicates, + bool ignore, bool local_file,thr_lock_type lock_type); int write_record(TABLE *table,COPY_INFO *info); diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 5265857f3b1..33ce62bc5cf 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -1029,20 +1029,19 @@ uint check_ulonglong(const char *str, uint length) } /* check_ulonlong */ - /* - FUNCTION: append_escaped() - + Quote special characters in a string. + + SYNOPSIS + append_escaped(to_str, from_str) + to_str (in) A pointer to a String. + from_str (to) A pointer to an allocated string + DESCRIPTION append_escaped() takes a String type variable, where it appends escaped the second argument. Only characters that require escaping will be escaped. - ARGUMENTS - A pointer to a String variable, where results will be appended - A pointer to a String variable, which is appended to the result - String, escaping those characters that require it. - RETURN VALUES 0 Success 1 Out of memory 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 @@ -1703,6 +1703,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_class.h b/sql/sql_class.h index 7978aec8f1d..ce60ed06cfd 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -29,7 +29,7 @@ class Slave_log_event; enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE }; enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME }; -enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_IGNORE, DUP_UPDATE }; +enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE }; enum enum_log_type { LOG_CLOSED, LOG_TO_BE_OPENED, LOG_NORMAL, LOG_NEW, LOG_BIN}; enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, DELAY_KEY_WRITE_ALL }; @@ -201,7 +201,8 @@ typedef struct st_copy_info { ha_rows error_count; enum enum_duplicates handle_duplicates; int escape_char, last_errno; -/* for INSERT ... UPDATE */ + bool ignore; + /* for INSERT ... UPDATE */ List<Item> *update_fields; List<Item> *update_values; } COPY_INFO; @@ -1232,19 +1233,21 @@ class select_insert :public select_result_interceptor { COPY_INFO info; select_insert(TABLE *table_par, List<Item> *fields_par, - enum_duplicates duplic) + enum_duplicates duplic, bool ignore) :table(table_par), fields(fields_par), last_insert_id(0) { bzero((char*) &info,sizeof(info)); + info.ignore= ignore; info.handle_duplicates=duplic; } select_insert(TABLE *table_par, List<Item> *fields_par, List<Item> *update_fields, List<Item> *update_values, - enum_duplicates duplic) + enum_duplicates duplic, bool ignore) :table(table_par), fields(fields_par), last_insert_id(0) { bzero((char*) &info,sizeof(info)); - info.handle_duplicates=duplic; + info.ignore= ignore; + info.handle_duplicates= duplic; info.update_fields= update_fields; info.update_values= update_values; } @@ -1273,8 +1276,8 @@ public: HA_CREATE_INFO *create_info_par, List<create_field> &fields_par, List<Key> &keys_par, - List<Item> &select_fields,enum_duplicates duplic) - :select_insert (NULL, &select_fields, duplic), db(db_name), + List<Item> &select_fields,enum_duplicates duplic, bool ignore) + :select_insert (NULL, &select_fields, duplic, ignore), db(db_name), name(table_name), extra_fields(&fields_par),keys(&keys_par), create_info(create_info_par), lock(0) {} @@ -1525,11 +1528,11 @@ class multi_update :public select_result_interceptor uint table_count; Copy_field *copy_field; enum enum_duplicates handle_duplicates; - bool do_update, trans_safe, transactional_tables, log_delayed; + bool do_update, trans_safe, transactional_tables, log_delayed, ignore; public: multi_update(THD *thd_arg, TABLE_LIST *ut, List<Item> *fields, - List<Item> *values, enum_duplicates handle_duplicates); + List<Item> *values, enum_duplicates handle_duplicates, bool ignore); ~multi_update(); int prepare(List<Item> &list, SELECT_LEX_UNIT *u); bool send_data(List<Item> &items); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 29d86a99ff3..8b4a0f0f6d0 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -57,8 +57,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, DBUG_RETURN(1); } - if (thd->lex->duplicates == DUP_IGNORE) - thd->lex->select_lex.no_error= 1; + thd->lex->select_lex.no_error= thd->lex->ignore; /* Test if the user wants to delete all rows */ if (!using_limit && const_cond && (!conds || conds->val_int()) && diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 622176e22cc..92c429bcfde 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -22,7 +22,7 @@ static int check_null_fields(THD *thd,TABLE *entry); #ifndef EMBEDDED_LIBRARY static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list); -static int write_delayed(THD *thd,TABLE *table, enum_duplicates dup, +static int write_delayed(THD *thd,TABLE *table, enum_duplicates dup, bool ignore, char *query, uint query_length, int log_on); static void end_delayed_insert(THD *thd); extern "C" pthread_handler_decl(handle_delayed_insert,arg); @@ -111,7 +111,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<List_item> &values_list, List<Item> &update_fields, List<Item> &update_values, - enum_duplicates duplic) + enum_duplicates duplic, + bool ignore) { int error, res; /* @@ -222,9 +223,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, */ info.records= info.deleted= info.copied= info.updated= 0; + info.ignore= ignore; info.handle_duplicates=duplic; - info.update_fields=&update_fields; - info.update_values=&update_values; + info.update_fields= &update_fields; + info.update_values= &update_values; /* Count warnings for all inserts. For single line insert, generate an error if try to set a NOT NULL field @@ -289,7 +291,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, #ifndef EMBEDDED_LIBRARY if (lock_type == TL_WRITE_DELAYED) { - error=write_delayed(thd,table,duplic,query, thd->query_length, log_on); + error=write_delayed(thd, table, duplic, ignore, query, thd->query_length, log_on); query=0; } else @@ -395,7 +397,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, else { char buff[160]; - if (duplic == DUP_IGNORE) + if (ignore) sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, (lock_type == TL_WRITE_DELAYED) ? (ulong) 0 : (ulong) (info.records - info.copied), (ulong) thd->cuted_fields); @@ -591,7 +593,7 @@ int write_record(TABLE *table,COPY_INFO *info) } else if ((error=table->file->write_row(table->record[0]))) { - if (info->handle_duplicates != DUP_IGNORE || + if (!info->ignore || (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)) goto err; } @@ -647,14 +649,14 @@ public: char *record,*query; enum_duplicates dup; time_t start_time; - bool query_start_used,last_insert_id_used,insert_id_used; + bool query_start_used,last_insert_id_used,insert_id_used, ignore; int log_query; ulonglong last_insert_id; timestamp_auto_set_type timestamp_field_type; uint query_length; - delayed_row(enum_duplicates dup_arg, int log_query_arg) - :record(0),query(0),dup(dup_arg),log_query(log_query_arg) {} + delayed_row(enum_duplicates dup_arg, bool ignore_arg, int log_query_arg) + :record(0),query(0),dup(dup_arg),ignore(ignore_arg),log_query(log_query_arg) {} ~delayed_row() { x_free(record); @@ -966,7 +968,7 @@ TABLE *delayed_insert::get_local_table(THD* client_thd) /* Put a question in queue */ -static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, +static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, bool ignore, char *query, uint query_length, int log_on) { delayed_row *row=0; @@ -979,7 +981,7 @@ static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, pthread_cond_wait(&di->cond_client,&di->mutex); thd->proc_info="storing row into queue"; - if (thd->killed || !(row= new delayed_row(duplic, log_on))) + if (thd->killed || !(row= new delayed_row(duplic, ignore, log_on))) goto err; if (!query) @@ -1340,8 +1342,9 @@ bool delayed_insert::handle_inserts(void) thd.insert_id_used=row->insert_id_used; table->timestamp_field_type= row->timestamp_field_type; + info.ignore= row->ignore; info.handle_duplicates= row->dup; - if (info.handle_duplicates == DUP_IGNORE || + if (info.ignore || info.handle_duplicates == DUP_REPLACE) { table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); @@ -1459,7 +1462,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) restore_record(table,default_values); // Get empty record table->next_number_field=table->found_next_number_field; thd->cuted_fields=0; - if (info.handle_duplicates == DUP_IGNORE || + if (info.ignore || info.handle_duplicates == DUP_REPLACE) table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->start_bulk_insert((ha_rows) 0); @@ -1601,7 +1604,7 @@ bool select_insert::send_eof() DBUG_RETURN(1); } char buff[160]; - if (info.handle_duplicates == DUP_IGNORE) + if (info.ignore) sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, (ulong) (info.records - info.copied), (ulong) thd->cuted_fields); else @@ -1645,7 +1648,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) restore_record(table,default_values); // Get empty record thd->cuted_fields=0; - if (info.handle_duplicates == DUP_IGNORE || + if (info.ignore || info.handle_duplicates == DUP_REPLACE) table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->start_bulk_insert((ha_rows) 0); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index d2ac0df1472..5730073bd35 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -158,6 +158,7 @@ void lex_start(THD *thd, uchar *buf,uint length) lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE); lex->sql_command=SQLCOM_END; lex->duplicates= DUP_ERROR; + lex->ignore= 0; lex->proc_list.first= 0; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 8421be7e735..e2e0bc61c23 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -618,7 +618,7 @@ typedef struct st_lex bool in_comment, ignore_space, verbose, no_write_to_binlog; bool derived_tables; bool safe_to_cache_query; - bool subqueries; + bool subqueries, ignore; ALTER_INFO alter_info; /* Prepared statements SQL syntax:*/ LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */ diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 17ab472c87b..c4f5b1427af 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -80,6 +80,7 @@ static int read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, List<Item> &fields, enum enum_duplicates handle_duplicates, + bool ignore, bool read_file_from_client,thr_lock_type lock_type) { char name[FN_REFLEN]; @@ -165,7 +166,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, /* We can't give an error in the middle when using LOCAL files */ if (read_file_from_client && handle_duplicates == DUP_ERROR) - handle_duplicates=DUP_IGNORE; + ignore= 1; #ifndef EMBEDDED_LIBRARY if (read_file_from_client) @@ -216,6 +217,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, COPY_INFO info; bzero((char*) &info,sizeof(info)); + info.ignore= ignore; info.handle_duplicates=handle_duplicates; info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX; @@ -237,6 +239,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, lf_info.db = db; lf_info.table_name = table_list->real_name; lf_info.fields = &fields; + lf_info.ignore= ignore; lf_info.handle_dup = handle_duplicates; lf_info.wrote_create_file = 0; lf_info.last_pos_in_file = HA_POS_ERROR; @@ -267,7 +270,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; table->next_number_field=table->found_next_number_field; - if (handle_duplicates == DUP_IGNORE || + if (ignore || handle_duplicates == DUP_REPLACE) table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); ha_enable_transaction(thd, FALSE); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index cd8e73c446d..c81aefc9cea 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -64,7 +64,7 @@ const char *command_name[]={ "Drop DB", "Refresh", "Shutdown", "Statistics", "Processlist", "Connect","Kill","Debug","Ping","Time","Delayed insert","Change user", "Binlog Dump","Table Dump", "Connect Out", "Register Slave", - "Prepare", "Prepare Execute", "Long Data", "Close stmt", + "Prepare", "Execute", "Long Data", "Close stmt", "Reset stmt", "Set option", "Error" // Last command number }; @@ -1547,7 +1547,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, packet, (uint) (pend-packet), thd->charset()); table_list.alias= table_list.real_name= conv_name.str; packet= pend+1; - // command not cachable => no gap for data base name + thd->query_length= strlen(packet); // for simplicity: don't optimize if (!(thd->query=fields=thd->memdup(packet,thd->query_length+1))) break; mysql_log.write(thd,command,"%s %s",table_list.real_name,fields); @@ -2393,7 +2393,8 @@ mysql_execute_command(THD *thd) &lex->create_info, lex->create_list, lex->key_list, - select_lex->item_list,lex->duplicates))) + select_lex->item_list, lex->duplicates, + lex->ignore))) { /* CREATE from SELECT give its SELECT_LEX for SELECT, @@ -2532,7 +2533,7 @@ unsent_create_error: lex->key_list, select_lex->order_list.elements, (ORDER *) select_lex->order_list.first, - lex->duplicates, &lex->alter_info); + lex->duplicates, lex->ignore, &lex->alter_info); } break; } @@ -2694,7 +2695,7 @@ unsent_create_error: select_lex->order_list.elements, (ORDER *) select_lex->order_list.first, select_lex->select_limit, - lex->duplicates); + lex->duplicates, lex->ignore); if (thd->net.report_error) res= -1; break; @@ -2707,7 +2708,7 @@ unsent_create_error: &lex->value_list, select_lex->where, select_lex->options, - lex->duplicates, unit, select_lex); + lex->duplicates, lex->ignore, unit, select_lex); break; } case SQLCOM_REPLACE: @@ -2715,9 +2716,9 @@ unsent_create_error: { if ((res= insert_precheck(thd, tables))) break; - res = mysql_insert(thd,tables,lex->field_list,lex->many_values, - lex->update_list, lex->value_list, - lex->duplicates); + res= mysql_insert(thd,tables,lex->field_list,lex->many_values, + lex->update_list, lex->value_list, + lex->duplicates, lex->ignore); if (thd->net.report_error) res= -1; break; @@ -2755,7 +2756,7 @@ unsent_create_error: lex->duplicates)) && (result= new select_insert(tables->table, &lex->field_list, &lex->update_list, &lex->value_list, - lex->duplicates))) + lex->duplicates, lex->ignore))) { TABLE *table= tables->table; /* Skip first table, which is the table we are inserting in */ @@ -3065,7 +3066,7 @@ unsent_create_error: goto error; } res=mysql_load(thd, lex->exchange, tables, lex->field_list, - lex->duplicates, (bool) lex->local_file, lex->lock_option); + lex->duplicates, lex->ignore, (bool) lex->local_file, lex->lock_option); break; } @@ -5118,7 +5119,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, &create_info, table_list, fields, keys, 0, (ORDER*)0, - DUP_ERROR, &alter_info)); + DUP_ERROR, 0, &alter_info)); } @@ -5137,7 +5138,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info) DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, &create_info, table_list, fields, keys, 0, (ORDER*)0, - DUP_ERROR, alter_info)); + DUP_ERROR, 0, alter_info)); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 20ebc23e240..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); } @@ -1592,7 +1596,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, DBUG_RETURN(1); } - mysql_log.write(thd, COM_PREPARE, "%s", packet); + mysql_log.write(thd, COM_PREPARE, "[%lu] %s", stmt->id, packet); thd->current_arena= stmt; mysql_init_query(thd, (uchar *) thd->query, thd->query_length); @@ -1792,6 +1796,9 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) if (stmt->param_count && stmt->set_params_data(stmt, &expanded_query)) goto set_params_data_err; #endif + mysql_log.write(thd, COM_EXECUTE, "[%lu] %s", stmt->id, + expanded_query.length() ? expanded_query.c_ptr() : + stmt->query); thd->protocol= &thd->protocol_prep; // Switch to binary protocol execute_stmt(thd, stmt, &expanded_query, TRUE); thd->protocol= &thd->protocol_simple; // Use normal protocol diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 2f0d8d3aa0d..fd165ad1fa5 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1380,7 +1380,7 @@ err: int log_loaded_block(IO_CACHE* file) { - LOAD_FILE_INFO* lf_info; + LOAD_FILE_INFO *lf_info; uint block_len ; /* file->request_pos contains position where we started last read */ @@ -1402,7 +1402,7 @@ int log_loaded_block(IO_CACHE* file) { Create_file_log_event c(lf_info->thd,lf_info->ex,lf_info->db, lf_info->table_name, *lf_info->fields, - lf_info->handle_dup, buffer, + lf_info->handle_dup, lf_info->ignore, buffer, block_len, lf_info->log_delayed); mysql_bin_log.write(&c); lf_info->wrote_create_file = 1; diff --git a/sql/sql_repl.h b/sql/sql_repl.h index 3c17540b664..21b3d2955f7 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -67,7 +67,7 @@ typedef struct st_load_file_info enum enum_duplicates handle_dup; char* db; char* table_name; - bool wrote_create_file, log_delayed; + bool wrote_create_file, log_delayed, ignore; } LOAD_FILE_INFO; int log_loaded_block(IO_CACHE* file); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 610a98d1983..03e322d28ee 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -468,7 +468,7 @@ JOIN::optimize() optimized= 1; // Ignore errors of execution if option IGNORE present - if (thd->lex->duplicates == DUP_IGNORE) + if (thd->lex->ignore) thd->lex->current_select->no_error= 1; #ifdef HAVE_REF_TO_FIELDS // Not done yet /* Add HAVING to WHERE if possible */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 88a56d26e35..8929872c466 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1404,14 +1404,18 @@ store_create_info(THD *thd, TABLE *table, String *packet) if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) && !limited_mysql_mode && !foreign_db_mode) { - if (table->db_type == DB_TYPE_HEAP && - key_info->algorithm == HA_KEY_ALG_BTREE) + if (key_info->algorithm == HA_KEY_ALG_BTREE) packet->append(" TYPE BTREE", 11); + if (key_info->algorithm == HA_KEY_ALG_HASH) + packet->append(" TYPE HASH", 10); + // +BAR: send USING only in non-default case: non-spatial rtree if ((key_info->algorithm == HA_KEY_ALG_RTREE) && !(key_info->flags & HA_SPATIAL)) packet->append(" TYPE RTREE", 11); + + // No need to send TYPE FULLTEXT, it is sent as FULLTEXT KEY } packet->append(" (", 2); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f9f635081cb..c3bfbe086f1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -36,6 +36,7 @@ static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end); static int copy_data_between_tables(TABLE *from,TABLE *to, List<create_field> &create, enum enum_duplicates handle_duplicates, + bool ignore, uint order_num, ORDER *order, ha_rows *copied,ha_rows *deleted); @@ -2686,7 +2687,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, TABLE_LIST *table_list, List<create_field> &fields, List<Key> &keys, uint order_num, ORDER *order, - enum enum_duplicates handle_duplicates, + enum enum_duplicates handle_duplicates, bool ignore, ALTER_INFO *alter_info, bool do_send_ok) { TABLE *table,*new_table; @@ -3205,7 +3206,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, copied=deleted=0; if (!new_table->is_view) error=copy_data_between_tables(table,new_table,create_list, - handle_duplicates, + handle_duplicates, ignore, order_num, order, &copied, &deleted); thd->last_insert_id=next_insert_id; // Needed for correct log thd->count_cuted_fields= CHECK_FIELD_IGNORE; @@ -3425,6 +3426,7 @@ static int copy_data_between_tables(TABLE *from,TABLE *to, List<create_field> &create, enum enum_duplicates handle_duplicates, + bool ignore, uint order_num, ORDER *order, ha_rows *copied, ha_rows *deleted) @@ -3517,7 +3519,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, current query id */ from->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1); - if (handle_duplicates == DUP_IGNORE || + if (ignore || handle_duplicates == DUP_REPLACE) to->file->extra(HA_EXTRA_IGNORE_DUP_KEY); thd->row_count= 0; @@ -3543,7 +3545,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, } if ((error=to->file->write_row((byte*) to->record[0]))) { - if ((handle_duplicates != DUP_IGNORE && + if ((!ignore && handle_duplicates != DUP_REPLACE) || (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)) @@ -3619,7 +3621,7 @@ int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info, table_list, lex->create_list, lex->key_list, 0, (ORDER *) 0, - DUP_ERROR, &lex->alter_info, do_send_ok)); + DUP_ERROR, 0, &lex->alter_info, do_send_ok)); } diff --git a/sql/sql_union.cc b/sql/sql_union.cc index b35209faeb2..f89b234f5b0 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -45,10 +45,10 @@ select_union::select_union(TABLE *table_par) { bzero((char*) &info,sizeof(info)); /* - We can always use DUP_IGNORE because the temporary table will only + We can always use IGNORE because the temporary table will only contain a unique key if we are using not using UNION ALL */ - info.handle_duplicates= DUP_IGNORE; + info.ignore= 1; } select_union::~select_union() diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 2b27cff13e2..761e8d6de8b 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -54,7 +54,8 @@ int mysql_update(THD *thd, COND *conds, uint order_num, ORDER *order, ha_rows limit, - enum enum_duplicates handle_duplicates) + enum enum_duplicates handle_duplicates, + bool ignore) { bool using_limit=limit != HA_POS_ERROR; bool safe_update= thd->options & OPTION_SAFE_UPDATES; @@ -274,7 +275,7 @@ int mysql_update(THD *thd, } } - if (handle_duplicates == DUP_IGNORE) + if (ignore) table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); init_read_record(&info,thd,table,select,0,1); @@ -299,8 +300,7 @@ int mysql_update(THD *thd, { updated++; } - else if (handle_duplicates != DUP_IGNORE || - error != HA_ERR_FOUND_DUPP_KEY) + else if (!ignore || error != HA_ERR_FOUND_DUPP_KEY) { thd->fatal_error(); // Force error message table->file->print_error(error,MYF(0)); @@ -476,7 +476,7 @@ int mysql_multi_update(THD *thd, List<Item> *values, COND *conds, ulong options, - enum enum_duplicates handle_duplicates, + enum enum_duplicates handle_duplicates, bool ignore, SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex) { int res; @@ -667,7 +667,7 @@ int mysql_multi_update(THD *thd, } if (!(result=new multi_update(thd, update_list, fields, values, - handle_duplicates))) + handle_duplicates, ignore))) DBUG_RETURN(-1); res= mysql_select(thd, &select_lex->ref_pointer_array, @@ -684,11 +684,11 @@ int mysql_multi_update(THD *thd, multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list, List<Item> *field_list, List<Item> *value_list, - enum enum_duplicates handle_duplicates_arg) + enum enum_duplicates handle_duplicates_arg, bool ignore_arg) :all_tables(table_list), update_tables(0), thd(thd_arg), tmp_tables(0), updated(0), found(0), fields(field_list), values(value_list), table_count(0), copy_field(0), handle_duplicates(handle_duplicates_arg), - do_update(1), trans_safe(0), transactional_tables(1) + do_update(1), trans_safe(0), transactional_tables(1), ignore(ignore_arg) {} @@ -1021,8 +1021,7 @@ bool multi_update::send_data(List<Item> ¬_used_values) table->record[0]))) { updated--; - if (handle_duplicates != DUP_IGNORE || - error != HA_ERR_FOUND_DUPP_KEY) + if (!ignore || error != HA_ERR_FOUND_DUPP_KEY) { thd->fatal_error(); // Force error message table->file->print_error(error,MYF(0)); @@ -1154,8 +1153,7 @@ int multi_update::do_updates(bool from_send_error) if ((local_error=table->file->update_row(table->record[1], table->record[0]))) { - if (local_error != HA_ERR_FOUND_DUPP_KEY || - handle_duplicates != DUP_IGNORE) + if (!ignore || local_error != HA_ERR_FOUND_DUPP_KEY) goto err; } updated++; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a09694ee1e6..4fcc72bc90e 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; } @@ -1849,8 +1842,9 @@ alter: { THD *thd= YYTHD; LEX *lex= thd->lex; - lex->sql_command = SQLCOM_ALTER_TABLE; - lex->name=0; + lex->sql_command= SQLCOM_ALTER_TABLE; + lex->name= 0; + lex->duplicates= DUP_ERROR; if (!lex->select_lex.add_table_to_list(thd, $4, NULL, TL_OPTION_UPDATING)) YYABORT; @@ -2035,8 +2029,9 @@ opt_column: | COLUMN_SYM {}; opt_ignore: - /* empty */ { Lex->duplicates=DUP_ERROR; } - | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }; + /* empty */ { Lex->ignore= 0;} + | IGNORE_SYM { Lex->ignore= 1;} + ; opt_restrict: /* empty */ {} @@ -4012,7 +4007,8 @@ insert: INSERT { LEX *lex= Lex; - lex->sql_command = SQLCOM_INSERT; + lex->sql_command= SQLCOM_INSERT; + lex->duplicates= DUP_ERROR; /* for subselects */ lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; @@ -4174,6 +4170,7 @@ update: mysql_init_select(lex); lex->sql_command= SQLCOM_UPDATE; lex->lock_option= TL_UNLOCK; /* Will be set later */ + lex->duplicates= DUP_ERROR; } opt_low_priority opt_ignore join_table_list SET update_list @@ -4233,6 +4230,7 @@ delete: LEX *lex= Lex; lex->sql_command= SQLCOM_DELETE; lex->lock_option= lex->thd->update_lock_default; + lex->ignore= 0; lex->select_lex.init_order(); } opt_delete_options single_multi {} @@ -4289,7 +4287,7 @@ opt_delete_options: opt_delete_option: QUICK { Select->options|= OPTION_QUICK; } | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } - | IGNORE_SYM { Lex->duplicates= DUP_IGNORE; }; + | IGNORE_SYM { Lex->ignore= 1; }; truncate: TRUNCATE_SYM opt_table_sym table_name @@ -4698,6 +4696,8 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING_sys lex->sql_command= SQLCOM_LOAD; lex->lock_option= $3; lex->local_file= $4; + lex->duplicates= DUP_ERROR; + lex->ignore= 0; if (!(lex->exchange= new sql_exchange($6.str,0))) YYABORT; lex->field_list.empty(); @@ -4735,7 +4735,7 @@ load_data_lock: opt_duplicate: /* empty */ { Lex->duplicates=DUP_ERROR; } | REPLACE { Lex->duplicates=DUP_REPLACE; } - | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }; + | IGNORE_SYM { Lex->ignore= 1; }; opt_field_term: /* empty */ diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 8345c53202c..997b8ce93d6 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -298,6 +298,7 @@ static int my_strnxfrm_big5(CHARSET_INFO *cs __attribute__((unused)), const uchar * src, uint srclen) { uint16 e; + uint dstlen= len; len = srclen; while (len--) @@ -312,7 +313,9 @@ static int my_strnxfrm_big5(CHARSET_INFO *cs __attribute__((unused)), } else *dest++ = sort_order_big5[(uchar) *src++]; } - return srclen; + if (dstlen > srclen) + bfill(dest, dstlen - srclen, ' '); + return dstlen; } #if 0 diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 7d17f62c8d0..95c52512243 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -341,13 +341,27 @@ static int my_wildcmp_bin(CHARSET_INFO *cs, static int my_strnxfrm_bin(CHARSET_INFO *cs __attribute__((unused)), - uchar * dest, uint len, - const uchar *src, - uint srclen __attribute__((unused))) + uchar * dest, uint dstlen, + const uchar *src, uint srclen) { if (dest != src) - memcpy(dest,src,len= min(len,srclen)); - return len; + memcpy(dest, src, min(dstlen,srclen)); + if (dstlen > srclen) + bfill(dest + srclen, dstlen - srclen, 0); + return dstlen; +} + + +static +int my_strnxfrm_8bit_bin(CHARSET_INFO *cs __attribute__((unused)), + uchar * dest, uint dstlen, + const uchar *src, uint srclen) +{ + if (dest != src) + memcpy(dest, src, min(dstlen,srclen)); + if (dstlen > srclen) + bfill(dest + srclen, dstlen - srclen, ' '); + return dstlen; } @@ -417,7 +431,7 @@ MY_COLLATION_HANDLER my_collation_8bit_bin_handler = NULL, /* init */ my_strnncoll_8bit_bin, my_strnncollsp_8bit_bin, - my_strnxfrm_bin, + my_strnxfrm_8bit_bin, my_like_range_simple, my_wildcmp_bin, my_strcasecmp_bin, diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index 2177a18504e..5725e81b15e 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -296,16 +296,18 @@ static int my_strnxfrm_czech(CHARSET_INFO *cs __attribute__((unused)), int value; const uchar * p, * store; int pass = 0; - int totlen = 0; + uint totlen = 0; p = src; store = src; do { NEXT_CMP_VALUE(src, p, store, pass, value, (int)srclen); - ADD_TO_RESULT(dest, (int)len, totlen, value); + ADD_TO_RESULT(dest, len, totlen, value); } while (value); - return totlen; + if (len > totlen) + bfill(dest + totlen, len - totlen, ' '); + return len; } #undef IS_END diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 0be56e8d946..731ad58a2fb 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -2659,6 +2659,7 @@ static int my_strnxfrm_gbk(CHARSET_INFO *cs __attribute__((unused)), const uchar * src, uint srclen) { uint16 e; + uint dstlen= len; len = srclen; while (len--) @@ -2673,7 +2674,9 @@ static int my_strnxfrm_gbk(CHARSET_INFO *cs __attribute__((unused)), } else *dest++ = sort_order_gbk[(uchar) *src++]; } - return srclen; + if (dstlen > srclen) + bfill(dest, dstlen - srclen, ' '); + return dstlen; } diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index 5f1850b7772..32d9a227c2f 100644 --- a/strings/ctype-latin1.c +++ b/strings/ctype-latin1.c @@ -637,7 +637,6 @@ static int my_strnxfrm_latin1_de(CHARSET_INFO *cs __attribute__((unused)), uchar * dest, uint len, const uchar * src, uint srclen) { - const uchar *dest_orig = dest; const uchar *de = dest + len; const uchar *se = src + srclen; for ( ; src < se && dest < de ; src++) @@ -647,7 +646,9 @@ static int my_strnxfrm_latin1_de(CHARSET_INFO *cs __attribute__((unused)), if ((chr=combo2map[*src]) && dest < de) *dest++=chr; } - return (int) (dest - dest_orig); + if (dest < de) + bfill(dest, de - dest, ' '); + return (int) len; } diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 3cdf7f460cd..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--; @@ -412,13 +412,14 @@ static int my_strnncollsp_mb_bin(CHARSET_INFO * cs __attribute__((unused)), static int my_strnxfrm_mb_bin(CHARSET_INFO *cs __attribute__((unused)), - uchar * dest, uint len, - const uchar *src, - uint srclen __attribute__((unused))) + uchar * dest, uint dstlen, + const uchar *src, uint srclen) { if (dest != src) - memcpy(dest,src,len= min(len,srclen)); - return len; + memcpy(dest, src, min(dstlen, srclen)); + if (dstlen > srclen) + bfill(dest + srclen, dstlen - srclen, ' '); + return dstlen; } diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index a019665a235..5bfa9e52595 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -21,27 +21,68 @@ #include "stdarg.h" +/* + Converts a string into its sort key. + + SYNOPSIS + my_strnxfrm_xxx() + + IMPLEMENTATION + + The my_strxfrm_xxx() function transforms a string pointed to by + 'src' with length 'srclen' according to the charset+collation + pair 'cs' and copies the result key into 'dest'. + + Comparing two strings using memcmp() after my_strnxfrm_xxx() + is equal to comparing two original strings with my_strnncollsp_xxx(). + + Not more than 'dstlen' bytes are written into 'dst'. + To garantee that the whole string is transformed, 'dstlen' must be + at least srclen*cs->strnxfrm_multiply bytes long. Otherwise, + consequent memcmp() may return a non-accurate result. + + If the source string is too short to fill whole 'dstlen' bytes, + then the 'dest' string is padded up to 'dstlen', ensuring that: + + "a" == "a " + "a\0" < "a" + "a\0" < "a " + + my_strnxfrm_simple() is implemented for 8bit charsets and + simple collations with one-to-one string->key transformation. + + See also implementations for various charsets/collations in + other ctype-xxx.c files. + + RETURN + + Target len 'dstlen'. + +*/ + int my_strnxfrm_simple(CHARSET_INFO * cs, uchar *dest, uint len, const uchar *src, uint srclen) { uchar *map= cs->sort_order; + uint dstlen= len; set_if_smaller(len, srclen); if (dest != src) { const uchar *end; for ( end=src+len; src < end ; ) *dest++= map[*src++]; - return len; } else { const uchar *end; for ( end=dest+len; dest < end ; dest++) *dest= (char) map[(uchar) *dest]; - return len; } + if (dstlen > len) + bfill(dest, dstlen - len, ' '); + return dstlen; } int my_strnncoll_simple(CHARSET_INFO * cs, const uchar *s, uint slen, diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index a8b5394f8c5..c0b33a13cdd 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -291,7 +291,9 @@ static int my_strnxfrm_sjis(CHARSET_INFO *cs __attribute__((unused)), else *dest++ = sort_order_sjis[(uchar)*src++]; } - return srclen; + if (len > srclen) + bfill(dest, len - srclen, ' '); + return len; } diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 5d37aa965d9..3a43c556ac8 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -631,9 +631,13 @@ int my_strnxfrm_tis620(CHARSET_INFO *cs __attribute__((unused)), uchar * dest, uint len, const uchar * src, uint srclen) { + uint dstlen= len; len= (uint) (strmake((char*) dest, (char*) src, min(len, srclen)) - (char*) dest); - return (int) thai2sortable(dest, len); + len= thai2sortable(dest, len); + if (dstlen > len) + bfill(dest + len, dstlen - len, ' '); + return dstlen; } diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index 89c876ad10c..452ca263433 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -7214,8 +7214,7 @@ static int my_strnxfrm_uca(CHARSET_INFO *cs, uchar *dst, uint dstlen, const uchar *src, uint srclen) { - uchar *de = dst + dstlen; - const uchar *dst_orig = dst; + 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); @@ -7226,8 +7225,17 @@ static int my_strnxfrm_uca(CHARSET_INFO *cs, dst[1]= s_res & 0xFF; dst+= 2; } - for ( ; dst < de; *dst++='\0'); - return dst - dst_orig; + s_res= cs->sort_order_big[0][0x20 * cs->sort_order[0]]; + while (dst < de) + { + dst[0]= s_res >> 8; + dst[1]= s_res & 0xFF; + dst+= 2; + } + if (dstlen & 1) /* if odd number then fill the last char */ + *dst= '\0'; + + return dstlen; } diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 403d31aa15b..936e2b6fdce 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -347,7 +347,6 @@ static int my_strnxfrm_ucs2(CHARSET_INFO *cs, int plane; uchar *de = dst + dstlen; const uchar *se = src + srclen; - const uchar *dst_orig = dst; while( src < se && dst < de ) { @@ -367,7 +366,9 @@ static int my_strnxfrm_ucs2(CHARSET_INFO *cs, } dst+=res; } - return dst - dst_orig; + if (dst < de) + cs->cset->fill(cs, dst, de - dst, ' '); + return dstlen; } @@ -1377,7 +1378,9 @@ int my_strnxfrm_ucs2_bin(CHARSET_INFO *cs __attribute__((unused)), { if (dst != src) memcpy(dst,src,srclen= min(dstlen,srclen)); - return srclen; + if (dstlen > srclen) + cs->cset->fill(cs, dst + srclen, dstlen - srclen, ' '); + return dstlen; } diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index ce9346eb475..502d0ec285e 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -2228,7 +2228,6 @@ static int my_strnxfrm_utf8(CHARSET_INFO *cs, int plane; uchar *de = dst + dstlen; const uchar *se = src + srclen; - const uchar *dst_orig = dst; while( src < se && dst < de ) { @@ -2248,7 +2247,9 @@ static int my_strnxfrm_utf8(CHARSET_INFO *cs, } dst+=res; } - return dst - dst_orig; + if (dst < de) + bfill(dst, de - dst, ' '); + return dstlen; } static int my_ismbchar_utf8(CHARSET_INFO *cs,const char *b, const char *e) diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 4ada3d47bf5..98389a9a5a4 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -503,7 +503,9 @@ static int my_strnxfrm_win1250ch(CHARSET_INFO * cs __attribute__((unused)), dest[totlen] = value; totlen++; } while (value) ; - return totlen; + if (len > totlen) + bfill(dest + totlen, len - totlen, ' '); + return len; } #undef IS_END diff --git a/support-files/MySQL-shared-compat.spec.sh b/support-files/MySQL-shared-compat.spec.sh index 068daadab58..e3c88c9415f 100644 --- a/support-files/MySQL-shared-compat.spec.sh +++ b/support-files/MySQL-shared-compat.spec.sh @@ -26,7 +26,8 @@ # # Change this to match the version of the shared libs you want to include # -%define version4 @MYSQL_NO_DASH_VERSION@ +%define version41 @MYSQL_NO_DASH_VERSION@ +%define version40 4.0.23 %define version3 3.23.58 Name: MySQL-shared-compat @@ -36,26 +37,31 @@ License: GPL Group: Applications/Databases URL: http://www.mysql.com/ Autoreqprov: on -Version: %{version4} +Version: %{version41} Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build Obsoletes: MySQL-shared, mysql-shared Provides: MySQL-shared -Summary: MySQL shared libraries for MySQL %{version4} and %{version3} -Source0: MySQL-shared-%{version4}-0.%{_arch}.rpm -Source1: MySQL-shared-%{version3}-1.%{_arch}.rpm +Summary: MySQL shared client libraries for MySQL %{version41}, %{version40} and %{version3} +# We simply use the "MySQL-shared" subpackages as input sources instead of +# rebuilding all from source +Source0: MySQL-shared-%{version41}-0.%{_arch}.rpm +Source1: MySQL-shared-%{version40}-0.%{_arch}.rpm +Source2: MySQL-shared-%{version3}-1.%{_arch}.rpm # No need to include the RPMs once more - they can be downloaded seperately # if you want to rebuild this package NoSource: 0 NoSource: 1 +NoSource: 2 BuildRoot: %{_tmppath}/%{name}-%{version}-build %description -This package includes the shared libraries for both MySQL %{version3} and -MySQL %{version4}. Install this package instead of "MySQL-shared", if you -have applications installed that are dynamically linked against MySQL -3.23.xx but you want to upgrade to MySQL 4.0.xx without breaking the library -dependencies. +This package includes the shared libraries for both MySQL %{version3}, +MySQL %{version40} as well as MySQL %{version41}. +Install this package instead of "MySQL-shared", if you have applications +installed that are dynamically linked against older versions of the MySQL +client library but you want to upgrade to MySQL 4.1.xx without breaking the +library dependencies. %install [ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT; @@ -63,6 +69,8 @@ mkdir -p $RPM_BUILD_ROOT cd $RPM_BUILD_ROOT rpm2cpio %{SOURCE0} | cpio -iv --make-directories rpm2cpio %{SOURCE1} | cpio -iv --make-directories +rpm2cpio %{SOURCE2} | cpio -iv --make-directories +/sbin/ldconfig -n $RPM_BUILD_ROOT%{_libdir} %clean [ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT; diff --git a/tests/client_test.c b/tests/client_test.c index dc18929341c..beaff795d0e 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -11503,6 +11503,29 @@ static void test_rewind(void) rc= mysql_stmt_close(stmt); } + +/* Bug#6761 - mysql_list_fields doesn't work */ + +static void test_bug6761(void) +{ + const char *stmt_text; + MYSQL_RES *res; + int rc; + myheader("test_bug6761"); + + stmt_text= "CREATE TABLE t1 (a int, b char(255), c decimal)"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + res= mysql_list_fields(mysql, "t1", "%"); + DIE_UNLESS(res && mysql_num_fields(res) == 3); + mysql_free_result(res); + + stmt_text= "DROP TABLE t1"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); +} + /* Read and parse arguments and MySQL options from my.cnf */ @@ -11709,6 +11732,7 @@ static struct my_tests_st my_tests[]= { { "test_bug4172", test_bug4172 }, { "test_conversion", test_conversion }, { "test_rewind", test_rewind }, + { "test_bug6761", test_bug6761 }, { 0, 0 } }; |