summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore1
-rw-r--r--BUILD/Makefile.am2
-rwxr-xr-xBUILD/check-cpu6
-rw-r--r--BUILD/compile-amd64-max-sci8
-rw-r--r--BUILD/compile-pentium64-max-sci9
-rwxr-xr-xBitKeeper/triggers/post-commit46
-rwxr-xr-xBitKeeper/triggers/pre-outgoing.crash-protect.pl82
-rwxr-xr-xBitKeeper/triggers/pre-resolve.crash-protect.pl82
-rwxr-xr-xCMakeLists.txt2
-rw-r--r--Makefile.am10
-rwxr-xr-xclient/CMakeLists.txt68
-rw-r--r--client/mysqldump.c74
-rw-r--r--client/mysqltest.c274
-rw-r--r--cmd-line-utils/libedit/el_term.h10
-rw-r--r--config/ac-macros/ha_ndbcluster.m42
-rw-r--r--configure.in46
-rw-r--r--heap/hp_hash.c25
-rw-r--r--include/keycache.h1
-rw-r--r--include/m_ctype.h3
-rw-r--r--include/m_string.h3
-rw-r--r--include/my_global.h11
-rw-r--r--include/my_sys.h2
-rw-r--r--include/my_time.h1
-rw-r--r--include/mysql_com.h5
-rw-r--r--include/thr_lock.h5
-rw-r--r--include/violite.h3
-rwxr-xr-xlibmysql/CMakeLists.txt4
-rw-r--r--libmysql/libmysql.c33
-rw-r--r--libmysqld/Makefile.am2
-rw-r--r--libmysqld/examples/Makefile.am3
-rw-r--r--libmysqld/lib_sql.cc2
-rw-r--r--libmysqld/libmysqld.def4
-rw-r--r--myisam/mi_check.c13
-rw-r--r--myisam/mi_key.c12
-rw-r--r--myisam/sort.c16
-rw-r--r--myisammrg/myrg_def.h5
-rw-r--r--myisammrg/myrg_open.c12
-rw-r--r--mysql-test/Makefile.am2
-rw-r--r--mysql-test/include/federated.inc1
-rw-r--r--mysql-test/include/have_log_bin.inc4
-rw-r--r--mysql-test/include/is_debug_build.inc4
-rw-r--r--mysql-test/include/master-slave.inc3
-rw-r--r--mysql-test/include/show_binlog_events.inc4
-rw-r--r--mysql-test/include/uses_vardir.inc14
-rw-r--r--mysql-test/include/wait_for_slave_io_to_stop.inc33
-rw-r--r--mysql-test/include/wait_for_slave_param.inc26
-rw-r--r--mysql-test/include/wait_for_slave_sql_to_stop.inc30
-rw-r--r--mysql-test/include/wait_for_slave_to_start.inc35
-rw-r--r--mysql-test/include/wait_for_slave_to_stop.inc37
-rw-r--r--mysql-test/lib/mtr_cases.pl20
-rw-r--r--mysql-test/lib/mtr_process.pl169
-rw-r--r--mysql-test/lib/mtr_report.pl7
-rwxr-xr-xmysql-test/mysql-test-run.pl66
-rw-r--r--mysql-test/r/analyse.result24
-rw-r--r--mysql-test/r/auto_increment.result4
-rw-r--r--mysql-test/r/backup.result6
-rw-r--r--mysql-test/r/bigint.result26
-rw-r--r--mysql-test/r/binary.result38
-rw-r--r--mysql-test/r/binlog.result4
-rw-r--r--mysql-test/r/binlog_innodb.result23
-rw-r--r--mysql-test/r/binlog_killed.result12
-rw-r--r--mysql-test/r/blackhole.result4
-rw-r--r--mysql-test/r/create.result2
-rw-r--r--mysql-test/r/csv.result21
-rw-r--r--mysql-test/r/ctype_big5.result13
-rw-r--r--mysql-test/r/ctype_cp932_binlog.result15
-rw-r--r--mysql-test/r/ctype_cp932_notembedded.result17
-rw-r--r--mysql-test/r/ctype_ldml.result296
-rw-r--r--mysql-test/r/ctype_ucs2_def.result8
-rw-r--r--mysql-test/r/date_formats.result18
-rw-r--r--mysql-test/r/error_simulation.result19
-rw-r--r--mysql-test/r/func_date_add.result11
-rw-r--r--mysql-test/r/func_gconcat.result47
-rw-r--r--mysql-test/r/func_in.result27
-rw-r--r--mysql-test/r/func_sapdb.result6
-rw-r--r--mysql-test/r/func_str.result92
-rw-r--r--mysql-test/r/gis.result21
-rw-r--r--mysql-test/r/grant2.result42
-rw-r--r--mysql-test/r/group_min_max.result21
-rw-r--r--mysql-test/r/have_log_bin.require2
-rw-r--r--mysql-test/r/heap_hash.result16
-rw-r--r--mysql-test/r/information_schema.result11
-rw-r--r--mysql-test/r/innodb.result62
-rw-r--r--mysql-test/r/innodb_mysql.result59
-rw-r--r--mysql-test/r/insert.result2
-rw-r--r--mysql-test/r/insert_select.result35
-rw-r--r--mysql-test/r/insert_update.result18
-rw-r--r--mysql-test/r/join_outer.result15
-rw-r--r--mysql-test/r/key.result12
-rw-r--r--mysql-test/r/key_cache.result31
-rw-r--r--mysql-test/r/kill.result86
-rw-r--r--mysql-test/r/limit.result11
-rw-r--r--mysql-test/r/lock.result3
-rw-r--r--mysql-test/r/long_tmpdir.result3
-rw-r--r--mysql-test/r/merge.result32
-rw-r--r--mysql-test/r/metadata.result52
-rw-r--r--mysql-test/r/mix_innodb_myisam_binlog.result30
-rw-r--r--mysql-test/r/multi_update.result34
-rw-r--r--mysql-test/r/myisam.result26
-rw-r--r--mysql-test/r/mysql_upgrade.result19
-rw-r--r--mysql-test/r/mysqlbinlog.result6
-rw-r--r--mysql-test/r/mysqldump.result19
-rw-r--r--mysql-test/r/mysqltest.result135
-rw-r--r--mysql-test/r/ndb_backup_print.result64
-rw-r--r--mysql-test/r/ndb_basic.result71
-rw-r--r--mysql-test/r/ndb_insert.result169
-rw-r--r--mysql-test/r/ndb_restore.result9
-rw-r--r--mysql-test/r/null.result18
-rw-r--r--mysql-test/r/null_key.result2
-rw-r--r--mysql-test/r/olap.result4
-rw-r--r--mysql-test/r/preload.result13
-rw-r--r--mysql-test/r/ps.result39
-rw-r--r--mysql-test/r/ps_2myisam.result9
-rw-r--r--mysql-test/r/ps_3innodb.result9
-rw-r--r--mysql-test/r/ps_4heap.result9
-rw-r--r--mysql-test/r/ps_5merge.result18
-rw-r--r--mysql-test/r/ps_6bdb.result9
-rw-r--r--mysql-test/r/ps_7ndb.result9
-rw-r--r--mysql-test/r/query_cache.result60
-rw-r--r--mysql-test/r/repair.result14
-rw-r--r--mysql-test/r/rpl_change_master.result70
-rw-r--r--mysql-test/r/rpl_failed_optimize.result5
-rw-r--r--mysql-test/r/rpl_grant.result77
-rw-r--r--mysql-test/r/rpl_loaddata.result4
-rw-r--r--mysql-test/r/rpl_log_pos.result83
-rw-r--r--mysql-test/r/rpl_rotate_logs.result5
-rw-r--r--mysql-test/r/rpl_skip_error.result19
-rw-r--r--mysql-test/r/rpl_ssl.result1
-rw-r--r--mysql-test/r/rpl_user_variables.result40
-rw-r--r--mysql-test/r/rpl_view.result6
-rw-r--r--mysql-test/r/sp-error.result6
-rw-r--r--mysql-test/r/sp-prelocking.result13
-rw-r--r--mysql-test/r/sp.result57
-rw-r--r--mysql-test/r/sp_trans.result20
-rw-r--r--mysql-test/r/sp_trans_log.result20
-rw-r--r--mysql-test/r/strict.result20
-rw-r--r--mysql-test/r/subselect.result37
-rw-r--r--mysql-test/r/subselect_notembedded.result2
-rw-r--r--mysql-test/r/trigger.result31
-rw-r--r--mysql-test/r/type_date.result26
-rw-r--r--mysql-test/r/type_datetime.result51
-rw-r--r--mysql-test/r/type_decimal.result9
-rw-r--r--mysql-test/r/type_enum.result7
-rw-r--r--mysql-test/r/type_float.result33
-rw-r--r--mysql-test/r/udf.result23
-rw-r--r--mysql-test/r/user_var.result36
-rw-r--r--mysql-test/r/view.result187
-rw-r--r--mysql-test/r/view_grant.result4
-rw-r--r--mysql-test/r/warnings.result6
-rw-r--r--mysql-test/std_data/Index.xml71
-rw-r--r--mysql-test/suite/large_tests/README.TXT13
-rw-r--r--mysql-test/suite/large_tests/r/alter_table.result37
-rw-r--r--mysql-test/suite/large_tests/t/alter_table.test47
-rw-r--r--mysql-test/t/backup.test5
-rw-r--r--mysql-test/t/bigint.test16
-rw-r--r--mysql-test/t/binary.test38
-rw-r--r--mysql-test/t/binlog.test6
-rw-r--r--mysql-test/t/binlog_innodb.test39
-rw-r--r--mysql-test/t/binlog_killed.test248
-rw-r--r--mysql-test/t/blackhole.test20
-rw-r--r--mysql-test/t/cast.test8
-rw-r--r--mysql-test/t/csv.test18
-rw-r--r--mysql-test/t/ctype_big5.test18
-rw-r--r--mysql-test/t/ctype_cp932_binlog.test3
-rw-r--r--mysql-test/t/ctype_cp932_notembedded.test32
-rw-r--r--mysql-test/t/ctype_ldml-master.opt2
-rw-r--r--mysql-test/t/ctype_ldml.test63
-rw-r--r--mysql-test/t/ctype_ucs2_def.test16
-rw-r--r--mysql-test/t/ctype_ucs_binlog.test1
-rw-r--r--mysql-test/t/date_formats.test2
-rw-r--r--mysql-test/t/disabled.def4
-rw-r--r--mysql-test/t/drop_temp_table.test3
-rw-r--r--mysql-test/t/error_simulation-master.opt1
-rw-r--r--mysql-test/t/error_simulation.test29
-rw-r--r--mysql-test/t/flush_block_commit_notembedded.test4
-rw-r--r--mysql-test/t/func_date_add.test10
-rw-r--r--mysql-test/t/func_gconcat.test30
-rw-r--r--mysql-test/t/func_in.test31
-rw-r--r--mysql-test/t/func_sapdb.test2
-rw-r--r--mysql-test/t/func_str.test48
-rw-r--r--mysql-test/t/gis.test13
-rw-r--r--mysql-test/t/grant.test2
-rw-r--r--mysql-test/t/grant2.test74
-rw-r--r--mysql-test/t/greedy_optimizer.test4
-rw-r--r--mysql-test/t/group_min_max.test22
-rw-r--r--mysql-test/t/heap_hash.test25
-rw-r--r--mysql-test/t/information_schema.test15
-rw-r--r--mysql-test/t/innodb.test73
-rw-r--r--mysql-test/t/innodb_mysql.test74
-rw-r--r--mysql-test/t/insert_select-binlog.test1
-rw-r--r--mysql-test/t/insert_select.test25
-rw-r--r--mysql-test/t/insert_update.test16
-rw-r--r--mysql-test/t/join.test6
-rw-r--r--mysql-test/t/join_outer.test16
-rw-r--r--mysql-test/t/key.test12
-rw-r--r--mysql-test/t/key_cache.test27
-rw-r--r--mysql-test/t/kill.test189
-rw-r--r--mysql-test/t/limit.test17
-rw-r--r--mysql-test/t/long_tmpdir-master.opt1
-rw-r--r--mysql-test/t/long_tmpdir-master.sh3
-rw-r--r--mysql-test/t/long_tmpdir.test9
-rw-r--r--mysql-test/t/merge.test21
-rw-r--r--mysql-test/t/metadata.test32
-rw-r--r--mysql-test/t/mix_innodb_myisam_binlog.test54
-rw-r--r--mysql-test/t/multi_update.test41
-rw-r--r--mysql-test/t/myisam.test16
-rw-r--r--mysql-test/t/mysql.test2
-rw-r--r--mysql-test/t/mysql_upgrade.test13
-rw-r--r--mysql-test/t/mysqlbinlog-cp932.test3
-rw-r--r--mysql-test/t/mysqlbinlog.test16
-rw-r--r--mysql-test/t/mysqlbinlog2.test3
-rw-r--r--mysql-test/t/mysqldump.test11
-rw-r--r--mysql-test/t/mysqltest.test270
-rw-r--r--mysql-test/t/ndb_backup_print.test66
-rw-r--r--mysql-test/t/ndb_basic.test40
-rw-r--r--mysql-test/t/ndb_index_ordered.test2
-rw-r--r--mysql-test/t/ndb_insert.test137
-rw-r--r--mysql-test/t/ndb_restore.test8
-rw-r--r--mysql-test/t/order_by.test4
-rw-r--r--mysql-test/t/outfile.test12
-rw-r--r--mysql-test/t/ps.test8
-rw-r--r--mysql-test/t/query_cache.test58
-rw-r--r--mysql-test/t/row.test2
-rw-r--r--mysql-test/t/rpl000015.test2
-rw-r--r--mysql-test/t/rpl000017.test2
-rw-r--r--mysql-test/t/rpl_change_master.test4
-rw-r--r--mysql-test/t/rpl_grant.test42
-rw-r--r--mysql-test/t/rpl_loaddata.test10
-rw-r--r--mysql-test/t/rpl_log_pos.test33
-rw-r--r--mysql-test/t/rpl_packet.test2
-rw-r--r--mysql-test/t/rpl_rotate_logs.test17
-rw-r--r--mysql-test/t/rpl_skip_error.test21
-rw-r--r--mysql-test/t/rpl_ssl.test3
-rw-r--r--mysql-test/t/rpl_user_variables.test45
-rw-r--r--mysql-test/t/rpl_view.test12
-rw-r--r--mysql-test/t/sp-code.test2
-rw-r--r--mysql-test/t/sp-error.test6
-rw-r--r--mysql-test/t/sp-prelocking.test31
-rw-r--r--mysql-test/t/sp.test22
-rw-r--r--mysql-test/t/sp_trans.test29
-rw-r--r--mysql-test/t/sp_trans_log.test33
-rw-r--r--mysql-test/t/strict.test10
-rw-r--r--mysql-test/t/subselect.test53
-rw-r--r--mysql-test/t/subselect3.test4
-rw-r--r--mysql-test/t/subselect_notembedded.test7
-rw-r--r--mysql-test/t/trigger.test70
-rw-r--r--mysql-test/t/type_date.test13
-rw-r--r--mysql-test/t/type_datetime.test36
-rw-r--r--mysql-test/t/type_decimal.test14
-rw-r--r--mysql-test/t/type_enum.test8
-rw-r--r--mysql-test/t/type_float.test20
-rw-r--r--mysql-test/t/udf.test24
-rw-r--r--mysql-test/t/user_var-binlog.test3
-rw-r--r--mysql-test/t/user_var.test15
-rw-r--r--mysql-test/t/view.test115
-rw-r--r--mysys/charset-def.c6
-rw-r--r--mysys/charset.c36
-rw-r--r--mysys/mf_keycache.c11
-rw-r--r--mysys/my_init.c36
-rw-r--r--mysys/my_seek.c18
-rw-r--r--mysys/my_thr_init.c36
-rw-r--r--ndb/include/debugger/EventLogger.hpp2
-rw-r--r--ndb/include/mgmapi/ndbd_exit_codes.h2
-rw-r--r--ndb/include/ndbapi/Ndb.hpp9
-rw-r--r--ndb/src/common/transporter/Packer.cpp5
-rw-r--r--ndb/src/common/transporter/SCI_Transporter.cpp216
-rw-r--r--ndb/src/common/transporter/SCI_Transporter.hpp18
-rw-r--r--ndb/src/common/transporter/TCP_Transporter.hpp4
-rw-r--r--ndb/src/common/transporter/TransporterRegistry.cpp75
-rw-r--r--ndb/src/kernel/blocks/ERROR_codes.txt3
-rw-r--r--ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp17
-rw-r--r--ndb/src/kernel/blocks/dbdict/Dbdict.cpp50
-rw-r--r--ndb/src/kernel/blocks/dbdih/DbdihMain.cpp8
-rw-r--r--ndb/src/kernel/blocks/dblqh/Dblqh.hpp5
-rw-r--r--ndb/src/kernel/blocks/dblqh/DblqhInit.cpp9
-rw-r--r--ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp7
-rw-r--r--ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp2
-rw-r--r--ndb/src/kernel/blocks/qmgr/QmgrMain.cpp2
-rw-r--r--ndb/src/kernel/error/ndbd_exit_codes.c3
-rw-r--r--ndb/src/kernel/vm/WatchDog.cpp8
-rw-r--r--ndb/src/mgmclient/CommandInterpreter.cpp278
-rw-r--r--ndb/src/mgmclient/Makefile.am3
-rw-r--r--ndb/src/ndbapi/Ndb.cpp97
-rw-r--r--ndb/test/include/NdbRestarter.hpp3
-rw-r--r--ndb/test/ndbapi/testNdbApi.cpp38
-rw-r--r--ndb/test/ndbapi/testNodeRestart.cpp81
-rw-r--r--ndb/test/run-test/daily-basic-tests.txt8
-rwxr-xr-xscripts/CMakeLists.txt14
-rw-r--r--scripts/make_binary_distribution.sh72
-rwxr-xr-xscripts/make_win_bin_dist44
-rw-r--r--scripts/mysql_system_tables_fix.sql1
-rw-r--r--server-tools/instance-manager/mysql_connection.cc4
-rw-r--r--sql-common/client.c22
-rw-r--r--sql-common/my_time.c35
-rwxr-xr-xsql/CMakeLists.txt2
-rw-r--r--sql/Makefile.am3
-rw-r--r--sql/examples/ha_tina.cc4
-rw-r--r--sql/field.cc304
-rw-r--r--sql/field.h66
-rw-r--r--sql/field_conv.cc17
-rw-r--r--sql/filesort.cc40
-rw-r--r--sql/ha_blackhole.h3
-rw-r--r--sql/ha_myisam.cc29
-rw-r--r--sql/ha_myisammrg.cc37
-rw-r--r--sql/ha_myisammrg.h1
-rw-r--r--sql/ha_ndbcluster.cc120
-rw-r--r--sql/handler.cc6
-rw-r--r--sql/handler.h4
-rw-r--r--sql/init.cc13
-rw-r--r--sql/item.cc115
-rw-r--r--sql/item.h48
-rw-r--r--sql/item_cmpfunc.cc34
-rw-r--r--sql/item_create.cc1
-rw-r--r--sql/item_func.cc129
-rw-r--r--sql/item_func.h16
-rw-r--r--sql/item_strfunc.cc7
-rw-r--r--sql/item_sum.cc14
-rw-r--r--sql/item_timefunc.cc272
-rw-r--r--sql/item_timefunc.h48
-rw-r--r--sql/lock.cc7
-rw-r--r--sql/log.cc2
-rw-r--r--sql/log_event.cc38
-rw-r--r--sql/log_event.h3
-rw-r--r--sql/my_decimal.cc2
-rw-r--r--sql/my_decimal.h2
-rw-r--r--sql/mysql_priv.h44
-rw-r--r--sql/mysqld.cc59
-rw-r--r--sql/net_serv.cc24
-rw-r--r--sql/protocol.cc12
-rw-r--r--sql/protocol.h18
-rw-r--r--sql/set_var.cc10
-rw-r--r--sql/share/errmsg.txt3
-rw-r--r--sql/sp.cc2
-rw-r--r--sql/sp_head.cc5
-rw-r--r--sql/sql_acl.cc32
-rw-r--r--sql/sql_base.cc31
-rw-r--r--sql/sql_class.cc59
-rw-r--r--sql/sql_class.h23
-rw-r--r--sql/sql_client.cc7
-rw-r--r--sql/sql_error.cc4
-rw-r--r--sql/sql_error.h2
-rw-r--r--sql/sql_insert.cc68
-rw-r--r--sql/sql_lex.cc8
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_load.cc6
-rw-r--r--sql/sql_parse.cc84
-rw-r--r--sql/sql_prepare.cc47
-rw-r--r--sql/sql_repl.cc4
-rw-r--r--sql/sql_select.cc225
-rw-r--r--sql/sql_show.cc36
-rw-r--r--sql/sql_table.cc166
-rw-r--r--sql/sql_update.cc263
-rw-r--r--sql/sql_view.cc133
-rw-r--r--sql/sql_yacc.yy56
-rw-r--r--sql/structs.h6
-rw-r--r--sql/table.cc79
-rw-r--r--sql/table.h25
-rw-r--r--sql/time.cc38
-rw-r--r--sql/tztime.cc88
-rw-r--r--sql/tztime.h10
-rw-r--r--sql/udf_example.c3
-rw-r--r--sql/unireg.cc4
-rw-r--r--sql/unireg.h1
-rw-r--r--strings/ctype-big5.c4
-rw-r--r--strings/ctype-bin.c25
-rw-r--r--strings/ctype-gbk.c4
-rw-r--r--strings/ctype-mb.c7
-rw-r--r--strings/ctype-sjis.c4
-rw-r--r--strings/ctype-uca.c4
-rw-r--r--strings/ctype-ucs2.c5
-rw-r--r--strings/ctype.c2
-rw-r--r--strings/strtod.c57
-rw-r--r--tests/mysql_client_test.c177
-rw-r--r--vio/vio_priv.h1
-rw-r--r--vio/viosocket.c42
-rwxr-xr-xwin/create_manifest.js7
376 files changed, 9611 insertions, 2408 deletions
diff --git a/.bzrignore b/.bzrignore
index d1de21857db..8c632f8f890 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -708,7 +708,6 @@ mysql-test/r/*.err
mysql-test/r/*.log
mysql-test/r/*.out
mysql-test/r/*.reject
-mysql-test/r/*.warnings
mysql-test/r/alter_table.err
mysql-test/r/archive.err
mysql-test/r/bdb-alter-table-1.err
diff --git a/BUILD/Makefile.am b/BUILD/Makefile.am
index 3fd61790903..d06106d4431 100644
--- a/BUILD/Makefile.am
+++ b/BUILD/Makefile.am
@@ -28,6 +28,7 @@ EXTRA_DIST = FINISH.sh \
compile-alpha-debug \
compile-amd64-debug-max \
compile-amd64-max \
+ compile-amd64-max-sci \
compile-darwin-mwcc \
compile-dist \
compile-hpux11-parisc2-aCC \
@@ -53,6 +54,7 @@ EXTRA_DIST = FINISH.sh \
compile-pentium-valgrind-max \
compile-pentium64-debug \
compile-pentium64-debug-max \
+ compile-pentium64-max-sci \
compile-pentium64-valgrind-max \
compile-ppc \
compile-ppc-debug \
diff --git a/BUILD/check-cpu b/BUILD/check-cpu
index 8969f92bda4..48a5b5371e3 100755
--- a/BUILD/check-cpu
+++ b/BUILD/check-cpu
@@ -104,6 +104,12 @@ check_cpu () {
*Athlon*64*)
cpu_arg="athlon64";
;;
+ *Turion*)
+ cpu_arg="athlon64";
+ ;;
+ *Opteron*)
+ cpu_arg="athlon64";
+ ;;
*Athlon*)
cpu_arg="athlon";
;;
diff --git a/BUILD/compile-amd64-max-sci b/BUILD/compile-amd64-max-sci
new file mode 100644
index 00000000000..4afa9004742
--- /dev/null
+++ b/BUILD/compile-amd64-max-sci
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+path=`dirname $0`
+. "$path/SETUP.sh"
+extra_flags="$amd64_cflags $fast_cflags -g"
+extra_configs="$amd64_configs $max_configs --with-ndb-sci=/opt/DIS"
+
+. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium64-max-sci b/BUILD/compile-pentium64-max-sci
new file mode 100644
index 00000000000..9ebb1988475
--- /dev/null
+++ b/BUILD/compile-pentium64-max-sci
@@ -0,0 +1,9 @@
+#! /bin/sh
+
+path=`dirname $0`
+. "$path/SETUP.sh"
+
+extra_flags="$pentium64_cflags $fast_cflags -g"
+extra_configs="$pentium_configs $max_configs --with-ndb-sci=/opt/DIS"
+
+. "$path/FINISH.sh"
diff --git a/BitKeeper/triggers/post-commit b/BitKeeper/triggers/post-commit
index 8051cf98b7a..865d7cdac92 100755
--- a/BitKeeper/triggers/post-commit
+++ b/BitKeeper/triggers/post-commit
@@ -33,6 +33,13 @@ then
exit
fi
+IS_MERGE=`bk changes -r+ -k -m`
+if [ "$IS_MERGE" = "" ]
+then
+ echo Merge changeset, not sending mails
+ exit
+fi
+
CHANGESET=`bk -R prs -r+ -h -d':P:::I:' ChangeSet`
CSETKEY=`bk -R prs -r+ -h -d':KEY:' ChangeSet`
#
@@ -48,44 +55,35 @@ WL=`bk -R prs -r+ -h -d':C:' ChangeSet | \
s/.*\(WL#[0-9][0-9]*\)/ \1/p'`
if [ "$BUG" = "" ]
then
- TO=dev-public@mysql.com
+# TO=dev-public@mysql.com
BS=""
BH=""
else
- TO=dev-bugs@mysql.com
+# TO=dev-bugs@mysql.com
BS=" BUG#$BUG"
# need newline here
BH="X-Bug: $BUG
"
fi
+
#++
-# dev-public@ / dev-bugs@
+# commits@ or dev-private@ mail
#--
- echo "Commit successful, notifying developers at $TO"
- (
- cat <<EOF
-List-ID: <bk.mysql-$VERSION>
-From: $FROM
-To: $TO
-Subject: bk commit - $VERSION tree ($CHANGESET)${BS}${WL}
-X-CSetKey: <$CSETKEY>
-$BH
-EOF
- bk changes -v -r+
- bk cset -r+ -d
- ) > $BKROOT/BitKeeper/tmp/dev_public.txt
-$SENDMAIL -t < $BKROOT/BitKeeper/tmp/dev_public.txt
+LIST="commits"
+TO="commits@lists.mysql.com"
+if [ -f .tree-is-private ]
+then
+ LIST="dev-private"
+ TO="dev-private@mysql.com"
+fi
-#++
-# commits@ mail
-#--
- echo "Notifying commits list at $COMMITS"
+ echo "Notifying $LIST list at $TO"
(
cat <<EOF
List-ID: <bk.mysql-$VERSION>
From: $FROM
-To: $COMMITS
+To: $TO
Subject: bk commit into $VERSION tree ($CHANGESET)$BS
X-CSetKey: <$CSETKEY>
$BH
@@ -98,7 +96,7 @@ see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
EOF
bk changes -v -r+
- bk cset -r+ -d
+ bk rset -r+ -ah | bk gnupatch -h -dup -T
) | bk sed -e ${LIMIT}q > $BKROOT/BitKeeper/tmp/commits.txt
$SENDMAIL -t < $BKROOT/BitKeeper/tmp/commits.txt
@@ -120,7 +118,7 @@ Subject: bk commit - $VERSION tree (Manual) ($CHANGESET)$BS
EOF
bk changes -v -r+
- bk cset -r+ -d
+ bk rset -r+ -ah | bk gnupatch -h -dup -T
) > $BKROOT/BitKeeper/tmp/docs.txt
$SENDMAIL -t < $BKROOT/BitKeeper/tmp/docs.txt
fi
diff --git a/BitKeeper/triggers/pre-outgoing.crash-protect.pl b/BitKeeper/triggers/pre-outgoing.crash-protect.pl
new file mode 100755
index 00000000000..b83e356e3f8
--- /dev/null
+++ b/BitKeeper/triggers/pre-outgoing.crash-protect.pl
@@ -0,0 +1,82 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+
+my $event= $ENV{BK_EVENT};
+unless($event eq 'outgoing pull' || $event eq 'outgoing push' ||
+ $event eq 'resolve') {
+ exit 0;
+}
+
+my @bad_csets=
+ ( 'monty@mysql.com|ChangeSet|20060418090255|16983',
+ 'monty@mysql.com|ChangeSet|20060418090458|02628',
+ 'monty@mysql.com|ChangeSet|20060419084236|49576',
+ 'monty@mysql.com|ChangeSet|20060503164655|51444',
+ 'monty@mysql.com|ChangeSet|20060503225814|60133',
+ 'monty@mysql.com|ChangeSet|20060504033006|54878',
+ 'monty@mysql.com|ChangeSet|20060504130520|48660',
+ 'monty@mysql.com|ChangeSet|20060504164102|03511',
+ 'monty@mysql.com|ChangeSet|20060504193112|04109',
+ 'monty@mysql.com|ChangeSet|20060505015314|02799',
+ 'monty@mysql.com|ChangeSet|20060505084007|16704',
+ 'monty@mysql.com|ChangeSet|20060505104008|16695',
+ 'monty@mysql.com|ChangeSet|20060505171041|13924',
+ 'monty@mysql.com|ChangeSet|20060508121933|13866',
+ 'monty@mysql.com|ChangeSet|20060508160902|15029',
+ 'monty@mysql.com|ChangeSet|20060509145448|38636',
+ 'monty@mysql.com|ChangeSet|20060509224111|40037',
+ 'monty@mysql.com|ChangeSet|20060510090758|40678',
+ 'monty@mysql.com|ChangeSet|20060515164104|46760',
+ 'monty@mysql.com|ChangeSet|20060530114549|35852',
+ 'monty@mysql.com|ChangeSet|20060605032828|23579',
+ 'monty@mysql.com|ChangeSet|20060605033011|10641',
+ 'monty@mysql.com|ChangeSet|20060605060652|09843',
+ 'msvensson@neptunus.(none)|ChangeSet|20060605094744|10838',
+ 'msvensson@neptunus.(none)|ChangeSet|20060605105746|11800',
+ 'msvensson@neptunus.(none)|ChangeSet|20060605122345|12772',
+ 'jmiller@mysql.com|ChangeSet|20060531210831|36442',
+ 'jmiller@mysql.com|ChangeSet|20060602151941|36118',
+ 'jmiller@mysql.com|ChangeSet|20060602152136|27762',
+ 'jmiller@mysql.com|ChangeSet|20060605121748|12864',
+ 'jmiller@mysql.com|ChangeSet|20060605160304|14798',
+ 'jimw@mysql.com|ChangeSet|20060605210201|14667',
+ 'igor@rurik.mysql.com|ChangeSet|20060605220727|15265',
+ 'igor@rurik.mysql.com|ChangeSet|20060605221206|15134',
+ 'stewart@mysql.com|ChangeSet|20060525073521|11169',
+ 'stewart@mysql.com|ChangeSet|20060605154220|12975',
+ 'stewart@mysql.com|ChangeSet|20060606040001|15337',
+ 'hartmut@mysql.com/linux.site|ChangeSet|20070413121444|50289'
+ );
+
+# Read the list of changesets.
+my $csetlist = $ENV{BK_CSETLIST};
+if(!defined($csetlist) || !open(FH, '<', $csetlist)) {
+ die "Failed to open list of incoming changesets '$csetlist': $!.\n";
+}
+my @csets = <FH>;
+close FH;
+
+# Reject any attempt to push/pull a bad changeset.
+for my $cs (@csets) {
+ # Do this the raw way, don't want to be bitten by different EOL conventions
+ # on server and client (Unix/Windows/Mac).
+ $cs =~ s/\x0d?\x0a?$//s;
+ if(grep($_ eq $cs, @bad_csets)) {
+ print <<END;
+BAD CHANGESET DETECTED! $event REJECTED!
+
+The changeset with key '$cs' was detected in the attempted push or pull.
+This changeset is from the corrupt part of the crashed mysql-5.1-new tree.
+Pushing or pulling this changeset would result in corruption of the new tree,
+and therefore the operation has been rejected.
+
+Contact Kristian Nielsen (knielsen\@mysql.com, IRC knielsen) if you have any
+questions regarding this.
+END
+ exit 1;
+ }
+}
+
+exit 0;
diff --git a/BitKeeper/triggers/pre-resolve.crash-protect.pl b/BitKeeper/triggers/pre-resolve.crash-protect.pl
new file mode 100755
index 00000000000..b83e356e3f8
--- /dev/null
+++ b/BitKeeper/triggers/pre-resolve.crash-protect.pl
@@ -0,0 +1,82 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+
+my $event= $ENV{BK_EVENT};
+unless($event eq 'outgoing pull' || $event eq 'outgoing push' ||
+ $event eq 'resolve') {
+ exit 0;
+}
+
+my @bad_csets=
+ ( 'monty@mysql.com|ChangeSet|20060418090255|16983',
+ 'monty@mysql.com|ChangeSet|20060418090458|02628',
+ 'monty@mysql.com|ChangeSet|20060419084236|49576',
+ 'monty@mysql.com|ChangeSet|20060503164655|51444',
+ 'monty@mysql.com|ChangeSet|20060503225814|60133',
+ 'monty@mysql.com|ChangeSet|20060504033006|54878',
+ 'monty@mysql.com|ChangeSet|20060504130520|48660',
+ 'monty@mysql.com|ChangeSet|20060504164102|03511',
+ 'monty@mysql.com|ChangeSet|20060504193112|04109',
+ 'monty@mysql.com|ChangeSet|20060505015314|02799',
+ 'monty@mysql.com|ChangeSet|20060505084007|16704',
+ 'monty@mysql.com|ChangeSet|20060505104008|16695',
+ 'monty@mysql.com|ChangeSet|20060505171041|13924',
+ 'monty@mysql.com|ChangeSet|20060508121933|13866',
+ 'monty@mysql.com|ChangeSet|20060508160902|15029',
+ 'monty@mysql.com|ChangeSet|20060509145448|38636',
+ 'monty@mysql.com|ChangeSet|20060509224111|40037',
+ 'monty@mysql.com|ChangeSet|20060510090758|40678',
+ 'monty@mysql.com|ChangeSet|20060515164104|46760',
+ 'monty@mysql.com|ChangeSet|20060530114549|35852',
+ 'monty@mysql.com|ChangeSet|20060605032828|23579',
+ 'monty@mysql.com|ChangeSet|20060605033011|10641',
+ 'monty@mysql.com|ChangeSet|20060605060652|09843',
+ 'msvensson@neptunus.(none)|ChangeSet|20060605094744|10838',
+ 'msvensson@neptunus.(none)|ChangeSet|20060605105746|11800',
+ 'msvensson@neptunus.(none)|ChangeSet|20060605122345|12772',
+ 'jmiller@mysql.com|ChangeSet|20060531210831|36442',
+ 'jmiller@mysql.com|ChangeSet|20060602151941|36118',
+ 'jmiller@mysql.com|ChangeSet|20060602152136|27762',
+ 'jmiller@mysql.com|ChangeSet|20060605121748|12864',
+ 'jmiller@mysql.com|ChangeSet|20060605160304|14798',
+ 'jimw@mysql.com|ChangeSet|20060605210201|14667',
+ 'igor@rurik.mysql.com|ChangeSet|20060605220727|15265',
+ 'igor@rurik.mysql.com|ChangeSet|20060605221206|15134',
+ 'stewart@mysql.com|ChangeSet|20060525073521|11169',
+ 'stewart@mysql.com|ChangeSet|20060605154220|12975',
+ 'stewart@mysql.com|ChangeSet|20060606040001|15337',
+ 'hartmut@mysql.com/linux.site|ChangeSet|20070413121444|50289'
+ );
+
+# Read the list of changesets.
+my $csetlist = $ENV{BK_CSETLIST};
+if(!defined($csetlist) || !open(FH, '<', $csetlist)) {
+ die "Failed to open list of incoming changesets '$csetlist': $!.\n";
+}
+my @csets = <FH>;
+close FH;
+
+# Reject any attempt to push/pull a bad changeset.
+for my $cs (@csets) {
+ # Do this the raw way, don't want to be bitten by different EOL conventions
+ # on server and client (Unix/Windows/Mac).
+ $cs =~ s/\x0d?\x0a?$//s;
+ if(grep($_ eq $cs, @bad_csets)) {
+ print <<END;
+BAD CHANGESET DETECTED! $event REJECTED!
+
+The changeset with key '$cs' was detected in the attempted push or pull.
+This changeset is from the corrupt part of the crashed mysql-5.1-new tree.
+Pushing or pulling this changeset would result in corruption of the new tree,
+and therefore the operation has been rejected.
+
+Contact Kristian Nielsen (knielsen\@mysql.com, IRC knielsen) if you have any
+questions regarding this.
+END
+ exit 1;
+ }
+}
+
+exit 0;
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 890ee2676e8..54df0befad9 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -158,7 +158,7 @@ IF(EMBED_MANIFESTS)
STRING(REGEX MATCH "MANIFEST:NO" tmp_manifest ${CMAKE_EXE_LINKER_FLAGS})
IF(NOT tmp_manifest)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
- ENDIF(tmp_manifest)
+ ENDIF(NOT tmp_manifest)
# Set the processor architecture.
IF(CMAKE_GENERATOR MATCHES "Visual Studio 8 2005 Win64")
SET(PROCESSOR_ARCH "X64")
diff --git a/Makefile.am b/Makefile.am
index 992a6f6d755..186a3ec2453 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -157,6 +157,16 @@ test-bt:
@PERL@ ./mysql-test-run.pl --force --comment=funcs1_ps --ps-protocol --suite=funcs_1
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --force --comment=funcs2 --suite=funcs_2
+ -cd mysql-test ; MTR_BUILD_THREAD=auto \
+ @PERL@ ./mysql-test-run.pl --force --comment=rowlock --suite=row_lock
+ -if [ -d mysql-test/suite/nist ] ; then \
+ cd mysql-test ; MTR_BUILD_THREAD=auto \
+ @PERL@ ./mysql-test-run.pl --comment=NIST+normal --force --suite=nist ; \
+ fi
+ -if [ -d mysql-test/suite/nist ] ; then \
+ cd mysql-test ; MTR_BUILD_THREAD=auto \
+ @PERL@ ./mysql-test-run.pl --comment=NIST+ps --force --suite=nist --ps-protocol ; \
+ fi
test-bt-debug:
-cd mysql-test ; MTR_BUILD_THREAD=auto \
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index 6e37d02ecd8..8eaa04f8392 100755
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -19,16 +19,53 @@ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
# The old Windows build method used renamed (.cc -> .cpp) source files, fails
# in #include in mysqlbinlog.cc. So disable that using the USING_CMAKE define.
-ADD_DEFINITIONS(-DUSING_CMAKE)
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
- ${CMAKE_SOURCE_DIR}/zlib
- ${CMAKE_SOURCE_DIR}/extra/yassl/include
+ADD_DEFINITIONS(-DUSING_CMAKE -DYASSL_PREFIX -DUSE_TLS)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_SOURCE_DIR}/zlib
+ ${CMAKE_SOURCE_DIR}/extra/yassl/include
+ ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/include
+ ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/mySTL
${CMAKE_SOURCE_DIR}/libmysql
${CMAKE_SOURCE_DIR}/regex
${CMAKE_SOURCE_DIR}/mysys
${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/strings)
+SET(YASSL_SOURCES ../extra/yassl/src/buffer.cpp
+ ../extra/yassl/src/cert_wrapper.cpp
+ ../extra/yassl/src/crypto_wrapper.cpp
+ ../extra/yassl/src/handshake.cpp
+ ../extra/yassl/src/lock.cpp
+ ../extra/yassl/src/log.cpp
+ ../extra/yassl/src/socket_wrapper.cpp
+ ../extra/yassl/src/ssl.cpp
+ ../extra/yassl/src/timer.cpp
+ ../extra/yassl/src/yassl_error.cpp
+ ../extra/yassl/src/yassl_imp.cpp
+ ../extra/yassl/src/yassl_int.cpp)
+
+SET(TAOCRYPT_SOURCES ../extra/yassl/taocrypt/src/aes.cpp
+ ../extra/yassl/taocrypt/src/aestables.cpp
+ ../extra/yassl/taocrypt/src/algebra.cpp
+ ../extra/yassl/taocrypt/src/arc4.cpp
+ ../extra/yassl/taocrypt/src/asn.cpp
+ ../extra/yassl/taocrypt/src/coding.cpp
+ ../extra/yassl/taocrypt/src/des.cpp
+ ../extra/yassl/taocrypt/src/dh.cpp
+ ../extra/yassl/taocrypt/src/dsa.cpp
+ ../extra/yassl/taocrypt/src/file.cpp
+ ../extra/yassl/taocrypt/src/hash.cpp
+ ../extra/yassl/taocrypt/src/integer.cpp
+ ../extra/yassl/taocrypt/src/md2.cpp
+ ../extra/yassl/taocrypt/src/md4.cpp
+ ../extra/yassl/taocrypt/src/md5.cpp
+ ../extra/yassl/taocrypt/src/misc.cpp
+ ../extra/yassl/taocrypt/src/random.cpp
+ ../extra/yassl/taocrypt/src/ripemd.cpp
+ ../extra/yassl/taocrypt/src/rsa.cpp
+ ../extra/yassl/taocrypt/src/sha.cpp)
+
ADD_LIBRARY(mysqlclient ../mysys/array.c ../strings/bchange.c ../strings/bmove.c
../strings/bmove_upp.c ../mysys/charset-def.c ../mysys/charset.c
../sql-common/client.c ../strings/ctype-big5.c ../strings/ctype-bin.c
@@ -63,39 +100,42 @@ ADD_LIBRARY(mysqlclient ../mysys/array.c ../strings/bchange.c ../strings/bmove.c
../strings/strmov.c ../strings/strnlen.c ../strings/strnmov.c ../strings/strtod.c
../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c
../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c
- ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c)
+ ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c
+ ${YASSL_SOURCES} ${TAOCRYPT_SOURCES}
+ )
+
ADD_DEPENDENCIES(mysqlclient GenError)
ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc)
LINK_DIRECTORIES(${MYSQL_BINARY_DIR}/mysys ${MYSQL_BINARY_DIR}/zlib)
-TARGET_LINK_LIBRARIES(mysql mysqlclient mysys yassl taocrypt zlib dbug wsock32)
+TARGET_LINK_LIBRARIES(mysql mysqlclient mysys zlib dbug wsock32)
ADD_EXECUTABLE(mysqltest mysqltest.c)
-TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys yassl taocrypt zlib dbug regex wsock32)
+TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys zlib dbug regex wsock32)
ADD_EXECUTABLE(mysqlcheck mysqlcheck.c)
-TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient dbug yassl taocrypt zlib wsock32)
+TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient dbug zlib wsock32)
ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c)
-TARGET_LINK_LIBRARIES(mysqldump mysqlclient mysys dbug yassl taocrypt zlib wsock32)
+TARGET_LINK_LIBRARIES(mysqldump mysqlclient mysys dbug zlib wsock32)
ADD_EXECUTABLE(mysqlimport mysqlimport.c)
-TARGET_LINK_LIBRARIES(mysqlimport mysqlclient mysys dbug yassl taocrypt zlib wsock32)
+TARGET_LINK_LIBRARIES(mysqlimport mysqlclient mysys dbug zlib wsock32)
ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c ../mysys/my_getpagesize.c)
-TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient mysys dbug yassl taocrypt zlib wsock32)
+TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient mysys dbug zlib wsock32)
ADD_DEPENDENCIES(mysql_upgrade GenFixPrivs)
ADD_EXECUTABLE(mysqlshow mysqlshow.c)
-TARGET_LINK_LIBRARIES(mysqlshow mysqlclient mysys dbug yassl taocrypt zlib wsock32)
+TARGET_LINK_LIBRARIES(mysqlshow mysqlclient mysys dbug zlib wsock32)
ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc ../mysys/mf_tempdir.c ../mysys/my_new.cc
../mysys/my_bit.c ../mysys/my_bitmap.c
../mysys/base64.c)
-TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient dbug yassl taocrypt zlib wsock32)
+TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient dbug zlib wsock32)
ADD_EXECUTABLE(mysqladmin mysqladmin.cc)
-TARGET_LINK_LIBRARIES(mysqladmin mysqlclient mysys dbug yassl taocrypt zlib wsock32)
+TARGET_LINK_LIBRARIES(mysqladmin mysqlclient mysys dbug zlib wsock32)
ADD_EXECUTABLE(echo echo.c)
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 4f908b531b1..fc461a5f559 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -1456,6 +1456,9 @@ static uint dump_routines_for_db(char *db)
if (lock_tables)
mysql_query(mysql, "LOCK TABLES mysql.proc READ");
+ if (opt_compact)
+ fprintf(sql_file, "\n/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;\n");
+
fprintf(sql_file, "DELIMITER ;;\n");
/* 0, retrieve and dump functions, 1, procedures */
@@ -2106,8 +2109,11 @@ static void dump_triggers_for_table(char *table,
DBUG_VOID_RETURN;
}
if (mysql_num_rows(result))
- fprintf(sql_file, "\n/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;\n\
-DELIMITER ;;\n");
+ {
+ if (opt_compact)
+ fprintf(sql_file, "\n/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;\n");
+ fprintf(sql_file, "\nDELIMITER ;;\n");
+ }
while ((row= mysql_fetch_row(result)))
{
fprintf(sql_file,
@@ -2529,15 +2535,18 @@ static void dump_table(char *table, char *db)
plus 2 bytes for '0x' prefix.
- In non-HEX mode we need up to 2 bytes per character,
plus 2 bytes for leading and trailing '\'' characters.
+ Also we need to reserve 1 byte for terminating '\0'.
*/
- dynstr_realloc_checked(&extended_row,length * 2+2);
+ dynstr_realloc_checked(&extended_row,length * 2 + 2 + 1);
if (opt_hex_blob && is_blob)
{
dynstr_append_checked(&extended_row, "0x");
extended_row.length+= mysql_hex_string(extended_row.str +
extended_row.length,
row[i], length);
- extended_row.str[extended_row.length]= '\0';
+ DBUG_ASSERT(extended_row.length+1 <= extended_row.max_length);
+ /* mysql_hex_string() already terminated string by '\0' */
+ DBUG_ASSERT(extended_row.str[extended_row.length] == '\0');
}
else
{
@@ -3262,10 +3271,41 @@ static int do_unlock_tables(MYSQL *mysql_con)
return mysql_query_with_error_report(mysql_con, 0, "UNLOCK TABLES");
}
+static int get_bin_log_name(MYSQL *mysql_con,
+ char* buff_log_name, uint buff_len)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+ if (mysql_query(mysql_con, "SHOW MASTER STATUS") ||
+ !(res= mysql_store_result(mysql)))
+ return 1;
-static int do_reset_master(MYSQL *mysql_con)
+ if (!(row= mysql_fetch_row(res)))
+ {
+ mysql_free_result(res);
+ return 1;
+ }
+ /*
+ Only one row is returned, and the first column is the name of the
+ active log.
+ */
+ strmake(buff_log_name, row[0], buff_len - 1);
+
+ mysql_free_result(res);
+ return 0;
+}
+
+static int purge_bin_logs_to(MYSQL *mysql_con, char* log_name)
{
- return mysql_query_with_error_report(mysql_con, 0, "RESET MASTER");
+ DYNAMIC_STRING str;
+ int err;
+ init_dynamic_string_checked(&str, "PURGE BINARY LOGS TO '", 1024, 1024);
+ dynstr_append_checked(&str, log_name);
+ dynstr_append_checked(&str, "'");
+ err = mysql_query_with_error_report(mysql_con, 0, str.str);
+ dynstr_free(&str);
+ return err;
}
@@ -3789,6 +3829,7 @@ static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size)
int main(int argc, char **argv)
{
+ char bin_log_name[FN_REFLEN];
int exit_code;
MY_INIT("mysqldump");
@@ -3825,8 +3866,13 @@ int main(int argc, char **argv)
goto err;
if (opt_single_transaction && start_transaction(mysql))
goto err;
- if (opt_delete_master_logs && do_reset_master(mysql))
- goto err;
+ if (opt_delete_master_logs)
+ {
+ if (mysql_refresh(mysql, REFRESH_LOG) ||
+ get_bin_log_name(mysql, bin_log_name, sizeof(bin_log_name)))
+ goto err;
+ flush_logs= 0;
+ }
if (opt_lock_all_tables || opt_master_data)
{
if (flush_logs && mysql_refresh(mysql, REFRESH_LOG))
@@ -3850,6 +3896,18 @@ int main(int argc, char **argv)
/* One or more databases, all tables */
dump_databases(argv);
}
+
+ /* ensure dumped data flushed */
+ if (md_result_file && fflush(md_result_file))
+ {
+ if (!first_error)
+ first_error= EX_MYSQLERR;
+ goto err;
+ }
+ /* everything successful, purge the old logs files */
+ if (opt_delete_master_logs && purge_bin_logs_to(mysql, bin_log_name))
+ goto err;
+
#ifdef HAVE_SMEM
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
#endif
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 6f6412e1f02..7eb80e4594f 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -271,7 +271,7 @@ enum enum_commands {
Q_EXEC, Q_DELIMITER,
Q_DISABLE_ABORT_ON_ERROR, Q_ENABLE_ABORT_ON_ERROR,
Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS,
- Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL, Q_QUERY_SORTED,
+ Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL, Q_SORTED_RESULT,
Q_START_TIMER, Q_END_TIMER,
Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL,
Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT,
@@ -341,7 +341,7 @@ const char *command_names[]=
"horizontal_results",
"query_vertical",
"query_horizontal",
- "query_sorted",
+ "sorted_result",
"start_timer",
"end_timer",
"character_set",
@@ -496,6 +496,10 @@ void handle_error(struct st_command*,
void handle_no_error(struct st_command*);
#ifdef EMBEDDED_LIBRARY
+
+/* attributes of the query thread */
+pthread_attr_t cn_thd_attrib;
+
/*
send_one_query executes query in separate thread what is
necessary in embedded library to run 'send' in proper way.
@@ -534,7 +538,7 @@ static int do_send_query(struct st_connection *cn, const char *q, int q_len,
cn->cur_query= q;
cn->cur_query_len= q_len;
cn->query_done= 0;
- if (pthread_create(&tid, NULL, send_one_query, (void*)cn))
+ if (pthread_create(&tid, &cn_thd_attrib, send_one_query, (void*)cn))
die("Cannot start new thread for query");
return 0;
@@ -1143,6 +1147,50 @@ void check_require(DYNAMIC_STRING* ds, const char *fname)
}
+/*
+ Remove surrounding chars from string
+
+ Return 1 if first character is found but not last
+*/
+static int strip_surrounding(char* str, char c1, char c2)
+{
+ char* ptr= str;
+
+ /* Check if the first non space character is c1 */
+ while(*ptr && my_isspace(charset_info, *ptr))
+ ptr++;
+ if (*ptr == c1)
+ {
+ /* Replace it with a space */
+ *ptr= ' ';
+
+ /* Last non space charecter should be c2 */
+ ptr= strend(str)-1;
+ while(*ptr && my_isspace(charset_info, *ptr))
+ ptr--;
+ if (*ptr == c2)
+ {
+ /* Replace it with \0 */
+ *ptr= 0;
+ }
+ else
+ {
+ /* Mismatch detected */
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+static void strip_parentheses(struct st_command *command)
+{
+ if (strip_surrounding(command->first_argument, '(', ')'))
+ die("%.*s - argument list started with '%c' must be ended with '%c'",
+ command->first_word_len, command->query, '(', ')');
+}
+
+
static byte *get_var_key(const byte* var, uint* len,
my_bool __attribute__((unused)) t)
{
@@ -1398,12 +1446,11 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
init_dynamic_string(&ds_query, 0, (end - query) + 32, 256);
do_eval(&ds_query, query, end, FALSE);
- if (mysql_real_query(mysql, ds_query.str, ds_query.length) ||
- !(res = mysql_store_result(mysql)))
- {
+ if (mysql_real_query(mysql, ds_query.str, ds_query.length))
die("Error running query '%s': %d %s", ds_query.str,
mysql_errno(mysql), mysql_error(mysql));
- }
+ if (!(res= mysql_store_result(mysql)))
+ die("Query '%s' didn't return a result set", ds_query.str);
dynstr_free(&ds_query);
if ((row = mysql_fetch_row(res)) && row[0])
@@ -1457,6 +1504,130 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
}
+/*
+ Set variable from the result of a field in a query
+
+ This function is useful when checking for a certain value
+ in the output from a query that can't be restricted to only
+ return some values. A very good example of that is most SHOW
+ commands.
+
+ SYNOPSIS
+ var_set_query_get_value()
+
+ DESCRIPTION
+ let $variable= query_get_value(<query to run>,<column name>,<row no>);
+
+ <query to run> - The query that should be sent to the server
+ <column name> - Name of the column that holds the field be compared
+ against the expected value
+ <row no> - Number of the row that holds the field to be
+ compared against the expected value
+
+*/
+
+void var_set_query_get_value(struct st_command *command, VAR *var)
+{
+ ulong row_no;
+ int col_no= -1;
+ MYSQL_RES* res;
+ MYSQL* mysql= &cur_con->mysql;
+
+ static DYNAMIC_STRING ds_query;
+ static DYNAMIC_STRING ds_col;
+ static DYNAMIC_STRING ds_row;
+ const struct command_arg query_get_value_args[] = {
+ "query", ARG_STRING, TRUE, &ds_query, "Query to run",
+ "column name", ARG_STRING, TRUE, &ds_col, "Name of column",
+ "row number", ARG_STRING, TRUE, &ds_row, "Number for row",
+ };
+
+ DBUG_ENTER("var_set_query_get_value");
+ LINT_INIT(res);
+
+ strip_parentheses(command);
+ DBUG_PRINT("info", ("query: %s", command->query));
+ check_command_args(command, command->first_argument, query_get_value_args,
+ sizeof(query_get_value_args)/sizeof(struct command_arg),
+ ',');
+
+ DBUG_PRINT("info", ("query: %s", ds_query.str));
+ DBUG_PRINT("info", ("col: %s", ds_col.str));
+
+ /* Convert row number to int */
+ if (!str2int(ds_row.str, 10, (long) 0, (long) INT_MAX, &row_no))
+ die("Invalid row number: '%s'", ds_row.str);
+ DBUG_PRINT("info", ("row: %s, row_no: %ld", ds_row.str, row_no));
+ dynstr_free(&ds_row);
+
+ /* Remove any surrounding "'s from the query - if there is any */
+ if (strip_surrounding(ds_query.str, '"', '"'))
+ die("Mismatched \"'s around query '%s'", ds_query.str);
+
+ /* Run the query */
+ if (mysql_real_query(mysql, ds_query.str, ds_query.length))
+ die("Error running query '%s': %d %s", ds_query.str,
+ mysql_errno(mysql), mysql_error(mysql));
+ if (!(res= mysql_store_result(mysql)))
+ die("Query '%s' didn't return a result set", ds_query.str);
+
+ {
+ /* Find column number from the given column name */
+ uint i;
+ uint num_fields= mysql_num_fields(res);
+ MYSQL_FIELD *fields= mysql_fetch_fields(res);
+
+ for (i= 0; i < num_fields; i++)
+ {
+ if (strcmp(fields[i].name, ds_col.str) == 0 &&
+ strlen(fields[i].name) == ds_col.length)
+ {
+ col_no= i;
+ break;
+ }
+ }
+ if (col_no == -1)
+ {
+ mysql_free_result(res);
+ die("Could not find column '%s' in the result of '%s'",
+ ds_col.str, ds_query.str);
+ }
+ DBUG_PRINT("info", ("Found column %d with name '%s'",
+ i, fields[i].name));
+ }
+ dynstr_free(&ds_col);
+
+ {
+ /* Get the value */
+ MYSQL_ROW row;
+ ulong rows= 0;
+ const char* value= "No such row";
+
+ while ((row= mysql_fetch_row(res)))
+ {
+ if (++rows == row_no)
+ {
+
+ DBUG_PRINT("info", ("At row %ld, column %d is '%s'",
+ row_no, col_no, row[col_no]));
+ /* Found the row to get */
+ if (row[col_no])
+ value= row[col_no];
+ else
+ value= "NULL";
+
+ break;
+ }
+ }
+ eval_expr(var, value, 0);
+ }
+ dynstr_free(&ds_query);
+ mysql_free_result(res);
+
+ DBUG_VOID_RETURN;
+}
+
+
void var_copy(VAR *dest, VAR *src)
{
dest->int_val= src->int_val;
@@ -1480,26 +1651,47 @@ void var_copy(VAR *dest, VAR *src)
void eval_expr(VAR *v, const char *p, const char **p_end)
{
- static int MIN_VAR_ALLOC= 32; /* MASV why 32? */
- VAR *vp;
+
+ DBUG_ENTER("eval_expr");
+ DBUG_PRINT("enter", ("p: '%s'", p));
+
if (*p == '$')
{
+ VAR *vp;
if ((vp= var_get(p, p_end, 0, 0)))
- {
var_copy(v, vp);
- return;
- }
+ DBUG_VOID_RETURN;
}
- else if (*p == '`')
+
+ if (*p == '`')
{
var_query_set(v, p, p_end);
+ DBUG_VOID_RETURN;
}
- else
+
+ {
+ /* Check if this is a "let $var= query_get_value()" */
+ const char* get_value_str= "query_get_value";
+ const size_t len= strlen(get_value_str);
+ if (strncmp(p, get_value_str, len)==0)
+ {
+ struct st_command command;
+ memset(&command, 0, sizeof(command));
+ command.query= (char*)p;
+ command.first_word_len= len;
+ command.first_argument= command.query + len;
+ command.end= (char*)*p_end;
+ var_set_query_get_value(&command, v);
+ DBUG_VOID_RETURN;
+ }
+ }
+
{
int new_val_len = (p_end && *p_end) ?
(int) (*p_end - p) : (int) strlen(p);
if (new_val_len + 1 >= v->alloced_len)
{
+ static int MIN_VAR_ALLOC= 32;
v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ?
MIN_VAR_ALLOC : new_val_len + 1;
if (!(v->str_val =
@@ -1512,9 +1704,10 @@ void eval_expr(VAR *v, const char *p, const char **p_end)
memcpy(v->str_val, p, new_val_len);
v->str_val[new_val_len] = 0;
v->int_val=atoi(p);
+ DBUG_PRINT("info", ("atoi on '%s', returns: %d", p, v->int_val));
v->int_dirty=0;
}
- return;
+ DBUG_VOID_RETURN;
}
@@ -3453,7 +3646,6 @@ void do_connect(struct st_command *command)
int con_port= opt_port;
char *con_options;
bool con_ssl= 0, con_compress= 0;
- char *ptr;
static DYNAMIC_STRING ds_connection_name;
static DYNAMIC_STRING ds_host;
@@ -3481,20 +3673,7 @@ void do_connect(struct st_command *command)
DBUG_ENTER("do_connect");
DBUG_PRINT("enter",("connect: %s", command->first_argument));
- /* Remove parenteses around connect arguments */
- if ((ptr= strstr(command->first_argument, "(")))
- {
- /* Replace it with a space */
- *ptr= ' ';
- if ((ptr= strstr(command->first_argument, ")")))
- {
- /* Replace it with \0 */
- *ptr= 0;
- }
- else
- die("connect - argument list started with '(' must be ended with ')'");
- }
-
+ strip_parentheses(command);
check_command_args(command, command->first_argument, connect_args,
sizeof(connect_args)/sizeof(struct command_arg),
',');
@@ -4192,16 +4371,12 @@ int read_command(struct st_command** command_ptr)
DBUG_RETURN(0);
}
if (!(*command_ptr= command=
- (struct st_command*) my_malloc(sizeof(*command), MYF(MY_WME))) ||
+ (struct st_command*) my_malloc(sizeof(*command),
+ MYF(MY_WME|MY_ZEROFILL))) ||
insert_dynamic(&q_lines, (gptr) &command))
die(NullS);
-
- command->require_file[0]= 0;
- command->first_word_len= 0;
- command->query_len= 0;
-
command->type= Q_UNKNOWN;
- command->query_buf= command->query= 0;
+
read_command_buf[0]= 0;
if (read_line(read_command_buf, sizeof(read_command_buf)))
{
@@ -5999,6 +6174,12 @@ int main(int argc, char **argv)
next_con= connections + 1;
cur_con= connections;
+#ifdef EMBEDDED_LIBRARY
+ /* set appropriate stack for the 'query' threads */
+ (void) pthread_attr_init(&cn_thd_attrib);
+ pthread_attr_setstacksize(&cn_thd_attrib, DEFAULT_THREAD_STACK);
+#endif /*EMBEDDED_LIBRARY*/
+
/* Init file stack */
memset(file_stack, 0, sizeof(file_stack));
file_stack_end=
@@ -6040,6 +6221,11 @@ int main(int argc, char **argv)
init_dynamic_string(&ds_warning_messages, "", 0, 2048);
parse_args(argc, argv);
+ var_set_int("$PS_PROTOCOL", ps_protocol);
+ var_set_int("$SP_PROTOCOL", sp_protocol);
+ var_set_int("$VIEW_PROTOCOL", view_protocol);
+ var_set_int("$CURSOR_PROTOCOL", cursor_protocol);
+
DBUG_PRINT("info",("result_file: '%s'",
result_file_name ? result_file_name : ""));
if (mysql_server_init(embedded_server_arg_count,
@@ -6176,13 +6362,19 @@ int main(int argc, char **argv)
case Q_DISPLAY_HORIZONTAL_RESULTS:
display_result_vertically= FALSE;
break;
+ case Q_SORTED_RESULT:
+ /*
+ Turn on sorting of result set, will be reset after next
+ command
+ */
+ display_result_sorted= TRUE;
+ break;
case Q_LET: do_let(command); break;
case Q_EVAL_RESULT:
eval_result = 1; break;
case Q_EVAL:
case Q_QUERY_VERTICAL:
case Q_QUERY_HORIZONTAL:
- case Q_QUERY_SORTED:
if (command->query == command->query_buf)
{
/* Skip the first part of command, i.e query_xxx */
@@ -6194,7 +6386,6 @@ int main(int argc, char **argv)
case Q_REAP:
{
my_bool old_display_result_vertically= display_result_vertically;
- my_bool old_display_result_sorted= display_result_sorted;
/* Default is full query, both reap and send */
int flags= QUERY_REAP_FLAG | QUERY_SEND_FLAG;
@@ -6211,7 +6402,6 @@ int main(int argc, char **argv)
/* Check for special property for this query */
display_result_vertically|= (command->type == Q_QUERY_VERTICAL);
- display_result_sorted= (command->type == Q_QUERY_SORTED);
if (save_file[0])
{
@@ -6224,7 +6414,6 @@ int main(int argc, char **argv)
/* Restore settings */
display_result_vertically= old_display_result_vertically;
- display_result_sorted= old_display_result_sorted;
break;
}
@@ -6385,6 +6574,9 @@ int main(int argc, char **argv)
the replace structures should be cleared
*/
free_all_replace();
+
+ /* Also reset "sorted_result" */
+ display_result_sorted= FALSE;
}
last_command_executed= command_executed;
diff --git a/cmd-line-utils/libedit/el_term.h b/cmd-line-utils/libedit/el_term.h
index 9e5588ee96f..00ca48e38e2 100644
--- a/cmd-line-utils/libedit/el_term.h
+++ b/cmd-line-utils/libedit/el_term.h
@@ -90,6 +90,16 @@ extern char* tgoto(const char*, int, int);
extern char* tgetstr(char*, char**);
#endif
+
+#if !HAVE_DECL_TGOTO
+/*
+ 'tgoto' is not declared in the system header files, this causes
+ problems on 64-bit systems. The function returns a 64 bit pointer
+ but caller see it as "int" and it's thus truncated to 32-bit
+*/
+extern char* tgoto(const char*, int, int);
+#endif
+
protected void term_move_to_line(EditLine *, int);
protected void term_move_to_char(EditLine *, int);
protected void term_clear_EOL(EditLine *, int);
diff --git a/config/ac-macros/ha_ndbcluster.m4 b/config/ac-macros/ha_ndbcluster.m4
index a4963a5e20e..55fe6ad8350 100644
--- a/config/ac-macros/ha_ndbcluster.m4
+++ b/config/ac-macros/ha_ndbcluster.m4
@@ -22,7 +22,7 @@ AC_DEFUN([MYSQL_CHECK_NDB_OPTIONS], [
if test -f "$mysql_sci_dir/lib/libsisci.a" -a \
-f "$mysql_sci_dir/include/sisci_api.h"; then
NDB_SCI_INCLUDES="-I$mysql_sci_dir/include"
- NDB_SCI_LIBS="-L$mysql_sci_dir/lib -lsisci"
+ NDB_SCI_LIBS="$mysql_sci_dir/lib/libsisci.a"
AC_MSG_RESULT([-- including sci transporter])
AC_DEFINE([NDB_SCI_TRANSPORTER], [1],
[Including Ndb Cluster DB sci transporter])
diff --git a/configure.in b/configure.in
index a779ab80ced..5f02b5eae63 100644
--- a/configure.in
+++ b/configure.in
@@ -7,7 +7,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, 5.0.44)
+AM_INIT_AUTOMAKE(mysql, 5.0.46)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
@@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0
# ndb version
NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=0
-NDB_VERSION_BUILD=44
+NDB_VERSION_BUILD=46
NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ?
@@ -507,7 +507,7 @@ then
FIND_PROC="$PS \$\$PID | grep -v grep | grep \$\$MYSQLD > /dev/null"
else
case $SYSTEM_TYPE in
- *freebsd*)
+ *freebsd*|*dragonfly*)
FIND_PROC="$PS p \$\$PID | grep -v grep | grep \$\$MYSQLD > /dev/null"
;;
*darwin*)
@@ -776,6 +776,7 @@ AC_CHECK_HEADERS(fcntl.h float.h floatingpoint.h ieeefp.h limits.h \
sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \
sys/ioctl.h malloc.h sys/malloc.h sys/ipc.h sys/shm.h linux/config.h \
+ sys/prctl.h \
sys/resource.h sys/param.h)
#--------------------------------------------------------------------
@@ -1127,7 +1128,7 @@ case $SYSTEM_TYPE in
MAX_C_OPTIMIZE="-O"
fi
;;
- *freebsd*)
+ *freebsd*|*dragonfly*)
AC_MSG_WARN([Adding fix for interrupted reads])
OSVERSION=`sysctl -a | grep osreldate | awk '{ print $2 }'`
if test "$OSVERSION" -gt "480100" && \
@@ -1736,6 +1737,12 @@ AC_ARG_WITH(client-ldflags,
[CLIENT_EXTRA_LDFLAGS=])
AC_SUBST(CLIENT_EXTRA_LDFLAGS)
+AC_ARG_WITH(mysqld-libs,
+ [ --with-mysqld-libs Extra libraries to link with for mysqld],
+ [MYSQLD_EXTRA_LIBS=$withval],
+ [MYSQLD_EXTRA_LIBS=])
+AC_SUBST(MYSQLD_EXTRA_LIBS)
+
AC_ARG_WITH(lib-ccflags,
[ --with-lib-ccflags Extra CC options for libraries],
[LIB_EXTRA_CCFLAGS=$withval],
@@ -1946,6 +1953,19 @@ else
fi
AC_SUBST(TERMCAP_LIB)
+# Check if the termcap function 'tgoto' is already declared in
+# system header files or if it need to be declared locally
+AC_CHECK_DECLS(tgoto,,,[
+#ifdef HAVE_CURSES_H
+# include <curses.h>
+#elif HAVE_NCURSES_H
+# include <ncurses.h>
+#endif
+#ifdef HAVE_TERM_H
+# include <term.h>
+#endif
+])
+
LIBEDIT_LOBJECTS=""
AC_CHECK_FUNC(strunvis, ,[LIBEDIT_LOBJECTS="$LIBEDIT_LOBJECTS unvis.o"])
AC_CHECK_FUNC(strvis, ,[LIBEDIT_LOBJECTS="$LIBEDIT_LOBJECTS vis.o"])
@@ -2006,12 +2026,20 @@ case "$target" in
;;
esac
-# isinf() could be a function or a macro (HPUX)
-AC_MSG_CHECKING(for isinf with <math.h>)
+# Check that isinf() is available in math.h and can be used in both C and C++
+# code
+AC_MSG_CHECKING(for isinf in <math.h>)
AC_TRY_LINK([#include <math.h>], [float f = 0.0; int r = isinf(f); return r],
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_ISINF, [1], [isinf() macro or function]),
- AC_MSG_RESULT(no))
+ AC_MSG_RESULT(yes)
+ AC_MSG_CHECKING(whether isinf() can be used in C++ code)
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_LINK([#include <math.h>], [float f = 0.0; int r = isinf(f); return r],
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_ISINF, [1], [isinf() macro or function]),
+ AC_MSG_RESULT(no))
+ AC_LANG_RESTORE,
+ AC_MSG_RESULT(no))
CFLAGS="$ORG_CFLAGS"
diff --git a/heap/hp_hash.c b/heap/hp_hash.c
index c5a30a3ef65..d8eee9c794c 100644
--- a/heap/hp_hash.c
+++ b/heap/hp_hash.c
@@ -379,7 +379,13 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
{
- register ulong nr=0;
+ /*
+ Note, if a key consists of a combination of numeric and
+ a text columns, it most likely won't work well.
+ Making text columns work with NEW_HASH_FUNCTION
+ needs also changes in strings/ctype-xxx.c.
+ */
+ ulong nr= 1, nr2= 4;
HA_KEYSEG *seg,*endseg;
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
@@ -401,14 +407,15 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
}
if (seg->type == HA_KEYTYPE_TEXT)
{
- seg->charset->hash_sort(seg->charset,pos,((uchar*)key)-pos,&nr,NULL);
+ seg->charset->coll->hash_sort(seg->charset, pos, ((uchar*)key)-pos,
+ &nr, &nr2);
}
else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */
{
uint pack_length= 2; /* Key packing is constant */
uint length= uint2korr(pos);
- seg->charset->hash_sort(seg->charset, pos+pack_length, length, &nr,
- NULL);
+ seg->charset->coll->hash_sort(seg->charset, pos+pack_length, length,
+ &nr, &nr2);
key+= pack_length;
}
else
@@ -428,7 +435,7 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
{
- register ulong nr=0;
+ ulong nr= 1, nr2= 4;
HA_KEYSEG *seg,*endseg;
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
@@ -444,14 +451,16 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
}
if (seg->type == HA_KEYTYPE_TEXT)
{
- seg->charset->hash_sort(seg->charset,pos,((uchar*)key)-pos,&nr,NULL);
+ uint char_length= seg->length; /* TODO: fix to use my_charpos() */
+ seg->charset->coll->hash_sort(seg->charset, pos, char_length,
+ &nr, &nr2);
}
else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */
{
uint pack_length= seg->bit_start;
uint length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos));
- seg->charset->hash_sort(seg->charset, pos+pack_length,
- length, &nr, NULL);
+ seg->charset->coll->hash_sort(seg->charset, pos+pack_length,
+ length, &nr, &nr2);
}
else
{
diff --git a/include/keycache.h b/include/keycache.h
index dc763b8cc08..54c099fc474 100644
--- a/include/keycache.h
+++ b/include/keycache.h
@@ -46,7 +46,6 @@ typedef struct st_key_cache
my_bool key_cache_inited;
my_bool resize_in_flush; /* true during flush of resize operation */
my_bool can_be_used; /* usage of cache for read/write is allowed */
- uint key_cache_shift;
ulong key_cache_mem_size; /* specified size of the cache memory */
uint key_cache_block_size; /* size of the page buffer of a cache block */
ulong min_warm_blocks; /* min number of warm blocks; */
diff --git a/include/m_ctype.h b/include/m_ctype.h
index f33fd015733..9f21ac16a05 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -281,10 +281,11 @@ extern CHARSET_INFO my_charset_tis620_thai_ci;
extern CHARSET_INFO my_charset_tis620_bin;
extern CHARSET_INFO my_charset_ucs2_general_ci;
extern CHARSET_INFO my_charset_ucs2_bin;
-extern CHARSET_INFO my_charset_ucs2_general_uca;
+extern CHARSET_INFO my_charset_ucs2_unicode_ci;
extern CHARSET_INFO my_charset_ujis_japanese_ci;
extern CHARSET_INFO my_charset_ujis_bin;
extern CHARSET_INFO my_charset_utf8_general_ci;
+extern CHARSET_INFO my_charset_utf8_unicode_ci;
extern CHARSET_INFO my_charset_utf8_bin;
extern CHARSET_INFO my_charset_cp1250_czech_ci;
diff --git a/include/m_string.h b/include/m_string.h
index 349084ab21e..981111b8718 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -105,6 +105,9 @@ extern char *stpcpy(char *, const char *); /* For AIX with gcc 2.95.3 */
extern char NEAR _dig_vec_upper[];
extern char NEAR _dig_vec_lower[];
+/* Defined in strtod.c */
+extern const double log_10[309];
+
#ifdef BAD_STRING_COMPILER
#define strmov(A,B) (memccpy(A,B,0,INT_MAX)-1)
#else
diff --git a/include/my_global.h b/include/my_global.h
index e9b371d8d30..f32a987ffb1 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -792,12 +792,11 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define isnan(x) ((x) != (x))
#endif
-#if !defined(HAVE_ISINF)
-/* The configure check for "isinf with math.h" has failed */
-#ifdef isinf
-#undef isinf
-#endif
-#define isinf(X) (!finite(X) && !isnan(X))
+#ifdef HAVE_ISINF
+/* isinf() can be used in both C and C++ code */
+#define my_isinf(X) isinf(X)
+#else
+#define my_isinf(X) (!finite(X) && !isnan(X))
#endif
/* Define missing math constants. */
diff --git a/include/my_sys.h b/include/my_sys.h
index 615a074e814..7df2718c7b1 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -66,8 +66,8 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_ALLOW_ZERO_PTR 64 /* my_realloc() ; zero ptr -> malloc */
#define MY_FREE_ON_ERROR 128 /* my_realloc() ; Free old ptr on error */
#define MY_HOLD_ON_ERROR 256 /* my_realloc() ; Return old ptr on error */
-#define MY_THREADSAFE 128 /* pread/pwrite: Don't allow interrupts */
#define MY_DONT_OVERWRITE_FILE 1024 /* my_copy: Don't overwrite file */
+#define MY_THREADSAFE 2048 /* my_seek(): lock fd mutex */
#define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */
#define MY_GIVE_INFO 2 /* Give time info about process*/
diff --git a/include/my_time.h b/include/my_time.h
index 0e57b3d4af4..99eb5c36c6b 100644
--- a/include/my_time.h
+++ b/include/my_time.h
@@ -92,6 +92,7 @@ int check_time_range(struct st_mysql_time *, int *warning);
long calc_daynr(uint year,uint month,uint day);
uint calc_days_in_year(uint year);
+uint year_2000_handling(uint year);
void init_time(void);
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 93409b2ea1d..889579e3622 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -345,6 +345,11 @@ my_bool net_write_command(NET *net,unsigned char command,
int net_real_write(NET *net,const char *packet,unsigned long len);
unsigned long my_net_read(NET *net);
+#ifdef _global_h
+void my_net_set_write_timeout(NET *net, uint timeout);
+void my_net_set_read_timeout(NET *net, uint timeout);
+#endif
+
/*
The following function is not meant for normal usage
Currently it's used internally by manager.c
diff --git a/include/thr_lock.h b/include/thr_lock.h
index 966522fe3e3..aa5eb7426ae 100644
--- a/include/thr_lock.h
+++ b/include/thr_lock.h
@@ -54,6 +54,11 @@ enum thr_lock_type { TL_IGNORE=-1,
TL_WRITE_CONCURRENT_INSERT,
/* Write used by INSERT DELAYED. Allows READ locks */
TL_WRITE_DELAYED,
+ /*
+ parser only! Late bound low_priority flag.
+ At open_tables() becomes thd->update_lock_default.
+ */
+ TL_WRITE_DEFAULT,
/* WRITE lock that has lower priority than TL_READ */
TL_WRITE_LOW_PRIORITY,
/* Normal WRITE lock */
diff --git a/include/violite.h b/include/violite.h
index 63388c170c9..7b57667541a 100644
--- a/include/violite.h
+++ b/include/violite.h
@@ -88,7 +88,6 @@ my_bool vio_peer_addr(Vio* vio, char *buf, uint16 *port);
/* Remotes in_addr */
void vio_in_addr(Vio *vio, struct in_addr *in);
my_bool vio_poll_read(Vio *vio,uint timeout);
-void vio_timeout(Vio *vio,uint which, uint timeout);
#ifdef HAVE_OPENSSL
#include <openssl/opensslv.h>
@@ -101,7 +100,9 @@ void vio_timeout(Vio *vio,uint which, uint timeout);
#define HEADER_DES_LOCL_H dummy_something
#define YASSL_MYSQL_COMPATIBLE
+#ifndef YASSL_PREFIX
#define YASSL_PREFIX
+#endif
/* Set yaSSL to use same type as MySQL do for socket handles */
typedef my_socket YASSL_SOCKET_T;
#define YASSL_SOCKET_T_DEFINED
diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
index 647f6bd5e33..3b18531f6c0 100755
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
@@ -18,6 +18,10 @@ INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake")
# storage does not work properly in DLLs.
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS")
+SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS")
+SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS")
+SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS")
+SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS")
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/zlib
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index e80684a1b1e..cb60fb20863 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -67,8 +67,6 @@
ulong net_buffer_length=8192;
ulong max_allowed_packet= 1024L*1024L*1024L;
-ulong net_read_timeout= CLIENT_NET_READ_TIMEOUT;
-ulong net_write_timeout= CLIENT_NET_WRITE_TIMEOUT;
#ifdef EMBEDDED_LIBRARY
@@ -1528,8 +1526,8 @@ my_bool STDCALL mysql_embedded(void)
void my_net_local_init(NET *net)
{
net->max_packet= (uint) net_buffer_length;
- net->read_timeout= (uint) net_read_timeout;
- net->write_timeout=(uint) net_write_timeout;
+ my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
+ my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
net->retry_count= 1;
net->max_packet_size= max(net_buffer_length, max_allowed_packet);
}
@@ -3665,33 +3663,38 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
case MYSQL_TYPE_FLOAT:
{
/*
- We need to store data in the buffer before the truncation check to
+ We need to mark the local variable volatile to
workaround Intel FPU executive precision feature.
(See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 for details)
- AFAIU it does not guarantee to work.
*/
- float data;
+ volatile float data;
if (is_unsigned)
+ {
data= (float) ulonglong2double(value);
+ *param->error= ((ulonglong) value) != ((ulonglong) data);
+ }
else
- data= (float) value;
+ {
+ data= (float)value;
+ *param->error= value != ((longlong) data);
+ }
floatstore(buffer, data);
- *param->error= is_unsigned ?
- ((ulonglong) value) != ((ulonglong) (*(float*) buffer)) :
- ((longlong) value) != ((longlong) (*(float*) buffer));
break;
}
case MYSQL_TYPE_DOUBLE:
{
- double data;
+ volatile double data;
if (is_unsigned)
+ {
data= ulonglong2double(value);
+ *param->error= ((ulonglong) value) != ((ulonglong) data);
+ }
else
+ {
data= (double)value;
+ *param->error= value != ((longlong) data);
+ }
doublestore(buffer, data);
- *param->error= is_unsigned ?
- ((ulonglong) value) != ((ulonglong) (*(double*) buffer)) :
- ((longlong) value) != ((longlong) (*(double*) buffer));
break;
}
case MYSQL_TYPE_TIME:
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
index 95e3e539eee..81da1e43cc9 100644
--- a/libmysqld/Makefile.am
+++ b/libmysqld/Makefile.am
@@ -81,7 +81,7 @@ INC_LIB= $(top_builddir)/regex/libregex.a \
$(top_builddir)/mysys/libmysys.a \
$(top_builddir)/strings/libmystrings.a \
$(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/vio/libvio.a
+ $(top_builddir)/vio/libvio.a @NDB_SCI_LIBS@
#
diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am
index f30951a5d81..e0dd8491688 100644
--- a/libmysqld/examples/Makefile.am
+++ b/libmysqld/examples/Makefile.am
@@ -35,7 +35,8 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I$(srcdir) \
-I$(top_srcdir) -I$(top_srcdir)/client -I$(top_srcdir)/regex \
$(openssl_includes)
LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs)
-LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS)
+LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS) \
+ @NDB_SCI_LIBS@
mysqltest_embedded_LINK = $(CXXLINK)
mysqltest_embedded_SOURCES = mysqltest.c
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 26d761bf6fd..7ac663480c8 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -590,7 +590,7 @@ void *create_embedded_thd(int client_flag)
thd->set_time();
thd->init_for_queries();
thd->client_capabilities= client_flag;
- thd->real_id= (pthread_t) thd;
+ thd->real_id= (pthread_t)thd->thread_id;
thd->db= NULL;
thd->db_length= 0;
diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def
index 0e80681700f..8829112fefd 100644
--- a/libmysqld/libmysqld.def
+++ b/libmysqld/libmysqld.def
@@ -29,8 +29,8 @@ EXPORTS
my_print_variables
my_realloc
my_strdup
- my_thread_end
- my_thread_init
+ mysql_thread_end
+ mysql_thread_init
myodbc_remove_escape
mysql_affected_rows
mysql_autocommit
diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index 444dc2a1da9..ed0a84e737d 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -335,7 +335,7 @@ int chk_size(MI_CHECK *param, register MI_INFO *info)
flush_key_blocks(info->s->key_cache,
info->s->kfile, FLUSH_FORCE_WRITE);
- size=my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0));
+ size= my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(MY_THREADSAFE));
if ((skr=(my_off_t) info->state->key_file_length) != size)
{
/* Don't give error if file generated by myisampack */
@@ -595,7 +595,8 @@ static int chk_index_down(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
{
/* purecov: begin tested */
/* Give it a chance to fit in the real file size. */
- my_off_t max_length= my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(0));
+ my_off_t max_length= my_seek(info->s->kfile, 0L, MY_SEEK_END,
+ MYF(MY_THREADSAFE));
mi_check_print_error(param, "Invalid key block position: %s "
"key block size: %u file_length: %s",
llstr(page, llbuff), keyinfo->block_length,
@@ -4052,10 +4053,10 @@ int test_if_almost_full(MI_INFO *info)
{
if (info->s->options & HA_OPTION_COMPRESS_RECORD)
return 0;
- return (my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0))/10*9 >
- (my_off_t) (info->s->base.max_key_file_length) ||
- my_seek(info->dfile,0L,MY_SEEK_END,MYF(0))/10*9 >
- (my_off_t) info->s->base.max_data_file_length);
+ return my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(MY_THREADSAFE)) / 10 * 9 >
+ (my_off_t) info->s->base.max_key_file_length ||
+ my_seek(info->dfile, 0L, MY_SEEK_END, MYF(0)) / 10 * 9 >
+ (my_off_t) info->s->base.max_data_file_length;
}
/* Recreate table with bigger more alloced record-data */
diff --git a/myisam/mi_key.c b/myisam/mi_key.c
index b203286d544..377972b5a5f 100644
--- a/myisam/mi_key.c
+++ b/myisam/mi_key.c
@@ -252,16 +252,16 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
if (keyseg->flag & HA_SPACE_PACK)
{
uchar *end=pos+length;
- if (type != HA_KEYTYPE_NUM)
- {
- while (end > pos && end[-1] == ' ')
- end--;
- }
- else
+ if (type == HA_KEYTYPE_NUM)
{
while (pos < end && pos[0] == ' ')
pos++;
}
+ else if (type != HA_KEYTYPE_BINARY)
+ {
+ while (end > pos && end[-1] == ' ')
+ end--;
+ }
k_length-=length;
length=(uint) (end-pos);
FIX_LENGTH(cs, pos, length, char_length);
diff --git a/myisam/sort.c b/myisam/sort.c
index e4c01ac939d..f48161b7c8e 100644
--- a/myisam/sort.c
+++ b/myisam/sort.c
@@ -138,8 +138,9 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
while (memavl >= MIN_SORT_MEMORY)
{
- if ((my_off_t) (records+1)*(sort_length+sizeof(char*)) <=
- (my_off_t) memavl)
+ if ((records < UINT_MAX32) &&
+ ((my_off_t) (records + 1) *
+ (sort_length + sizeof(char*)) <= (my_off_t) memavl))
keys= records+1;
else
do
@@ -151,7 +152,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
keys < (uint) maxbuffer)
{
mi_check_print_error(info->sort_info->param,
- "sort_buffer_size is to small");
+ "myisam_sort_buffer_size is too small");
goto err;
}
}
@@ -175,7 +176,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
}
if (memavl < MIN_SORT_MEMORY)
{
- mi_check_print_error(info->sort_info->param,"Sort buffer to small"); /* purecov: tested */
+ mi_check_print_error(info->sort_info->param,"MyISAM sort buffer too small"); /* purecov: tested */
goto err; /* purecov: tested */
}
(*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */
@@ -369,7 +370,7 @@ pthread_handler_t thr_find_all_keys(void *arg)
keys < (uint) maxbuffer)
{
mi_check_print_error(sort_param->sort_info->param,
- "sort_buffer_size is to small");
+ "myisam_sort_buffer_size is too small");
goto err;
}
}
@@ -397,7 +398,7 @@ pthread_handler_t thr_find_all_keys(void *arg)
if (memavl < MIN_SORT_MEMORY)
{
mi_check_print_error(sort_param->sort_info->param,
- "Sort buffer too small");
+ "MyISAM sort buffer too small");
goto err; /* purecov: tested */
}
@@ -773,7 +774,7 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
{
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
buffpek+i,buffpek+i+MERGEBUFF-1))
- break; /* purecov: inspected */
+ goto cleanup;
}
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
buffpek+i,buffpek+ *maxbuffer))
@@ -783,6 +784,7 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
temp=from_file; from_file=to_file; to_file=temp;
*maxbuffer= (int) (lastbuff-buffpek)-1;
}
+cleanup:
close_cached_file(to_file); /* This holds old result */
if (to_file == t_file)
*t_file=t_file2; /* Copy result file */
diff --git a/myisammrg/myrg_def.h b/myisammrg/myrg_def.h
index 344bd4edd3c..bc114523a80 100644
--- a/myisammrg/myrg_def.h
+++ b/myisammrg/myrg_def.h
@@ -29,4 +29,7 @@ extern pthread_mutex_t THR_LOCK_open;
int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag);
int _myrg_mi_read_record(MI_INFO *info, byte *buf);
-
+#ifdef __cplusplus
+extern "C"
+#endif
+void myrg_print_wrong_table(const char *table_name);
diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c
index afab21dfa3d..0e82e429afd 100644
--- a/myisammrg/myrg_open.c
+++ b/myisammrg/myrg_open.c
@@ -90,6 +90,11 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0))))
{
my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
+ if (handle_locking & HA_OPEN_FOR_REPAIR)
+ {
+ myrg_print_wrong_table(buff);
+ continue;
+ }
goto err;
}
if (!m_info) /* First file */
@@ -118,6 +123,11 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
if (m_info->reclength != isam->s->base.reclength)
{
my_errno=HA_ERR_WRONG_MRG_TABLE_DEF;
+ if (handle_locking & HA_OPEN_FOR_REPAIR)
+ {
+ myrg_print_wrong_table(buff);
+ continue;
+ }
goto err;
}
m_info->options|= isam->s->options;
@@ -131,6 +141,8 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
m_info->tables);
}
+ if (my_errno == HA_ERR_WRONG_MRG_TABLE_DEF)
+ goto err;
if (!m_info && !(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO),
MYF(MY_WME | MY_ZEROFILL))))
goto err;
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index 6c7207b0b2d..ebc2bbb83e8 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -60,6 +60,7 @@ dist-hook:
$(INSTALL_DATA) $(srcdir)/include/*.test $(distdir)/include
$(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.require $(distdir)/r
$(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(distdir)/std_data
+ $(INSTALL_DATA) $(srcdir)/std_data/Index.xml $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.dat $(srcdir)/std_data/*.000001 $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.pem $(distdir)/std_data
@@ -94,6 +95,7 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(DESTDIR)$(testdir)/std_data
+ $(INSTALL_DATA) $(srcdir)/std_data/Index.xml $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.pem $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.frm $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.MY* $(DESTDIR)$(testdir)/std_data
diff --git a/mysql-test/include/federated.inc b/mysql-test/include/federated.inc
index c8e8ededa11..7bdb2efaa8b 100644
--- a/mysql-test/include/federated.inc
+++ b/mysql-test/include/federated.inc
@@ -1,3 +1,4 @@
+--source include/have_log_bin.inc
--source include/not_embedded.inc
--source ./include/have_federated_db.inc
diff --git a/mysql-test/include/have_log_bin.inc b/mysql-test/include/have_log_bin.inc
new file mode 100644
index 00000000000..11530dc953e
--- /dev/null
+++ b/mysql-test/include/have_log_bin.inc
@@ -0,0 +1,4 @@
+-- require r/have_log_bin.require
+disable_query_log;
+show variables like "log_bin";
+enable_query_log;
diff --git a/mysql-test/include/is_debug_build.inc b/mysql-test/include/is_debug_build.inc
deleted file mode 100644
index 23a2814e2bb..00000000000
--- a/mysql-test/include/is_debug_build.inc
+++ /dev/null
@@ -1,4 +0,0 @@
--- require r/is_debug_build.require
---disable_query_log
-select instr(version(), "debug") > 0;
---enable_query_log
diff --git a/mysql-test/include/master-slave.inc b/mysql-test/include/master-slave.inc
index ea09f4e842b..0c27a1d8225 100644
--- a/mysql-test/include/master-slave.inc
+++ b/mysql-test/include/master-slave.inc
@@ -1,3 +1,6 @@
+# Replication tests need binlog
+source include/have_log_bin.inc;
+
connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,);
connect (master1,127.0.0.1,root,,test,$MASTER_MYPORT,);
connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,);
diff --git a/mysql-test/include/show_binlog_events.inc b/mysql-test/include/show_binlog_events.inc
new file mode 100644
index 00000000000..5d60fb19cb5
--- /dev/null
+++ b/mysql-test/include/show_binlog_events.inc
@@ -0,0 +1,4 @@
+--let $binlog_start=98
+--replace_column 5 #
+--replace_regex /\/\* xid=.* \*\//\/* XID *\//
+--eval show binlog events from $binlog_start
diff --git a/mysql-test/include/uses_vardir.inc b/mysql-test/include/uses_vardir.inc
new file mode 100644
index 00000000000..950de698a43
--- /dev/null
+++ b/mysql-test/include/uses_vardir.inc
@@ -0,0 +1,14 @@
+#
+# Some tests uses LOAD DATA with a relative path
+# and need to see for example ../std_data
+#
+# Also if an absolute path was used, the server might be started
+# with --secure-file-priv and wouldn't be allowed to LOAD a file
+# outside of it's vardir anyway
+#
+
+
+if (`select LOCATE('$MYSQLTEST_VARDIR', REPLACE(@@datadir, '\\\\', '/')) != 1`)
+{
+ skip Need mysqld in MYSQLTEST_VARDIR;
+}
diff --git a/mysql-test/include/wait_for_slave_io_to_stop.inc b/mysql-test/include/wait_for_slave_io_to_stop.inc
new file mode 100644
index 00000000000..004f8bbbd8d
--- /dev/null
+++ b/mysql-test/include/wait_for_slave_io_to_stop.inc
@@ -0,0 +1,33 @@
+###################################################
+#Author: Jeb
+#Date: 2007-06-11
+#Purpose: used for io errors on the slave. If Slave gets an io
+# error, the io trhead should stop
+#Details:
+# 1) Fill in and setup variables
+# 2) loop through looking for
+# sql threads to stop
+# 3) If loops too long die.
+####################################################
+connection slave;
+let $my_show= SHOW SLAVE STATUS;
+let $sql_running= Slave_IO_Running;
+let $row_number= 1;
+let $run= 1;
+let $counter= 300;
+
+while ($run)
+{
+ let $io_result= query_get_value("SHOW SLAVE STATUS", Slave_IO_Running, $row_number);
+ if (`SELECT '$io_result' = 'No'`){
+ let $run= 0;
+ }
+ sleep 0.1;
+ if (!$counter){
+ --echo "Failed while waiting for slave IO thread to stop"
+ SHOW SLAVE STATUS;
+ exit;
+ }
+ dec $counter;
+}
+
diff --git a/mysql-test/include/wait_for_slave_param.inc b/mysql-test/include/wait_for_slave_param.inc
new file mode 100644
index 00000000000..fed97195aba
--- /dev/null
+++ b/mysql-test/include/wait_for_slave_param.inc
@@ -0,0 +1,26 @@
+# include/wait_for_slave_param.inc
+#
+# SUMMARY
+#
+# Waits until SHOW SLAVE STATUS has returned a spicified value.
+#
+# USAGE
+#
+# let $slave_param= Slave_SQL_Running;
+# let $slave_param_value= No;
+# --source include/slave_wait_param.inc
+
+let $slave_wait_param_counter= 300;
+let $slave_value= query_get_value("SHOW SLAVE STATUS", $slave_param, 1);
+while (`select "$slave_value" != "$slave_param_value"`)
+{
+ dec $slave_wait_param_counter;
+ if (!$slave_wait_param_counter)
+ {
+ --echo ERROR: failed while waiting for slave parameter $slave_param: $slave_param_value
+ query_vertical show slave status;
+ exit;
+ }
+ sleep 0.1;
+ let $slave_value= query_get_value("SHOW SLAVE STATUS", $slave_param, 1);
+}
diff --git a/mysql-test/include/wait_for_slave_sql_to_stop.inc b/mysql-test/include/wait_for_slave_sql_to_stop.inc
new file mode 100644
index 00000000000..ee765c81f6a
--- /dev/null
+++ b/mysql-test/include/wait_for_slave_sql_to_stop.inc
@@ -0,0 +1,30 @@
+###################################################
+#Author: Jeb
+#Date: 2007-06-11
+#Purpose: used for SQL errors on the slave. If Slave gets a sql
+# error, the SQL trhead should stop
+#Details:
+# 1) Fill in and setup variables
+# 2) loop through looking for
+# sql threads to stop
+# 3) If loops too long die.
+####################################################
+connection slave;
+let $row_number= 1;
+let $run= 1;
+let $counter= 300;
+
+while ($run)
+{
+ let $sql_result= query_get_value("SHOW SLAVE STATUS", Slave_SQL_Running, $row_number);
+ if (`SELECT '$sql_result' = 'No'`){
+ let $run= 0;
+ }
+ sleep 0.1;
+ if (!$counter){
+ --echo "Failed while waiting for slave SQL thread to stop"
+ SHOW SLAVE STATUS;
+ exit;
+ }
+ dec $counter;
+}
diff --git a/mysql-test/include/wait_for_slave_to_start.inc b/mysql-test/include/wait_for_slave_to_start.inc
new file mode 100644
index 00000000000..84e1d646efe
--- /dev/null
+++ b/mysql-test/include/wait_for_slave_to_start.inc
@@ -0,0 +1,35 @@
+###################################################
+#Author: Jeb
+#Date: 2007-06-11
+#Purpose: To wait a brief time for slave to start
+#Details:
+# 1) Fill in and setup variables
+# 2) loop through looking for both
+# io and sql threads to start
+# 3) If loops too long die.
+####################################################
+connection slave;
+let $row_number= 1;
+let $run= 1;
+let $counter= 300;
+
+while ($run)
+{
+ let $io_result= query_get_value("SHOW SLAVE STATUS", Slave_IO_Running, $row_number);
+ if (`SELECT '$io_result' = 'Yes'`){
+
+ let $sql_result= query_get_value("SHOW SLAVE STATUS", Slave_SQL_Running, $row_number);
+ if (`SELECT '$sql_result' = 'Yes'`){
+ let $run= 0;
+ }
+ }
+ sleep 0.1;
+ if (!$counter){
+ --echo "Failed while waiting for slave to start"
+ SHOW SLAVE STATUS;
+ exit;
+ }
+ dec $counter;
+}
+
+
diff --git a/mysql-test/include/wait_for_slave_to_stop.inc b/mysql-test/include/wait_for_slave_to_stop.inc
new file mode 100644
index 00000000000..13acbecb835
--- /dev/null
+++ b/mysql-test/include/wait_for_slave_to_stop.inc
@@ -0,0 +1,37 @@
+###################################################
+#Author: Jeb
+#Date: 2007-06-11
+#Purpose: To replace the mysqltest.c executable
+# wait_for_slave_to_stop function and
+# return this to the test language.
+#Details:
+# 1) Fill in and setup variables
+# 2) loop through looking for both
+# io and sql threads to stop
+# 3) If loops too long die.
+####################################################
+connection slave;
+let $row_number= 1;
+let $run= 1;
+let $counter= 300;
+
+while ($run)
+{
+ let $io_result= query_get_value("SHOW SLAVE STATUS", Slave_IO_Running, $row_number);
+ if (`SELECT '$io_result' = 'No'`){
+
+ let $sql_result= query_get_value("SHOW SLAVE STATUS", Slave_SQL_Running, $row_number);
+ if (`SELECT '$sql_result' = 'No'`){
+ let $run= 0;
+ }
+ }
+ sleep 0.1;
+ if (!$counter){
+ --echo "Failed while waiting for slave to stop"
+ SHOW SLAVE STATUS;
+ exit;
+ }
+ dec $counter;
+}
+
+
diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl
index 1d157ea3401..5e176dce109 100644
--- a/mysql-test/lib/mtr_cases.pl
+++ b/mysql-test/lib/mtr_cases.pl
@@ -596,6 +596,25 @@ sub collect_one_test_case($$$$$$$) {
}
}
+ if ( $tinfo->{'need_binlog'} )
+ {
+ if (grep(/^--skip-log-bin/, @::opt_extra_mysqld_opt) )
+ {
+ $tinfo->{'skip'}= 1;
+ $tinfo->{'comment'}= "Test need binlog";
+ return;
+ }
+ }
+ else
+ {
+ if ( $::mysql_version_id >= 50100 )
+ {
+ # Test does not need binlog, add --skip-binlog to
+ # the options used when starting it
+ push(@{$tinfo->{'master_opt'}}, "--skip-log-bin");
+ }
+ }
+
}
}
@@ -608,6 +627,7 @@ our @tags=
["include/have_binlog_format_row.inc", "binlog_format", "row"],
["include/have_binlog_format_statement.inc", "binlog_format", "stmt"],
["include/have_binlog_format_mixed.inc", "binlog_format", "mixed"],
+ ["include/have_log_bin.inc", "need_binlog", 1],
["include/big_test.inc", "big_test", 1],
["include/have_debug.inc", "need_debug", 1],
["include/have_ndb.inc", "ndb_test", 1],
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index ac2e049a67c..e4fd3390c5f 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -547,72 +547,87 @@ sub mtr_kill_leftovers () {
}
-# Check that all processes in list are killed
-# The argument is a list of 'ports', 'pids', 'pidfiles' and 'socketfiles'
-# for which shutdown has been started. Make sure they all get killed
-# in one way or the other.
#
-# FIXME On Cygwin, and maybe some other platforms, $srv->{'pid'} and
-# the pid in $srv->{'pidfile'} will not be the same PID. We need to try to kill
-# both I think.
-
+# Check that all processes in "spec" are shutdown gracefully
+# else kill them off hard
+#
sub mtr_check_stop_servers ($) {
my $spec= shift;
# Return if no processes are defined
return if ! @$spec;
- #mtr_report("mtr_check_stop_servers");
+ mtr_verbose("mtr_check_stop_servers");
+ # ----------------------------------------------------------------------
+ # Wait until servers in "spec" has stopped listening
+ # to their ports or timeout occurs
+ # ----------------------------------------------------------------------
mtr_ping_with_timeout(\@$spec);
# ----------------------------------------------------------------------
- # We loop with waitpid() nonblocking to see how many of the ones we
- # are to kill, actually got killed by mysqladmin or ndb_mgm
- #
- # Note that we don't rely on this, the mysqld server might have stopped
- # listening to the port, but still be alive. But it is a start.
+ # Use waitpid() nonblocking for a little while, to see how
+ # many process's will exit sucessfully.
+ # This is the normal case.
# ----------------------------------------------------------------------
-
+ my $wait_counter= 50; # Max number of times to redo the loop
foreach my $srv ( @$spec )
{
+ my $pid= $srv->{'pid'};
my $ret_pid;
- if ( $srv->{'pid'} )
+ if ( $pid )
{
- $ret_pid= waitpid($srv->{'pid'},&WNOHANG);
- if ($ret_pid == $srv->{'pid'})
+ $ret_pid= waitpid($pid,&WNOHANG);
+ if ($ret_pid == $pid)
{
mtr_verbose("Caught exit of process $ret_pid");
$srv->{'pid'}= 0;
}
+ elsif ($ret_pid == 0)
+ {
+ mtr_verbose("Process $pid is still alive");
+ if ($wait_counter-- > 0)
+ {
+ # Give the processes more time to exit
+ select(undef, undef, undef, (0.1));
+ redo;
+ }
+ }
else
{
- # mtr_warning("caught exit of unknown child $ret_pid");
+ mtr_warning("caught exit of unknown child $ret_pid");
}
}
}
# ----------------------------------------------------------------------
- # We know the process was started from this file, so there is a PID
- # saved, or else we have nothing to do.
- # Might be that is is recorded to be missing, but we failed to
- # take away the PID file earlier, then we do it now.
+ # The processes that haven't yet exited need to
+ # be killed hard, put them in "kill_pids" hash
# ----------------------------------------------------------------------
-
- my %mysqld_pids;
-
+ my %kill_pids;
foreach my $srv ( @$spec )
{
- if ( $srv->{'pid'} )
+ my $pid= $srv->{'pid'};
+ if ( $pid )
{
- $mysqld_pids{$srv->{'pid'}}= 1;
+ # Server is still alive, put it in list to be hard killed
+ $kill_pids{$pid}= 1;
+
+ # Write a message to the process's error log (if it has one)
+ # that it's being killed hard.
+ if ( defined $srv->{'errfile'} )
+ {
+ mtr_tofile($srv->{'errfile'}, "Note: Forcing kill of process $pid\n");
+ }
+ mtr_warning("Forcing kill of process $pid");
+
}
else
{
- # Server is dead, we remove the pidfile if any
- # Race, could have been removed between I tested with -f
- # and the unlink() below, so I better check again with -f
-
+ # Server is dead, remove the pidfile if it exists
+ #
+ # Race, could have been removed between test with -f
+ # and the unlink() below, so better check again with -f
if ( -f $srv->{'pidfile'} and ! unlink($srv->{'pidfile'}) and
-f $srv->{'pidfile'} )
{
@@ -621,69 +636,35 @@ sub mtr_check_stop_servers ($) {
}
}
- # ----------------------------------------------------------------------
- # If all the processes in list already have been killed,
- # then we don't have to do anything.
- # ----------------------------------------------------------------------
-
- if ( ! keys %mysqld_pids )
+ if ( ! keys %kill_pids )
{
+ # All processes has exited gracefully
return;
}
- # ----------------------------------------------------------------------
- # In mtr_mysqladmin_shutdown() we only waited for the mysqld servers
- # not to listen to the port. But we are not sure we got them all
- # killed. If we suspect it lives, try nice kill with SIG_TERM. Note
- # that for true Win32 processes, kill(0,$pid) will not return 1.
- # ----------------------------------------------------------------------
-
- start_reap_all(); # Avoid zombies
-
- my @mysqld_pids= keys %mysqld_pids;
- mtr_kill_processes(\@mysqld_pids);
-
- stop_reap_all(); # Get into control again
+ mtr_kill_processes(\%kill_pids);
# ----------------------------------------------------------------------
- # Now, we check if all we can find using kill(0,$pid) are dead,
- # and just assume the rest are. We cleanup socket and PID files.
+ # All processes are killed, cleanup leftover files
# ----------------------------------------------------------------------
-
{
my $errors= 0;
foreach my $srv ( @$spec )
{
if ( $srv->{'pid'} )
{
- if ( kill(0,$srv->{'pid'}) )
- {
- # FIXME In Cygwin there seem to be some fast reuse
- # of PIDs, so dying may not be the right thing to do.
- $errors++;
- mtr_warning("can't kill process $srv->{'pid'}");
- }
- else
+ # Server has been hard killed, clean it's resources
+ foreach my $file ($srv->{'pidfile'}, $srv->{'sockfile'})
{
- # We managed to kill it at last
- # FIXME In Cygwin, we will get here even if the process lives.
-
- # Not needed as we know the process is dead, but to be safe
- # we unlink and check success in two steps. We first unlink
- # without checking the error code, and then check if the
- # file still exists.
-
- foreach my $file ($srv->{'pidfile'}, $srv->{'sockfile'})
+ # Know it is dead so should be no race, careful anyway
+ if ( defined $file and -f $file and ! unlink($file) and -f $file )
{
- # Know it is dead so should be no race, careful anyway
- if ( defined $file and -f $file and ! unlink($file) and -f $file )
- {
- $errors++;
- mtr_warning("couldn't delete $file");
- }
- }
- $srv->{'pid'}= 0;
- }
+ $errors++;
+ mtr_warning("couldn't delete $file");
+ }
+ }
+
+ $srv->{'pid'}= 0;
}
}
if ( $errors )
@@ -701,12 +682,9 @@ sub mtr_check_stop_servers ($) {
}
}
}
-
- # FIXME We just assume they are all dead, for Cygwin we are not
- # really sure
-
}
+
# Wait for all the process in the list to terminate
sub mtr_wait_blocking($) {
my $admin_pids= shift;
@@ -1095,9 +1073,9 @@ sub sleep_until_file_created ($$$) {
sub mtr_kill_processes ($) {
my $pids = shift;
- mtr_verbose("mtr_kill_processes " . join(" ", @$pids));
+ mtr_verbose("mtr_kill_processes (" . join(" ", keys %{$pids}) . ")");
- foreach my $pid (@$pids)
+ foreach my $pid (keys %{$pids})
{
if ($pid <= 0)
@@ -1106,11 +1084,26 @@ sub mtr_kill_processes ($) {
next;
}
- foreach my $sig (15, 9)
+ my $signaled_procs= kill(9, $pid);
+ if ($signaled_procs == 0)
{
- last if mtr_im_kill_process([ $pid ], $sig, 10, 1);
+ # No such process existed, assume it's killed
+ mtr_verbose("killed $pid(no such process)");
+ }
+ else
+ {
+ my $ret_pid= waitpid($pid,0);
+ if ($ret_pid == $pid)
+ {
+ mtr_verbose("killed $pid(got the pid)");
+ }
+ elsif ($ret_pid == -1)
+ {
+ mtr_verbose("killed $pid(got -1)");
+ }
}
}
+ mtr_verbose("done killing processes");
}
diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl
index d08208d37a6..1abfc6b6b57 100644
--- a/mysql-test/lib/mtr_report.pl
+++ b/mysql-test/lib/mtr_report.pl
@@ -272,6 +272,7 @@ sub mtr_report_stats ($) {
{
foreach my $errlog ( sort glob("$::opt_vardir/log/*.err") )
{
+ my $testname= "";
unless ( open(ERR, $errlog) )
{
mtr_warning("can't read $errlog");
@@ -287,10 +288,14 @@ sub mtr_report_stats ($) {
{
next; # Skip these lines
}
+ if ( /CURRENT_TEST: (.*)/ )
+ {
+ $testname= $1;
+ }
if ( /$pattern/ )
{
$found_problems= 1;
- print WARN $_;
+ print WARN basename($errlog) . ": $testname: $_";
}
}
}
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index c494626bbae..08090e5b96f 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -903,6 +903,9 @@ sub command_line_setup () {
$opt_skip_ndbcluster= 1; # Turn off use of NDB cluster
$opt_skip_ssl= 1; # Turn off use of SSL
+ # Turn off use of bin log
+ push(@opt_extra_mysqld_opt, "--skip-log-bin");
+
if ( $opt_extern )
{
mtr_error("Can't use --extern with --embedded-server");
@@ -1071,7 +1074,7 @@ sub command_line_setup () {
# On some operating systems, there is a limit to the length of a
# UNIX domain socket's path far below PATH_MAX, so try to avoid long
# socket path names.
- $sockdir = tempdir(CLEANUP => 0) if ( length($sockdir) >= 80 );
+ $sockdir = tempdir(CLEANUP => 0) if ( length($sockdir) >= 70 );
$master->[0]=
{
@@ -1784,6 +1787,17 @@ sub environment_setup () {
split(':', $ENV{'DYLD_LIBRARY_PATH'}) : ());
mtr_debug("DYLD_LIBRARY_PATH: $ENV{'DYLD_LIBRARY_PATH'}");
+ # The environment variable used for shared libs on AIX
+ $ENV{'SHLIB_PATH'}= join(":", @ld_library_paths,
+ $ENV{'SHLIB_PATH'} ?
+ split(':', $ENV{'SHLIB_PATH'}) : ());
+ mtr_debug("SHLIB_PATH: $ENV{'SHLIB_PATH'}");
+
+ # The environment variable used for shared libs on hp-ux
+ $ENV{'LIBPATH'}= join(":", @ld_library_paths,
+ $ENV{'LIBPATH'} ?
+ split(':', $ENV{'LIBPATH'}) : ());
+ mtr_debug("LIBPATH: $ENV{'LIBPATH'}");
# --------------------------------------------------------------------------
# Also command lines in .opt files may contain env vars
@@ -1792,6 +1806,18 @@ sub environment_setup () {
$ENV{'CHARSETSDIR'}= $path_charsetsdir;
$ENV{'UMASK'}= "0660"; # The octal *string*
$ENV{'UMASK_DIR'}= "0770"; # The octal *string*
+
+ #
+ # MySQL tests can produce output in various character sets
+ # (especially, ctype_xxx.test). To avoid confusing Perl
+ # with output which is incompatible with the current locale
+ # settings, we reset the current values of LC_ALL and LC_CTYPE to "C".
+ # For details, please see
+ # Bug#27636 tests fails if LC_* variables set to *_*.UTF-8
+ #
+ $ENV{'LC_ALL'}= "C";
+ $ENV{'LC_CTYPE'}= "C";
+
$ENV{'LC_COLLATE'}= "C";
$ENV{'USE_RUNNING_SERVER'}= $opt_extern;
$ENV{'MYSQL_TEST_DIR'}= $glob_mysql_test_dir;
@@ -2307,16 +2333,23 @@ sub check_running_as_root () {
close FILE;
}
- chmod(oct("0755"), $test_file);
- unlink($test_file);
+ # Some filesystems( for example CIFS) allows reading a file
+ # although mode was set to 0000, but in that case a stat on
+ # the file will not return 0000
+ my $file_mode= (stat($test_file))[2] & 07777;
$ENV{'MYSQL_TEST_ROOT'}= "NO";
- if ($result eq "MySQL")
+ mtr_verbose("result: $result, file_mode: $file_mode");
+ if ($result eq "MySQL" && $file_mode == 0)
{
mtr_warning("running this script as _root_ will cause some " .
"tests to be skipped");
$ENV{'MYSQL_TEST_ROOT'}= "YES";
}
+
+ chmod(oct("0755"), $test_file);
+ unlink($test_file);
+
}
@@ -3285,9 +3318,12 @@ sub find_testcase_skipped_reason($)
{
my ($tinfo)= @_;
- # Open mysqltest-time
- my $F= IO::File->new($path_timefile) or
- mtr_error("can't open file \"$path_timefile\": $!");
+ # Set default message
+ $tinfo->{'comment'}= "Detected by testcase(no log file)";
+
+ # Open mysqltest-time(the mysqltest log file)
+ my $F= IO::File->new($path_timefile)
+ or return;
my $reason;
while ( my $line= <$F> )
@@ -3340,8 +3376,8 @@ sub analyze_testcase_failure($)
my ($tinfo)= @_;
# Open mysqltest.log
- my $F= IO::File->new($path_timefile) or
- mtr_error("can't open file \"$path_timefile\": $!");
+ my $F= IO::File->new($path_timefile)
+ or return;
while ( my $line= <$F> )
{
@@ -3600,6 +3636,9 @@ sub do_before_start_master ($) {
# FIXME what about second master.....
+ # Don't delete anything if starting dirty
+ return if ($opt_start_dirty);
+
foreach my $bin ( glob("$opt_vardir/log/master*-bin*") )
{
unlink($bin);
@@ -3631,6 +3670,9 @@ sub do_before_start_slave ($) {
my $tname= $tinfo->{'name'};
my $init_script= $tinfo->{'master_sh'};
+ # Don't delete anything if starting dirty
+ return if ($opt_start_dirty);
+
foreach my $bin ( glob("$opt_vardir/log/slave*-bin*") )
{
unlink($bin);
@@ -3740,8 +3782,7 @@ sub mysqld_arguments ($$$$) {
"%s--log-slow-queries=%s-slow.log", $prefix, $log_base_path);
# Check if "extra_opt" contains --skip-log-bin
- my $skip_binlog= grep(/^--skip-log-bin/, @$extra_opt);
-
+ my $skip_binlog= grep(/^--skip-log-bin/, @$extra_opt, @opt_extra_mysqld_opt);
if ( $mysqld->{'type'} eq 'master' )
{
if (! ($opt_skip_master_binlog || $skip_binlog) )
@@ -4055,6 +4096,7 @@ sub stop_all_servers () {
pidfile => $mysqld->{'path_pid'},
sockfile => $mysqld->{'path_sock'},
port => $mysqld->{'port'},
+ errfile => $mysqld->{'path_myerr'},
});
$mysqld->{'pid'}= 0; # Assume we are done with it
@@ -4261,6 +4303,7 @@ sub run_testcase_stop_servers($$$) {
pidfile => $mysqld->{'path_pid'},
sockfile => $mysqld->{'path_sock'},
port => $mysqld->{'port'},
+ errfile => $mysqld->{'path_myerr'},
});
$mysqld->{'pid'}= 0; # Assume we are done with it
@@ -4311,6 +4354,7 @@ sub run_testcase_stop_servers($$$) {
pidfile => $mysqld->{'path_pid'},
sockfile => $mysqld->{'path_sock'},
port => $mysqld->{'port'},
+ errfile => $mysqld->{'path_myerr'},
});
diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result
index 0ecc462fb70..49722d5b0ab 100644
--- a/mysql-test/r/analyse.result
+++ b/mysql-test/r/analyse.result
@@ -39,10 +39,10 @@ t2 CREATE TABLE `t2` (
`Field_name` varbinary(255) NOT NULL default '',
`Min_value` varbinary(255) default NULL,
`Max_value` varbinary(255) default NULL,
- `Min_length` int(11) NOT NULL default '0',
- `Max_length` int(11) NOT NULL default '0',
- `Empties_or_zeros` int(11) NOT NULL default '0',
- `Nulls` int(11) NOT NULL default '0',
+ `Min_length` bigint(11) NOT NULL default '0',
+ `Max_length` bigint(11) NOT NULL default '0',
+ `Empties_or_zeros` bigint(11) NOT NULL default '0',
+ `Nulls` bigint(11) NOT NULL default '0',
`Avg_value_or_avg_length` varbinary(255) NOT NULL default '',
`Std` varbinary(255) default NULL,
`Optimal_fieldtype` varbinary(64) NOT NULL default ''
@@ -58,10 +58,10 @@ t2 CREATE TABLE `t2` (
`Field_name` varbinary(255) NOT NULL default '',
`Min_value` varbinary(255) default NULL,
`Max_value` varbinary(255) default NULL,
- `Min_length` int(11) NOT NULL default '0',
- `Max_length` int(11) NOT NULL default '0',
- `Empties_or_zeros` int(11) NOT NULL default '0',
- `Nulls` int(11) NOT NULL default '0',
+ `Min_length` bigint(11) NOT NULL default '0',
+ `Max_length` bigint(11) NOT NULL default '0',
+ `Empties_or_zeros` bigint(11) NOT NULL default '0',
+ `Nulls` bigint(11) NOT NULL default '0',
`Avg_value_or_avg_length` varbinary(255) NOT NULL default '',
`Std` varbinary(255) default NULL,
`Optimal_fieldtype` varbinary(64) NOT NULL default ''
@@ -81,10 +81,10 @@ t2 CREATE TABLE `t2` (
`Field_name` varbinary(255) NOT NULL default '',
`Min_value` varbinary(255) default NULL,
`Max_value` varbinary(255) default NULL,
- `Min_length` int(11) NOT NULL default '0',
- `Max_length` int(11) NOT NULL default '0',
- `Empties_or_zeros` int(11) NOT NULL default '0',
- `Nulls` int(11) NOT NULL default '0',
+ `Min_length` bigint(11) NOT NULL default '0',
+ `Max_length` bigint(11) NOT NULL default '0',
+ `Empties_or_zeros` bigint(11) NOT NULL default '0',
+ `Nulls` bigint(11) NOT NULL default '0',
`Avg_value_or_avg_length` varbinary(255) NOT NULL default '',
`Std` varbinary(255) default NULL,
`Optimal_fieldtype` varbinary(64) NOT NULL default ''
diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result
index d0058118e4c..90ba00e1019 100644
--- a/mysql-test/r/auto_increment.result
+++ b/mysql-test/r/auto_increment.result
@@ -232,7 +232,7 @@ a b
delete from t1 where a=0;
update t1 set a=NULL where b=6;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 4
+Warning 1048 Column 'a' cannot be null
update t1 set a=300 where b=7;
SET SQL_MODE='';
insert into t1(a,b)values(NULL,8);
@@ -274,7 +274,7 @@ a b
delete from t1 where a=0;
update t1 set a=NULL where b=13;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 9
+Warning 1048 Column 'a' cannot be null
update t1 set a=500 where b=14;
select * from t1 order by b;
a b
diff --git a/mysql-test/r/backup.result b/mysql-test/r/backup.result
index 29702e583cc..14313ba490f 100644
--- a/mysql-test/r/backup.result
+++ b/mysql-test/r/backup.result
@@ -4,18 +4,16 @@ create table t4(n int);
backup table t4 to '../bogus';
Table Op Msg_type Msg_text
test.t4 backup error Failed copying .frm file (errno: X)
+test.t4 backup Error Can't create/write to file 'MYSQLTEST_VARDIR/bogus/t4.frm' (Errcode: X)
test.t4 backup status Operation failed
-Warnings:
-Error 1 Can't create/write to file 'MYSQLTEST_VARDIR/bogus/t4.frm' (Errcode: X)
backup table t4 to '../tmp';
Table Op Msg_type Msg_text
test.t4 backup status OK
backup table t4 to '../tmp';
Table Op Msg_type Msg_text
test.t4 backup error Failed copying .frm file (errno: X)
+test.t4 backup Error Can't create/write to file 'MYSQLTEST_VARDIR/tmp/t4.frm' (Errcode: X)
test.t4 backup status Operation failed
-Warnings:
-Error 1 Can't create/write to file 'MYSQLTEST_VARDIR/tmp/t4.frm' (Errcode: X)
drop table t4;
restore table t4 from '../tmp';
Table Op Msg_type Msg_text
diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result
index f18d1c9b583..064304b27aa 100644
--- a/mysql-test/r/bigint.result
+++ b/mysql-test/r/bigint.result
@@ -362,3 +362,29 @@ cast(-19999999999999999999 as signed)
-9223372036854775808
Warnings:
Error 1292 Truncated incorrect DECIMAL value: ''
+select -9223372036854775808;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def -9223372036854775808 8 20 20 N 32897 0 63
+-9223372036854775808
+-9223372036854775808
+select -(9223372036854775808);
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def -(9223372036854775808) 8 20 20 N 32897 0 63
+-(9223372036854775808)
+-9223372036854775808
+select -((9223372036854775808));
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def -((9223372036854775808)) 8 20 20 N 32897 0 63
+-((9223372036854775808))
+-9223372036854775808
+select -(-(9223372036854775808));
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def -(-(9223372036854775808)) 246 21 19 N 129 0 63
+-(-(9223372036854775808))
+9223372036854775808
+select --9223372036854775808, ---9223372036854775808, ----9223372036854775808;
+--9223372036854775808 ---9223372036854775808 ----9223372036854775808
+9223372036854775808 -9223372036854775808 9223372036854775808
+select -(-9223372036854775808), -(-(-9223372036854775808));
+-(-9223372036854775808) -(-(-9223372036854775808))
+9223372036854775808 -9223372036854775808
diff --git a/mysql-test/r/binary.result b/mysql-test/r/binary.result
index c5673d1c00d..c8b3768b7ce 100644
--- a/mysql-test/r/binary.result
+++ b/mysql-test/r/binary.result
@@ -160,3 +160,41 @@ hex(col1)
62000000000000000000
62200000000000000000
drop table t1;
+CREATE TABLE t1 (
+a binary(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
+index idx(a)
+);
+INSERT INTO t1 SET a=unhex('1F9480179366F2BF567E1C4B964C1EF029087575');
+INSERT INTO t1 SET a=unhex('1F9480179366F2BF567E1C4B964C1EF029082020');
+INSERT INTO t1 SET a=unhex('1F9480179366F2BF567E1C4B964C1EF029080707');
+SELECT hex(a) FROM t1 order by a;
+hex(a)
+1F9480179366F2BF567E1C4B964C1EF029080707
+1F9480179366F2BF567E1C4B964C1EF029082020
+1F9480179366F2BF567E1C4B964C1EF029087575
+EXPLAIN SELECT hex(a) FROM t1 order by a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL idx 20 NULL 3 Using index
+SELECT hex(a) from t1 WHERE a=unhex('1F9480179366F2BF567E1C4B964C1EF029082020');
+hex(a)
+1F9480179366F2BF567E1C4B964C1EF029082020
+EXPLAIN
+SELECT hex(a) from t1 WHERE a=unhex('1F9480179366F2BF567E1C4B964C1EF029082020');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx idx 20 const 1 Using where; Using index
+SELECT hex(a) from t1 WHERE a=unhex('1F9480179366F2BF567E1C4B964C1EF02908');
+hex(a)
+DROP TABLE t1;
+CREATE TABLE t1 (
+id numeric(20) NOT NULL,
+lang varchar(8) NOT NULL,
+msg varchar(32) NOT NULL,
+PRIMARY KEY (id,lang)
+);
+INSERT INTO t1 VALUES (33, 'en', 'zzzzzzz');
+INSERT INTO t1 VALUES (31, 'en', 'xxxxxxx');
+INSERT INTO t1 VALUES (32, 'en', 'yyyyyyy');
+SELECT * FROM t1 WHERE id=32;
+id lang msg
+32 en yyyyyyy
+DROP TABLE t1;
diff --git a/mysql-test/r/binlog.result b/mysql-test/r/binlog.result
index 25930c31735..6807da16e66 100644
--- a/mysql-test/r/binlog.result
+++ b/mysql-test/r/binlog.result
@@ -17,7 +17,7 @@ master-bin.000001 # Query 1 # use `test`; insert t1 values (5)
master-bin.000001 # Query 1 # use `test`; COMMIT
master-bin.000001 # Query 1 # use `test`; BEGIN
master-bin.000001 # Query 1 # use `test`; insert t2 values (5)
-master-bin.000001 # Xid 1 # COMMIT /* xid=12 */
+master-bin.000001 # Xid 1 # COMMIT /* XID */
drop table t1,t2;
reset master;
create table t1 (n int) engine=innodb;
@@ -128,7 +128,7 @@ master-bin.000001 # Query 1 # use `test`; insert into t1 values(4 + 4)
master-bin.000001 # Query 1 # use `test`; insert into t1 values(3 + 4)
master-bin.000001 # Query 1 # use `test`; insert into t1 values(2 + 4)
master-bin.000001 # Query 1 # use `test`; insert into t1 values(1 + 4)
-master-bin.000001 # Xid 1 # COMMIT /* xid=19 */
+master-bin.000001 # Xid 1 # COMMIT /* XID */
master-bin.000001 # Rotate 1 # master-bin.000002;pos=4
show binlog events in 'master-bin.000002' from 98;
Log_name Pos Event_type Server_id End_log_pos Info
diff --git a/mysql-test/r/binlog_innodb.result b/mysql-test/r/binlog_innodb.result
new file mode 100644
index 00000000000..93414a13ba1
--- /dev/null
+++ b/mysql-test/r/binlog_innodb.result
@@ -0,0 +1,23 @@
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 0
+show status like "binlog_cache_disk_use";
+Variable_name Value
+Binlog_cache_disk_use 0
+create table t1 (a int) engine=innodb;
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 1
+show status like "binlog_cache_disk_use";
+Variable_name Value
+Binlog_cache_disk_use 1
+begin;
+delete from t1;
+commit;
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 2
+show status like "binlog_cache_disk_use";
+Variable_name Value
+Binlog_cache_disk_use 1
+drop table t1;
diff --git a/mysql-test/r/binlog_killed.result b/mysql-test/r/binlog_killed.result
new file mode 100644
index 00000000000..ba4f38fb4c1
--- /dev/null
+++ b/mysql-test/r/binlog_killed.result
@@ -0,0 +1,12 @@
+create table t1 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB;
+create table t2 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=MyISAM;
+create table t3 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB;
+select get_lock("a", 20);
+get_lock("a", 20)
+1
+reset master;
+insert into t2 values (null, null), (null, get_lock("a", 10));
+select @result /* must be zero either way */;
+@result
+0
+drop table t1,t2,t3;
diff --git a/mysql-test/r/blackhole.result b/mysql-test/r/blackhole.result
index 0ee5f326e0f..5ab4931b53b 100644
--- a/mysql-test/r/blackhole.result
+++ b/mysql-test/r/blackhole.result
@@ -123,6 +123,10 @@ master-bin.000001 # Query 1 # use `test`; create table t3 like t1
master-bin.000001 # Query 1 # use `test`; insert into t1 select * from t3
master-bin.000001 # Query 1 # use `test`; replace into t1 select * from t3
drop table t1,t2,t3;
+CREATE TABLE t1(a INT) ENGINE=BLACKHOLE;
+INSERT DELAYED INTO t1 VALUES(1);
+ERROR HY000: Table storage engine for 't1' doesn't have this option
+DROP TABLE t1;
CREATE TABLE t1(a INT, b INT) ENGINE=BLACKHOLE;
DELETE FROM t1 WHERE a=10;
ALTER TABLE t1 ADD INDEX(a);
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index e1262c7d2c2..c1f72ce317c 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -13,7 +13,7 @@ Warnings:
Note 1050 Table 't1' already exists
insert into t1 values (""),(null);
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'b' at row 2
+Warning 1048 Column 'b' cannot be null
select * from t1;
b
diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result
index 8ec79e9d7a9..3900597d2a6 100644
--- a/mysql-test/r/csv.result
+++ b/mysql-test/r/csv.result
@@ -5009,3 +5009,24 @@ select * from bug15205;
val
drop table bug15205;
drop table bug15205_2;
+set names latin1;
+create table t1 (
+c varchar(1),
+name varchar(64)
+) character set latin1 engine=csv;
+insert into t1 values (0xC0,'LATIN CAPITAL LETTER A WITH GRAVE');
+insert into t1 values (0xE0,'LATIN SMALL LETTER A WITH GRAVE');
+insert into t1 values (0xEE,'LATIN SMALL LETTER I WITH CIRCUMFLEX');
+insert into t1 values (0xFE,'LATIN SMALL LETTER THORN');
+insert into t1 values (0xF7,'DIVISION SIGN');
+insert into t1 values (0xFF,'LATIN SMALL LETTER Y WITH DIAERESIS');
+select hex(c), c, name from t1 order by 1;
+hex(c) c name
+C0 À LATIN CAPITAL LETTER A WITH GRAVE
+E0 à LATIN SMALL LETTER A WITH GRAVE
+EE î LATIN SMALL LETTER I WITH CIRCUMFLEX
+F7 ÷ DIVISION SIGN
+FE þ LATIN SMALL LETTER THORN
+FF ÿ LATIN SMALL LETTER Y WITH DIAERESIS
+drop table t1;
+End of 5.0 tests
diff --git a/mysql-test/r/ctype_big5.result b/mysql-test/r/ctype_big5.result
index 6574908101c..3f1a87838cf 100644
--- a/mysql-test/r/ctype_big5.result
+++ b/mysql-test/r/ctype_big5.result
@@ -192,3 +192,16 @@ drop table t1;
select hex(convert(_big5 0xC84041 using ucs2));
hex(convert(_big5 0xC84041 using ucs2))
003F0041
+End of 4.1 tests
+create table t1 (a blob);
+insert into t1 values (0xEE00);
+delete from t1;
+select hex(load_file('test/t1.txt'));
+hex(load_file('test/t1.txt'))
+5CEE5C300A
+load data infile 't1.txt' into table t1;
+select hex(a) from t1;
+hex(a)
+EE00
+drop table t1;
+End of 5.0 tests
diff --git a/mysql-test/r/ctype_cp932_binlog.result b/mysql-test/r/ctype_cp932_binlog.result
index ff295961008..3385cd20ec4 100644
--- a/mysql-test/r/ctype_cp932_binlog.result
+++ b/mysql-test/r/ctype_cp932_binlog.result
@@ -9,8 +9,7 @@ EXECUTE stmt1 USING @var1;
SHOW BINLOG EVENTS FROM 98;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 98 Query 1 188 use `test`; CREATE TABLE t1(f1 blob)
-master-bin.000001 188 User var 1 227 @`var1`=_binary 0x8300 COLLATE binary
-master-bin.000001 227 Query 1 323 use `test`; INSERT INTO t1 VALUES(@'var1')
+master-bin.000001 188 Query 1 283 use `test`; INSERT INTO t1 VALUES(0x8300)
SELECT HEX(f1) FROM t1;
HEX(f1)
8300
@@ -30,17 +29,17 @@ HEX(s1) HEX(s2) d
466F6F2773206120426172 ED40ED41ED42 47.93
DROP PROCEDURE bug18293|
DROP TABLE t4|
-SHOW BINLOG EVENTS FROM 402|
+SHOW BINLOG EVENTS FROM 362|
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 402 Query 1 568 use `test`; CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1,
+master-bin.000001 362 Query 1 528 use `test`; CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1,
s2 CHAR(50) CHARACTER SET cp932,
d DECIMAL(10,2))
-master-bin.000001 568 Query 1 816 use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE bug18293 (IN ins1 CHAR(50),
+master-bin.000001 528 Query 1 776 use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE bug18293 (IN ins1 CHAR(50),
IN ins2 CHAR(50) CHARACTER SET cp932,
IN ind DECIMAL(10,2))
BEGIN
INSERT INTO t4 VALUES (ins1, ins2, ind);
END
-master-bin.000001 816 Query 1 1035 use `test`; INSERT INTO t4 VALUES ( NAME_CONST('ins1',_latin1 0x466F6F2773206120426172), NAME_CONST('ins2',_cp932 0xED40ED41ED42), NAME_CONST('ind',47.93))
-master-bin.000001 1035 Query 1 1124 use `test`; DROP PROCEDURE bug18293
-master-bin.000001 1124 Query 1 1203 use `test`; DROP TABLE t4
+master-bin.000001 776 Query 1 995 use `test`; INSERT INTO t4 VALUES ( NAME_CONST('ins1',_latin1 0x466F6F2773206120426172), NAME_CONST('ins2',_cp932 0xED40ED41ED42), NAME_CONST('ind',47.93))
+master-bin.000001 995 Query 1 1084 use `test`; DROP PROCEDURE bug18293
+master-bin.000001 1084 Query 1 1163 use `test`; DROP TABLE t4
diff --git a/mysql-test/r/ctype_cp932_notembedded.result b/mysql-test/r/ctype_cp932_notembedded.result
deleted file mode 100644
index c58bfc65454..00000000000
--- a/mysql-test/r/ctype_cp932_notembedded.result
+++ /dev/null
@@ -1,17 +0,0 @@
-drop table if exists t1;
-set names cp932;
-set character_set_database = cp932;
-RESET MASTER;
-CREATE TABLE t1(f1 blob);
-PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
-SET @var1= x'8300';
-EXECUTE stmt1 USING @var1;
-SHOW BINLOG EVENTS FROM 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 188 use `test`; CREATE TABLE t1(f1 blob)
-master-bin.000001 188 User var 1 227 @`var1`=_binary 0x8300 COLLATE binary
-master-bin.000001 227 Query 1 323 use `test`; INSERT INTO t1 VALUES(@'var1')
-SELECT HEX(f1) FROM t1;
-HEX(f1)
-8300
-DROP table t1;
diff --git a/mysql-test/r/ctype_ldml.result b/mysql-test/r/ctype_ldml.result
new file mode 100644
index 00000000000..f3d3ff700f0
--- /dev/null
+++ b/mysql-test/r/ctype_ldml.result
@@ -0,0 +1,296 @@
+drop table if exists t1;
+set names utf8;
+show variables like 'character_sets_dir%';
+Variable_name Value
+character_sets_dir MYSQL_TEST_DIR/std_data/
+show collation like 'utf8_test_ci';
+Collation Charset Id Default Compiled Sortlen
+utf8_test_ci utf8 240 8
+create table t1 (c1 char(1) character set utf8 collate utf8_test_ci);
+insert into t1 values ('a');
+select * from t1 where c1='b';
+c1
+a
+drop table t1;
+show collation like 'ucs2_test_ci';
+Collation Charset Id Default Compiled Sortlen
+ucs2_test_ci ucs2 241 8
+create table t1 (c1 char(1) character set ucs2 collate ucs2_test_ci);
+insert into t1 values ('a');
+select * from t1 where c1='b';
+c1
+a
+drop table t1;
+show collation like 'ucs2_vn_ci';
+Collation Charset Id Default Compiled Sortlen
+ucs2_vn_ci ucs2 242 8
+create table t1 (c1 char(1) character set ucs2 collate ucs2_vn_ci);
+insert into t1 values (0x0061),(0x0041),(0x00E0),(0x00C0),(0x1EA3),(0x1EA2),
+(0x00E3),(0x00C3),(0x00E1),(0x00C1),(0x1EA1),(0x1EA0);
+insert into t1 values (0x0103),(0x0102),(0x1EB1),(0x1EB0),(0x1EB3),(0x1EB2),
+(0x1EB5),(0x1EB4),(0x1EAF),(0x1EAE),(0x1EB7),(0x1EB6);
+insert into t1 values (0x00E2),(0x00C2),(0x1EA7),(0x1EA6),(0x1EA9),(0x1EA8),
+(0x1EAB),(0x1EAA),(0x1EA5),(0x1EA4),(0x1EAD),(0x1EAC);
+insert into t1 values ('b'),('B'),('c'),('C');
+insert into t1 values ('d'),('D'),(0x0111),(0x0110);
+insert into t1 values (0x0065),(0x0045),(0x00E8),(0x00C8),(0x1EBB),(0x1EBA),
+(0x1EBD),(0x1EBC),(0x00E9),(0x00C9),(0x1EB9),(0x1EB8);
+insert into t1 values (0x00EA),(0x00CA),(0x1EC1),(0x1EC0),(0x1EC3),(0x1EC2),
+(0x1EC5),(0x1EC4),(0x1EBF),(0x1EBE),(0x1EC7),(0x1EC6);
+insert into t1 values ('g'),('G'),('h'),('H');
+insert into t1 values (0x0069),(0x0049),(0x00EC),(0x00CC),(0x1EC9),(0x1EC8),
+(0x0129),(0x0128),(0x00ED),(0x00CD),(0x1ECB),(0x1ECA);
+insert into t1 values ('k'),('K'),('l'),('L'),('m'),('M');
+insert into t1 values (0x006F),(0x004F),(0x00F2),(0x00D2),(0x1ECF),(0x1ECE),
+(0x00F5),(0x00D5),(0x00F3),(0x00D3),(0x1ECD),(0x1ECC);
+insert into t1 values (0x00F4),(0x00D4),(0x1ED3),(0x1ED2),(0x1ED5),(0x1ED4),
+(0x1ED7),(0x1ED6),(0x1ED1),(0x1ED0),(0x1ED9),(0x1ED8);
+insert into t1 values (0x01A1),(0x01A0),(0x1EDD),(0x1EDC),(0x1EDF),(0x1EDE),
+(0x1EE1),(0x1EE0),(0x1EDB),(0x1EDA),(0x1EE3),(0x1EE2);
+insert into t1 values ('p'),('P'),('q'),('Q'),('r'),('R'),('s'),('S'),('t'),('T');
+insert into t1 values (0x0075),(0x0055),(0x00F9),(0x00D9),(0x1EE7),(0x1EE6),
+(0x0169),(0x0168),(0x00FA),(0x00DA),(0x1EE5),(0x1EE4);
+insert into t1 values (0x01B0),(0x01AF),(0x1EEB),(0x1EEA),(0x1EED),(0x1EEC),
+(0x1EEF),(0x1EEE),(0x1EE9),(0x1EE8),(0x1EF1),(0x1EF0);
+insert into t1 values ('v'),('V'),('x'),('X');
+insert into t1 values (0x0079),(0x0059),(0x1EF3),(0x1EF2),(0x1EF7),(0x1EF6),
+(0x1EF9),(0x1EF8),(0x00FD),(0x00DD),(0x1EF5),(0x1EF4);
+select hex(c1) as h, c1 from t1 order by c1, h;
+h c1
+0041 A
+0061 a
+00C0 À
+00C1 Ã
+00C3 Ã
+00E0 à
+00E1 á
+00E3 ã
+1EA0 Ạ
+1EA1 ạ
+1EA2 Ả
+1EA3 ả
+0102 Ä‚
+0103 ă
+1EAE Ắ
+1EAF ắ
+1EB0 Ằ
+1EB1 ằ
+1EB2 Ẳ
+1EB3 ẳ
+1EB4 Ẵ
+1EB5 ẵ
+1EB6 Ặ
+1EB7 ặ
+00C2 Â
+00E2 â
+1EA4 Ấ
+1EA5 ấ
+1EA6 Ầ
+1EA7 ầ
+1EA8 Ẩ
+1EA9 ẩ
+1EAA Ẫ
+1EAB ẫ
+1EAC Ậ
+1EAD ậ
+0042 B
+0062 b
+0043 C
+0063 c
+0044 D
+0064 d
+0110 Ä
+0111 Ä‘
+0045 E
+0065 e
+00C8 È
+00C9 É
+00E8 è
+00E9 é
+1EB8 Ẹ
+1EB9 ẹ
+1EBA Ẻ
+1EBB ẻ
+1EBC Ẽ
+1EBD ẽ
+00CA Ê
+00EA ê
+1EBE Ế
+1EBF ế
+1EC0 Ề
+1EC1 á»
+1EC2 Ể
+1EC3 ể
+1EC4 Ễ
+1EC5 á»…
+1EC6 Ệ
+1EC7 ệ
+0047 G
+0067 g
+0048 H
+0068 h
+0049 I
+0069 i
+00CC Ì
+00CD Ã
+00EC ì
+00ED í
+0128 Ĩ
+0129 Ä©
+1EC8 Ỉ
+1EC9 ỉ
+1ECA Ị
+1ECB ị
+004B K
+006B k
+004C L
+006C l
+004D M
+006D m
+004F O
+006F o
+00D2 Ã’
+00D3 Ó
+00D5 Õ
+00F2 ò
+00F3 ó
+00F5 õ
+1ECC Ọ
+1ECD á»
+1ECE Ỏ
+1ECF á»
+00D4 Ô
+00F4 ô
+1ED0 á»
+1ED1 ố
+1ED2 á»’
+1ED3 ồ
+1ED4 á»”
+1ED5 ổ
+1ED6 á»–
+1ED7 á»—
+1ED8 Ộ
+1ED9 á»™
+01A0 Æ 
+01A1 Æ¡
+1EDA Ớ
+1EDB á»›
+1EDC Ờ
+1EDD á»
+1EDE Ở
+1EDF ở
+1EE0 á» 
+1EE1 ỡ
+1EE2 Ợ
+1EE3 ợ
+0050 P
+0070 p
+0051 Q
+0071 q
+0052 R
+0072 r
+0053 S
+0073 s
+0054 T
+0074 t
+0055 U
+0075 u
+00D9 Ù
+00DA Ú
+00F9 ù
+00FA ú
+0168 Ũ
+0169 Å©
+1EE4 Ụ
+1EE5 ụ
+1EE6 Ủ
+1EE7 á»§
+01AF Ư
+01B0 ư
+1EE8 Ứ
+1EE9 ứ
+1EEA Ừ
+1EEB ừ
+1EEC Ử
+1EED á»­
+1EEE á»®
+1EEF ữ
+1EF0 á»°
+1EF1 á»±
+0056 V
+0076 v
+0058 X
+0078 x
+0059 Y
+0079 y
+00DD Ã
+00FD ý
+1EF2 Ỳ
+1EF3 ỳ
+1EF4 á»´
+1EF5 ỵ
+1EF6 á»¶
+1EF7 á»·
+1EF8 Ỹ
+1EF9 ỹ
+select group_concat(hex(c1) order by hex(c1)) from t1 group by c1;
+group_concat(hex(c1) order by hex(c1))
+0041,0061,00C0,00C1,00C3,00E0,00E1,00E3,1EA0,1EA1,1EA2,1EA3
+0102,0103,1EAE,1EAF,1EB0,1EB1,1EB2,1EB3,1EB4,1EB5,1EB6,1EB7
+00C2,00E2,1EA4,1EA5,1EA6,1EA7,1EA8,1EA9,1EAA,1EAB,1EAC,1EAD
+0042,0062
+0043,0063
+0044,0064
+0110,0111
+0045,0065,00C8,00C9,00E8,00E9,1EB8,1EB9,1EBA,1EBB,1EBC,1EBD
+00CA,00EA,1EBE,1EBF,1EC0,1EC1,1EC2,1EC3,1EC4,1EC5,1EC6,1EC7
+0047,0067
+0048,0068
+0049,0069,00CC,00CD,00EC,00ED,0128,0129,1EC8,1EC9,1ECA,1ECB
+004B,006B
+004C,006C
+004D,006D
+004F,006F,00D2,00D3,00D5,00F2,00F3,00F5,1ECC,1ECD,1ECE,1ECF
+00D4,00F4,1ED0,1ED1,1ED2,1ED3,1ED4,1ED5,1ED6,1ED7,1ED8,1ED9
+01A0,01A1,1EDA,1EDB,1EDC,1EDD,1EDE,1EDF,1EE0,1EE1,1EE2,1EE3
+0050,0070
+0051,0071
+0052,0072
+0053,0073
+0054,0074
+0055,0075,00D9,00DA,00F9,00FA,0168,0169,1EE4,1EE5,1EE6,1EE7
+01AF,01B0,1EE8,1EE9,1EEA,1EEB,1EEC,1EED,1EEE,1EEF,1EF0,1EF1
+0056,0076
+0058,0078
+0059,0079,00DD,00FD,1EF2,1EF3,1EF4,1EF5,1EF6,1EF7,1EF8,1EF9
+select group_concat(c1 order by hex(c1) SEPARATOR '') from t1 group by c1;
+group_concat(c1 order by hex(c1) SEPARATOR '')
+AaÀÃÃàáãẠạẢả
+ĂăẮắẰằẲẳẴẵẶặ
+ÂâẤấẦầẨẩẪẫẬậ
+Bb
+Cc
+Dd
+ÄÄ‘
+EeÈÉèéẸẹẺẻẼẽ
+ÊêẾếỀá»á»‚ểỄễỆệ
+Gg
+Hh
+IiÃŒÃìíĨĩỈỉỊị
+Kk
+Ll
+Mm
+OoÒÓÕòóõỌá»á»Žá»
+Ôôá»á»‘ỒồỔổỖỗỘộ
+ƠơỚớỜá»á»žá»Ÿá» á»¡á»¢á»£
+Pp
+Qq
+Rr
+Ss
+Tt
+UuÙÚùúŨũỤụỦủ
+ƯưỨứỪừỬửỮữỰự
+Vv
+Xx
+YyÃýỲỳỴỵỶỷỸỹ
+drop table t1;
diff --git a/mysql-test/r/ctype_ucs2_def.result b/mysql-test/r/ctype_ucs2_def.result
index 2f9dc4ae616..c076ca36cdb 100644
--- a/mysql-test/r/ctype_ucs2_def.result
+++ b/mysql-test/r/ctype_ucs2_def.result
@@ -7,3 +7,11 @@ character_set_server ucs2
DROP TABLE IF EXISTS t1;
create table t1 (a int);
drop table t1;
+CREATE TABLE t1(col1 VARCHAR(32) CHARACTER SET ucs2 COLLATE ucs2_bin NOT NULL,
+col2 VARCHAR(32) CHARACTER SET ucs2 COLLATE ucs2_bin NOT NULL,
+UNIQUE KEY key1 USING HASH (col1, col2)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES('A', 'A'), ('B', 'B'), ('C', 'C');
+INSERT INTO t1 VALUES('A ', 'A ');
+ERROR 23000: Duplicate entry '' for key 1
+DROP TABLE t1;
+End of 5.0 tests
diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result
index f4ec6830cd5..d62c865bb3c 100644
--- a/mysql-test/r/date_formats.result
+++ b/mysql-test/r/date_formats.result
@@ -88,6 +88,8 @@ create table t1 (date char(30), format char(30) not null);
insert into t1 values
('2003-01-02 10:11:12', '%Y-%m-%d %H:%i:%S'),
('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S.%#'),
+('0003-01-02 8:11:2.123456', '%Y-%m-%d %H:%i:%S.%#'),
+('03-01-02 8:11:2.123456', '%Y-%m-%d %H:%i:%S.%#'),
('2003-01-02 10:11:12 PM', '%Y-%m-%d %h:%i:%S %p'),
('2003-01-02 01:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f%p'),
('2003-01-02 02:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f %p'),
@@ -119,6 +121,8 @@ select date,format,str_to_date(date, format) as str_to_date from t1;
date format str_to_date
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
+0003-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 0003-01-02 08:11:02
+03-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450
@@ -150,6 +154,8 @@ select date,format,concat('',str_to_date(date, format)) as con from t1;
date format con
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
+0003-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 0003-01-02 08:11:02
+03-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450
@@ -181,6 +187,8 @@ select date,format,cast(str_to_date(date, format) as datetime) as datetime from
date format datetime
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
+0003-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 0003-01-02 08:11:02
+03-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450
@@ -212,6 +220,8 @@ select date,format,DATE(str_to_date(date, format)) as date2 from t1;
date format date2
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02
+0003-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 0003-01-02
+03-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 2003-01-02
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02
@@ -243,6 +253,8 @@ select date,format,TIME(str_to_date(date, format)) as time from t1;
date format time
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 10:11:12
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 08:11:02
+0003-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 08:11:02
+03-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 08:11:02
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 22:11:12
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.123450
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.123450
@@ -274,6 +286,8 @@ select date,format,concat(TIME(str_to_date(date, format))) as time2 from t1;
date format time2
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 10:11:12
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 08:11:02
+0003-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 08:11:02
+03-01-02 8:11:2.123456 %Y-%m-%d %H:%i:%S.%# 08:11:02
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 22:11:12
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.123450
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.123450
@@ -399,14 +413,14 @@ select date,format,str_to_date(date, format) as str_to_date from t1;
date format str_to_date
10:20:10AM %h:%i:%s 0000-00-00 10:20:10
2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12
-03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 0003-01-02 22:11:12
+03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
Warnings:
Warning 1292 Truncated incorrect datetime value: '10:20:10AM'
select date,format,concat(str_to_date(date, format),'') as con from t1;
date format con
10:20:10AM %h:%i:%s 0000-00-00 10:20:10
2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12
-03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 0003-01-02 22:11:12
+03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
Warnings:
Warning 1292 Truncated incorrect datetime value: '10:20:10AM'
drop table t1;
diff --git a/mysql-test/r/error_simulation.result b/mysql-test/r/error_simulation.result
new file mode 100644
index 00000000000..805e8fabbd8
--- /dev/null
+++ b/mysql-test/r/error_simulation.result
@@ -0,0 +1,19 @@
+DROP TABLE IF EXISTS t1;
+Warnings:
+Note 1051 Unknown table 't1'
+CREATE TABLE t1 (
+a varchar(32) character set utf8 collate utf8_bin NOT NULL,
+b varchar(32) character set utf8 collate utf8_bin NOT NULL )
+ENGINE=MyISAM DEFAULT CHARSET=utf8;
+INSERT INTO t1 VALUES
+('AAAAAAAAAA','AAAAAAAAAA'), ('AAAAAAAAAB','AAAAAAAAAB '),
+('AAAAAAAAAB','AAAAAAAAAB'), ('AAAAAAAAAC','AAAAAAAAAC'),
+('AAAAAAAAAD','AAAAAAAAAD'), ('AAAAAAAAAE','AAAAAAAAAE'),
+('AAAAAAAAAF','AAAAAAAAAF'), ('AAAAAAAAAG','AAAAAAAAAG'),
+('AAAAAAAAAH','AAAAAAAAAH'), ('AAAAAAAAAI','AAAAAAAAAI'),
+('AAAAAAAAAJ','AAAAAAAAAJ'), ('AAAAAAAAAK','AAAAAAAAAK');
+set tmp_table_size=1024;
+SELECT MAX(a) FROM t1 GROUP BY a,b;
+ERROR 23000: Can't write; duplicate key in table ''
+set tmp_table_size=default;
+DROP TABLE t1;
diff --git a/mysql-test/r/func_date_add.result b/mysql-test/r/func_date_add.result
index ac5709260fd..a7f2383848d 100644
--- a/mysql-test/r/func_date_add.result
+++ b/mysql-test/r/func_date_add.result
@@ -84,4 +84,15 @@ CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR
SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK;
CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK
2006-10-03
+create table t1 (a int, b varchar(10));
+insert into t1 values (1, '2001-01-01'),(2, '2002-02-02');
+select '2007-01-01' + interval a day from t1;
+'2007-01-01' + interval a day
+2007-01-02
+2007-01-03
+select b + interval a day from t1;
+b + interval a day
+2001-01-02
+2002-02-04
+drop table t1;
End of 5.0 tests
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result
index 20df776ec1b..8b71ad1940e 100644
--- a/mysql-test/r/func_gconcat.result
+++ b/mysql-test/r/func_gconcat.result
@@ -763,4 +763,51 @@ Warnings:
Warning 1260 1 line(s) were cut by GROUP_CONCAT()
SET group_concat_max_len = DEFAULT;
DROP TABLE t1;
+SET group_concat_max_len= 65535;
+CREATE TABLE t1( a TEXT, b INTEGER );
+INSERT INTO t1 VALUES ( 'a', 0 ), ( 'b', 1 );
+SELECT GROUP_CONCAT( a ORDER BY b ) FROM t1;
+GROUP_CONCAT( a ORDER BY b )
+a,b
+SELECT GROUP_CONCAT(DISTINCT a ORDER BY b) FROM t1;
+GROUP_CONCAT(DISTINCT a ORDER BY b)
+a,b
+SELECT GROUP_CONCAT(DISTINCT a) FROM t1;
+GROUP_CONCAT(DISTINCT a)
+a,b
+SET group_concat_max_len= 10;
+SELECT GROUP_CONCAT(a ORDER BY b) FROM t1;
+GROUP_CONCAT(a ORDER BY b)
+a,b
+SELECT GROUP_CONCAT(DISTINCT a ORDER BY b) FROM t1;
+GROUP_CONCAT(DISTINCT a ORDER BY b)
+a,b
+SELECT GROUP_CONCAT(DISTINCT a) FROM t1;
+GROUP_CONCAT(DISTINCT a)
+a,b
+SET group_concat_max_len= 65535;
+CREATE TABLE t2( a TEXT );
+INSERT INTO t2 VALUES( REPEAT( 'a', 5000 ) );
+INSERT INTO t2 VALUES( REPEAT( 'b', 5000 ) );
+INSERT INTO t2 VALUES( REPEAT( 'a', 5000 ) );
+SELECT LENGTH( GROUP_CONCAT( DISTINCT a ) ) FROM t2;
+LENGTH( GROUP_CONCAT( DISTINCT a ) )
+10001
+CREATE TABLE t3( a TEXT, b INT );
+INSERT INTO t3 VALUES( REPEAT( 'a', 65534 ), 1 );
+INSERT INTO t3 VALUES( REPEAT( 'a', 65535 ), 2 );
+INSERT INTO t3 VALUES( REPEAT( 'a', 65536 ), 3 );
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+SELECT LENGTH( GROUP_CONCAT( a ) ) FROM t3 WHERE b = 1;
+LENGTH( GROUP_CONCAT( a ) )
+65534
+SELECT LENGTH( GROUP_CONCAT( a ) ) FROM t3 WHERE b = 2;
+LENGTH( GROUP_CONCAT( a ) )
+65535
+SELECT LENGTH( GROUP_CONCAT( a ) ) FROM t3 WHERE b = 3;
+LENGTH( GROUP_CONCAT( a ) )
+65535
+SET group_concat_max_len= DEFAULT;
+DROP TABLE t1, t2, t3;
End of 5.0 tests
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index a3e0773649f..99b16d29eb9 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -431,15 +431,17 @@ insert into t2 values(13491727406643098568),
(0x8000000400000001),
(0x8000004000000001),
(0x8000040000000001);
-SELECT HEX(a) FROM t2 WHERE a IN (0xBB3C3E98175D33C8, 42);
+SELECT HEX(a) FROM t2 WHERE a IN
+(CAST(0xBB3C3E98175D33C8 AS UNSIGNED),
+42);
HEX(a)
BB3C3E98175D33C8
SELECT HEX(a) FROM t2 WHERE a IN
-(0xBB3C3E98175D33C8,
-0x7fffffffffffffff,
-0x8000000000000000,
-0x8000000000000400,
-0x8000000000000401,
+(CAST(0xBB3C3E98175D33C8 AS UNSIGNED),
+CAST(0x7fffffffffffffff AS UNSIGNED),
+CAST(0x8000000000000000 AS UNSIGNED),
+CAST(0x8000000000000400 AS UNSIGNED),
+CAST(0x8000000000000401 AS UNSIGNED),
42);
HEX(a)
BB3C3E98175D33C8
@@ -447,15 +449,22 @@ BB3C3E98175D33C8
8000000000000000
8000000000000400
8000000000000401
-SELECT HEX(a) FROM t2 WHERE a IN (0x7fffffffffffffff,0x8000000000000001);
+SELECT HEX(a) FROM t2 WHERE a IN
+(CAST(0x7fffffffffffffff AS UNSIGNED),
+CAST(0x8000000000000001 AS UNSIGNED));
HEX(a)
7FFFFFFFFFFFFFFF
8000000000000001
-SELECT HEX(a) FROM t2 WHERE a IN (0x7ffffffffffffffe,0x7fffffffffffffff);
+SELECT HEX(a) FROM t2 WHERE a IN
+(CAST(0x7ffffffffffffffe AS UNSIGNED),
+CAST(0x7fffffffffffffff AS UNSIGNED));
HEX(a)
7FFFFFFFFFFFFFFE
7FFFFFFFFFFFFFFF
-SELECT HEX(a) FROM t2 WHERE a IN (0x7ffffffffffffffe,0x7fffffffffffffff,'abc');
+SELECT HEX(a) FROM t2 WHERE a IN
+(0x7ffffffffffffffe,
+0x7fffffffffffffff,
+'abc');
HEX(a)
7FFFFFFFFFFFFFFE
7FFFFFFFFFFFFFFF
diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result
index 4a6ec9a7ba0..dbae7e551e5 100644
--- a/mysql-test/r/func_sapdb.result
+++ b/mysql-test/r/func_sapdb.result
@@ -75,6 +75,12 @@ NULL
select weekofyear("1997-11-30 23:59:59.000001");
weekofyear("1997-11-30 23:59:59.000001")
48
+select makedate(03,1);
+makedate(03,1)
+2003-01-01
+select makedate('0003',1);
+makedate('0003',1)
+2003-01-01
select makedate(1997,1);
makedate(1997,1)
1997-01-01
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index d8afbe13c76..ce9633006af 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -2061,4 +2061,96 @@ C
2707236321
DROP TABLE t1, t2;
DROP VIEW v1;
+SELECT LOCATE('foo', NULL) FROM DUAL;
+LOCATE('foo', NULL)
+NULL
+SELECT LOCATE(NULL, 'o') FROM DUAL;
+LOCATE(NULL, 'o')
+NULL
+SELECT LOCATE(NULL, NULL) FROM DUAL;
+LOCATE(NULL, NULL)
+NULL
+SELECT LOCATE('foo', NULL) IS NULL FROM DUAL;
+LOCATE('foo', NULL) IS NULL
+1
+SELECT LOCATE(NULL, 'o') IS NULL FROM DUAL;
+LOCATE(NULL, 'o') IS NULL
+1
+SELECT LOCATE(NULL, NULL) IS NULL FROM DUAL;
+LOCATE(NULL, NULL) IS NULL
+1
+SELECT ISNULL(LOCATE('foo', NULL)) FROM DUAL;
+ISNULL(LOCATE('foo', NULL))
+1
+SELECT ISNULL(LOCATE(NULL, 'o')) FROM DUAL;
+ISNULL(LOCATE(NULL, 'o'))
+1
+SELECT ISNULL(LOCATE(NULL, NULL)) FROM DUAL;
+ISNULL(LOCATE(NULL, NULL))
+1
+SELECT LOCATE('foo', NULL) <=> NULL FROM DUAL;
+LOCATE('foo', NULL) <=> NULL
+1
+SELECT LOCATE(NULL, 'o') <=> NULL FROM DUAL;
+LOCATE(NULL, 'o') <=> NULL
+1
+SELECT LOCATE(NULL, NULL) <=> NULL FROM DUAL;
+LOCATE(NULL, NULL) <=> NULL
+1
+CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a varchar(10), p varchar(10));
+INSERT INTO t1 VALUES (1, 'foo', 'o');
+INSERT INTO t1 VALUES (2, 'foo', NULL);
+INSERT INTO t1 VALUES (3, NULL, 'o');
+INSERT INTO t1 VALUES (4, NULL, NULL);
+SELECT id, LOCATE(a,p) FROM t1;
+id LOCATE(a,p)
+1 0
+2 NULL
+3 NULL
+4 NULL
+SELECT id, LOCATE(a,p) IS NULL FROM t1;
+id LOCATE(a,p) IS NULL
+1 0
+2 1
+3 1
+4 1
+SELECT id, ISNULL(LOCATE(a,p)) FROM t1;
+id ISNULL(LOCATE(a,p))
+1 0
+2 1
+3 1
+4 1
+SELECT id, LOCATE(a,p) <=> NULL FROM t1;
+id LOCATE(a,p) <=> NULL
+1 0
+2 1
+3 1
+4 1
+SELECT id FROM t1 WHERE LOCATE(a,p) IS NULL;
+id
+2
+3
+4
+SELECT id FROM t1 WHERE LOCATE(a,p) <=> NULL;
+id
+2
+3
+4
+DROP TABLE t1;
+SELECT SUBSTR('foo',1,0) FROM DUAL;
+SUBSTR('foo',1,0)
+
+SELECT SUBSTR('foo',1,CAST(0 AS SIGNED)) FROM DUAL;
+SUBSTR('foo',1,CAST(0 AS SIGNED))
+
+SELECT SUBSTR('foo',1,CAST(0 AS UNSIGNED)) FROM DUAL;
+SUBSTR('foo',1,CAST(0 AS UNSIGNED))
+
+CREATE TABLE t1 (a varchar(10), len int unsigned);
+INSERT INTO t1 VALUES ('bar', 2), ('foo', 0);
+SELECT SUBSTR(a,1,len) FROM t1;
+SUBSTR(a,1,len)
+ba
+
+DROP TABLE t1;
End of 5.0 tests
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index 73e5b054f80..d1f292cda0c 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -864,4 +864,25 @@ SELECT Overlaps(@horiz1, @point2) FROM DUAL;
Overlaps(@horiz1, @point2)
0
DROP TABLE t1;
+create table t1(f1 geometry, f2 point, f3 linestring);
+select f1 from t1 union select f1 from t1;
+f1
+insert into t1 (f2,f3) values (GeomFromText('POINT(1 1)'),
+GeomFromText('LINESTRING(0 0,1 1,2 2)'));
+select AsText(f2),AsText(f3) from t1;
+AsText(f2) AsText(f3)
+POINT(1 1) LINESTRING(0 0,1 1,2 2)
+select AsText(a) from (select f2 as a from t1 union select f3 from t1) t;
+AsText(a)
+POINT(1 1)
+LINESTRING(0 0,1 1,2 2)
+create table t2 as select f2 as a from t1 union select f3 from t1;
+desc t2;
+Field Type Null Key Default Extra
+a point YES NULL
+select AsText(a) from t2;
+AsText(a)
+POINT(1 1)
+LINESTRING(0 0,1 1,2 2)
+drop table t1, t2;
End of 5.0 tests
diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result
index ff9b7bc6f1f..6de9a83aeed 100644
--- a/mysql-test/r/grant2.result
+++ b/mysql-test/r/grant2.result
@@ -380,3 +380,45 @@ drop function f2;
drop table t2;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM `a@`@localhost;
drop user `a@`@localhost;
+drop database if exists mysqltest_1;
+drop database if exists mysqltest_2;
+drop user mysqltest_u1@localhost;
+create database mysqltest_1;
+create database mysqltest_2;
+grant all on mysqltest_1.* to mysqltest_u1@localhost;
+use mysqltest_2;
+create table t1 (i int);
+show create table mysqltest_2.t1;
+ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1'
+create table t1 like mysqltest_2.t1;
+ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1'
+grant select on mysqltest_2.t1 to mysqltest_u1@localhost;
+show create table mysqltest_2.t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+create table t1 like mysqltest_2.t1;
+use test;
+drop database mysqltest_1;
+drop database mysqltest_2;
+drop user mysqltest_u1@localhost;
+grant all on `mysqltest\_%`.* to mysqltest_1@localhost with grant option;
+grant usage on *.* to mysqltest_2@localhost;
+create database mysqltest_1;
+use mysqltest_1;
+create table t1 (f1 int);
+grant create on `mysqltest\_1`.* to mysqltest_2@localhost;
+grant select on mysqltest_1.t1 to mysqltest_2@localhost;
+create database mysqltest_3;
+ERROR 42000: Access denied for user 'mysqltest_2'@'localhost' to database 'mysqltest_3'
+use mysqltest_1;
+create table t2(f1 int);
+select * from t1;
+f1
+drop database mysqltest_1;
+revoke all privileges, grant option from mysqltest_1@localhost;
+revoke all privileges, grant option from mysqltest_2@localhost;
+drop user mysqltest_1@localhost;
+drop user mysqltest_2@localhost;
+End of 5.0 tests
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index 7583aa14db8..2e5193f8563 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -2286,3 +2286,24 @@ Variable_name Value
Handler_read_key 8
Handler_read_next 1
DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int, INDEX idx(a));
+INSERT INTO t1 VALUES
+(4), (2), (1), (2), (4), (2), (1), (4),
+(4), (2), (1), (2), (2), (4), (1), (4);
+EXPLAIN SELECT DISTINCT(a) FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range NULL idx 5 NULL 9 Using index for group-by
+SELECT DISTINCT(a) FROM t1;
+a
+1
+2
+4
+EXPLAIN SELECT SQL_BIG_RESULT DISTINCT(a) FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range NULL idx 5 NULL 9 Using index for group-by
+SELECT SQL_BIG_RESULT DISTINCT(a) FROM t1;
+a
+1
+2
+4
+DROP TABLE t1;
diff --git a/mysql-test/r/have_log_bin.require b/mysql-test/r/have_log_bin.require
new file mode 100644
index 00000000000..d4fd77e4f8d
--- /dev/null
+++ b/mysql-test/r/have_log_bin.require
@@ -0,0 +1,2 @@
+Variable_name Value
+log_bin ON
diff --git a/mysql-test/r/heap_hash.result b/mysql-test/r/heap_hash.result
index 80abcebbfea..cb47573b502 100644
--- a/mysql-test/r/heap_hash.result
+++ b/mysql-test/r/heap_hash.result
@@ -366,3 +366,19 @@ explain select a from t1 where a in (1,3);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 4 Using where
drop table t1;
+End of 4.1 tests
+CREATE TABLE t1(col1 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+col2 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+UNIQUE KEY key1 USING HASH (col1, col2)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES('A', 'A');
+INSERT INTO t1 VALUES('A ', 'A ');
+ERROR 23000: Duplicate entry 'A -A ' for key 1
+DROP TABLE t1;
+CREATE TABLE t1(col1 VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+col2 VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+UNIQUE KEY key1 USING HASH (col1, col2)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES('A', 'A');
+INSERT INTO t1 VALUES('A ', 'A ');
+ERROR 23000: Duplicate entry 'A -A ' for key 1
+DROP TABLE t1;
+End of 5.0 tests
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index db703df1f52..4947fd7aecc 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -1315,3 +1315,14 @@ TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1
TRIGGERS information_schema.TRIGGERS 1
USER_PRIVILEGES information_schema.USER_PRIVILEGES 1
VIEWS information_schema.VIEWS 1
+create table t1(f1 int);
+create view v1 as select f1+1 as a from t1;
+create table t2 (f1 int, f2 int);
+create view v2 as select f1+1 as a, f2 as b from t2;
+select table_name, is_updatable from information_schema.views;
+table_name is_updatable
+v1 NO
+v2 YES
+delete from v1;
+drop view v1,v2;
+drop table t1,t2;
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 9f327ca1901..80b46e5098a 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1086,6 +1086,39 @@ n d
1 30
2 20
drop table t1,t2;
+CREATE TABLE `t1` (
+`a` int(11) NOT NULL auto_increment,
+`b` int(11) default NULL,
+PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
+CREATE TABLE `t2` (
+`a` int(11) NOT NULL auto_increment,
+`b` int(11) default NULL,
+PRIMARY KEY (`a`)
+) ENGINE=INNODB DEFAULT CHARSET=latin1 ;
+insert into t1 values (1,1),(2,2);
+insert into t2 values (1,1),(4,4);
+reset master;
+UPDATE t2,t1 SET t2.a=t1.a+2;
+ERROR 23000: Duplicate entry '3' for key 1
+select * from t2 /* must be (3,1), (4,4) */;
+a b
+1 1
+4 4
+show master status /* there must no UPDATE in binlog */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 98
+delete from t1;
+delete from t2;
+insert into t1 values (1,2),(3,4),(4,4);
+insert into t2 values (1,2),(3,4),(4,4);
+reset master;
+UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
+ERROR 23000: Duplicate entry '4' for key 1
+show master status /* there must be no UPDATE query event */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 98
+drop table t1, t2;
create table t1 (a int, b int) engine=innodb;
insert into t1 values(20,null);
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
@@ -1640,29 +1673,6 @@ t2 CREATE TABLE `t2` (
CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`b`) REFERENCES `t1` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
drop table t2, t1;
-show status like "binlog_cache_use";
-Variable_name Value
-Binlog_cache_use 155
-show status like "binlog_cache_disk_use";
-Variable_name Value
-Binlog_cache_disk_use 0
-create table t1 (a int) engine=innodb;
-show status like "binlog_cache_use";
-Variable_name Value
-Binlog_cache_use 156
-show status like "binlog_cache_disk_use";
-Variable_name Value
-Binlog_cache_disk_use 1
-begin;
-delete from t1;
-commit;
-show status like "binlog_cache_use";
-Variable_name Value
-Binlog_cache_use 157
-show status like "binlog_cache_disk_use";
-Variable_name Value
-Binlog_cache_disk_use 1
-drop table t1;
create table t1 (c char(10), index (c,c)) engine=innodb;
ERROR 42S21: Duplicate column name 'c'
create table t1 (c1 char(10), c2 char(10), index (c1,c2,c1)) engine=innodb;
@@ -1782,13 +1792,13 @@ Variable_name Value
Innodb_page_size 16384
show status like "Innodb_rows_deleted";
Variable_name Value
-Innodb_rows_deleted 2070
+Innodb_rows_deleted 72
show status like "Innodb_rows_inserted";
Variable_name Value
-Innodb_rows_inserted 31727
+Innodb_rows_inserted 29732
show status like "Innodb_rows_updated";
Variable_name Value
-Innodb_rows_updated 29530
+Innodb_rows_updated 29532
show status like "Innodb_row_lock_waits";
Variable_name Value
Innodb_row_lock_waits 0
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index 45cb116f08b..11c7c2aedc9 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -617,4 +617,63 @@ EXPLAIN SELECT COUNT(*) FROM t2 WHERE stat_id IN (1,3) AND acct_id=785;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range idx1,idx2 idx1 9 NULL 2 Using where; Using index
DROP TABLE t1,t2;
+create table t1(a int) engine=innodb;
+alter table t1 comment '123';
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) default NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='123'
+drop table t1;
+CREATE TABLE t1 (a CHAR(2), KEY (a)) ENGINE = InnoDB DEFAULT CHARSET=UTF8;
+INSERT INTO t1 VALUES ('uk'),('bg');
+SELECT * FROM t1 WHERE a = 'uk';
+a
+uk
+DELETE FROM t1 WHERE a = 'uk';
+SELECT * FROM t1 WHERE a = 'uk';
+a
+UPDATE t1 SET a = 'us' WHERE a = 'uk';
+SELECT * FROM t1 WHERE a = 'uk';
+a
+CREATE TABLE t2 (a CHAR(2), KEY (a)) ENGINE = InnoDB;
+INSERT INTO t2 VALUES ('uk'),('bg');
+SELECT * FROM t2 WHERE a = 'uk';
+a
+uk
+DELETE FROM t2 WHERE a = 'uk';
+SELECT * FROM t2 WHERE a = 'uk';
+a
+INSERT INTO t2 VALUES ('uk');
+UPDATE t2 SET a = 'us' WHERE a = 'uk';
+SELECT * FROM t2 WHERE a = 'uk';
+a
+CREATE TABLE t3 (a CHAR(2), KEY (a)) ENGINE = MyISAM;
+INSERT INTO t3 VALUES ('uk'),('bg');
+SELECT * FROM t3 WHERE a = 'uk';
+a
+uk
+DELETE FROM t3 WHERE a = 'uk';
+SELECT * FROM t3 WHERE a = 'uk';
+a
+INSERT INTO t3 VALUES ('uk');
+UPDATE t3 SET a = 'us' WHERE a = 'uk';
+SELECT * FROM t3 WHERE a = 'uk';
+a
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+switch to connection c1
+SET AUTOCOMMIT=0;
+INSERT INTO t2 VALUES (1);
+switch to connection c2
+SET AUTOCOMMIT=0;
+LOCK TABLES t1 READ, t2 READ;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+switch to connection c1
+COMMIT;
+INSERT INTO t1 VALUES (1);
+switch to connection default
+SET AUTOCOMMIT=default;
+DROP TABLE t1,t2;
End of 5.0 tests
diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result
index fa6e23d09f9..8a0a3ba848c 100644
--- a/mysql-test/r/insert.result
+++ b/mysql-test/r/insert.result
@@ -63,7 +63,7 @@ insert into t1 values(NULL);
ERROR 23000: Column 'id' cannot be null
insert into t1 values (1), (NULL), (2);
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'id' at row 2
+Warning 1048 Column 'id' cannot be null
select * from t1;
id
1
diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result
index a96add7eb9a..8cb94072818 100644
--- a/mysql-test/r/insert_select.result
+++ b/mysql-test/r/insert_select.result
@@ -606,8 +606,8 @@ NULL 2 100
create table t2(No int not null, Field int not null, Count int not null);
insert into t2 Select null, Field, Count From t1 Where Month=20030901 and Type=2;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'No' at row 1
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'No' at row 2
+Warning 1048 Column 'No' cannot be null
+Warning 1048 Column 'No' cannot be null
select * from t2;
No Field Count
0 1 100
@@ -688,7 +688,16 @@ ERROR 42S22: Unknown column 't2.x' in 'field list'
drop table t1,t2;
CREATE TABLE t1 (a int PRIMARY KEY);
INSERT INTO t1 values (1), (2);
+flush status;
INSERT INTO t1 SELECT a + 2 FROM t1 LIMIT 1;
+show status like 'Handler_read%';
+Variable_name Value
+Handler_read_first 1
+Handler_read_key 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_next 1
DROP TABLE t1;
CREATE TABLE t1 (x int, y int);
CREATE TABLE t2 (z int, y int);
@@ -773,3 +782,25 @@ d
20
20
DROP TABLE t1,t2;
+CREATE TABLE t1 (
+id INT AUTO_INCREMENT PRIMARY KEY,
+prev_id INT,
+join_id INT DEFAULT 0);
+INSERT INTO t1 (prev_id) VALUES (NULL), (1), (2);
+SELECT * FROM t1;
+id prev_id join_id
+1 NULL 0
+2 1 0
+3 2 0
+CREATE TABLE t2 (join_id INT);
+INSERT INTO t2 (join_id) VALUES (0);
+INSERT INTO t1 (prev_id) SELECT id
+FROM t2 LEFT JOIN t1 ON t1.join_id = t2.join_id
+ORDER BY id DESC LIMIT 1;
+SELECT * FROM t1;
+id prev_id join_id
+1 NULL 0
+2 1 0
+3 2 0
+4 3 0
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/insert_update.result b/mysql-test/r/insert_update.result
index 375961292a3..20cde86101e 100644
--- a/mysql-test/r/insert_update.result
+++ b/mysql-test/r/insert_update.result
@@ -378,7 +378,7 @@ id c1 cnt
INSERT IGNORE INTO t1 (id,c1) SELECT 1,NULL
ON DUPLICATE KEY UPDATE c1=NULL, cnt=cnt+1;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c1' at row 1
+Warning 1048 Column 'c1' cannot be null
Error 1048 Column 'c1' cannot be null
SELECT * FROM t1;
id c1 cnt
@@ -386,10 +386,24 @@ id c1 cnt
INSERT IGNORE INTO t1 (id,c1) SELECT * FROM t2
ON DUPLICATE KEY UPDATE c1=NULL, cnt=cnt+1;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c1' at row 1
+Warning 1048 Column 'c1' cannot be null
Error 1048 Column 'c1' cannot be null
SELECT * FROM t1;
id c1 cnt
1 0 3
2 2 1
DROP TABLE t1;
+create table t1(f1 int primary key,
+f2 timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP);
+insert into t1(f1) values(1);
+select @stamp1:=f2 from t1;
+@stamp1:=f2
+#
+insert into t1(f1) values(1) on duplicate key update f1=1;
+select @stamp2:=f2 from t1;
+@stamp2:=f2
+#
+select if( @stamp1 = @stamp2, "correct", "wrong");
+if( @stamp1 = @stamp2, "correct", "wrong")
+correct
+drop table t1;
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index c62601946c2..1366a8fe97a 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -1239,3 +1239,18 @@ Handler_read_prev 0
Handler_read_rnd 0
Handler_read_rnd_next 6
DROP TABLE t1,t2;
+CREATE TABLE t1 (c int PRIMARY KEY, e int NOT NULL);
+INSERT INTO t1 VALUES (1,0), (2,1);
+CREATE TABLE t2 (d int PRIMARY KEY);
+INSERT INTO t2 VALUES (1), (2), (3);
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WHERE c=1 AND d IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 index NULL PRIMARY 4 NULL 3 Using where; Using index; Not exists
+SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WHERE c=1 AND d IS NULL;
+c e d
+1 0 NULL
+SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WHERE c=1 AND d<=>NULL;
+c e d
+1 0 NULL
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result
index ec15eaa97f5..5a707770ab8 100644
--- a/mysql-test/r/key.result
+++ b/mysql-test/r/key.result
@@ -159,8 +159,8 @@ CREATE TABLE t1 (c CHAR(10) NOT NULL,i INT NOT NULL AUTO_INCREMENT,
UNIQUE (c,i));
INSERT INTO t1 (c) VALUES (NULL),(NULL);
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c' at row 1
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c' at row 2
+Warning 1048 Column 'c' cannot be null
+Warning 1048 Column 'c' cannot be null
SELECT * FROM t1;
c i
1
@@ -455,3 +455,11 @@ ORDER BY c.b, c.d
a b c d e f g h i j a b c d
2 2 1 2004-11-30 12:00:00 1 0 0 0 0 0 2 3388000 -553000 NULL
DROP TABLE t1, t2;
+CREATE TABLE t1( a TINYINT, KEY(a) ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES( 1 );
+ALTER TABLE t1 DISABLE KEYS;
+EXPLAIN SELECT MAX(a) FROM t1 FORCE INDEX(a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1
+DROP TABLE t1;
+End of 5.0 tests.
diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result
index a1bf3d0e128..08d8059f61b 100644
--- a/mysql-test/r/key_cache.result
+++ b/mysql-test/r/key_cache.result
@@ -191,10 +191,8 @@ cache index t1 in unknown_key_cache;
ERROR HY000: Unknown key cache 'unknown_key_cache'
cache index t1 key (unknown_key) in keycache1;
Table Op Msg_type Msg_text
-test.t1 assign_to_keycache error Key 'unknown_key' doesn't exist in table 't1'
+test.t1 assign_to_keycache Error Key 'unknown_key' doesn't exist in table 't1'
test.t1 assign_to_keycache status Operation failed
-Warnings:
-Error 1176 Key 'unknown_key' doesn't exist in table 't1'
select @@keycache2.key_buffer_size;
@@keycache2.key_buffer_size
4194304
@@ -341,3 +339,30 @@ Warning 1438 Cannot drop default keycache
select @@global.key_buffer_size;
@@global.key_buffer_size
2097152
+SET @bug28478_key_cache_block_size= @@global.key_cache_block_size;
+SET GLOBAL key_cache_block_size= 1536;
+CREATE TABLE t1 (
+id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+c1 CHAR(150),
+c2 CHAR(150),
+c3 CHAR(150),
+KEY(c1, c2, c3)
+) ENGINE= MyISAM;
+INSERT INTO t1 (c1, c2, c3) VALUES
+('a', 'b', 'c'), ('b', 'c', 'd'), ('c', 'd', 'e'), ('d', 'e', 'f'),
+('e', 'f', 'g'), ('f', 'g', 'h'), ('g', 'h', 'i'), ('h', 'i', 'j'),
+('i', 'j', 'k'), ('j', 'k', 'l'), ('k', 'l', 'm'), ('l', 'm', 'n'),
+('m', 'n', 'o'), ('n', 'o', 'p'), ('o', 'p', 'q'), ('p', 'q', 'r'),
+('q', 'r', 's'), ('r', 's', 't'), ('s', 't', 'u'), ('t', 'u', 'v'),
+('u', 'v', 'w'), ('v', 'w', 'x'), ('w', 'x', 'y'), ('x', 'y', 'z');
+INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1;
+INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1;
+INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+SHOW VARIABLES LIKE 'key_cache_block_size';
+Variable_name Value
+key_cache_block_size 1536
+SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size;
+DROP TABLE t1;
diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result
index cf5486d1091..7ddabe74c5f 100644
--- a/mysql-test/r/kill.result
+++ b/mysql-test/r/kill.result
@@ -22,7 +22,7 @@ create table t2 (id int unsigned not null);
insert into t2 select id from t1;
create table t3 (kill_id int);
insert into t3 values(connection_id());
-select id from t1 where id in (select distinct id from t2);
+select id from t1 where id in (select distinct a.id from t2 a, t2 b, t2 c, t2 d group by a.id, b.id, c.id, d.id having a.id between 10 and 20);
select ((@id := kill_id) - kill_id) from t3;
((@id := kill_id) - kill_id)
0
@@ -41,3 +41,87 @@ select 1;
select RELEASE_LOCK("a");
RELEASE_LOCK("a")
1
+create table t1(f1 int);
+create function bug27563() returns int(11)
+deterministic
+begin
+declare continue handler for sqlstate '70100' set @a:= 'killed';
+declare continue handler for sqlexception set @a:= 'exception';
+set @a= get_lock("lock27563", 10);
+return 1;
+end|
+select get_lock("lock27563",10);
+get_lock("lock27563",10)
+1
+insert into t1 values (bug27563());
+ERROR 70100: Query execution was interrupted
+select @a;
+@a
+NULL
+select * from t1;
+f1
+insert into t1 values(0);
+update t1 set f1= bug27563();
+ERROR 70100: Query execution was interrupted
+select @a;
+@a
+NULL
+select * from t1;
+f1
+0
+insert into t1 values(1);
+delete from t1 where bug27563() is null;
+ERROR 70100: Query execution was interrupted
+select @a;
+@a
+NULL
+select * from t1;
+f1
+0
+1
+select * from t1 where f1= bug27563();
+ERROR 70100: Query execution was interrupted
+select @a;
+@a
+NULL
+create procedure proc27563()
+begin
+declare continue handler for sqlstate '70100' set @a:= 'killed';
+declare continue handler for sqlexception set @a:= 'exception';
+select get_lock("lock27563",10);
+select "shouldn't be selected";
+end|
+call proc27563();
+get_lock("lock27563",10)
+NULL
+ERROR 70100: Query execution was interrupted
+select @a;
+@a
+NULL
+create table t2 (f2 int);
+create trigger trg27563 before insert on t1 for each row
+begin
+declare continue handler for sqlstate '70100' set @a:= 'killed';
+declare continue handler for sqlexception set @a:= 'exception';
+set @a:= get_lock("lock27563",10);
+insert into t2 values(1);
+end|
+insert into t1 values(2),(3);
+ERROR 70100: Query execution was interrupted
+select @a;
+@a
+NULL
+select * from t1;
+f1
+0
+1
+select * from t2;
+f2
+select release_lock("lock27563");
+release_lock("lock27563")
+1
+drop table t1, t2;
+drop function bug27563;
+drop procedure proc27563;
+PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40 WHERE a1=a2 AND a2=a3 AND a3=a4 AND a4=a5 AND a5=a6 AND a6=a7 AND a7=a8 AND a8=a9 AND a9=a10 AND a10=a11 AND a11=a12 AND a12=a13 AND a13=a14 AND a14=a15 AND a15=a16 AND a16=a17 AND a17=a18 AND a18=a19 AND a19=a20 AND a20=a21 AND a21=a22 AND a22=a23 AND a23=a24 AND a24=a25 AND a25=a26 AND a26=a27 AND a27=a28 AND a28=a29 AND a29=a30 AND a30=a31 AND a31=a32 AND a32=a33 AND a33=a34 AND a34=a35 AND a35=a36 AND a36=a37 AND a37=a38 AND a38=a39 AND a39=a40 ';
+EXECUTE stmt;
diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result
index ac96ac8ff17..01d7d7ca218 100644
--- a/mysql-test/r/limit.result
+++ b/mysql-test/r/limit.result
@@ -91,3 +91,14 @@ select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3;
c
28
drop table t1;
+prepare s from "select 1 limit ?";
+set @a='qwe';
+execute s using @a;
+ERROR HY000: Incorrect arguments to EXECUTE
+prepare s from "select 1 limit 1, ?";
+execute s using @a;
+ERROR HY000: Incorrect arguments to EXECUTE
+prepare s from "select 1 limit ?, ?";
+execute s using @a, @a;
+ERROR HY000: Incorrect arguments to EXECUTE
+End of 5.0 tests
diff --git a/mysql-test/r/lock.result b/mysql-test/r/lock.result
index 079b0253ff6..a5a78ecc986 100644
--- a/mysql-test/r/lock.result
+++ b/mysql-test/r/lock.result
@@ -40,7 +40,8 @@ test.t1 check status OK
lock tables t1 write;
check table t2;
Table Op Msg_type Msg_text
-test.t2 check error Table 't2' was not locked with LOCK TABLES
+test.t2 check Error Table 't2' was not locked with LOCK TABLES
+test.t2 check error Corrupt
insert into t1 select index1,nr from t1;
ERROR HY000: Table 't1' was not locked with LOCK TABLES
unlock tables;
diff --git a/mysql-test/r/long_tmpdir.result b/mysql-test/r/long_tmpdir.result
new file mode 100644
index 00000000000..7e6dd34ced1
--- /dev/null
+++ b/mysql-test/r/long_tmpdir.result
@@ -0,0 +1,3 @@
+create view v1 as select table_name from information_schema.tables;
+drop view v1;
+End of 5.0 tests
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index 27465dd96f6..42669eeb66f 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -844,4 +844,36 @@ insert into t1 values (1);
ERROR HY000: Table 't1' is read only
drop table t2;
drop table t1;
+CREATE TABLE tm1(a INT) ENGINE=MERGE UNION=(t1, t2);
+SELECT * FROM tm1;
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+CHECK TABLE tm1;
+Table Op Msg_type Msg_text
+test.tm1 check Error Table 'test.t1' is differently defined or of non-MyISAM type or doesn't exist
+test.tm1 check Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist
+test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+test.tm1 check error Corrupt
+CREATE TABLE t1(a INT);
+SELECT * FROM tm1;
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+CHECK TABLE tm1;
+Table Op Msg_type Msg_text
+test.tm1 check Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist
+test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+test.tm1 check error Corrupt
+CREATE TABLE t2(a BLOB);
+SELECT * FROM tm1;
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+CHECK TABLE tm1;
+Table Op Msg_type Msg_text
+test.tm1 check Error Table 'test.t2' is differently defined or of non-MyISAM type or doesn't exist
+test.tm1 check Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+test.tm1 check error Corrupt
+ALTER TABLE t2 MODIFY a INT;
+SELECT * FROM tm1;
+a
+CHECK TABLE tm1;
+Table Op Msg_type Msg_text
+test.tm1 check status OK
+DROP TABLE tm1, t1, t2;
End of 5.0 tests
diff --git a/mysql-test/r/metadata.result b/mysql-test/r/metadata.result
index 34e961395c4..4a776b6a253 100644
--- a/mysql-test/r/metadata.result
+++ b/mysql-test/r/metadata.result
@@ -130,3 +130,55 @@ def v3 renamed 8 12 0 Y 32896 0 63
renamed
drop table t1;
drop view v1,v2,v3;
+select a.* from (select 2147483648 as v_large) a;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def a v_large v_large 8 10 10 N 32769 0 63
+v_large
+2147483648
+select a.* from (select 214748364 as v_small) a;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def a v_small v_small 3 9 9 N 32769 0 63
+v_small
+214748364
+CREATE TABLE t1 (c1 CHAR(1));
+CREATE TABLE t2 (c2 CHAR(1));
+CREATE VIEW v1 AS SELECT t1.c1 FROM t1;
+CREATE VIEW v2 AS SELECT t2.c2 FROM t2;
+INSERT INTO t1 VALUES ('1'), ('2'), ('3');
+INSERT INTO t2 VALUES ('1'), ('2'), ('3'), ('2');
+SELECT v1.c1 FROM v1 JOIN t2 ON c1=c2 ORDER BY 1;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def test t1 v1 c1 c1 254 1 1 Y 0 0 8
+c1
+1
+2
+2
+3
+SELECT v1.c1, v2.c2 FROM v1 JOIN v2 ON c1=c2;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def test t1 v1 c1 c1 254 1 1 Y 0 0 8
+def test t2 v2 c2 c2 254 1 1 Y 0 0 8
+c1 c2
+1 1
+2 2
+3 3
+2 2
+SELECT v1.c1, v2.c2 FROM v1 JOIN v2 ON c1=c2 GROUP BY v1.c1;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def test t1 v1 c1 c1 254 1 1 Y 32768 0 8
+def test t2 v2 c2 c2 254 1 1 Y 0 0 8
+c1 c2
+1 1
+2 2
+3 3
+SELECT v1.c1, v2.c2 FROM v1 JOIN v2 ON c1=c2 GROUP BY v1.c1 ORDER BY v2.c2;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def test t1 v1 c1 c1 254 1 1 Y 32768 0 8
+def test t2 v2 c2 c2 254 1 1 Y 0 0 8
+c1 c2
+1 1
+2 2
+3 3
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+End of 5.0 tests
diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result
index a8b132ae927..8fc5bfca3ef 100644
--- a/mysql-test/r/mix_innodb_myisam_binlog.result
+++ b/mysql-test/r/mix_innodb_myisam_binlog.result
@@ -11,7 +11,7 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 98 Query 1 # use `test`; BEGIN
master-bin.000001 166 Query 1 # use `test`; insert into t1 values(1)
master-bin.000001 253 Query 1 # use `test`; insert into t2 select * from t1
-master-bin.000001 347 Xid 1 # COMMIT /* xid=8 */
+master-bin.000001 347 Xid 1 # COMMIT /* XID */
delete from t1;
delete from t2;
reset master;
@@ -47,7 +47,7 @@ master-bin.000001 253 Query 1 # use `test`; savepoint my_savepoint
master-bin.000001 338 Query 1 # use `test`; insert into t1 values(4)
master-bin.000001 425 Query 1 # use `test`; insert into t2 select * from t1
master-bin.000001 519 Query 1 # use `test`; rollback to savepoint my_savepoint
-master-bin.000001 616 Xid 1 # COMMIT /* xid=25 */
+master-bin.000001 616 Xid 1 # COMMIT /* XID */
delete from t1;
delete from t2;
reset master;
@@ -74,7 +74,7 @@ master-bin.000001 338 Query 1 # use `test`; insert into t1 values(6)
master-bin.000001 425 Query 1 # use `test`; insert into t2 select * from t1
master-bin.000001 519 Query 1 # use `test`; rollback to savepoint my_savepoint
master-bin.000001 616 Query 1 # use `test`; insert into t1 values(7)
-master-bin.000001 703 Xid 1 # COMMIT /* xid=37 */
+master-bin.000001 703 Xid 1 # COMMIT /* XID */
delete from t1;
delete from t2;
reset master;
@@ -101,7 +101,7 @@ insert into t2 select * from t1;
show binlog events from 98;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 98 Query 1 # use `test`; insert into t1 values(9)
-master-bin.000001 185 Xid 1 # COMMIT /* xid=60 */
+master-bin.000001 185 Xid 1 # COMMIT /* XID */
master-bin.000001 212 Query 1 # use `test`; insert into t2 select * from t1
delete from t1;
delete from t2;
@@ -112,18 +112,18 @@ insert into t2 select * from t1;
show binlog events from 98;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 98 Query 1 # use `test`; insert into t1 values(10)
-master-bin.000001 186 Xid 1 # COMMIT /* xid=66 */
+master-bin.000001 186 Xid 1 # COMMIT /* XID */
master-bin.000001 213 Query 1 # use `test`; insert into t2 select * from t1
insert into t1 values(11);
commit;
show binlog events from 98;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 98 Query 1 # use `test`; insert into t1 values(10)
-master-bin.000001 186 Xid 1 # COMMIT /* xid=66 */
+master-bin.000001 186 Xid 1 # COMMIT /* XID */
master-bin.000001 213 Query 1 # use `test`; insert into t2 select * from t1
master-bin.000001 307 Query 1 # use `test`; BEGIN
master-bin.000001 375 Query 1 # use `test`; insert into t1 values(11)
-master-bin.000001 463 Xid 1 # COMMIT /* xid=68 */
+master-bin.000001 463 Xid 1 # COMMIT /* XID */
alter table t2 engine=INNODB;
delete from t1;
delete from t2;
@@ -137,7 +137,7 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 98 Query 1 # use `test`; BEGIN
master-bin.000001 166 Query 1 # use `test`; insert into t1 values(12)
master-bin.000001 254 Query 1 # use `test`; insert into t2 select * from t1
-master-bin.000001 348 Xid 1 # COMMIT /* xid=78 */
+master-bin.000001 348 Xid 1 # COMMIT /* XID */
delete from t1;
delete from t2;
reset master;
@@ -161,7 +161,7 @@ show binlog events from 98;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 98 Query 1 # use `test`; BEGIN
master-bin.000001 166 Query 1 # use `test`; insert into t1 values(14)
-master-bin.000001 254 Xid 1 # COMMIT /* xid=94 */
+master-bin.000001 254 Xid 1 # COMMIT /* XID */
delete from t1;
delete from t2;
reset master;
@@ -182,7 +182,7 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 98 Query 1 # use `test`; BEGIN
master-bin.000001 166 Query 1 # use `test`; insert into t1 values(16)
master-bin.000001 254 Query 1 # use `test`; insert into t1 values(18)
-master-bin.000001 342 Xid 1 # COMMIT /* xid=105 */
+master-bin.000001 342 Xid 1 # COMMIT /* XID */
delete from t1;
delete from t2;
alter table t2 type=MyISAM;
@@ -234,19 +234,19 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 98 Query 1 # use `test`; BEGIN
master-bin.000001 166 Query 1 # use `test`; insert into t1 values(16)
master-bin.000001 254 Query 1 # use `test`; insert into t1 values(18)
-master-bin.000001 342 Xid 1 # COMMIT /* xid=105 */
+master-bin.000001 342 Xid 1 # COMMIT /* XID */
master-bin.000001 369 Query 1 # use `test`; delete from t1
-master-bin.000001 446 Xid 1 # COMMIT /* xid=114 */
+master-bin.000001 446 Xid 1 # COMMIT /* XID */
master-bin.000001 473 Query 1 # use `test`; delete from t2
-master-bin.000001 550 Xid 1 # COMMIT /* xid=115 */
+master-bin.000001 550 Xid 1 # COMMIT /* XID */
master-bin.000001 577 Query 1 # use `test`; alter table t2 type=MyISAM
master-bin.000001 666 Query 1 # use `test`; insert into t1 values (1)
-master-bin.000001 754 Xid 1 # COMMIT /* xid=117 */
+master-bin.000001 754 Xid 1 # COMMIT /* XID */
master-bin.000001 781 Query 1 # use `test`; insert into t2 values (20)
master-bin.000001 870 Query 1 # use `test`; drop table t1,t2
master-bin.000001 949 Query 1 # use `test`; create temporary table ti (a int) engine=innodb
master-bin.000001 1059 Query 1 # use `test`; insert into ti values(1)
-master-bin.000001 1146 Xid 1 # COMMIT /* xid=132 */
+master-bin.000001 1146 Xid 1 # COMMIT /* XID */
master-bin.000001 1173 Query 1 # use `test`; create temporary table t1 (a int) engine=myisam
master-bin.000001 1283 Query 1 # use `test`; insert t1 values (1)
master-bin.000001 1366 Query 1 # use `test`; create table t0 (n int)
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result
index 78872f27c47..0f624e3ee8d 100644
--- a/mysql-test/r/multi_update.result
+++ b/mysql-test/r/multi_update.result
@@ -524,3 +524,37 @@ a
30
drop view v1;
drop table t1, t2;
+CREATE TABLE `t1` (
+`a` int(11) NOT NULL auto_increment,
+`b` int(11) default NULL,
+PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
+CREATE TABLE `t2` (
+`a` int(11) NOT NULL auto_increment,
+`b` int(11) default NULL,
+PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
+insert into t1 values (1,1),(2,2);
+insert into t2 values (1,1),(4,4);
+reset master;
+UPDATE t2,t1 SET t2.a=t1.a+2;
+ERROR 23000: Duplicate entry '3' for key 1
+select * from t2 /* must be (3,1), (4,4) */;
+a b
+3 1
+4 4
+show master status /* there must be the UPDATE query event */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 189
+delete from t1;
+delete from t2;
+insert into t1 values (1,2),(3,4),(4,4);
+insert into t2 values (1,2),(3,4),(4,4);
+reset master;
+UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
+ERROR 23000: Duplicate entry '4' for key 1
+show master status /* there must be the UPDATE query event */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 204
+drop table t1, t2;
+end of tests
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 94f2f1f72b3..7fc29cd13ca 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -1780,4 +1780,30 @@ create table t3 (c1 int) engine=myisam pack_keys=default;
create table t4 (c1 int) engine=myisam pack_keys=2;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '2' at line 1
drop table t1, t2, t3;
+CREATE TABLE t1(a INT, b INT, KEY inx (a), UNIQUE KEY uinx (b)) ENGINE=MyISAM;
+INSERT INTO t1(a,b) VALUES (1,1),(2,2),(3,3),(4,4),(5,5);
+SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
+a
+1
+ALTER TABLE t1 DISABLE KEYS;
+SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
+a
+1
+SELECT a FROM t1 USE INDEX (inx) WHERE a=1;
+a
+1
+SELECT b FROM t1 FORCE INDEX (uinx) WHERE b=1;
+b
+1
+SELECT b FROM t1 USE INDEX (uinx) WHERE b=1;
+b
+1
+SELECT a FROM t1 FORCE INDEX (inx,uinx) WHERE a=1;
+a
+1
+ALTER TABLE t1 ENABLE KEYS;
+SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
+a
+1
+DROP TABLE t1;
End of 5.0 tests
diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result
index 0c32f413bd8..b3b606bd1fc 100644
--- a/mysql-test/r/mysql_upgrade.result
+++ b/mysql-test/r/mysql_upgrade.result
@@ -60,3 +60,22 @@ DROP USER mysqltest1@'%';
Run mysql_upgrade with a non existing server socket
mysqlcheck: Got error: 2005: Unknown MySQL server host 'not_existing_host' (errno) when trying to connect
FATAL ERROR: Upgrade failed
+set GLOBAL sql_mode='STRICT_ALL_TABLES,ANSI_QUOTES,NO_ZERO_DATE';
+mysql.columns_priv OK
+mysql.db OK
+mysql.func OK
+mysql.help_category OK
+mysql.help_keyword OK
+mysql.help_relation OK
+mysql.help_topic OK
+mysql.host OK
+mysql.proc OK
+mysql.procs_priv OK
+mysql.tables_priv OK
+mysql.time_zone OK
+mysql.time_zone_leap_second OK
+mysql.time_zone_name OK
+mysql.time_zone_transition OK
+mysql.time_zone_transition_type OK
+mysql.user OK
+set GLOBAL sql_mode=default;
diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
index a50d131cca8..1ba198dfd75 100644
--- a/mysql-test/r/mysqlbinlog.result
+++ b/mysql-test/r/mysqlbinlog.result
@@ -312,4 +312,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+CREATE TABLE t1 (c1 CHAR(10));
+flush logs;
+INSERT INTO t1 VALUES ('0123456789');
+flush logs;
+DROP TABLE t1;
+# Query thread_id=REMOVED exec_time=REMOVED error_code=REMOVED
End of 5.0 tests
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index d9198ffeb48..7865148905e 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -2238,7 +2238,6 @@ INSERT INTO `t1` VALUES (1,NULL),(2,NULL),(4,NULL),(11,NULL);
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
UNLOCK TABLES;
-/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;
DELIMITER ;;
/*!50003 SET SESSION SQL_MODE="" */;;
/*!50003 CREATE */ /*!50017 DEFINER=`root`@`localhost` */ /*!50003 TRIGGER `trg1` BEFORE INSERT ON `t1` FOR EACH ROW begin
@@ -2272,7 +2271,6 @@ LOCK TABLES `t2` WRITE;
/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
UNLOCK TABLES;
-/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;
DELIMITER ;;
/*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER" */;;
/*!50003 CREATE */ /*!50017 DEFINER=`root`@`localhost` */ /*!50003 TRIGGER `trg4` BEFORE INSERT ON `t2` FOR EACH ROW begin
@@ -2630,7 +2628,6 @@ INSERT INTO "t1 test" VALUES (1),(2),(3);
/*!40000 ALTER TABLE "t1 test" ENABLE KEYS */;
UNLOCK TABLES;
-/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;
DELIMITER ;;
/*!50003 SET SESSION SQL_MODE="" */;;
/*!50003 CREATE */ /*!50017 DEFINER=`root`@`localhost` */ /*!50003 TRIGGER `test trig` BEFORE INSERT ON `t1 test` FOR EACH ROW BEGIN
@@ -2791,7 +2788,6 @@ LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
UNLOCK TABLES;
-/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;
DELIMITER ;;
/*!50003 SET SESSION SQL_MODE="IGNORE_SPACE" */;;
/*!50003 CREATE */ /*!50017 DEFINER=`root`@`localhost` */ /*!50003 TRIGGER `tr1` BEFORE INSERT ON `t1` FOR EACH ROW BEGIN
@@ -3293,12 +3289,16 @@ create database mysqldump_test_db;
grant all privileges on mysqldump_test_db.* to user1;
grant all privileges on mysqldump_test_db.* to user2;
create procedure mysqldump_test_db.sp1() select 'hello';
+
+/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;
DELIMITER ;;
-- insufficient privileges to SHOW CREATE PROCEDURE `sp1`
-- does user2 have permissions on mysql.proc?
DELIMITER ;
+
+/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;
DELIMITER ;;
/*!50003 SET SESSION SQL_MODE=""*/;;
/*!50003 CREATE*/ /*!50020 DEFINER=`user1`@`%`*/ /*!50003 PROCEDURE `sp1`()
@@ -3310,5 +3310,16 @@ drop user user1;
drop user user2;
drop database mysqldump_test_db;
#
+# Bug #28522: buffer overrun by '\0' byte using --hex-blob.
+#
+CREATE TABLE t1 (c1 INT, c2 LONGBLOB);
+INSERT INTO t1 SET c1=11, c2=REPEAT('q',509);
+CREATE TABLE `t1` (
+ `c1` int(11) default NULL,
+ `c2` longblob
+);
+INSERT INTO `t1` VALUES (11,0x7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171);
+DROP TABLE t1;
+#
# End of 5.0 tests
#
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index c4ed4d8b19d..8cf5f99dca3 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -339,6 +339,7 @@ here is the sourced script
In loop
here is the sourced script
+here is the sourced script
mysqltest: At line 1: Missing argument to sleep
mysqltest: At line 1: Missing argument to real_sleep
mysqltest: At line 1: Invalid argument to sleep "abc"
@@ -410,7 +411,6 @@ mysqltest: At line 1: Wrong column number to replace_column in 'replace_column a
mysqltest: At line 1: Wrong column number to replace_column in 'replace_column a 1'
mysqltest: At line 1: Wrong column number to replace_column in 'replace_column 1 b c '
mysqltest: At line 1: Invalid integer argument "10!"
-mysqltest: At line 1: End of line junk detected: "!"
mysqltest: At line 1: Invalid integer argument "a"
mysqltest: At line 1: Missing required argument 'connection name' to command 'connect'
mysqltest: At line 1: Missing required argument 'connection name' to command 'connect'
@@ -557,6 +557,12 @@ a b c
2 Part 2 2007-04-05 00:00:00
2 Part 3 2007-04-05 00:00:00
select * from t1;
+a b c
+1 Line 1 2007-04-05 00:00:00
+2 Part 2 2007-04-05 00:00:00
+1 Line 1 2007-04-05 00:00:00
+2 Part 3 2007-04-05 00:00:00
+select * from t1;
select '';
@@ -572,4 +578,131 @@ hep
select "hepp";
hepp
hepp
+drop table t1;
+SELECT 2 as "my_col"
+UNION
+SELECT 1;
+my_col
+1
+2
+SELECT 2 as "my_col" UNION SELECT 1;
+my_col
+1
+2
+SELECT 2 as "my_col"
+UNION
+SELECT 1;
+my_col
+1
+2
+SELECT '2' as "3"
+UNION
+SELECT '1';
+3
+1
+2
+CREATE TABLE t1( a CHAR);
+SELECT * FROM t1;
+a
+DROP TABLE t1;
+SELECT NULL as "my_col1",2 AS "my_col2"
+UNION
+SELECT NULL,1;
+my_col1 my_col2
+NULL 2
+NULL 1
+SELECT NULL as "my_col1",2 AS "my_col2"
+UNION
+SELECT NULL,1;
+my_col1 my_col2
+NULL 1
+NULL 2
+SELECT 2 as "my_col1",NULL AS "my_col2"
+UNION
+SELECT 1,NULL;
+my_col1 my_col2
+2 NULL
+1 NULL
+SELECT 2 as "my_col1",NULL AS "my_col2"
+UNION
+SELECT 1,NULL;
+my_col1 my_col2
+1 NULL
+2 NULL
+SET @a = 17;
+SELECT 2 as "my_col"
+UNION
+SELECT 1;
+my_col
+2
+1
+SELECT 2 as "my_col"
+UNION
+SELECT 1;
+my_col
+1
+2
+SELECT '2' as "my_col1",2 as "my_col2"
+UNION
+SELECT '1',1 from t2;
+ERROR 42S02: Table 'test.t2' doesn't exist
+SELECT '1' as "my_col1",2 as "my_col2"
+UNION
+SELECT '2',1;
+my_col1 my_col2
+# 1
+# 2
+CREATE TABLE t1 (f1 INT);
+INSERT INTO t1 SET f1 = 1024;
+INSERT INTO t1 SELECT f1 - 1 FROM t1;
+INSERT INTO t1 SELECT f1 - 2 FROM t1;
+INSERT INTO t1 SELECT f1 - 4 FROM t1;
+INSERT INTO t1 SELECT f1 - 8 FROM t1;
+INSERT INTO t1 SELECT f1 - 16 FROM t1;
+INSERT INTO t1 SELECT f1 - 32 FROM t1;
+INSERT INTO t1 SELECT f1 - 64 FROM t1;
+INSERT INTO t1 SELECT f1 - 128 FROM t1;
+INSERT INTO t1 SELECT f1 - 256 FROM t1;
+INSERT INTO t1 SELECT f1 - 512 FROM t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+CREATE TABLE t1(
+a int, b varchar(255), c datetime
+);
+SHOW COLUMNS FROM t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b varchar(255) YES NULL
+c datetime YES NULL
+statement=SHOW COLUMNS FROM t1 row_number=1, column_name="Type", Value=int(11)
+statement="SHOW COLUMNS FROM t1" row_number=1, column_name="Type", Value=int(11)
+statement=SHOW COLUMNS FROM t1 row_number=1, column_name=Default, Value=NULL
+value= ->A B<-
+value= 1
+mysqltest: At line 1: query_get_value - argument list started with '(' must be ended with ')'
+mysqltest: At line 1: Missing required argument 'query' to command 'query_get_value'
+mysqltest: At line 1: Missing required argument 'column name' to command 'query_get_value'
+mysqltest: At line 1: Missing required argument 'row number' to command 'query_get_value'
+value= No such row
+value= No such row
+mysqltest: At line 1: Invalid row number: 'notnumber'
+mysqltest: At line 1: Could not find column 'column_not_exists' in the result of 'SHOW COLUMNS FROM t1'
+mysqltest: At line 1: Query 'SET @A = 1' didn't return a result set
+mysqltest: At line 1: Could not find column '1 AS B' in the result of 'SELECT 1 AS A'
+value= No such row
+mysqltest: At line 1: Error running query 'SHOW COLNS FROM t1': 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'COLNS FROM t1' at line 1
+
+Field Type Null Key Default Extra
+a int(11) YES -><- NULL
+b varchar(255) YES -><- NULL
+c datetime YES -><- NULL
+
+Number of columns with Default NULL: 3
+
+SHOW COLUMNS FROM t1;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+b varchar(255) YES NULL
+c datetime YES NULL
+drop table t1;
End of tests
diff --git a/mysql-test/r/ndb_backup_print.result b/mysql-test/r/ndb_backup_print.result
new file mode 100644
index 00000000000..fdd929802b2
--- /dev/null
+++ b/mysql-test/r/ndb_backup_print.result
@@ -0,0 +1,64 @@
+use test;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
+Connected to Management Server at: :
+Waiting for completed, this may take several minutes
+Node : Backup started from node
+Node : Backup started from node completed
+ StartGCP: StopGCP:
+ #Records: #LogRecords:
+ Data: bytes Log: bytes
+create table t1
+(pk int key
+,a1 BIT(1), a2 BIT(5), a3 BIT(33), a4 BIT(63), a5 BIT(64)
+,b1 TINYINT, b2 TINYINT UNSIGNED
+,c1 SMALLINT, c2 SMALLINT UNSIGNED
+,d1 INT, d2 INT UNSIGNED
+,e1 BIGINT, e2 BIGINT UNSIGNED
+,f1 CHAR(1) BINARY, f2 CHAR(32) BINARY, f3 CHAR(255) BINARY
+,g1 VARCHAR(32) BINARY, g2 VARCHAR(255) BINARY, g3 VARCHAR(1000) BINARY
+,h1 BINARY(1), h2 BINARY(8), h3 BINARY(255)
+,i1 VARBINARY(32), i2 VARBINARY(255), i3 VARBINARY(1000)
+) engine ndb;
+insert into t1 values
+(1
+,0x1, 0x17, 0x789a, 0x789abcde, 0xfedc0001
+,127, 255
+,32767, 65535
+,2147483647, 4294967295
+,9223372036854775807, 18446744073709551615
+,'1','12345678901234567890123456789012','123456789'
+ ,'1','12345678901234567890123456789012','123456789'
+ ,0x12,0x123456789abcdef0, 0x012345
+,0x12,0x123456789abcdef0, 0x00123450
+);
+insert into t1 values
+(2
+,0, 0, 0, 0, 0
+,-128, 0
+,-32768, 0
+,-2147483648, 0
+,-9223372036854775808, 0
+,'','',''
+ ,'','',''
+ ,0x0,0x0,0x0
+,0x0,0x0,0x0
+);
+insert into t1 values
+(3
+,NULL,NULL,NULL,NULL,NULL
+,NULL,NULL
+,NULL,NULL
+,NULL,NULL
+,NULL,NULL
+,NULL,NULL,NULL
+,NULL,NULL,NULL
+,NULL,NULL,NULL
+,NULL,NULL,NULL
+);
+Connected to Management Server at: :
+Waiting for completed, this may take several minutes
+Node : Backup started from node
+Node : Backup started from node completed
+ StartGCP: StopGCP:
+ #Records: #LogRecords:
+ Data: bytes Log: bytes
diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result
index 75ccc6cd39e..346b1d5741b 100644
--- a/mysql-test/r/ndb_basic.result
+++ b/mysql-test/r/ndb_basic.result
@@ -770,4 +770,75 @@ c abc ab
d ab ab
e abc abc
DROP TABLE t1;
+create table t1 (a int not null primary key, b int not null) engine=ndb;
+create table t2 (a int not null primary key, b int not null) engine=ndb;
+insert into t1 values (1,10), (2,20), (3,30);
+insert into t2 values (1,10), (2,20), (3,30);
+select * from t1 order by a;
+a b
+1 10
+2 20
+3 30
+delete from t1 where a > 0 order by a desc limit 1;
+select * from t1 order by a;
+a b
+1 10
+2 20
+delete from t1,t2 using t1,t2 where t1.a = t2.a;
+select * from t2 order by a;
+a b
+3 30
+drop table t1,t2;
+create table t1 (a int not null primary key, b int not null) engine=ndb;
+insert into t1 values (1,10), (2,20), (3,30);
+insert into t1 set a=1, b=100;
+ERROR 23000: Duplicate entry '1' for key 1
+insert ignore into t1 set a=1, b=100;
+select * from t1 order by a;
+a b
+1 10
+2 20
+3 30
+insert into t1 set a=1, b=1000 on duplicate key update b=b+1;
+select * from t1 order by a;
+a b
+1 11
+2 20
+3 30
+drop table t1;
+create table t1 (a int not null primary key, b int not null) engine=ndb;
+create table t2 (c int not null primary key, d int not null) engine=ndb;
+insert into t1 values (1,10), (2,10), (3,30), (4, 30);
+insert into t2 values (1,10), (2,10), (3,30), (4, 30);
+update t1 set a = 1 where a = 3;
+ERROR 23000: Duplicate entry '1' for key 1
+select * from t1 order by a;
+a b
+1 10
+2 10
+3 30
+4 30
+update t1 set b = 1 where a > 1 order by a desc limit 1;
+select * from t1 order by a;
+a b
+1 10
+2 10
+3 30
+4 1
+update t1,t2 set a = 1, c = 1 where a = 3 and c = 3;
+ERROR 23000: Duplicate entry '1' for key 1
+select * from t1 order by a;
+a b
+1 10
+2 10
+3 30
+4 1
+update ignore t1,t2 set a = 1, c = 1 where a = 3 and c = 3;
+select * from t1 order by a;
+a b
+1 10
+2 10
+3 30
+4 1
+drop table t1,t2;
End of 5.0 tests
diff --git a/mysql-test/r/ndb_insert.result b/mysql-test/r/ndb_insert.result
index e7275bde2b8..b5349ecb59c 100644
--- a/mysql-test/r/ndb_insert.result
+++ b/mysql-test/r/ndb_insert.result
@@ -657,3 +657,172 @@ a b
2 NULL
3 NULL
drop table t1;
+CREATE TABLE t1 (
+pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+b INT NOT NULL,
+c INT NOT NULL UNIQUE
+) ENGINE=NDBCLUSTER;
+CREATE TABLE t2 (
+pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+b INT NOT NULL,
+c INT NOT NULL UNIQUE
+) ENGINE=MYISAM;
+SET @@session.auto_increment_increment=10;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+SELECT * FROM t1 ORDER BY pk;
+pk b c
+1 1 0
+11 2 1
+21 3 2
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+COUNT(t1.pk)
+3
+TRUNCATE t1;
+TRUNCATE t2;
+SET @@session.auto_increment_offset=5;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t1 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6);
+SELECT * FROM t1 ORDER BY pk;
+pk b c
+5 1 0
+15 2 1
+25 3 2
+27 4 3
+35 5 4
+99 6 5
+105 7 6
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+COUNT(t1.pk)
+7
+TRUNCATE t1;
+TRUNCATE t2;
+SET @@session.auto_increment_increment=2;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+SELECT * FROM t1 ORDER BY pk;
+pk b c
+1 1 0
+3 2 1
+5 3 2
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+COUNT(t1.pk)
+3
+DROP TABLE t1, t2;
+CREATE TABLE t1 (
+pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+b INT NOT NULL,
+c INT NOT NULL UNIQUE
+) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7;
+CREATE TABLE t2 (
+pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+b INT NOT NULL,
+c INT NOT NULL UNIQUE
+) ENGINE=MYISAM AUTO_INCREMENT = 7;
+SET @@session.auto_increment_offset=1;
+SET @@session.auto_increment_increment=1;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+SELECT * FROM t1 ORDER BY pk;
+pk b c
+7 1 0
+8 2 1
+9 3 2
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+COUNT(t1.pk)
+3
+DROP TABLE t1, t2;
+CREATE TABLE t1 (
+pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+b INT NOT NULL,
+c INT NOT NULL UNIQUE
+) ENGINE=NDBCLUSTER AUTO_INCREMENT = 3;
+CREATE TABLE t2 (
+pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+b INT NOT NULL,
+c INT NOT NULL UNIQUE
+) ENGINE=MYISAM AUTO_INCREMENT = 3;
+SET @@session.auto_increment_offset=5;
+SET @@session.auto_increment_increment=10;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+SELECT * FROM t1 ORDER BY pk;
+pk b c
+5 1 0
+15 2 1
+25 3 2
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+COUNT(t1.pk)
+3
+DROP TABLE t1, t2;
+CREATE TABLE t1 (
+pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+b INT NOT NULL,
+c INT NOT NULL UNIQUE
+) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7;
+CREATE TABLE t2 (
+pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+b INT NOT NULL,
+c INT NOT NULL UNIQUE
+) ENGINE=MYISAM AUTO_INCREMENT = 7;
+SET @@session.auto_increment_offset=5;
+SET @@session.auto_increment_increment=10;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+SELECT * FROM t1 ORDER BY pk;
+pk b c
+15 1 0
+25 2 1
+35 3 2
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+COUNT(t1.pk)
+3
+DROP TABLE t1, t2;
+CREATE TABLE t1 (
+pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+b INT NOT NULL,
+c INT NOT NULL UNIQUE
+) ENGINE=NDBCLUSTER AUTO_INCREMENT = 5;
+CREATE TABLE t2 (
+pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+b INT NOT NULL,
+c INT NOT NULL UNIQUE
+) ENGINE=MYISAM AUTO_INCREMENT = 5;
+SET @@session.auto_increment_offset=5;
+SET @@session.auto_increment_increment=10;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+SELECT * FROM t1 ORDER BY pk;
+pk b c
+5 1 0
+15 2 1
+25 3 2
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+COUNT(t1.pk)
+3
+DROP TABLE t1, t2;
+CREATE TABLE t1 (
+pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+b INT NOT NULL,
+c INT NOT NULL UNIQUE
+) ENGINE=NDBCLUSTER AUTO_INCREMENT = 100;
+CREATE TABLE t2 (
+pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+b INT NOT NULL,
+c INT NOT NULL UNIQUE
+) ENGINE=MYISAM AUTO_INCREMENT = 100;
+SET @@session.auto_increment_offset=5;
+SET @@session.auto_increment_increment=10;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+SELECT * FROM t1 ORDER BY pk;
+pk b c
+105 1 0
+115 2 1
+125 3 2
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+COUNT(t1.pk)
+3
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/ndb_restore.result b/mysql-test/r/ndb_restore.result
index bc31798cee7..9faac2df0a4 100644
--- a/mysql-test/r/ndb_restore.result
+++ b/mysql-test/r/ndb_restore.result
@@ -129,6 +129,13 @@ create table t7 engine=myisam as select * from t7_c;
create table t8 engine=myisam as select * from t8_c;
create table t9 engine=myisam as select * from t9_c;
create table t10 engine=myisam as select * from t10_c;
+CREATE TEMPORARY TABLE IF NOT EXISTS test.backup_info (id INT, backup_id INT) ENGINE = HEAP;
+DELETE FROM test.backup_info;
+LOAD DATA INFILE '../tmp.dat' INTO TABLE test.backup_info FIELDS TERMINATED BY ',';
+SELECT @the_backup_id:=backup_id FROM test.backup_info;
+@the_backup_id:=backup_id
+<the_backup_id>
+DROP TABLE test.backup_info;
drop table t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c, t10_c;
show tables;
Tables_in_test
@@ -276,4 +283,4 @@ Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length I
X X X X X X X X X X 10001 X X X X X X X
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9, t10;
drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c, t10_c;
-520093696,1
+520093696,<the_backup_id>
diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result
index daedfa50b80..c33adee76b2 100644
--- a/mysql-test/r/null.result
+++ b/mysql-test/r/null.result
@@ -97,39 +97,39 @@ Warnings:
Warning 1265 Data truncated for column 'd' at row 1
UPDATE t1 SET d=NULL;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'd' at row 1
+Warning 1048 Column 'd' cannot be null
INSERT INTO t1 (a) values (null);
ERROR 23000: Column 'a' cannot be null
INSERT INTO t1 (a) values (1/null);
ERROR 23000: Column 'a' cannot be null
INSERT INTO t1 (a) values (null),(null);
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 2
+Warning 1048 Column 'a' cannot be null
+Warning 1048 Column 'a' cannot be null
INSERT INTO t1 (b) values (null);
ERROR 23000: Column 'b' cannot be null
INSERT INTO t1 (b) values (1/null);
ERROR 23000: Column 'b' cannot be null
INSERT INTO t1 (b) values (null),(null);
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'b' at row 1
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'b' at row 2
+Warning 1048 Column 'b' cannot be null
+Warning 1048 Column 'b' cannot be null
INSERT INTO t1 (c) values (null);
ERROR 23000: Column 'c' cannot be null
INSERT INTO t1 (c) values (1/null);
ERROR 23000: Column 'c' cannot be null
INSERT INTO t1 (c) values (null),(null);
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c' at row 1
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c' at row 2
+Warning 1048 Column 'c' cannot be null
+Warning 1048 Column 'c' cannot be null
INSERT INTO t1 (d) values (null);
ERROR 23000: Column 'd' cannot be null
INSERT INTO t1 (d) values (1/null);
ERROR 23000: Column 'd' cannot be null
INSERT INTO t1 (d) values (null),(null);
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'd' at row 1
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'd' at row 2
+Warning 1048 Column 'd' cannot be null
+Warning 1048 Column 'd' cannot be null
select * from t1;
a b c d
0 0000-00-00 00:00:00 0
diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result
index 0b4ed15f659..8a440284c53 100644
--- a/mysql-test/r/null_key.result
+++ b/mysql-test/r/null_key.result
@@ -342,7 +342,7 @@ index (id2)
);
insert into t1 values(null,null),(1,1);
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'id2' at row 1
+Warning 1048 Column 'id2' cannot be null
select * from t1;
id id2
NULL 0
diff --git a/mysql-test/r/olap.result b/mysql-test/r/olap.result
index b1c29a5aadb..4a54b17316d 100644
--- a/mysql-test/r/olap.result
+++ b/mysql-test/r/olap.result
@@ -696,8 +696,8 @@ CREATE VIEW v1 AS
SELECT a, LENGTH(a), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP;
DESC v1;
Field Type Null Key Default Extra
-a int(11) YES 0
-LENGTH(a) int(10) YES NULL
+a bigint(11) YES NULL
+LENGTH(a) bigint(10) YES NULL
COUNT(*) bigint(21) NO 0
SELECT * FROM v1;
a LENGTH(a) COUNT(*)
diff --git a/mysql-test/r/preload.result b/mysql-test/r/preload.result
index 145fd22ffb6..24a6e594a14 100644
--- a/mysql-test/r/preload.result
+++ b/mysql-test/r/preload.result
@@ -143,10 +143,9 @@ Key_read_requests 0
Key_reads 0
load index into cache t3, t2 key (primary,b) ;
Table Op Msg_type Msg_text
-test.t3 preload_keys error Table 'test.t3' doesn't exist
+test.t3 preload_keys Error Table 'test.t3' doesn't exist
+test.t3 preload_keys error Corrupt
test.t2 preload_keys status OK
-Warnings:
-Error 1146 Table 'test.t3' doesn't exist
show status like "key_read%";
Variable_name Value
Key_read_requests 478
@@ -159,12 +158,10 @@ Key_read_requests 0
Key_reads 0
load index into cache t3 key (b), t2 key (c) ;
Table Op Msg_type Msg_text
-test.t3 preload_keys error Table 'test.t3' doesn't exist
-test.t2 preload_keys error Key 'c' doesn't exist in table 't2'
+test.t3 preload_keys Error Table 'test.t3' doesn't exist
+test.t3 preload_keys error Corrupt
+test.t2 preload_keys Error Key 'c' doesn't exist in table 't2'
test.t2 preload_keys status Operation failed
-Warnings:
-Error 1146 Table 'test.t3' doesn't exist
-Error 1176 Key 'c' doesn't exist in table 't2'
show status like "key_read%";
Variable_name Value
Key_read_requests 0
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 8a10a52ee65..4db588e5cac 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -1378,45 +1378,39 @@ prepare stmt from "repair table t1, t4, t3";
execute stmt;
Table Op Msg_type Msg_text
test.t1 repair status OK
-test.t4 repair error Table 'test.t4' doesn't exist
+test.t4 repair Error Table 'test.t4' doesn't exist
+test.t4 repair error Corrupt
test.t3 repair status OK
-Warnings:
-Error 1146 Table 'test.t4' doesn't exist
execute stmt;
Table Op Msg_type Msg_text
test.t1 repair status OK
-test.t4 repair error Table 'test.t4' doesn't exist
+test.t4 repair Error Table 'test.t4' doesn't exist
+test.t4 repair error Corrupt
test.t3 repair status OK
-Warnings:
-Error 1146 Table 'test.t4' doesn't exist
prepare stmt from "optimize table t1, t3, t4";
execute stmt;
Table Op Msg_type Msg_text
test.t1 optimize status OK
test.t3 optimize status OK
-test.t4 optimize error Table 'test.t4' doesn't exist
-Warnings:
-Error 1146 Table 'test.t4' doesn't exist
+test.t4 optimize Error Table 'test.t4' doesn't exist
+test.t4 optimize error Corrupt
execute stmt;
Table Op Msg_type Msg_text
test.t1 optimize status Table is already up to date
test.t3 optimize status Table is already up to date
-test.t4 optimize error Table 'test.t4' doesn't exist
-Warnings:
-Error 1146 Table 'test.t4' doesn't exist
+test.t4 optimize Error Table 'test.t4' doesn't exist
+test.t4 optimize error Corrupt
prepare stmt from "analyze table t4, t1";
execute stmt;
Table Op Msg_type Msg_text
-test.t4 analyze error Table 'test.t4' doesn't exist
+test.t4 analyze Error Table 'test.t4' doesn't exist
+test.t4 analyze error Corrupt
test.t1 analyze status Table is already up to date
-Warnings:
-Error 1146 Table 'test.t4' doesn't exist
execute stmt;
Table Op Msg_type Msg_text
-test.t4 analyze error Table 'test.t4' doesn't exist
+test.t4 analyze Error Table 'test.t4' doesn't exist
+test.t4 analyze error Corrupt
test.t1 analyze status Table is already up to date
-Warnings:
-Error 1146 Table 'test.t4' doesn't exist
deallocate prepare stmt;
drop table t1, t2, t3;
create database mysqltest_long_database_name_to_thrash_heap;
@@ -1683,4 +1677,13 @@ execute stmt;
ERROR 42S22: Unknown column 'y.value' in 'field list'
deallocate prepare stmt;
drop tables t1;
+prepare stmt from "create table t1 select ?";
+set @a=1.0;
+execute stmt using @a;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `?` decimal(2,1) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
End of 5.0 tests.
diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result
index a2f0fff086e..06941cf6497 100644
--- a/mysql-test/r/ps_2myisam.result
+++ b/mysql-test/r/ps_2myisam.result
@@ -1304,7 +1304,7 @@ set @arg00=NULL;
set @arg01=2;
execute stmt1 using @arg00, @arg01;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
+Warning 1048 Column 'a' cannot be null
select a,b from t1 order by a;
a b
0 two
@@ -2961,20 +2961,26 @@ delete from t9 ;
test_sequence
-- insert into date/time columns --
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1264 Out of range value adjusted for column 'c13' at row 1
@@ -3005,6 +3011,7 @@ Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value adjusted for column 'c16' at row 1
Warning 1264 Out of range value adjusted for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value adjusted for column 'c16' at row 1
Warning 1264 Out of range value adjusted for column 'c17' at row 1
diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result
index 17c83bdc87a..235660cbbaf 100644
--- a/mysql-test/r/ps_3innodb.result
+++ b/mysql-test/r/ps_3innodb.result
@@ -1287,7 +1287,7 @@ set @arg00=NULL;
set @arg01=2;
execute stmt1 using @arg00, @arg01;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
+Warning 1048 Column 'a' cannot be null
select a,b from t1 order by a;
a b
0 two
@@ -2944,20 +2944,26 @@ delete from t9 ;
test_sequence
-- insert into date/time columns --
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1264 Out of range value adjusted for column 'c13' at row 1
@@ -2988,6 +2994,7 @@ Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value adjusted for column 'c16' at row 1
Warning 1264 Out of range value adjusted for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value adjusted for column 'c16' at row 1
Warning 1264 Out of range value adjusted for column 'c17' at row 1
diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result
index 114891f1145..bf77ec7acf2 100644
--- a/mysql-test/r/ps_4heap.result
+++ b/mysql-test/r/ps_4heap.result
@@ -1288,7 +1288,7 @@ set @arg00=NULL;
set @arg01=2;
execute stmt1 using @arg00, @arg01;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
+Warning 1048 Column 'a' cannot be null
select a,b from t1 order by a;
a b
0 two
@@ -2945,20 +2945,26 @@ delete from t9 ;
test_sequence
-- insert into date/time columns --
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1264 Out of range value adjusted for column 'c13' at row 1
@@ -2989,6 +2995,7 @@ Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value adjusted for column 'c16' at row 1
Warning 1264 Out of range value adjusted for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value adjusted for column 'c16' at row 1
Warning 1264 Out of range value adjusted for column 'c17' at row 1
diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result
index 245d5766efd..f6aa716d932 100644
--- a/mysql-test/r/ps_5merge.result
+++ b/mysql-test/r/ps_5merge.result
@@ -1330,7 +1330,7 @@ set @arg00=NULL;
set @arg01=2;
execute stmt1 using @arg00, @arg01;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
+Warning 1048 Column 'a' cannot be null
select a,b from t1 order by a;
a b
0 two
@@ -2881,20 +2881,26 @@ delete from t9 ;
test_sequence
-- insert into date/time columns --
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1264 Out of range value adjusted for column 'c13' at row 1
@@ -2925,6 +2931,7 @@ Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value adjusted for column 'c16' at row 1
Warning 1264 Out of range value adjusted for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value adjusted for column 'c16' at row 1
Warning 1264 Out of range value adjusted for column 'c17' at row 1
@@ -4344,7 +4351,7 @@ set @arg00=NULL;
set @arg01=2;
execute stmt1 using @arg00, @arg01;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
+Warning 1048 Column 'a' cannot be null
select a,b from t1 order by a;
a b
0 two
@@ -5895,20 +5902,26 @@ delete from t9 ;
test_sequence
-- insert into date/time columns --
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1264 Out of range value adjusted for column 'c13' at row 1
@@ -5939,6 +5952,7 @@ Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value adjusted for column 'c16' at row 1
Warning 1264 Out of range value adjusted for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value adjusted for column 'c16' at row 1
Warning 1264 Out of range value adjusted for column 'c17' at row 1
diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result
index 6f6ecbb20b8..2c8b40e8818 100644
--- a/mysql-test/r/ps_6bdb.result
+++ b/mysql-test/r/ps_6bdb.result
@@ -1287,7 +1287,7 @@ set @arg00=NULL;
set @arg01=2;
execute stmt1 using @arg00, @arg01;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
+Warning 1048 Column 'a' cannot be null
select a,b from t1 order by a;
a b
0 two
@@ -2944,20 +2944,26 @@ delete from t9 ;
test_sequence
-- insert into date/time columns --
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1264 Out of range value adjusted for column 'c13' at row 1
@@ -2988,6 +2994,7 @@ Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value adjusted for column 'c16' at row 1
Warning 1264 Out of range value adjusted for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value adjusted for column 'c16' at row 1
Warning 1264 Out of range value adjusted for column 'c17' at row 1
diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result
index 65e9121a35e..a0bbeed34ee 100644
--- a/mysql-test/r/ps_7ndb.result
+++ b/mysql-test/r/ps_7ndb.result
@@ -1287,7 +1287,7 @@ set @arg00=NULL;
set @arg01=2;
execute stmt1 using @arg00, @arg01;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
+Warning 1048 Column 'a' cannot be null
select a,b from t1 order by a;
a b
0 two
@@ -2944,20 +2944,26 @@ delete from t9 ;
test_sequence
-- insert into date/time columns --
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c17' at row 1
Warnings:
Warning 1264 Out of range value adjusted for column 'c13' at row 1
@@ -2988,6 +2994,7 @@ Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value adjusted for column 'c16' at row 1
Warning 1264 Out of range value adjusted for column 'c17' at row 1
Warnings:
+Note 1265 Data truncated for column 'c13' at row 1
Warning 1265 Data truncated for column 'c15' at row 1
Warning 1264 Out of range value adjusted for column 'c16' at row 1
Warning 1264 Out of range value adjusted for column 'c17' at row 1
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index 79471ee5c02..b0f3fb77c0e 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -179,12 +179,22 @@ a
1
2
3
+select * from t1 where a IN (select sql_cache a from t1);
+a
+1
+2
+3
+select * from t1 where a IN (select a from t1 union select sql_cache a from t1);
+a
+1
+2
+3
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 4
show status like "Qcache_queries_in_cache";
Variable_name Value
-Qcache_queries_in_cache 2
+Qcache_queries_in_cache 1
set query_cache_type=on;
reset query cache;
show status like "Qcache_queries_in_cache";
@@ -195,6 +205,41 @@ a
1
2
3
+select * from t1 union select sql_no_cache * from t1;
+a
+1
+2
+3
+select * from t1 where a IN (select sql_no_cache a from t1);
+a
+1
+2
+3
+select * from t1 where a IN (select a from t1 union select sql_no_cache a from t1);
+a
+1
+2
+3
+select sql_cache sql_no_cache * from t1;
+a
+1
+2
+3
+select sql_cache * from t1 union select sql_no_cache * from t1;
+a
+1
+2
+3
+select sql_cache * from t1 where a IN (select sql_no_cache a from t1);
+a
+1
+2
+3
+select sql_cache * from t1 where a IN (select a from t1 union select sql_no_cache a from t1);
+a
+1
+2
+3
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
@@ -1405,7 +1450,20 @@ Only MyISAM tables support collections 1
Function MATCH ... AGAINST() is used to do a search 1
Full-text search in MySQL implements vector space model 1
drop function change_global;
+drop table t1;
set GLOBAL query_cache_type=default;
set GLOBAL query_cache_limit=default;
set GLOBAL query_cache_min_res_unit=default;
set GLOBAL query_cache_size= default;
+set GLOBAL query_cache_size=1000000;
+create table t1 (a char);
+insert into t1 values ('c');
+a
+drop table t1;
+set GLOBAL query_cache_size= default;
+set GLOBAL query_cache_size=1000000;
+create table t1 (a char);
+insert into t1 values ('c');
+a
+drop table t1;
+set GLOBAL query_cache_size= default;
diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result
index 54d53299743..bd746711f1f 100644
--- a/mysql-test/r/repair.result
+++ b/mysql-test/r/repair.result
@@ -26,16 +26,14 @@ t1 1 st_key 1 st A NULL NULL NULL YES BTREE disabled
drop table t1;
repair table t1 use_frm;
Table Op Msg_type Msg_text
-test.t1 repair error Table 'test.t1' doesn't exist
-Warnings:
-Error 1146 Table 'test.t1' doesn't exist
+test.t1 repair Error Table 'test.t1' doesn't exist
+test.t1 repair error Corrupt
create table t1 engine=myisam SELECT 1,"table 1";
flush tables;
repair table t1;
Table Op Msg_type Msg_text
-test.t1 repair error Incorrect file format 't1'
-Warnings:
-Error 130 Incorrect file format 't1'
+test.t1 repair Error Incorrect file format 't1'
+test.t1 repair error Corrupt
repair table t1 use_frm;
Table Op Msg_type Msg_text
test.t1 repair warning Number of rows changed from 0 to 1
@@ -79,12 +77,12 @@ INSERT INTO t1 VALUES
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0');
Warnings:
-Error 1034 sort_buffer_size is to small
+Error 1034 myisam_sort_buffer_size is too small
Error 1034 Number of rows changed from 0 to 157
SET myisam_repair_threads=2;
REPAIR TABLE t1;
Table Op Msg_type Msg_text
-test.t1 repair error sort_buffer_size is to small
+test.t1 repair error myisam_sort_buffer_size is too small
test.t1 repair warning Number of rows changed from 0 to 157
test.t1 repair status OK
SET myisam_repair_threads=@@global.myisam_repair_threads;
diff --git a/mysql-test/r/rpl_change_master.result b/mysql-test/r/rpl_change_master.result
index 7f2ba568fb3..98c42069470 100644
--- a/mysql-test/r/rpl_change_master.result
+++ b/mysql-test/r/rpl_change_master.result
@@ -12,12 +12,74 @@ insert into t1 values(1);
insert into t1 values(2);
stop slave;
show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 357 # # master-bin.000001 No No 0 0 183 # None 0 No #
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 357
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running No
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 183
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
change master to master_user='root';
show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 183 # # master-bin.000001 No No 0 0 183 # None 0 No #
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 183
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running No
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 183
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
start slave;
select * from t1;
n
diff --git a/mysql-test/r/rpl_failed_optimize.result b/mysql-test/r/rpl_failed_optimize.result
index c2c07dc6343..33a8cdc4a2f 100644
--- a/mysql-test/r/rpl_failed_optimize.result
+++ b/mysql-test/r/rpl_failed_optimize.result
@@ -15,7 +15,6 @@ Warnings:
Error 1205 Lock wait timeout exceeded; try restarting transaction
OPTIMIZE TABLE non_existing;
Table Op Msg_type Msg_text
-test.non_existing optimize error Table 'test.non_existing' doesn't exist
-Warnings:
-Error 1146 Table 'test.non_existing' doesn't exist
+test.non_existing optimize Error Table 'test.non_existing' doesn't exist
+test.non_existing optimize error Corrupt
drop table t1;
diff --git a/mysql-test/r/rpl_grant.result b/mysql-test/r/rpl_grant.result
new file mode 100644
index 00000000000..4d7ad298ce4
--- /dev/null
+++ b/mysql-test/r/rpl_grant.result
@@ -0,0 +1,77 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+**** On Master ****
+CREATE USER dummy@localhost;
+CREATE USER dummy1@localhost, dummy2@localhost;
+SELECT user, host FROM mysql.user WHERE user != 'root';
+user host
+dummy localhost
+dummy1 localhost
+dummy2 localhost
+SELECT COUNT(*) FROM mysql.user;
+COUNT(*)
+6
+**** On Slave ****
+SELECT user,host FROM mysql.user WHERE user != 'root';
+user host
+dummy localhost
+dummy1 localhost
+dummy2 localhost
+SELECT COUNT(*) FROM mysql.user;
+COUNT(*)
+6
+**** On Master ****
+DROP USER nonexisting@localhost;
+ERROR HY000: Operation DROP USER failed for 'nonexisting'@'localhost'
+DROP USER nonexisting@localhost, dummy@localhost;
+ERROR HY000: Operation DROP USER failed for 'nonexisting'@'localhost'
+DROP USER dummy1@localhost, dummy2@localhost;
+SELECT user, host FROM mysql.user WHERE user != 'root';
+user host
+SELECT COUNT(*) FROM mysql.user;
+COUNT(*)
+3
+**** On Slave ****
+SELECT user,host FROM mysql.user WHERE user != 'root';
+user host
+SELECT COUNT(*) FROM mysql.user;
+COUNT(*)
+3
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_PORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 609
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running Yes
+Slave_SQL_Running Yes
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 609
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result
index d69786c00a1..be137079c7a 100644
--- a/mysql-test/r/rpl_loaddata.result
+++ b/mysql-test/r/rpl_loaddata.result
@@ -80,3 +80,7 @@ ERROR 23000: Duplicate entry '2003-03-22' for key 1
drop table t2;
drop table t2;
drop table t1;
+CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB;
+LOAD DATA INFILE "../std_data_ln/words.dat" INTO TABLE t1;
+ERROR 23000: Duplicate entry 'Aarhus' for key 1
+DROP TABLE t1;
diff --git a/mysql-test/r/rpl_log_pos.result b/mysql-test/r/rpl_log_pos.result
index cf13756966e..b55326415bf 100644
--- a/mysql-test/r/rpl_log_pos.result
+++ b/mysql-test/r/rpl_log_pos.result
@@ -7,27 +7,78 @@ start slave;
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 98
-show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 98 # # master-bin.000001 Yes Yes 0 0 98 # None 0 No #
-stop slave;
-change master to master_log_pos=73;
-start slave;
stop slave;
change master to master_log_pos=73;
show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73 # # master-bin.000001 No No 0 0 73 # None 0 No #
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_PORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 73
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running No
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 73
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
start slave;
-show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73 # # master-bin.000001 No Yes 0 0 73 # None 0 No #
stop slave;
-change master to master_log_pos=173;
-start slave;
show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 173 # # master-bin.000001 No Yes 0 0 173 # None 0 No #
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_PORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 73
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running No
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 73
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 98
@@ -35,7 +86,6 @@ create table if not exists t1 (n int);
drop table if exists t1;
create table t1 (n int);
insert into t1 values (1),(2),(3);
-stop slave;
change master to master_log_pos=98;
start slave;
select * from t1;
@@ -44,3 +94,4 @@ n
2
3
drop table t1;
+End of 5.0 tests
diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result
index bf2ef98c87f..df42e76a0c8 100644
--- a/mysql-test/r/rpl_rotate_logs.result
+++ b/mysql-test/r/rpl_rotate_logs.result
@@ -50,7 +50,10 @@ show binary logs;
Log_name File_size
master-bin.000002 363
master-bin.000003 407
-purge master logs before now();
+select @time_for_purge:=DATE_ADD(UPDATE_TIME, INTERVAL 1 SECOND)
+from information_schema.tables
+where TABLE_SCHEMA="test" and TABLE_NAME="t2";
+purge master logs before (@time_for_purge);
show binary logs;
Log_name File_size
master-bin.000003 407
diff --git a/mysql-test/r/rpl_skip_error.result b/mysql-test/r/rpl_skip_error.result
index adc61f8c2c8..22ba357ef49 100644
--- a/mysql-test/r/rpl_skip_error.result
+++ b/mysql-test/r/rpl_skip_error.result
@@ -14,3 +14,22 @@ n
2
3
drop table t1;
+create table t1(a int primary key);
+insert into t1 values (1),(2);
+delete from t1 where @@server_id=1;
+set sql_mode=strict_trans_tables;
+select @@server_id;
+@@server_id
+1
+insert into t1 values (1),(2),(3);
+select @@server_id;
+@@server_id
+2
+select * from t1;
+a
+1
+2
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 843 # # master-bin.000001 Yes Yes 0 0 843 # None 0 No #
+drop table t1;
diff --git a/mysql-test/r/rpl_ssl.result b/mysql-test/r/rpl_ssl.result
index 6bc1e996965..1d3f4762693 100644
--- a/mysql-test/r/rpl_ssl.result
+++ b/mysql-test/r/rpl_ssl.result
@@ -92,3 +92,4 @@ Master_SSL_Cert MYSQL_TEST_DIR/std_data/client-cert.pem
Master_SSL_Cipher
Master_SSL_Key MYSQL_TEST_DIR/std_data/client-key.pem
Seconds_Behind_Master #
+End of 5.0 tests
diff --git a/mysql-test/r/rpl_user_variables.result b/mysql-test/r/rpl_user_variables.result
index 05f2b68042e..26ac2b26aaa 100644
--- a/mysql-test/r/rpl_user_variables.result
+++ b/mysql-test/r/rpl_user_variables.result
@@ -253,10 +253,44 @@ SELECT * from t2;
k
100
42
+drop table t1, t2;
+reset master;
+create table t1 (a int);
+prepare s from "insert into t1 values (@a),(?)";
+set @a=98;
+execute s using @a;
+prepare s from "insert into t1 values (?)";
+set @a=99;
+execute s using @a;
+prepare s from "insert into t1 select 100 limit ?";
+set @a=100;
+execute s using @a;
+show binlog events from 98;
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 98 Query 1 184 use `test`; create table t1 (a int)
+slave-bin.000001 184 User var 2 226 @`a`=98
+slave-bin.000001 226 Query 1 320 use `test`; insert into t1 values (@a),(98)
+slave-bin.000001 320 Query 1 409 use `test`; insert into t1 values (99)
+slave-bin.000001 409 Query 1 507 use `test`; insert into t1 select 100 limit 100
+select * from t1;
+a
+98
+98
+99
+100
+drop table t1;
+create table t1(a int, b int);
+prepare s1 from 'insert into t1 values (@x:=@x+1, ?)';
+set @x=1;
+execute s1 using @x;
+select * from t1;
+a b
+2 1
+select * from t1;
+a b
+2 1
+drop table t1;
End of 5.0 tests.
-DROP TABLE t1;
-DROP TABLE t2;
-DROP TABLE IF EXISTS t1;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
CREATE TABLE t1 (i INT);
diff --git a/mysql-test/r/rpl_view.result b/mysql-test/r/rpl_view.result
index be03f3f080a..be7ed6e8c2a 100644
--- a/mysql-test/r/rpl_view.result
+++ b/mysql-test/r/rpl_view.result
@@ -106,4 +106,10 @@ a b
1 6
drop table t1;
drop view v1;
+CREATE TABLE t1(a INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE VIEW v1 AS SELECT * FROM t1;
+ERROR 42S01: Table 'v1' already exists
+DROP VIEW v1;
+DROP TABLE t1;
End of 5.0 tests
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index bdcb51c4db8..7a2f812cde4 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -1030,7 +1030,7 @@ select bug12329();
bug12329()
101
execute stmt1;
-ERROR HY000: Table 't2' was not locked with LOCK TABLES
+ERROR 42S02: Table 'test.t2' doesn't exist
deallocate prepare stmt1;
drop function bug12329;
drop table t1, t2;
@@ -1152,12 +1152,12 @@ create trigger t1_ai after insert on t1 for each row insert into t2 values (new.
create view v1 as select * from t1;
drop table t2;
insert into v1 values (1);
-ERROR HY000: Table 't2' was not locked with LOCK TABLES
+ERROR 42S02: Table 'test.t2' doesn't exist
drop trigger t1_ai;
create function bug11555_1() returns int return (select max(i) from t2);
create trigger t1_ai after insert on t1 for each row set @a:=bug11555_1();
insert into v1 values (2);
-ERROR HY000: Table 't2' was not locked with LOCK TABLES
+ERROR 42S02: Table 'test.t2' doesn't exist
drop function bug11555_1;
drop table t1;
drop view v1;
diff --git a/mysql-test/r/sp-prelocking.result b/mysql-test/r/sp-prelocking.result
index 7d8dd862748..5eac54803f0 100644
--- a/mysql-test/r/sp-prelocking.result
+++ b/mysql-test/r/sp-prelocking.result
@@ -254,4 +254,17 @@ execute stmt;
deallocate prepare stmt;
drop function bug19634;
drop table t1, t2, t3;
+drop table if exists bug_27907_logs;
+drop table if exists bug_27907_t1;
+create table bug_27907_logs (a int);
+create table bug_27907_t1 (a int);
+create trigger bug_27907_t1_ai after insert on bug_27907_t1
+for each row
+begin
+insert into bug_27907_logs (a) values (1);
+end|
+drop table bug_27907_logs;
+insert into bug_27907_t1(a) values (1);
+ERROR 42S02: Table 'test.bug_27907_logs' doesn't exist
+drop table bug_27907_t1;
End of 5.0 tests
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index b5b79af031e..b411c65faee 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -4409,55 +4409,58 @@ Table Op Msg_type Msg_text
test.t1 repair status OK
test.t2 repair status OK
test.t3 repair status OK
-test.v1 repair error 'test.v1' is not BASE TABLE
+test.v1 repair Error 'test.v1' is not BASE TABLE
+test.v1 repair error Corrupt
Table Op Msg_type Msg_text
test.t1 optimize status OK
test.t2 optimize status OK
test.t3 optimize status OK
-test.v1 optimize error 'test.v1' is not BASE TABLE
+test.v1 optimize Error 'test.v1' is not BASE TABLE
+test.v1 optimize error Corrupt
Table Op Msg_type Msg_text
test.t1 analyze status Table is already up to date
test.t2 analyze status Table is already up to date
test.t3 analyze status Table is already up to date
-test.v1 analyze error 'test.v1' is not BASE TABLE
-Warnings:
-Error 1347 'test.v1' is not BASE TABLE
+test.v1 analyze Error 'test.v1' is not BASE TABLE
+test.v1 analyze error Corrupt
call bug13012()|
Table Op Msg_type Msg_text
test.t1 repair status OK
test.t2 repair status OK
test.t3 repair status OK
-test.v1 repair error 'test.v1' is not BASE TABLE
+test.v1 repair Error 'test.v1' is not BASE TABLE
+test.v1 repair error Corrupt
Table Op Msg_type Msg_text
test.t1 optimize status OK
test.t2 optimize status OK
test.t3 optimize status OK
-test.v1 optimize error 'test.v1' is not BASE TABLE
+test.v1 optimize Error 'test.v1' is not BASE TABLE
+test.v1 optimize error Corrupt
Table Op Msg_type Msg_text
test.t1 analyze status Table is already up to date
test.t2 analyze status Table is already up to date
test.t3 analyze status Table is already up to date
-test.v1 analyze error 'test.v1' is not BASE TABLE
-Warnings:
-Error 1347 'test.v1' is not BASE TABLE
+test.v1 analyze Error 'test.v1' is not BASE TABLE
+test.v1 analyze error Corrupt
call bug13012()|
Table Op Msg_type Msg_text
test.t1 repair status OK
test.t2 repair status OK
test.t3 repair status OK
-test.v1 repair error 'test.v1' is not BASE TABLE
+test.v1 repair Error 'test.v1' is not BASE TABLE
+test.v1 repair error Corrupt
Table Op Msg_type Msg_text
test.t1 optimize status OK
test.t2 optimize status OK
test.t3 optimize status OK
-test.v1 optimize error 'test.v1' is not BASE TABLE
+test.v1 optimize Error 'test.v1' is not BASE TABLE
+test.v1 optimize error Corrupt
Table Op Msg_type Msg_text
test.t1 analyze status Table is already up to date
test.t2 analyze status Table is already up to date
test.t3 analyze status Table is already up to date
-test.v1 analyze error 'test.v1' is not BASE TABLE
-Warnings:
-Error 1347 'test.v1' is not BASE TABLE
+test.v1 analyze Error 'test.v1' is not BASE TABLE
+test.v1 analyze error Corrupt
drop procedure bug13012|
drop view v1;
select * from t1|
@@ -4909,7 +4912,7 @@ create table t3 as select * from v1|
show create table t3|
Table Create Table
t3 CREATE TABLE `t3` (
- `j` int(11) default NULL
+ `j` bigint(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t3|
j
@@ -6018,6 +6021,8 @@ select bug20777(9223372036854775810) as '9223372036854775810 2**63+2';
select bug20777(-9223372036854775808) as 'lower bounds signed bigint';
lower bounds signed bigint
0
+Warnings:
+Warning 1264 Out of range value adjusted for column 'f1' at row 1
select bug20777(9223372036854775807) as 'upper bounds signed bigint';
upper bounds signed bigint
9223372036854775807
@@ -6030,9 +6035,13 @@ upper bounds unsigned bigint
select bug20777(18446744073709551616) as 'upper bounds unsigned bigint + 1';
upper bounds unsigned bigint + 1
18446744073709551615
+Warnings:
+Warning 1264 Out of range value adjusted for column 'f1' at row 1
select bug20777(-1) as 'lower bounds unsigned bigint - 1';
lower bounds unsigned bigint - 1
0
+Warnings:
+Warning 1264 Out of range value adjusted for column 'f1' at row 1
create table examplebug20777 as select
0 as 'i',
bug20777(9223372036854775806) as '2**63-2',
@@ -6044,7 +6053,12 @@ bug20777(18446744073709551615) as '2**64-1',
bug20777(18446744073709551616) as '2**64',
bug20777(0) as '0',
bug20777(-1) as '-1';
+Warnings:
+Warning 1264 Out of range value adjusted for column 'f1' at row 1
+Warning 1264 Out of range value adjusted for column 'f1' at row 1
insert into examplebug20777 values (1, 9223372036854775806, 9223372036854775807, 223372036854775808, 9223372036854775809, 18446744073709551614, 18446744073709551615, 8446744073709551616, 0, -1);
+Warnings:
+Warning 1264 Out of range value adjusted for column '-1' at row 1
show create table examplebug20777;
Table Create Table
examplebug20777 CREATE TABLE `examplebug20777` (
@@ -6152,3 +6166,14 @@ count(*)
3
drop table t1,t2;
drop function bug27354;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+CREATE FUNCTION metered(a INT) RETURNS INT RETURN 12;
+CREATE VIEW v1 AS SELECT test.metered(a) as metered FROM t1;
+SHOW CREATE VIEW v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`metered`(`t1`.`a`) AS `metered` from `t1`
+DROP VIEW v1;
+DROP FUNCTION metered;
+DROP TABLE t1;
+End of 5.0 tests
diff --git a/mysql-test/r/sp_trans.result b/mysql-test/r/sp_trans.result
index c74909e7e8f..564e31c9e32 100644
--- a/mysql-test/r/sp_trans.result
+++ b/mysql-test/r/sp_trans.result
@@ -530,23 +530,3 @@ count(*)
drop table t3, t4|
drop procedure bug14210|
set @@session.max_heap_table_size=default|
-CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM|
-CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB|
-insert into t2 values (1,1)|
-create function bug23333()
-RETURNS int(11)
-DETERMINISTIC
-begin
-insert into t1 values (null);
-select count(*) from t1 into @a;
-return @a;
-end|
-reset master|
-insert into t2 values (bug23333(),1)|
-ERROR 23000: Duplicate entry '1' for key 1
-show binlog events from 98 /* with fixes for #23333 will show there is the query */|
-Log_name Pos Event_type Server_id End_log_pos Info
-select count(*),@a from t1 /* must be 1,1 */|
-count(*) @a
-1 1
-drop table t1, t2|
diff --git a/mysql-test/r/sp_trans_log.result b/mysql-test/r/sp_trans_log.result
new file mode 100644
index 00000000000..96e6f76b23c
--- /dev/null
+++ b/mysql-test/r/sp_trans_log.result
@@ -0,0 +1,20 @@
+CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM|
+CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB|
+insert into t2 values (1,1)|
+create function bug23333()
+RETURNS int(11)
+DETERMINISTIC
+begin
+insert into t1 values (null);
+select count(*) from t1 into @a;
+return @a;
+end|
+reset master|
+insert into t2 values (bug23333(),1)|
+ERROR 23000: Duplicate entry '1' for key 1
+show binlog events from 98 /* with fixes for #23333 will show there is the query */|
+Log_name Pos Event_type Server_id End_log_pos Info
+select count(*),@a from t1 /* must be 1,1 */|
+count(*) @a
+1 1
+drop table t1, t2|
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index 74bd2a171e3..34869862a63 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -206,6 +206,8 @@ INSERT INTO t1 (col1) VALUES (STR_TO_DATE('15.10.2004','%d.%m.%Y'));
INSERT INTO t1 (col2) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'));
INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'));
INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
+Warnings:
+Note 1265 Data truncated for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
ERROR 22007: Incorrect date value: '2004-00-31 15:30:00' for column 'col1' at row 1
INSERT INTO t1 (col1) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i'));
@@ -991,16 +993,16 @@ ERROR 23000: Column 'col2' cannot be null
INSERT INTO t1 VALUES (103,'',NULL);
ERROR 23000: Column 'col3' cannot be null
UPDATE t1 SET col1=NULL WHERE col1 =100;
-ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'col1' at row 1
+ERROR 23000: Column 'col1' cannot be null
UPDATE t1 SET col2 =NULL WHERE col2 ='hello';
-ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1
+ERROR 23000: Column 'col2' cannot be null
UPDATE t1 SET col2 =NULL where col3 IS NOT NULL;
-ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1
+ERROR 23000: Column 'col2' cannot be null
INSERT IGNORE INTO t1 values (NULL,NULL,NULL);
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col1' at row 1
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col3' at row 1
+Warning 1048 Column 'col1' cannot be null
+Warning 1048 Column 'col2' cannot be null
+Warning 1048 Column 'col3' cannot be null
SELECT * FROM t1;
col1 col2 col3
100 hello 2004-08-20
@@ -1025,11 +1027,11 @@ ERROR HY000: Field 'col2' doesn't have a default value
INSERT INTO t1 (col1) SELECT 1;
ERROR HY000: Field 'col2' doesn't have a default value
INSERT INTO t1 SELECT 1,NULL;
-ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1
+ERROR 23000: Column 'col2' cannot be null
INSERT IGNORE INTO t1 values (NULL,NULL);
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col1' at row 1
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1
+Warning 1048 Column 'col1' cannot be null
+Warning 1048 Column 'col2' cannot be null
INSERT IGNORE INTO t1 (col1) values (3);
Warnings:
Warning 1364 Field 'col2' doesn't have a default value
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 92a4a6f3f5a..efd6a5ab572 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -2853,7 +2853,6 @@ a
3
4
DROP TABLE t1,t2,t3;
-purge master logs before (select adddate(current_timestamp(), interval -4 day));
CREATE TABLE t1 (f1 INT);
CREATE TABLE t2 (f2 INT);
INSERT INTO t1 VALUES (1);
@@ -4071,4 +4070,40 @@ id st
2 GA
4 FL
DROP TABLE t1,t2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT count(*) FROM t1 GROUP BY a) as res;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+Warnings:
+Note 1003 select `res`.`count(*)` AS `count(*)` from (select count(0) AS `count(*)` from `test`.`t1` group by `test`.`t1`.`a`) `res`
+DROP TABLE t1;
+CREATE TABLE t1 (
+a varchar(255) default NULL,
+b timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+INDEX idx(a,b)
+);
+CREATE TABLE t2 (
+a varchar(255) default NULL
+);
+INSERT INTO t1 VALUES ('abcdefghijk','2007-05-07 06:00:24');
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26');
+INSERT INTO `t2` VALUES ('abcdefghijk');
+INSERT INTO `t2` VALUES ('asdf');
+SET session sort_buffer_size=8192;
+SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2;
+d1
+1
+1
+DROP TABLE t1,t2;
End of 5.0 tests.
diff --git a/mysql-test/r/subselect_notembedded.result b/mysql-test/r/subselect_notembedded.result
index dd4b0701c32..44ae055425e 100644
--- a/mysql-test/r/subselect_notembedded.result
+++ b/mysql-test/r/subselect_notembedded.result
@@ -1 +1,3 @@
purge master logs before (select adddate(current_timestamp(), interval -4 day));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select adddate(current_timestamp(), interval -4 day))' at line 1
+purge master logs before adddate(current_timestamp(), interval -4 day);
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 3e6a901dc00..5405a632aa4 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -820,9 +820,9 @@ call p1();
drop trigger t1_bi;
create trigger t1_bi after insert on t1 for each row insert into t3 values (new.id);
execute stmt1;
-ERROR HY000: Table 't3' was not locked with LOCK TABLES
+ERROR 42S02: Table 'test.t3' doesn't exist
call p1();
-ERROR HY000: Table 't3' was not locked with LOCK TABLES
+ERROR 42S02: Table 'test.t3' doesn't exist
deallocate prepare stmt1;
drop procedure p1;
drop table t1, t2, t3;
@@ -1449,4 +1449,31 @@ isave
1
2
drop table t1, t2, t3;
+CREATE TABLE t1 (id INTEGER);
+CREATE TABLE t2 (id INTEGER);
+INSERT INTO t2 VALUES (1),(2);
+CREATE TRIGGER t1_test AFTER INSERT ON t1 FOR EACH ROW
+INSERT INTO t2 VALUES (new.id);
+SELECT GET_LOCK('B26162',120);
+GET_LOCK('B26162',120)
+1
+SELECT 'rl_acquirer', GET_LOCK('B26162',120), id FROM t2 WHERE id = 1;
+SET SESSION LOW_PRIORITY_UPDATES=1;
+SET GLOBAL LOW_PRIORITY_UPDATES=1;
+INSERT INTO t1 VALUES (5);
+SELECT 'rl_contender', id FROM t2 WHERE id > 1;
+SELECT RELEASE_LOCK('B26162');
+RELEASE_LOCK('B26162')
+1
+rl_acquirer GET_LOCK('B26162',120) id
+rl_acquirer 1 1
+SELECT RELEASE_LOCK('B26162');
+RELEASE_LOCK('B26162')
+1
+rl_contender id
+rl_contender 2
+DROP TRIGGER t1_test;
+DROP TABLE t1,t2;
+SET SESSION LOW_PRIORITY_UPDATES=DEFAULT;
+SET GLOBAL LOW_PRIORITY_UPDATES=DEFAULT;
End of 5.0 tests
diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result
index 644d4d971c6..9f51fc0371c 100644
--- a/mysql-test/r/type_date.result
+++ b/mysql-test/r/type_date.result
@@ -110,3 +110,29 @@ select 1 from t1 where cast('2000-01-01 12:01:01' as datetime) between start_dat
1
1
drop table t1;
+select @d:=1111, year(@d), month(@d), day(@d), cast(@d as date);
+@d:=1111 year(@d) month(@d) day(@d) cast(@d as date)
+1111 2000 11 11 2000-11-11
+select @d:=011111, year(@d), month(@d), day(@d), cast(@d as date);
+@d:=011111 year(@d) month(@d) day(@d) cast(@d as date)
+11111 2001 11 11 2001-11-11
+select @d:=1311, year(@d), month(@d), day(@d), cast(@d as date);
+@d:=1311 year(@d) month(@d) day(@d) cast(@d as date)
+1311 NULL NULL NULL NULL
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '1311'
+Warning 1292 Truncated incorrect datetime value: '1311'
+Warning 1292 Truncated incorrect datetime value: '1311'
+Warning 1292 Truncated incorrect datetime value: '1311'
+create table t1 (d date , dt datetime , ts timestamp);
+insert into t1 values (9912101,9912101,9912101);
+Warnings:
+Warning 1264 Out of range value adjusted for column 'd' at row 1
+Warning 1264 Out of range value adjusted for column 'dt' at row 1
+Warning 1265 Data truncated for column 'ts' at row 1
+insert into t1 values (11111,11111,11111);
+select * from t1;
+d dt ts
+0000-00-00 0000-00-00 00:00:00 0000-00-00 00:00:00
+2001-11-11 2001-11-11 00:00:00 2001-11-11 00:00:00
+drop table t1;
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index 48cc54fb3ef..9e47b5da2b6 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -192,6 +192,41 @@ CAST(CAST('2006-08-10 10:11:12' AS DATETIME) + INTERVAL 14 MICROSECOND AS DECIMA
SELECT CAST(CAST('10:11:12.098700' AS TIME) AS DECIMAL(20,6));
CAST(CAST('10:11:12.098700' AS TIME) AS DECIMAL(20,6))
101112.098700
+set @org_mode=@@sql_mode;
+create table t1 (da date default '1962-03-03 23:33:34', dt datetime default '1962-03-03');
+Warnings:
+Note 1265 Data truncated for column 'da' at row 1
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `da` date default '1962-03-03',
+ `dt` datetime default '1962-03-03 00:00:00'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+insert into t1 values ();
+insert into t1 values ('2007-03-23 13:49:38','2007-03-23 13:49:38');
+Warnings:
+Note 1265 Data truncated for column 'da' at row 1
+set @@sql_mode='ansi,traditional';
+insert into t1 values ('2007-03-23 13:49:38','2007-03-23 13:49:38');
+Warnings:
+Note 1265 Data truncated for column 'da' at row 1
+insert into t1 set dt='2007-03-23 13:49:38',da=dt;
+Warnings:
+Note 1265 Data truncated for column 'da' at row 1
+insert into t1 values ('2007-03-32','2007-03-23 13:49:38');
+ERROR 22007: Incorrect date value: '2007-03-32' for column 'da' at row 1
+select * from t1;
+da dt
+1962-03-03 1962-03-03 00:00:00
+2007-03-23 2007-03-23 13:49:38
+2007-03-23 2007-03-23 13:49:38
+2007-03-23 2007-03-23 13:49:38
+drop table t1;
+create table t1 (da date default '1962-03-32 23:33:34', dt datetime default '1962-03-03');
+ERROR 42000: Invalid default value for 'da'
+create table t1 (t time default '916:00:00 a');
+ERROR 42000: Invalid default value for 't'
+set @@sql_mode= @org_mode;
create table t1 (f1 date, f2 datetime, f3 timestamp);
insert into t1(f1) values(curdate());
select curdate() < now(), f1 < now(), cast(f1 as date) < now() from t1;
@@ -376,3 +411,19 @@ if(@bug28261 = f1, '', @bug28261:= f1)
2001-01-01
2002-02-02
drop table t1;
+create table t1(f1 datetime);
+insert into t1 values('2001-01-01'),('2002-02-02');
+select * from t1 where f1 between 20020101 and 20070101000000;
+f1
+2002-02-02 00:00:00
+select * from t1 where f1 between 2002010 and 20070101000000;
+f1
+2001-01-01 00:00:00
+2002-02-02 00:00:00
+Warnings:
+Warning 1292 Incorrect datetime value: '2002010' for column 'f1' at row 1
+select * from t1 where f1 between 20020101 and 2007010100000;
+f1
+Warnings:
+Warning 1292 Incorrect datetime value: '2007010100000' for column 'f1' at row 1
+drop table t1;
diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
index c9c42d18d68..3cf24529421 100644
--- a/mysql-test/r/type_decimal.result
+++ b/mysql-test/r/type_decimal.result
@@ -790,3 +790,12 @@ Warning 1292 Truncated incorrect datetime value: '0000-00-00'
Warning 1292 Truncated incorrect datetime value: '0000-00-00'
Warning 1292 Truncated incorrect datetime value: '0000-00-00'
drop table t1;
+CREATE TABLE t1 (
+qty decimal(16,6) default NULL,
+dps tinyint(3) unsigned default NULL
+);
+INSERT INTO t1 VALUES (1.1325,3);
+SELECT ROUND(qty,3), dps, ROUND(qty,dps) FROM t1;
+ROUND(qty,3) dps ROUND(qty,dps)
+1.133 3 1.133
+DROP TABLE t1;
diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result
index 2683201e25e..0b420c42cc7 100644
--- a/mysql-test/r/type_enum.result
+++ b/mysql-test/r/type_enum.result
@@ -1779,3 +1779,10 @@ create table t1(exhausting_charset enum('ABCDEFGHIJKLMNOPQRSTUVWXYZ','
 !"','#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~','xx\','yy\€','zz‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'));
ERROR 42000: Field separator argument is not what is expected; check the manual
End of 4.1 tests
+create table t1(f1 set('a','b'), index(f1));
+insert into t1 values(''),(''),('a'),('b');
+select * from t1 where f1='';
+f1
+
+
+drop table t1;
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index 188963c5bdf..53844d2cfe2 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -344,3 +344,36 @@ create table t1 (s1 float(0,2));
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 's1').
create table t1 (s1 float(1,2));
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 's1').
+create table t1 (f1 double(200, 0));
+insert into t1 values (1e199), (-1e199);
+insert into t1 values (1e200), (-1e200);
+insert into t1 values (2e200), (-2e200);
+Warnings:
+Warning 1264 Out of range value adjusted for column 'f1' at row 1
+Warning 1264 Out of range value adjusted for column 'f1' at row 2
+select f1 + 0e0 from t1;
+f1 + 0e0
+1e+199
+-1e+199
+1e+200
+-1e+200
+1e+200
+-1e+200
+drop table t1;
+create table t1 (f1 float(30, 0));
+insert into t1 values (1e29), (-1e29);
+insert into t1 values (1e30), (-1e30);
+insert into t1 values (2e30), (-2e30);
+Warnings:
+Warning 1264 Out of range value adjusted for column 'f1' at row 1
+Warning 1264 Out of range value adjusted for column 'f1' at row 2
+select f1 + 0e0 from t1;
+f1 + 0e0
+1.0000000150475e+29
+-1.0000000150475e+29
+1.0000000150475e+30
+-1.0000000150475e+30
+1.0000000150475e+30
+-1.0000000150475e+30
+drop table t1;
+End of 5.0 tests
diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result
index 7c52e7da496..2e9cf217ed6 100644
--- a/mysql-test/r/udf.result
+++ b/mysql-test/r/udf.result
@@ -273,4 +273,27 @@ drop function f3;
drop function metaphon;
drop function myfunc_double;
drop function myfunc_int;
+CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
+create table t1 (a char);
+set GLOBAL query_cache_size=1355776;
+reset query cache;
+select metaphon('MySQL') from t1;
+metaphon('MySQL')
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 0
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+select metaphon('MySQL') from t1;
+metaphon('MySQL')
+show status like "Qcache_hits";
+Variable_name Value
+Qcache_hits 0
+show status like "Qcache_queries_in_cache";
+Variable_name Value
+Qcache_queries_in_cache 0
+drop table t1;
+drop function metaphon;
+set GLOBAL query_cache_size=default;
End of 5.0 tests.
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index 753c982155c..80b5dccc198 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -317,3 +317,39 @@ SHOW COUNT(*) WARNINGS;
SHOW COUNT(*) ERRORS;
@@session.error_count
1
+create table t1(f1 int, f2 varchar(2), f3 float, f4 decimal(2,1));
+insert into t1 values
+(1, "a", 1.5, 1.6), (1, "a", 1.5, 1.6), (2, "b", 2.5, 2.6),
+(3, "c", 3.5, 3.6), (4, "d", 4.5, 4.6), (1, "a", 1.5, 1.6),
+(3, "c", 3.5, 3.6), (1, "a", 1.5, 1.6);
+select @a:=f1, count(f1) from t1 group by 1 desc;
+@a:=f1 count(f1)
+4 1
+3 2
+2 1
+1 4
+select @a:=f1, count(f1) from t1 group by 1 asc;
+@a:=f1 count(f1)
+1 4
+2 1
+3 2
+4 1
+select @a:=f2, count(f2) from t1 group by 1 desc;
+@a:=f2 count(f2)
+d 1
+c 2
+b 1
+a 4
+select @a:=f3, count(f3) from t1 group by 1 desc;
+@a:=f3 count(f3)
+4.5 1
+3.5 2
+2.5 1
+1.5 4
+select @a:=f4, count(f4) from t1 group by 1 desc;
+@a:=f4 count(f4)
+4.6 1
+3.6 2
+2.6 1
+1.6 4
+drop table t1;
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 8d9d802949d..9adb3f96142 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -23,6 +23,9 @@ c
5
6
11
+select is_updatable from information_schema.views where table_name='v1';
+is_updatable
+NO
create temporary table t1 (a int, b int);
select * from t1;
a b
@@ -322,6 +325,12 @@ create table t1 (a int, b int, primary key(a));
insert into t1 values (10,2), (20,3), (30,4), (40,5), (50,10);
create view v1 (a,c) as select a, b+1 from t1;
create algorithm=temptable view v2 (a,c) as select a, b+1 from t1;
+select is_updatable from information_schema.views where table_name='v2';
+is_updatable
+NO
+select is_updatable from information_schema.views where table_name='v1';
+is_updatable
+YES
update v1 set c=a+c;
ERROR HY000: Column 'c' is not updatable
update v2 set a=a+c;
@@ -604,6 +613,10 @@ insert into t1 values(5,'Hello, world of views');
create view v1 as select * from t1;
create view v2 as select * from v1;
update v2 set col2='Hello, view world';
+select is_updatable from information_schema.views;
+is_updatable
+YES
+YES
select * from t1;
col1 col2
5 Hello, view world
@@ -1377,7 +1390,9 @@ test.t1 check status OK
drop table t1;
check table v1;
Table Op Msg_type Msg_text
-test.v1 check error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+test.v1 check Error Table 'test.t1' doesn't exist
+test.v1 check Error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+test.v1 check error Corrupt
drop view v1;
create table t1 (a int);
create table t2 (a int);
@@ -1497,7 +1512,7 @@ insert into v3(b) values (10);
insert into v3(a) select a from t2;
insert into v3(b) select b from t2;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 2
+Warning 1048 Column 'a' cannot be null
insert into v3(a) values (1) on duplicate key update a=a+10000+VALUES(a);
select * from t1;
a b
@@ -1901,11 +1916,17 @@ CREATE VIEW v6 AS SELECT CONVERT_TZ(col1,'GMT','MET') FROM t2;
DROP TABLE t1;
CHECK TABLE v1, v2, v3, v4, v5, v6;
Table Op Msg_type Msg_text
-test.v1 check error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+test.v1 check Error Table 'test.t1' doesn't exist
+test.v1 check Error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+test.v1 check error Corrupt
test.v2 check status OK
-test.v3 check error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+test.v3 check Error Table 'test.t1' doesn't exist
+test.v3 check Error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+test.v3 check error Corrupt
test.v4 check status OK
-test.v5 check error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+test.v5 check Error Table 'test.t1' doesn't exist
+test.v5 check Error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+test.v5 check error Corrupt
test.v6 check status OK
drop view v1, v2, v3, v4, v5, v6;
drop table t2;
@@ -1925,11 +1946,17 @@ CREATE VIEW v6 AS SELECT f2() FROM t3;
drop function f1;
CHECK TABLE v1, v2, v3, v4, v5, v6;
Table Op Msg_type Msg_text
-test.v1 check error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+test.v1 check Error FUNCTION test.f1 does not exist
+test.v1 check Error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+test.v1 check error Corrupt
test.v2 check status OK
-test.v3 check error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+test.v3 check Error FUNCTION test.f1 does not exist
+test.v3 check Error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+test.v3 check error Corrupt
test.v4 check status OK
-test.v5 check error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+test.v5 check Error FUNCTION test.f1 does not exist
+test.v5 check Error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+test.v5 check error Corrupt
test.v6 check status OK
create function f1 () returns int return (select max(col1) from t1);
DROP TABLE t1;
@@ -2376,35 +2403,29 @@ CREATE TABLE t1(id INT);
CREATE VIEW v1 AS SELECT id FROM t1;
OPTIMIZE TABLE v1;
Table Op Msg_type Msg_text
-test.v1 optimize error 'test.v1' is not BASE TABLE
-Warnings:
-Error 1347 'test.v1' is not BASE TABLE
+test.v1 optimize Error 'test.v1' is not BASE TABLE
+test.v1 optimize error Corrupt
ANALYZE TABLE v1;
Table Op Msg_type Msg_text
-test.v1 analyze error 'test.v1' is not BASE TABLE
-Warnings:
-Error 1347 'test.v1' is not BASE TABLE
+test.v1 analyze Error 'test.v1' is not BASE TABLE
+test.v1 analyze error Corrupt
REPAIR TABLE v1;
Table Op Msg_type Msg_text
-test.v1 repair error 'test.v1' is not BASE TABLE
-Warnings:
-Error 1347 'test.v1' is not BASE TABLE
+test.v1 repair Error 'test.v1' is not BASE TABLE
+test.v1 repair error Corrupt
DROP TABLE t1;
OPTIMIZE TABLE v1;
Table Op Msg_type Msg_text
-test.v1 optimize error 'test.v1' is not BASE TABLE
-Warnings:
-Error 1347 'test.v1' is not BASE TABLE
+test.v1 optimize Error 'test.v1' is not BASE TABLE
+test.v1 optimize error Corrupt
ANALYZE TABLE v1;
Table Op Msg_type Msg_text
-test.v1 analyze error 'test.v1' is not BASE TABLE
-Warnings:
-Error 1347 'test.v1' is not BASE TABLE
+test.v1 analyze Error 'test.v1' is not BASE TABLE
+test.v1 analyze error Corrupt
REPAIR TABLE v1;
Table Op Msg_type Msg_text
-test.v1 repair error 'test.v1' is not BASE TABLE
-Warnings:
-Error 1347 'test.v1' is not BASE TABLE
+test.v1 repair Error 'test.v1' is not BASE TABLE
+test.v1 repair error Corrupt
DROP VIEW v1;
create definer = current_user() sql security invoker view v1 as select 1;
show create view v1;
@@ -2779,7 +2800,7 @@ CREATE TABLE t1 (i int, j int);
CREATE VIEW v1 AS SELECT COALESCE(i,j) FROM t1;
DESCRIBE v1;
Field Type Null Key Default Extra
-COALESCE(i,j) int(11) YES NULL
+COALESCE(i,j) bigint(11) YES NULL
CREATE TABLE t2 SELECT COALESCE(i,j) FROM t1;
DESCRIBE t2;
Field Type Null Key Default Extra
@@ -3367,4 +3388,116 @@ SHOW CREATE VIEW v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(1.23456789 as decimal(8,0)) AS `col`
DROP VIEW v1;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b INT, c INT DEFAULT 0);
+INSERT INTO t1 (a) VALUES (1), (2);
+INSERT INTO t2 (b) VALUES (1), (2);
+CREATE VIEW v1 AS SELECT t2.b,t2.c FROM t1, t2
+WHERE t1.a=t2.b AND t2.b < 3 WITH CHECK OPTION;
+SELECT * FROM v1;
+b c
+1 0
+2 0
+UPDATE v1 SET c=1 WHERE b=1;
+SELECT * FROM v1;
+b c
+1 1
+2 0
+DROP VIEW v1;
+DROP TABLE t1,t2;
+CREATE TABLE t1 (id int);
+CREATE TABLE t2 (id int, c int DEFAULT 0);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+CREATE VIEW v1 AS
+SELECT t2.c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+UPDATE v1 SET c=1;
+DROP VIEW v1;
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a1 INT, c INT DEFAULT 0);
+CREATE TABLE t2 (a2 INT);
+CREATE TABLE t3 (a3 INT);
+CREATE TABLE t4 (a4 INT);
+INSERT INTO t1 (a1) VALUES (1),(2);
+INSERT INTO t2 (a2) VALUES (1),(2);
+INSERT INTO t3 (a3) VALUES (1),(2);
+INSERT INTO t4 (a4) VALUES (1),(2);
+CREATE VIEW v1 AS
+SELECT t1.a1, t1.c FROM t1 JOIN t2 ON t1.a1=t2.a2 AND t1.c < 3
+WITH CHECK OPTION;
+SELECT * FROM v1;
+a1 c
+1 0
+2 0
+UPDATE v1 SET c=3;
+ERROR HY000: CHECK OPTION failed 'test.v1'
+PREPARE t FROM 'UPDATE v1 SET c=3';
+EXECUTE t;
+ERROR HY000: CHECK OPTION failed 'test.v1'
+EXECUTE t;
+ERROR HY000: CHECK OPTION failed 'test.v1'
+INSERT INTO v1(a1, c) VALUES (3, 3);
+ERROR HY000: CHECK OPTION failed 'test.v1'
+UPDATE v1 SET c=1 WHERE a1=1;
+SELECT * FROM v1;
+a1 c
+1 1
+2 0
+SELECT * FROM t1;
+a1 c
+1 1
+2 0
+CREATE VIEW v2 AS SELECT t1.a1, t1.c
+FROM (t1 JOIN t2 ON t1.a1=t2.a2 AND t1.c < 3)
+JOIN (t3 JOIN t4 ON t3.a3=t4.a4)
+ON t2.a2=t3.a3 WITH CHECK OPTION;
+SELECT * FROM v2;
+a1 c
+1 1
+2 0
+UPDATE v2 SET c=3;
+ERROR HY000: CHECK OPTION failed 'test.v2'
+PREPARE t FROM 'UPDATE v2 SET c=3';
+EXECUTE t;
+ERROR HY000: CHECK OPTION failed 'test.v2'
+EXECUTE t;
+ERROR HY000: CHECK OPTION failed 'test.v2'
+INSERT INTO v2(a1, c) VALUES (3, 3);
+ERROR HY000: CHECK OPTION failed 'test.v2'
+UPDATE v2 SET c=2 WHERE a1=1;
+SELECT * FROM v2;
+a1 c
+1 2
+2 0
+SELECT * FROM t1;
+a1 c
+1 2
+2 0
+DROP VIEW v1,v2;
+DROP TABLE t1,t2,t3,t4;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (1,2), (2,2), (1,3), (1,2);
+CREATE VIEW v1 AS SELECT a, b+1 as b FROM t1;
+SELECT b, SUM(a) FROM v1 WHERE b=3 GROUP BY b;
+b SUM(a)
+3 4
+EXPLAIN SELECT b, SUM(a) FROM v1 WHERE b=3 GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
+SELECT a, SUM(b) FROM v1 WHERE b=3 GROUP BY a;
+a SUM(b)
+1 6
+2 3
+EXPLAIN SELECT a, SUM(b) FROM v1 WHERE b=3 GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where; Using temporary; Using filesort
+SELECT a, SUM(b) FROM v1 WHERE a=1 GROUP BY a;
+a SUM(b)
+1 10
+EXPLAIN SELECT a, SUM(b) FROM v1 WHERE a=1 GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
+DROP VIEW v1;
+DROP TABLE t1;
End of 5.0 tests.
diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result
index 32dffa305e5..0f9ce47dec6 100644
--- a/mysql-test/r/view_grant.result
+++ b/mysql-test/r/view_grant.result
@@ -601,9 +601,9 @@ Warnings:
Note 1449 There is no 'no-such-user'@'localhost' registered
SHOW CREATE VIEW v;
View Create View
-v CREATE ALGORITHM=UNDEFINED DEFINER=`no-such-user`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `t1`.`a` AS `a` from `t1`
+v CREATE ALGORITHM=UNDEFINED DEFINER=`no-such-user`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `test`.`t1`.`a` AS `a` from `t1`
Warnings:
-Note 1449 There is no 'no-such-user'@'localhost' registered
+Warning 1356 View 'test.v' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
SELECT * FROM v;
ERROR HY000: There is no 'no-such-user'@'localhost' registered
DROP VIEW v;
diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result
index d0ad4ca6648..9ce1f9c825d 100644
--- a/mysql-test/r/warnings.result
+++ b/mysql-test/r/warnings.result
@@ -86,7 +86,7 @@ drop table t1;
create table t1(a tinyint NOT NULL, b tinyint unsigned, c char(5));
insert into t1 values(NULL,100,'mysql'),(10,-1,'mysql ab'),(500,256,'open source'),(20,NULL,'test');
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1
+Warning 1048 Column 'a' cannot be null
Warning 1264 Out of range value adjusted for column 'b' at row 2
Warning 1265 Data truncated for column 'c' at row 2
Warning 1264 Out of range value adjusted for column 'a' at row 3
@@ -99,7 +99,7 @@ Warning 1265 Data truncated for column 'c' at row 2
alter table t1 add d char(2);
update t1 set a=NULL where a=10;
Warnings:
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 2
+Warning 1048 Column 'a' cannot be null
update t1 set c='mysql ab' where c='test';
Warnings:
Warning 1265 Data truncated for column 'c' at row 4
@@ -115,7 +115,7 @@ Warnings:
Warning 1265 Data truncated for column 'b' at row 1
Warning 1265 Data truncated for column 'b' at row 2
Warning 1265 Data truncated for column 'b' at row 3
-Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 4
+Warning 1048 Column 'a' cannot be null
Warning 1265 Data truncated for column 'b' at row 4
insert into t2(b) values('mysqlab');
Warnings:
diff --git a/mysql-test/std_data/Index.xml b/mysql-test/std_data/Index.xml
new file mode 100644
index 00000000000..988dddcc68a
--- /dev/null
+++ b/mysql-test/std_data/Index.xml
@@ -0,0 +1,71 @@
+<charsets>
+
+ <charset name="utf8">
+ <collation name="utf8_test_ci" id="240">
+ <rules>
+ <reset>a</reset>
+ <s>b</s>
+ </rules>
+ </collation>
+
+ </charset>
+
+ <charset name="ucs2">
+ <collation name="ucs2_test_ci" id="241">
+ <rules>
+ <reset>a</reset>
+ <s>b</s>
+ </rules>
+ </collation>
+ <collation name="ucs2_vn_ci" id="242">
+ <!-- Vietnamese experimental collation -->
+ <rules>
+ <reset>A</reset>
+ <p>\u0103</p><t>\u0102</t>
+ <s>\u1EB1</s><t>\u1EB0</t>
+ <s>\u1EB3</s><t>\u1EB2</t>
+ <s>\u1EB5</s><t>\u1EB4</t>
+ <s>\u1EAF</s><t>\u1EAE</t>
+ <s>\u1EB7</s><t>\u1EB6</t>
+ <p>\u00E2</p><t>\u00C2</t>
+ <s>\u1EA7</s><t>\u1EA6</t>
+ <s>\u1EA9</s><t>\u1EA8</t>
+ <s>\u1EAB</s><t>\u1EAA</t>
+ <s>\u1EA5</s><t>\u1EA4</t>
+ <s>\u1EAD</s><t>\u1EAC</t>
+ <reset>D</reset>
+ <p>\u0111</p><t>\u0110</t>
+ <reset>E</reset>
+ <p>\u00EA</p><t>\u00CA</t>
+ <s>\u1EC1</s><t>\u1EC0</t>
+ <s>\u1EC3</s><t>\u1EC2</t>
+ <s>\u1EC5</s><t>\u1EC4</t>
+ <s>\u1EBF</s><t>\u1EBE</t>
+ <s>\u1EC7</s><t>\u1EC6</t>
+ <reset>O</reset>
+ <p>\u00F4</p><t>\u00D4</t>
+ <s>\u1ED3</s><t>\u1ED2</t>
+ <s>\u1ED5</s><t>\u1ED4</t>
+ <s>\u1ED7</s><t>\u1ED6</t>
+ <s>\u1ED1</s><t>\u1ED0</t>
+ <s>\u1ED9</s><t>\u1ED8</t>
+ <p>\u01A1</p><t>\u01A0</t>
+ <s>\u1EDD</s><t>\u1EDC</t>
+ <s>\u1EDF</s><t>\u1EDE</t>
+ <s>\u1EE1</s><t>\u1EE0</t>
+ <s>\u1EDB</s><t>\u1EDA</t>
+ <s>\u1EE3</s><t>\u1EE2</t>
+ <reset>U</reset>
+ <p>\u01B0</p><t>\u01AF</t>
+ <s>\u1EEB</s><t>\u1EEA</t>
+ <s>\u1EED</s><t>\u1EEC</t>
+ <s>\u1EEF</s><t>\u1EEE</t>
+ <s>\u1EE9</s><t>\u1EE8</t>
+ <s>\u1EF1</s><t>\u1EF0</t>
+ </rules>
+
+ </collation>
+
+ </charset>
+
+</charsets>
diff --git a/mysql-test/suite/large_tests/README.TXT b/mysql-test/suite/large_tests/README.TXT
new file mode 100644
index 00000000000..51cd4e41a40
--- /dev/null
+++ b/mysql-test/suite/large_tests/README.TXT
@@ -0,0 +1,13 @@
+large_test suite
+================
+
+Iggy Galarza 07/20/07
+---------------------
+
+This test suite should include any test that requires:
+1. Longer than the default timeout to complete.
+2. A considerable amount of disk space.
+
+These tests can be completed with the following command:
+
+mysql-test-run.pl --suite=large_tests --big-test --suite-timeout=6360 --testcase-timeout=795
diff --git a/mysql-test/suite/large_tests/r/alter_table.result b/mysql-test/suite/large_tests/r/alter_table.result
new file mode 100644
index 00000000000..921711e9812
--- /dev/null
+++ b/mysql-test/suite/large_tests/r/alter_table.result
@@ -0,0 +1,37 @@
+drop table if exists t1;
+create table `t1` (`c1` tinyint unsigned not null, key `c1` (`c1`))
+engine=myisam default charset=utf8;
+alter table `t1` disable keys;
+insert into t1 values (1),(2),(3),(4);
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1 limit 2147483647;
+alter table t1 enable keys;
+drop table t1;
diff --git a/mysql-test/suite/large_tests/t/alter_table.test b/mysql-test/suite/large_tests/t/alter_table.test
new file mode 100644
index 00000000000..61f0b34d904
--- /dev/null
+++ b/mysql-test/suite/large_tests/t/alter_table.test
@@ -0,0 +1,47 @@
+# The test for bug#27029 requires about 8 hours and 20 minutes on my
+# fastest machine. This test requires at least 60 GB of disk space.
+--source include/big_test.inc
+
+#
+# Bug#27029 alter table ... enable keys crashes mysqld on large table
+#
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+create table `t1` (`c1` tinyint unsigned not null, key `c1` (`c1`))
+engine=myisam default charset=utf8;
+alter table `t1` disable keys;
+insert into t1 values (1),(2),(3),(4);
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1 limit 2147483647; #Insert 4294967295 rows.
+alter table t1 enable keys;
+drop table t1;
diff --git a/mysql-test/t/backup.test b/mysql-test/t/backup.test
index a3339ecce69..6ff4144aaf2 100644
--- a/mysql-test/t/backup.test
+++ b/mysql-test/t/backup.test
@@ -1,3 +1,8 @@
+
+# The server need to be started in $MYSQLTEST_VARDIR since it
+# uses ../std_data_ln/
+-- source include/uses_vardir.inc
+
#
# This test is a bit tricky as we can't use backup table to overwrite an old
# table
diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test
index 9a5fb11229d..4aef7395184 100644
--- a/mysql-test/t/bigint.test
+++ b/mysql-test/t/bigint.test
@@ -294,3 +294,19 @@ drop table t1;
select cast(19999999999999999999 as signed);
select cast(-19999999999999999999 as signed);
+
+#
+# Bug #28625: -9223372036854775808 doesn't fit in BIGINT.
+#
+
+# PS protocol gives different metadata for `Max length' column
+--disable_ps_protocol
+--enable_metadata
+select -9223372036854775808;
+select -(9223372036854775808);
+select -((9223372036854775808));
+select -(-(9223372036854775808));
+--disable_metadata
+--endble_ps_protocol
+select --9223372036854775808, ---9223372036854775808, ----9223372036854775808;
+select -(-9223372036854775808), -(-(-9223372036854775808));
diff --git a/mysql-test/t/binary.test b/mysql-test/t/binary.test
index 4ab6ee9eaf1..1cc6ae07675 100644
--- a/mysql-test/t/binary.test
+++ b/mysql-test/t/binary.test
@@ -101,3 +101,41 @@ select hex(col1) from t1;
insert into t1 values ('b'),('b ');
select hex(col1) from t1;
drop table t1;
+
+#
+# Bug #29087: assertion abort for a search in a BINARY non-nullable index
+# by a key with trailing spaces
+#
+
+CREATE TABLE t1 (
+ a binary(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
+ index idx(a)
+);
+INSERT INTO t1 SET a=unhex('1F9480179366F2BF567E1C4B964C1EF029087575');
+INSERT INTO t1 SET a=unhex('1F9480179366F2BF567E1C4B964C1EF029082020');
+INSERT INTO t1 SET a=unhex('1F9480179366F2BF567E1C4B964C1EF029080707');
+
+SELECT hex(a) FROM t1 order by a;
+EXPLAIN SELECT hex(a) FROM t1 order by a;
+
+SELECT hex(a) from t1 WHERE a=unhex('1F9480179366F2BF567E1C4B964C1EF029082020');
+EXPLAIN
+SELECT hex(a) from t1 WHERE a=unhex('1F9480179366F2BF567E1C4B964C1EF029082020');
+
+SELECT hex(a) from t1 WHERE a=unhex('1F9480179366F2BF567E1C4B964C1EF02908');
+
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ id numeric(20) NOT NULL,
+ lang varchar(8) NOT NULL,
+ msg varchar(32) NOT NULL,
+ PRIMARY KEY (id,lang)
+);
+INSERT INTO t1 VALUES (33, 'en', 'zzzzzzz');
+INSERT INTO t1 VALUES (31, 'en', 'xxxxxxx');
+INSERT INTO t1 VALUES (32, 'en', 'yyyyyyy');
+SELECT * FROM t1 WHERE id=32;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/t/binlog.test b/mysql-test/t/binlog.test
index 1063940d378..accfa6a577f 100644
--- a/mysql-test/t/binlog.test
+++ b/mysql-test/t/binlog.test
@@ -1,9 +1,11 @@
#
# misc binlogging tests that do not require a slave running
#
+-- source include/have_log_bin.inc
-- source include/not_embedded.inc
-- source include/have_bdb.inc
-- source include/have_innodb.inc
+-- source include/have_log_bin.inc
--disable_warnings
drop table if exists t1, t2;
@@ -19,8 +21,8 @@ begin;
insert t2 values (5);
commit;
# first COMMIT must be Query_log_event, second - Xid_log_event
---replace_result "xid=21" "xid=12"
--replace_column 2 # 5 #
+--replace_regex /\/\* xid=.* \*\//\/* XID *\//
show binlog events from 98;
drop table t1,t2;
@@ -41,8 +43,8 @@ while ($1)
--enable_query_log
commit;
drop table t1;
---replace_result "xid=32" "xid=19"
--replace_column 2 # 5 #
+--replace_regex /\/\* xid=.* \*\//\/* XID *\//
show binlog events in 'master-bin.000001' from 98;
--replace_column 2 # 5 #
show binlog events in 'master-bin.000002' from 98;
diff --git a/mysql-test/t/binlog_innodb.test b/mysql-test/t/binlog_innodb.test
new file mode 100644
index 00000000000..2da7b2b0895
--- /dev/null
+++ b/mysql-test/t/binlog_innodb.test
@@ -0,0 +1,39 @@
+-- source include/have_innodb.inc
+-- source include/have_log_bin.inc
+
+
+#
+# Let us test binlog_cache_use and binlog_cache_disk_use status vars.
+# Actually this test has nothing to do with innodb per se, it just requires
+# transactional table.
+#
+show status like "binlog_cache_use";
+show status like "binlog_cache_disk_use";
+
+create table t1 (a int) engine=innodb;
+
+# Now we are going to create transaction which is long enough so its
+# transaction binlog will be flushed to disk...
+let $1=2000;
+disable_query_log;
+begin;
+while ($1)
+{
+ eval insert into t1 values( $1 );
+ dec $1;
+}
+commit;
+enable_query_log;
+show status like "binlog_cache_use";
+show status like "binlog_cache_disk_use";
+
+# Transaction which should not be flushed to disk and so should not
+# increase binlog_cache_disk_use.
+begin;
+delete from t1;
+commit;
+show status like "binlog_cache_use";
+show status like "binlog_cache_disk_use";
+drop table t1;
+
+
diff --git a/mysql-test/t/binlog_killed.test b/mysql-test/t/binlog_killed.test
new file mode 100644
index 00000000000..034895f17cb
--- /dev/null
+++ b/mysql-test/t/binlog_killed.test
@@ -0,0 +1,248 @@
+-- source include/have_innodb.inc
+--source include/not_embedded.inc
+--source include/have_log_bin.inc
+
+###
+### bug#22725 : incorrect killed error in binlogged query
+###
+
+connect (con1, localhost, root,,);
+connect (con2, localhost, root,,);
+
+create table t1 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB;
+create table t2 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=MyISAM;
+create table t3 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB;
+
+#
+# effective test for bug#22725
+#
+
+connection con1;
+select get_lock("a", 20);
+
+connection con2;
+let $ID= `select connection_id()`;
+reset master;
+send insert into t2 values (null, null), (null, get_lock("a", 10));
+
+
+connection con1;
+
+disable_abort_on_error;
+disable_query_log;
+disable_result_log;
+
+eval kill query $ID;
+
+connection con2;
+--error 0,ER_QUERY_INTERRUPTED
+reap;
+let $rows= `select count(*) from t2 /* must be 2 or 0 */`;
+
+--exec $MYSQL_BINLOG --start-position=126 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval select
+(@a:=load_file("$MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog"))
+is not null;
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+let $error_code= `select @a like "%#%error_code=0%" /* must return 1 or 0*/`;
+let $insert_binlogged= `select @a like "%insert into%" /* must return 1 or 0 */`;
+eval set @result= $rows- $error_code - $insert_binlogged;
+
+enable_abort_on_error;
+enable_query_log;
+enable_result_log;
+
+select @result /* must be zero either way */;
+
+# the functions are either *insensitive* to killing or killing can cause
+# strange problmes with the error propagation out of SF's stack
+# Bug#27563, Bug#27565, BUG#24971
+#
+# TODO: use if's block as regression test for the bugs or remove
+#
+if (0)
+{
+delimiter |;
+create function bug27563()
+RETURNS int(11)
+DETERMINISTIC
+begin
+ select get_lock("a", 10) into @a;
+ return 1;
+end|
+delimiter ;|
+
+# the function is sensitive to killing requiring innodb though with wrong client error
+# TO FIX in BUG#27565; TODO: remove --error 1105 afterwards
+delimiter |;
+create function bug27565()
+RETURNS int(11)
+DETERMINISTIC
+begin
+ select a from t1 where a=1 into @a for update;
+ return 1;
+end|
+delimiter ;|
+
+reset master;
+
+
+### ta table case: killing causes rollback
+
+# A. autocommit ON
+connection con1;
+select get_lock("a", 20);
+
+connection con2;
+let $ID= `select connection_id()`;
+send insert into t1 values (bug27563(),1);
+
+connection con1;
+eval kill query $ID;
+
+connection con2;
+# todo (re-record test): after bugs 27563,27565 got fixed affected rows will report zero
+--enable_info
+# todo: remove 0 return after fixing Bug#27563
+--error 0,ER_QUERY_INTERRUPTED
+reap; ### pb: wrong error
+--disable_info
+###--replace_column 2 # 5 #
+### show binlog events from 98 /* nothing in binlog unless Bug#27563 */;
+show master status /* must be only FD event unless Bug#27563 */;
+select count(*) from t1 /* must be zero unless Bug#27563 */;
+
+# M. multi-statement-ta
+connection con2;
+let $ID= `select connection_id()`;
+begin;
+send insert into t1 values (bug27563(),1);
+
+connection con1;
+eval kill query $ID;
+connection con2;
+# todo (re-record test): after bugs 27563,27565 got fixed affected rows will report zero
+--enable_info
+# todo: remove 0 return after fixing Bug#27563
+--error 0,ER_QUERY_INTERRUPTED
+reap;
+--disable_info
+select count(*) from t1 /* must be zero unless Bug#27563 */;
+commit;
+
+
+### non-ta table case: killing must be recorded in binlog
+
+reset master;
+
+connection con2;
+let $ID= `select connection_id()`;
+send insert into t2 values (bug27563(),1);
+
+connection con1;
+eval kill query $ID;
+
+connection con2;
+# todo: remove 0 return after fixing Bug#27563
+--error 0,ER_QUERY_INTERRUPTED
+reap;
+select count(*) from t2 /* must be one */;
+#show binlog events from 98 /* must have the insert on non-ta table */;
+show master status /* must have the insert event more to FD */;
+# the value of the error flag of KILLED_QUERY is tested further
+
+connection con1;
+select RELEASE_LOCK("a");
+
+### test with effective killing of SF()
+
+delete from t1;
+delete from t2;
+insert into t1 values (1,1);
+insert into t2 values (1,1);
+
+#
+# Bug#27565
+# test where KILL is propagated as error to the top level
+# still another bug with the error message to the user
+# todo: fix reexecute the result file after fixing
+#
+begin; update t1 set b=0 where a=1;
+
+connection con2;
+let $ID= `select connection_id()`;
+send update t2 set b=bug27565()-1 where a=1;
+
+connection con1;
+eval kill query $ID;
+commit;
+
+connection con2;
+# todo: fix Bug #27565 killed query of SF() is not reported correctly and
+# remove 1105 (wrong)
+#--error ER_QUERY_INTERRUPTED
+--error 1105,ER_QUERY_INTERRUPTED
+reap; ### pb: wrong error
+select * from t1 /* must be: (1,0) */;
+select * from t2 /* must be as before: (1,1) */;
+
+## bug#22725 with effective and propagating killing
+#
+# top-level ta-table
+connection con1;
+delete from t3;
+reset master;
+begin; update t1 set b=0 where a=1;
+
+connection con2;
+let $ID= `select connection_id()`;
+# the query won't perform completely since the function gets interrupted
+send insert into t3 values (0,0),(1,bug27565());
+
+connection con1;
+eval kill query $ID;
+rollback;
+
+connection con2;
+# todo: fix Bug #27565 killed query of SF() is not reported correctly and
+# remove 1105 (wrong)
+#--error ER_QUERY_INTERRUPTED
+--error 1105,ER_QUERY_INTERRUPTED
+reap; ### pb: wrong error
+select count(*) from t3 /* must be zero */;
+show master status /* nothing in binlog */;
+
+# top-level non-ta-table
+connection con1;
+delete from t2;
+reset master;
+begin; update t1 set b=0 where a=1;
+
+connection con2;
+let $ID= `select connection_id()`;
+# the query won't perform completely since the function gets intrurrupted
+send insert into t2 values (0,0),(1,bug27565()) /* non-ta t2 */;
+
+connection con1;
+eval kill query $ID;
+rollback;
+
+connection con2;
+# todo: fix Bug #27565 killed query of SF() is not reported correctly and
+# remove 1105 (wrong)
+#--error ER_QUERY_INTERRUPTED
+--error 1105,ER_QUERY_INTERRUPTED
+reap; ### pb: wrong error
+
+select count(*) from t2 /* count must be one */;
+show master status /* insert into non-ta must be in binlog */;
+
+drop function bug27563;
+drop function bug27565;
+}
+
+system rm $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog ;
+
+drop table t1,t2,t3;
+
diff --git a/mysql-test/t/blackhole.test b/mysql-test/t/blackhole.test
index 4bafad2d777..d8ffdeb8312 100644
--- a/mysql-test/t/blackhole.test
+++ b/mysql-test/t/blackhole.test
@@ -4,6 +4,11 @@
#
-- source include/not_embedded.inc
-- source include/have_blackhole.inc
+-- source include/have_log_bin.inc
+
+# The server need to be started in $MYSQLTEST_VARDIR since it
+# uses ../std_data_ln/
+-- source include/uses_vardir.inc
--disable_warnings
drop table if exists t1,t2;
@@ -109,7 +114,7 @@ insert into t1 values(1);
insert ignore into t1 values(1);
replace into t1 values(100);
create table t2 (a varchar(200)) engine=blackhole;
-load data infile '../std_data_ln/words.dat' into table t2;
+eval load data infile '../std_data_ln/words.dat' into table t2;
alter table t1 add b int;
alter table t1 drop b;
create table t3 like t1;
@@ -128,6 +133,17 @@ show binlog events;
drop table t1,t2,t3;
#
+# BUG#27998 - mysqld crashed when executing INSERT DELAYED on a BLACKHOLE
+# table
+#
+CREATE TABLE t1(a INT) ENGINE=BLACKHOLE;
+--error 1031
+INSERT DELAYED INTO t1 VALUES(1);
+DROP TABLE t1;
+
+# End of 4.1 tests
+
+#
#Bug#19717: DELETE Query Error on BLACKHOLE when using WHERE on column with UNIQUE INDEX
#
CREATE TABLE t1(a INT, b INT) ENGINE=BLACKHOLE;
@@ -142,4 +158,4 @@ ALTER TABLE t1 ADD PRIMARY KEY(a);
DELETE FROM t1 WHERE a=10;
DROP TABLE t1;
-# End of 4.1 tests
+# End of 5.0 tests
diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test
index 004ef69182d..b665eb86656 100644
--- a/mysql-test/t/cast.test
+++ b/mysql-test/t/cast.test
@@ -10,7 +10,13 @@ select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
select ~5, cast(~5 as signed);
explain extended select ~5, cast(~5 as signed);
select cast(5 as unsigned) -6.0;
-select cast(NULL as signed), cast(1/0 as signed);
+select cast(NULL as signed), cast(1/0 as signed);
+#
+# Bug #28250: Run-Time Check Failure #3 - The variable 'value' is being used
+# without being def
+#
+# The following line causes Run-Time Check Failure on
+# binaries built with Visual C++ 2005
select cast(NULL as unsigned), cast(1/0 as unsigned);
select cast("A" as binary) = "a", cast(BINARY "a" as CHAR) = "A";
select cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME);
diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test
index 687f3ea3918..b724b4ce47c 100644
--- a/mysql-test/t/csv.test
+++ b/mysql-test/t/csv.test
@@ -1410,3 +1410,21 @@ select * from bug15205;
drop table bug15205;
drop table bug15205_2;
+#
+# Bug#28862 "Extended Latin1 characters get lost in CVS engine"
+#
+set names latin1;
+create table t1 (
+ c varchar(1),
+ name varchar(64)
+) character set latin1 engine=csv;
+insert into t1 values (0xC0,'LATIN CAPITAL LETTER A WITH GRAVE');
+insert into t1 values (0xE0,'LATIN SMALL LETTER A WITH GRAVE');
+insert into t1 values (0xEE,'LATIN SMALL LETTER I WITH CIRCUMFLEX');
+insert into t1 values (0xFE,'LATIN SMALL LETTER THORN');
+insert into t1 values (0xF7,'DIVISION SIGN');
+insert into t1 values (0xFF,'LATIN SMALL LETTER Y WITH DIAERESIS');
+select hex(c), c, name from t1 order by 1;
+drop table t1;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/ctype_big5.test b/mysql-test/t/ctype_big5.test
index 200002cd235..8e17a27c550 100644
--- a/mysql-test/t/ctype_big5.test
+++ b/mysql-test/t/ctype_big5.test
@@ -63,4 +63,20 @@ drop table t1;
#
select hex(convert(_big5 0xC84041 using ucs2));
-# End of 4.1 tests
+--echo End of 4.1 tests
+
+#
+# Bug#26711 "binary content 0x00 sometimes becomes 0x5C 0x00 after dump/load"
+#
+create table t1 (a blob);
+insert into t1 values (0xEE00);
+--exec $MYSQL_DUMP --default-character-set=big5 -T $MYSQLTEST_VARDIR/master-data/test test t1
+delete from t1;
+select hex(load_file('test/t1.txt'));
+load data infile 't1.txt' into table t1;
+select hex(a) from t1;
+--exec rm $MYSQLTEST_VARDIR/master-data/test/t1.txt
+--exec rm $MYSQLTEST_VARDIR/master-data/test/t1.sql
+drop table t1;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/ctype_cp932_binlog.test b/mysql-test/t/ctype_cp932_binlog.test
index ee0e588fdae..7db8f311800 100644
--- a/mysql-test/t/ctype_cp932_binlog.test
+++ b/mysql-test/t/ctype_cp932_binlog.test
@@ -1,5 +1,6 @@
-- source include/not_embedded.inc
-- source include/have_cp932.inc
+-- source include/have_log_bin.inc
--character_set cp932
--disable_warnings
@@ -51,7 +52,7 @@ CALL bug18293("Foo's a Bar", _cp932 0xED40ED41ED42, 47.93)|
SELECT HEX(s1),HEX(s2),d FROM t4|
DROP PROCEDURE bug18293|
DROP TABLE t4|
-SHOW BINLOG EVENTS FROM 402|
+SHOW BINLOG EVENTS FROM 362|
delimiter ;|
# End of 5.0 tests
diff --git a/mysql-test/t/ctype_cp932_notembedded.test b/mysql-test/t/ctype_cp932_notembedded.test
deleted file mode 100644
index 52e7acc3f01..00000000000
--- a/mysql-test/t/ctype_cp932_notembedded.test
+++ /dev/null
@@ -1,32 +0,0 @@
--- source include/not_embedded.inc
--- source include/have_cp932.inc
-
---character_set cp932
---disable_warnings
-drop table if exists t1;
---enable_warnings
-
-set names cp932;
-set character_set_database = cp932;
-
-# Test prepared statement with 0x8300 sequence in parameter while
-# running with cp932 client character set.
-RESET MASTER;
-CREATE TABLE t1(f1 blob);
-PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
-SET @var1= x'8300';
-# TODO: Note that this doesn't actually test the code which was added for
-# bug#11338 because this syntax for prepared statements causes the PS to
-# be replicated differently than if we executed the PS from C or Java.
-# Using this syntax, variable names are inserted into the binlog instead
-# of values. The real goal of this test is to check the code that was
-# added to Item_param::query_val_str() in order to do hex encoding of
-# PS parameters when the client character set is cp932;
-# Bug#11338 has an example java program which can be used to verify this
-# code (and I have used it to test the fix) until there is some way to
-# exercise this code from mysql-test-run.
-EXECUTE stmt1 USING @var1;
-SHOW BINLOG EVENTS FROM 98;
-SELECT HEX(f1) FROM t1;
-DROP table t1;
-# end test for bug#11338
diff --git a/mysql-test/t/ctype_ldml-master.opt b/mysql-test/t/ctype_ldml-master.opt
new file mode 100644
index 00000000000..a2532d4cfd9
--- /dev/null
+++ b/mysql-test/t/ctype_ldml-master.opt
@@ -0,0 +1,2 @@
+--character-sets-dir=$MYSQL_TEST_DIR/std_data/
+
diff --git a/mysql-test/t/ctype_ldml.test b/mysql-test/t/ctype_ldml.test
new file mode 100644
index 00000000000..fc6ed0f2579
--- /dev/null
+++ b/mysql-test/t/ctype_ldml.test
@@ -0,0 +1,63 @@
+--source include/have_ucs2.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+set names utf8;
+
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+show variables like 'character_sets_dir%';
+
+show collation like 'utf8_test_ci';
+create table t1 (c1 char(1) character set utf8 collate utf8_test_ci);
+insert into t1 values ('a');
+select * from t1 where c1='b';
+drop table t1;
+
+show collation like 'ucs2_test_ci';
+create table t1 (c1 char(1) character set ucs2 collate ucs2_test_ci);
+insert into t1 values ('a');
+select * from t1 where c1='b';
+drop table t1;
+
+#
+# Vietnamese experimental collation
+#
+
+show collation like 'ucs2_vn_ci';
+create table t1 (c1 char(1) character set ucs2 collate ucs2_vn_ci);
+insert into t1 values (0x0061),(0x0041),(0x00E0),(0x00C0),(0x1EA3),(0x1EA2),
+ (0x00E3),(0x00C3),(0x00E1),(0x00C1),(0x1EA1),(0x1EA0);
+insert into t1 values (0x0103),(0x0102),(0x1EB1),(0x1EB0),(0x1EB3),(0x1EB2),
+ (0x1EB5),(0x1EB4),(0x1EAF),(0x1EAE),(0x1EB7),(0x1EB6);
+insert into t1 values (0x00E2),(0x00C2),(0x1EA7),(0x1EA6),(0x1EA9),(0x1EA8),
+ (0x1EAB),(0x1EAA),(0x1EA5),(0x1EA4),(0x1EAD),(0x1EAC);
+insert into t1 values ('b'),('B'),('c'),('C');
+insert into t1 values ('d'),('D'),(0x0111),(0x0110);
+insert into t1 values (0x0065),(0x0045),(0x00E8),(0x00C8),(0x1EBB),(0x1EBA),
+ (0x1EBD),(0x1EBC),(0x00E9),(0x00C9),(0x1EB9),(0x1EB8);
+insert into t1 values (0x00EA),(0x00CA),(0x1EC1),(0x1EC0),(0x1EC3),(0x1EC2),
+ (0x1EC5),(0x1EC4),(0x1EBF),(0x1EBE),(0x1EC7),(0x1EC6);
+insert into t1 values ('g'),('G'),('h'),('H');
+insert into t1 values (0x0069),(0x0049),(0x00EC),(0x00CC),(0x1EC9),(0x1EC8),
+ (0x0129),(0x0128),(0x00ED),(0x00CD),(0x1ECB),(0x1ECA);
+insert into t1 values ('k'),('K'),('l'),('L'),('m'),('M');
+insert into t1 values (0x006F),(0x004F),(0x00F2),(0x00D2),(0x1ECF),(0x1ECE),
+ (0x00F5),(0x00D5),(0x00F3),(0x00D3),(0x1ECD),(0x1ECC);
+insert into t1 values (0x00F4),(0x00D4),(0x1ED3),(0x1ED2),(0x1ED5),(0x1ED4),
+ (0x1ED7),(0x1ED6),(0x1ED1),(0x1ED0),(0x1ED9),(0x1ED8);
+insert into t1 values (0x01A1),(0x01A0),(0x1EDD),(0x1EDC),(0x1EDF),(0x1EDE),
+ (0x1EE1),(0x1EE0),(0x1EDB),(0x1EDA),(0x1EE3),(0x1EE2);
+insert into t1 values ('p'),('P'),('q'),('Q'),('r'),('R'),('s'),('S'),('t'),('T');
+insert into t1 values (0x0075),(0x0055),(0x00F9),(0x00D9),(0x1EE7),(0x1EE6),
+ (0x0169),(0x0168),(0x00FA),(0x00DA),(0x1EE5),(0x1EE4);
+insert into t1 values (0x01B0),(0x01AF),(0x1EEB),(0x1EEA),(0x1EED),(0x1EEC),
+ (0x1EEF),(0x1EEE),(0x1EE9),(0x1EE8),(0x1EF1),(0x1EF0);
+insert into t1 values ('v'),('V'),('x'),('X');
+insert into t1 values (0x0079),(0x0059),(0x1EF3),(0x1EF2),(0x1EF7),(0x1EF6),
+ (0x1EF9),(0x1EF8),(0x00FD),(0x00DD),(0x1EF5),(0x1EF4);
+select hex(c1) as h, c1 from t1 order by c1, h;
+select group_concat(hex(c1) order by hex(c1)) from t1 group by c1;
+select group_concat(c1 order by hex(c1) SEPARATOR '') from t1 group by c1;
+drop table t1;
diff --git a/mysql-test/t/ctype_ucs2_def.test b/mysql-test/t/ctype_ucs2_def.test
index e435d1fb07d..050710b208b 100644
--- a/mysql-test/t/ctype_ucs2_def.test
+++ b/mysql-test/t/ctype_ucs2_def.test
@@ -14,3 +14,19 @@ DROP TABLE IF EXISTS t1;
--enable_warnings
create table t1 (a int);
drop table t1;
+
+#
+# Bug #27643: query failed : 1114 (The table '' is full)
+#
+# Check that HASH indexes ignore trailing spaces when comparing
+# strings with the ucs2_bin collation
+
+CREATE TABLE t1(col1 VARCHAR(32) CHARACTER SET ucs2 COLLATE ucs2_bin NOT NULL,
+ col2 VARCHAR(32) CHARACTER SET ucs2 COLLATE ucs2_bin NOT NULL,
+ UNIQUE KEY key1 USING HASH (col1, col2)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES('A', 'A'), ('B', 'B'), ('C', 'C');
+--error ER_DUP_ENTRY
+INSERT INTO t1 VALUES('A ', 'A ');
+DROP TABLE t1;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/ctype_ucs_binlog.test b/mysql-test/t/ctype_ucs_binlog.test
index 2467d34386c..92d4458a9c2 100644
--- a/mysql-test/t/ctype_ucs_binlog.test
+++ b/mysql-test/t/ctype_ucs_binlog.test
@@ -1,5 +1,6 @@
--source include/not_embedded.inc
--source include/have_ucs2.inc
+--source include/have_log_bin.inc
#
# Check correct binlogging of UCS2 user variables (BUG#3875)
diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test
index 3054ec53faa..faa6d4242db 100644
--- a/mysql-test/t/date_formats.test
+++ b/mysql-test/t/date_formats.test
@@ -129,6 +129,8 @@ create table t1 (date char(30), format char(30) not null);
insert into t1 values
('2003-01-02 10:11:12', '%Y-%m-%d %H:%i:%S'),
('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S.%#'),
+('0003-01-02 8:11:2.123456', '%Y-%m-%d %H:%i:%S.%#'),
+('03-01-02 8:11:2.123456', '%Y-%m-%d %H:%i:%S.%#'),
('2003-01-02 10:11:12 PM', '%Y-%m-%d %h:%i:%S %p'),
('2003-01-02 01:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f%p'),
('2003-01-02 02:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f %p'),
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 85685234de9..9d6a9b57e9a 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -10,7 +10,9 @@
#
##############################################################################
-ndb_load : Bug#17233
user_limits : Bug#23921 random failure of user_limits.test
im_life_cycle : Bug#27851: Instance manager test im_life_cycle fails randomly
im_daemon_life_cycle : Bug#20294: Instance manager tests fail randomly
+im_options_set : Bug#20294: Instance manager tests fail randomly
+im_options_unset : Bug#20294: Instance manager tests fail randomly
+im_utils : Bug#20294: Instance manager tests fail randomly
diff --git a/mysql-test/t/drop_temp_table.test b/mysql-test/t/drop_temp_table.test
index bc06de4096c..b456e75576b 100644
--- a/mysql-test/t/drop_temp_table.test
+++ b/mysql-test/t/drop_temp_table.test
@@ -1,5 +1,4 @@
-# Embedded server doesn't support binlog
--- source include/not_embedded.inc
+-- source include/have_log_bin.inc
--disable_warnings
drop database if exists `drop-temp+table-test`;
diff --git a/mysql-test/t/error_simulation-master.opt b/mysql-test/t/error_simulation-master.opt
new file mode 100644
index 00000000000..edb77cfa85e
--- /dev/null
+++ b/mysql-test/t/error_simulation-master.opt
@@ -0,0 +1 @@
+--loose-debug=d,raise_error
diff --git a/mysql-test/t/error_simulation.test b/mysql-test/t/error_simulation.test
new file mode 100644
index 00000000000..8c044224b8a
--- /dev/null
+++ b/mysql-test/t/error_simulation.test
@@ -0,0 +1,29 @@
+-- source include/have_debug.inc
+
+#
+# Bug #28499: crash for grouping query when tmp_table_size is too small
+#
+
+DROP TABLE IF EXISTS t1;
+
+CREATE TABLE t1 (
+ a varchar(32) character set utf8 collate utf8_bin NOT NULL,
+ b varchar(32) character set utf8 collate utf8_bin NOT NULL )
+ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+INSERT INTO t1 VALUES
+ ('AAAAAAAAAA','AAAAAAAAAA'), ('AAAAAAAAAB','AAAAAAAAAB '),
+ ('AAAAAAAAAB','AAAAAAAAAB'), ('AAAAAAAAAC','AAAAAAAAAC'),
+ ('AAAAAAAAAD','AAAAAAAAAD'), ('AAAAAAAAAE','AAAAAAAAAE'),
+ ('AAAAAAAAAF','AAAAAAAAAF'), ('AAAAAAAAAG','AAAAAAAAAG'),
+ ('AAAAAAAAAH','AAAAAAAAAH'), ('AAAAAAAAAI','AAAAAAAAAI'),
+ ('AAAAAAAAAJ','AAAAAAAAAJ'), ('AAAAAAAAAK','AAAAAAAAAK');
+
+set tmp_table_size=1024;
+
+--error ER_DUP_KEY
+SELECT MAX(a) FROM t1 GROUP BY a,b;
+
+set tmp_table_size=default;
+
+DROP TABLE t1;
diff --git a/mysql-test/t/flush_block_commit_notembedded.test b/mysql-test/t/flush_block_commit_notembedded.test
index 4650a5a15a8..4a0300acf78 100644
--- a/mysql-test/t/flush_block_commit_notembedded.test
+++ b/mysql-test/t/flush_block_commit_notembedded.test
@@ -3,8 +3,10 @@
# We verify that we did not introduce a deadlock.
# This is intended to mimick how mysqldump and innobackup work.
+-- source include/have_log_bin.inc
+
# And it requires InnoDB
--- source include/not_embedded.inc
+-- source include/have_log_bin.inc
-- source include/have_innodb.inc
connect (con1,localhost,root,,);
diff --git a/mysql-test/t/func_date_add.test b/mysql-test/t/func_date_add.test
index b575eeececa..fc5a5cb2823 100644
--- a/mysql-test/t/func_date_add.test
+++ b/mysql-test/t/func_date_add.test
@@ -77,4 +77,14 @@ SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 MONTH;
SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR;
SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK;
+#
+# Bug#28450: The Item_date_add_interval in select list may fail the field
+# type assertion.
+#
+create table t1 (a int, b varchar(10));
+insert into t1 values (1, '2001-01-01'),(2, '2002-02-02');
+select '2007-01-01' + interval a day from t1;
+select b + interval a day from t1;
+drop table t1;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test
index 7771f216f69..767df5ae233 100644
--- a/mysql-test/t/func_gconcat.test
+++ b/mysql-test/t/func_gconcat.test
@@ -520,5 +520,35 @@ SELECT GROUP_CONCAT( a ORDER BY b ) FROM t1;
SELECT GROUP_CONCAT( DISTINCT a ORDER BY b ) FROM t1;
SET group_concat_max_len = DEFAULT;
DROP TABLE t1;
+# Bug #23856:GROUP_CONCAT and ORDER BY: junk from previous rows for query on I_S
+#
+SET group_concat_max_len= 65535;
+CREATE TABLE t1( a TEXT, b INTEGER );
+INSERT INTO t1 VALUES ( 'a', 0 ), ( 'b', 1 );
+SELECT GROUP_CONCAT( a ORDER BY b ) FROM t1;
+SELECT GROUP_CONCAT(DISTINCT a ORDER BY b) FROM t1;
+SELECT GROUP_CONCAT(DISTINCT a) FROM t1;
+SET group_concat_max_len= 10;
+SELECT GROUP_CONCAT(a ORDER BY b) FROM t1;
+SELECT GROUP_CONCAT(DISTINCT a ORDER BY b) FROM t1;
+SELECT GROUP_CONCAT(DISTINCT a) FROM t1;
+
+SET group_concat_max_len= 65535;
+CREATE TABLE t2( a TEXT );
+INSERT INTO t2 VALUES( REPEAT( 'a', 5000 ) );
+INSERT INTO t2 VALUES( REPEAT( 'b', 5000 ) );
+INSERT INTO t2 VALUES( REPEAT( 'a', 5000 ) );
+SELECT LENGTH( GROUP_CONCAT( DISTINCT a ) ) FROM t2;
+
+CREATE TABLE t3( a TEXT, b INT );
+INSERT INTO t3 VALUES( REPEAT( 'a', 65534 ), 1 );
+INSERT INTO t3 VALUES( REPEAT( 'a', 65535 ), 2 );
+INSERT INTO t3 VALUES( REPEAT( 'a', 65536 ), 3 );
+SELECT LENGTH( GROUP_CONCAT( a ) ) FROM t3 WHERE b = 1;
+SELECT LENGTH( GROUP_CONCAT( a ) ) FROM t3 WHERE b = 2;
+SELECT LENGTH( GROUP_CONCAT( a ) ) FROM t3 WHERE b = 3;
+
+SET group_concat_max_len= DEFAULT;
+DROP TABLE t1, t2, t3;
--echo End of 5.0 tests
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index 77592d015eb..a84ffada1ee 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -335,19 +335,28 @@ insert into t2 values(13491727406643098568),
(0x8000004000000001),
(0x8000040000000001);
-SELECT HEX(a) FROM t2 WHERE a IN (0xBB3C3E98175D33C8, 42);
+SELECT HEX(a) FROM t2 WHERE a IN
+ (CAST(0xBB3C3E98175D33C8 AS UNSIGNED),
+ 42);
SELECT HEX(a) FROM t2 WHERE a IN
-(0xBB3C3E98175D33C8,
- 0x7fffffffffffffff,
- 0x8000000000000000,
- 0x8000000000000400,
- 0x8000000000000401,
- 42);
-
-SELECT HEX(a) FROM t2 WHERE a IN (0x7fffffffffffffff,0x8000000000000001);
-SELECT HEX(a) FROM t2 WHERE a IN (0x7ffffffffffffffe,0x7fffffffffffffff);
-SELECT HEX(a) FROM t2 WHERE a IN (0x7ffffffffffffffe,0x7fffffffffffffff,'abc');
+ (CAST(0xBB3C3E98175D33C8 AS UNSIGNED),
+ CAST(0x7fffffffffffffff AS UNSIGNED),
+ CAST(0x8000000000000000 AS UNSIGNED),
+ CAST(0x8000000000000400 AS UNSIGNED),
+ CAST(0x8000000000000401 AS UNSIGNED),
+ 42);
+
+SELECT HEX(a) FROM t2 WHERE a IN
+ (CAST(0x7fffffffffffffff AS UNSIGNED),
+ CAST(0x8000000000000001 AS UNSIGNED));
+SELECT HEX(a) FROM t2 WHERE a IN
+ (CAST(0x7ffffffffffffffe AS UNSIGNED),
+ CAST(0x7fffffffffffffff AS UNSIGNED));
+SELECT HEX(a) FROM t2 WHERE a IN
+ (0x7ffffffffffffffe,
+ 0x7fffffffffffffff,
+ 'abc');
CREATE TABLE t3 (a BIGINT UNSIGNED);
INSERT INTO t3 VALUES (9223372036854775551);
diff --git a/mysql-test/t/func_sapdb.test b/mysql-test/t/func_sapdb.test
index 77d7366afe6..bb65cbaa774 100644
--- a/mysql-test/t/func_sapdb.test
+++ b/mysql-test/t/func_sapdb.test
@@ -41,6 +41,8 @@ select datediff("1997-11-30 23:59:59.000001",null);
select weekofyear("1997-11-30 23:59:59.000001");
+select makedate(03,1);
+select makedate('0003',1);
select makedate(1997,1);
select makedate(1997,0);
select makedate(9999,365);
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index bca977e6df3..1a32580aa0f 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -1076,4 +1076,52 @@ SELECT * FROM (SELECT * FROM v1) x;
DROP TABLE t1, t2;
DROP VIEW v1;
+#
+# Bug #27932: LOCATE with argument evaluated to NULL
+#
+
+SELECT LOCATE('foo', NULL) FROM DUAL;
+SELECT LOCATE(NULL, 'o') FROM DUAL;
+SELECT LOCATE(NULL, NULL) FROM DUAL;
+SELECT LOCATE('foo', NULL) IS NULL FROM DUAL;
+SELECT LOCATE(NULL, 'o') IS NULL FROM DUAL;
+SELECT LOCATE(NULL, NULL) IS NULL FROM DUAL;
+SELECT ISNULL(LOCATE('foo', NULL)) FROM DUAL;
+SELECT ISNULL(LOCATE(NULL, 'o')) FROM DUAL;
+SELECT ISNULL(LOCATE(NULL, NULL)) FROM DUAL;
+SELECT LOCATE('foo', NULL) <=> NULL FROM DUAL;
+SELECT LOCATE(NULL, 'o') <=> NULL FROM DUAL;
+SELECT LOCATE(NULL, NULL) <=> NULL FROM DUAL;
+
+CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a varchar(10), p varchar(10));
+
+INSERT INTO t1 VALUES (1, 'foo', 'o');
+INSERT INTO t1 VALUES (2, 'foo', NULL);
+INSERT INTO t1 VALUES (3, NULL, 'o');
+INSERT INTO t1 VALUES (4, NULL, NULL);
+
+SELECT id, LOCATE(a,p) FROM t1;
+SELECT id, LOCATE(a,p) IS NULL FROM t1;
+SELECT id, ISNULL(LOCATE(a,p)) FROM t1;
+SELECT id, LOCATE(a,p) <=> NULL FROM t1;
+SELECT id FROM t1 WHERE LOCATE(a,p) IS NULL;
+SELECT id FROM t1 WHERE LOCATE(a,p) <=> NULL;
+
+DROP TABLE t1;
+
+#
+# Bug #27130: SUBSTR with UNSIGNED 0 as the last argument
+#
+
+SELECT SUBSTR('foo',1,0) FROM DUAL;
+SELECT SUBSTR('foo',1,CAST(0 AS SIGNED)) FROM DUAL;
+SELECT SUBSTR('foo',1,CAST(0 AS UNSIGNED)) FROM DUAL;
+
+CREATE TABLE t1 (a varchar(10), len int unsigned);
+INSERT INTO t1 VALUES ('bar', 2), ('foo', 0);
+
+SELECT SUBSTR(a,1,len) FROM t1;
+
+DROP TABLE t1;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index ccc38db8dea..95ccc6272e2 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -557,4 +557,17 @@ SELECT Overlaps(@horiz1, @point2) FROM DUAL;
DROP TABLE t1;
+#
+# Bug#28763: Selecting geometry fields in UNION caused server crash.
+#
+create table t1(f1 geometry, f2 point, f3 linestring);
+select f1 from t1 union select f1 from t1;
+insert into t1 (f2,f3) values (GeomFromText('POINT(1 1)'),
+ GeomFromText('LINESTRING(0 0,1 1,2 2)'));
+select AsText(f2),AsText(f3) from t1;
+select AsText(a) from (select f2 as a from t1 union select f3 from t1) t;
+create table t2 as select f2 as a from t1 union select f3 from t1;
+desc t2;
+select AsText(a) from t2;
+drop table t1, t2;
--echo End of 5.0 tests
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index aa43e4225c5..32eb262fd51 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -890,7 +890,7 @@ REVOKE EXECUTE ON PROCEDURE t1 FROM some_user_name@1234567890abcdefghij123456789
# Bug #6774: Replication fails with Wrong usage of DB GRANT and GLOBAL PRIVILEGES
#
# Check if GRANT ... ON * ... fails when no database is selected
-connect (con1, localhost, root,,*NO-ONE*)
+connect (con1, localhost, root,,*NO-ONE*);
connection con1;
--error ER_NO_DB_ERROR
GRANT PROCESS ON * TO user@localhost;
diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test
index d08a9e3f83d..a3a8e2d5d53 100644
--- a/mysql-test/t/grant2.test
+++ b/mysql-test/t/grant2.test
@@ -513,3 +513,77 @@ disconnect bug13310;
connection default;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM `a@`@localhost;
drop user `a@`@localhost;
+
+
+#
+# Bug#25578 "CREATE TABLE LIKE does not require any privileges on source table"
+#
+--disable_warnings
+drop database if exists mysqltest_1;
+drop database if exists mysqltest_2;
+--enable_warnings
+--error 0,ER_CANNOT_USER
+drop user mysqltest_u1@localhost;
+
+create database mysqltest_1;
+create database mysqltest_2;
+grant all on mysqltest_1.* to mysqltest_u1@localhost;
+use mysqltest_2;
+create table t1 (i int);
+
+# Connect as user with all rights on mysqltest_1 but with no rights on mysqltest_2.
+connect (user1,localhost,mysqltest_u1,,mysqltest_1);
+connection user1;
+# As expected error is emitted
+--error ER_TABLEACCESS_DENIED_ERROR
+show create table mysqltest_2.t1;
+# This should emit error as well
+--error ER_TABLEACCESS_DENIED_ERROR
+create table t1 like mysqltest_2.t1;
+
+# Now let us check that SELECT privilege on the source is enough
+connection default;
+grant select on mysqltest_2.t1 to mysqltest_u1@localhost;
+connection user1;
+show create table mysqltest_2.t1;
+create table t1 like mysqltest_2.t1;
+
+# Clean-up
+connection default;
+use test;
+drop database mysqltest_1;
+drop database mysqltest_2;
+drop user mysqltest_u1@localhost;
+
+#
+# Bug#18660 Can't grant any privileges on single table in database
+# with underscore char
+#
+grant all on `mysqltest\_%`.* to mysqltest_1@localhost with grant option;
+grant usage on *.* to mysqltest_2@localhost;
+connect (con18600_1,localhost,mysqltest_1,,);
+
+create database mysqltest_1;
+use mysqltest_1;
+create table t1 (f1 int);
+
+grant create on `mysqltest\_1`.* to mysqltest_2@localhost;
+grant select on mysqltest_1.t1 to mysqltest_2@localhost;
+connect (con3,localhost,mysqltest_2,,);
+connection con3;
+--error 1044
+create database mysqltest_3;
+use mysqltest_1;
+create table t2(f1 int);
+select * from t1;
+connection default;
+drop database mysqltest_1;
+
+revoke all privileges, grant option from mysqltest_1@localhost;
+revoke all privileges, grant option from mysqltest_2@localhost;
+drop user mysqltest_1@localhost;
+drop user mysqltest_2@localhost;
+
+
+--echo End of 5.0 tests
+
diff --git a/mysql-test/t/greedy_optimizer.test b/mysql-test/t/greedy_optimizer.test
index 049d0ab09f7..b73f70c6a3e 100644
--- a/mysql-test/t/greedy_optimizer.test
+++ b/mysql-test/t/greedy_optimizer.test
@@ -145,11 +145,11 @@ select @@optimizer_prune_level;
#
# These are the values for the parameters that control the greedy optimizer
# (total 6 combinations - 3 for optimizer_search_depth, 2 for optimizer_prune_level):
---
+# 3:
# set optimizer_search_depth=0; - automatic
# set optimizer_search_depth=1; - min
# set optimizer_search_depth=62; - max (default)
---
+# 2:
# set optimizer_prune_level=0 - exhaustive;
# set optimizer_prune_level=1 - heuristic; # default
diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test
index b3049498f90..e1010c9fcfe 100644
--- a/mysql-test/t/group_min_max.test
+++ b/mysql-test/t/group_min_max.test
@@ -870,3 +870,25 @@ DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x
SHOW STATUS LIKE 'handler_read__e%';
DROP TABLE t1,t2,t3;
+
+#
+# Bug#25602: queries with DISTINCT and SQL_BIG_RESULT hint
+# for which loose scan optimization is applied
+#
+
+CREATE TABLE t1 (a int, INDEX idx(a));
+INSERT INTO t1 VALUES
+ (4), (2), (1), (2), (4), (2), (1), (4),
+ (4), (2), (1), (2), (2), (4), (1), (4);
+
+EXPLAIN SELECT DISTINCT(a) FROM t1;
+SELECT DISTINCT(a) FROM t1;
+EXPLAIN SELECT SQL_BIG_RESULT DISTINCT(a) FROM t1;
+SELECT SQL_BIG_RESULT DISTINCT(a) FROM t1;
+
+DROP TABLE t1;
+
+
+
+
+
diff --git a/mysql-test/t/heap_hash.test b/mysql-test/t/heap_hash.test
index 28a75a5ee11..c0f37fe490e 100644
--- a/mysql-test/t/heap_hash.test
+++ b/mysql-test/t/heap_hash.test
@@ -260,4 +260,27 @@ select a from t1 where a in (1,3);
explain select a from t1 where a in (1,3);
drop table t1;
-# End of 4.1 tests
+--echo End of 4.1 tests
+
+#
+# Bug #27643: query failed : 1114 (The table '' is full)
+#
+# Check that HASH indexes disregard trailing spaces when comparing
+# strings with binary collations
+
+CREATE TABLE t1(col1 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ col2 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ UNIQUE KEY key1 USING HASH (col1, col2)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES('A', 'A');
+--error ER_DUP_ENTRY
+INSERT INTO t1 VALUES('A ', 'A ');
+DROP TABLE t1;
+CREATE TABLE t1(col1 VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ col2 VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+ UNIQUE KEY key1 USING HASH (col1, col2)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES('A', 'A');
+--error ER_DUP_ENTRY
+INSERT INTO t1 VALUES('A ', 'A ');
+DROP TABLE t1;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index f8922317eb3..1d368ac6075 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -1023,4 +1023,19 @@ where t.table_schema = 'information_schema' and
group by c2.column_type order by num limit 1)
group by t.table_name order by num1, t.table_name;
+#
+# Bug#28266 IS_UPDATABLE field on VIEWS table in I_S database is wrong
+#
+create table t1(f1 int);
+create view v1 as select f1+1 as a from t1;
+create table t2 (f1 int, f2 int);
+create view v2 as select f1+1 as a, f2 as b from t2;
+select table_name, is_updatable from information_schema.views;
+#
+# Note: we can perform 'delete' for non updatable view.
+#
+delete from v1;
+drop view v1,v2;
+drop table t1,t2;
+
# End of 5.0 tests.
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index f7fa7366101..a9679c01071 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -754,6 +754,45 @@ select * from t2;
drop table t1,t2;
#
+# Bug#27716 multi-update did partially and has not binlogged
+#
+
+CREATE TABLE `t1` (
+ `a` int(11) NOT NULL auto_increment,
+ `b` int(11) default NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
+
+CREATE TABLE `t2` (
+ `a` int(11) NOT NULL auto_increment,
+ `b` int(11) default NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=INNODB DEFAULT CHARSET=latin1 ;
+
+# A. testing multi_update::send_eof() execution branch
+insert into t1 values (1,1),(2,2);
+insert into t2 values (1,1),(4,4);
+reset master;
+--error ER_DUP_ENTRY
+UPDATE t2,t1 SET t2.a=t1.a+2;
+# check
+select * from t2 /* must be (3,1), (4,4) */;
+show master status /* there must no UPDATE in binlog */;
+
+# B. testing multi_update::send_error() execution branch
+delete from t1;
+delete from t2;
+insert into t1 values (1,2),(3,4),(4,4);
+insert into t2 values (1,2),(3,4),(4,4);
+reset master;
+--error ER_DUP_ENTRY
+UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
+show master status /* there must be no UPDATE query event */;
+
+# cleanup bug#27716
+drop table t1, t2;
+
+#
# Testing of IFNULL
#
create table t1 (a int, b int) engine=innodb;
@@ -1155,40 +1194,6 @@ drop table t2, t1;
#
-# Let us test binlog_cache_use and binlog_cache_disk_use status vars.
-# Actually this test has nothing to do with innodb per se, it just requires
-# transactional table.
-#
-show status like "binlog_cache_use";
-show status like "binlog_cache_disk_use";
-
-create table t1 (a int) engine=innodb;
-
-# Now we are going to create transaction which is long enough so its
-# transaction binlog will be flushed to disk...
-let $1=2000;
-disable_query_log;
-begin;
-while ($1)
-{
- eval insert into t1 values( $1 );
- dec $1;
-}
-commit;
-enable_query_log;
-show status like "binlog_cache_use";
-show status like "binlog_cache_disk_use";
-
-# Transaction which should not be flushed to disk and so should not
-# increase binlog_cache_disk_use.
-begin;
-delete from t1;
-commit;
-show status like "binlog_cache_use";
-show status like "binlog_cache_disk_use";
-drop table t1;
-
-#
# Bug #6126: Duplicate columns in keys gives misleading error message
#
--error 1060
diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test
index d9e50add8bf..25ba9a258ff 100644
--- a/mysql-test/t/innodb_mysql.test
+++ b/mysql-test/t/innodb_mysql.test
@@ -597,4 +597,78 @@ EXPLAIN SELECT COUNT(*) FROM t2 WHERE stat_id IN (1,3) AND acct_id=785;
DROP TABLE t1,t2;
+#
+# Bug #28652: assert when alter innodb table operation
+#
+create table t1(a int) engine=innodb;
+alter table t1 comment '123';
+show create table t1;
+drop table t1;
+
+#
+# Bug #25866: Getting "#HY000 Can't find record in..." on and INSERT
+#
+CREATE TABLE t1 (a CHAR(2), KEY (a)) ENGINE = InnoDB DEFAULT CHARSET=UTF8;
+INSERT INTO t1 VALUES ('uk'),('bg');
+SELECT * FROM t1 WHERE a = 'uk';
+DELETE FROM t1 WHERE a = 'uk';
+SELECT * FROM t1 WHERE a = 'uk';
+UPDATE t1 SET a = 'us' WHERE a = 'uk';
+SELECT * FROM t1 WHERE a = 'uk';
+
+CREATE TABLE t2 (a CHAR(2), KEY (a)) ENGINE = InnoDB;
+INSERT INTO t2 VALUES ('uk'),('bg');
+SELECT * FROM t2 WHERE a = 'uk';
+DELETE FROM t2 WHERE a = 'uk';
+SELECT * FROM t2 WHERE a = 'uk';
+INSERT INTO t2 VALUES ('uk');
+UPDATE t2 SET a = 'us' WHERE a = 'uk';
+SELECT * FROM t2 WHERE a = 'uk';
+
+CREATE TABLE t3 (a CHAR(2), KEY (a)) ENGINE = MyISAM;
+INSERT INTO t3 VALUES ('uk'),('bg');
+SELECT * FROM t3 WHERE a = 'uk';
+DELETE FROM t3 WHERE a = 'uk';
+SELECT * FROM t3 WHERE a = 'uk';
+INSERT INTO t3 VALUES ('uk');
+UPDATE t3 SET a = 'us' WHERE a = 'uk';
+SELECT * FROM t3 WHERE a = 'uk';
+
+DROP TABLE t1,t2,t3;
+
+
+#
+# Bug #29154: LOCK TABLES is not atomic when >1 InnoDB tables are locked
+#
+
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT) ENGINE=InnoDB;
+
+CONNECT (c1,localhost,root,,);
+CONNECT (c2,localhost,root,,);
+
+--echo switch to connection c1
+CONNECTION c1;
+SET AUTOCOMMIT=0;
+INSERT INTO t2 VALUES (1);
+
+--echo switch to connection c2
+CONNECTION c2;
+SET AUTOCOMMIT=0;
+--error ER_LOCK_WAIT_TIMEOUT
+LOCK TABLES t1 READ, t2 READ;
+
+--echo switch to connection c1
+CONNECTION c1;
+COMMIT;
+INSERT INTO t1 VALUES (1);
+
+--echo switch to connection default
+CONNECTION default;
+SET AUTOCOMMIT=default;
+DISCONNECT c1;
+DISCONNECT c2;
+DROP TABLE t1,t2;
+
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/insert_select-binlog.test b/mysql-test/t/insert_select-binlog.test
index d4041f86ab5..4bff09577a7 100644
--- a/mysql-test/t/insert_select-binlog.test
+++ b/mysql-test/t/insert_select-binlog.test
@@ -1,5 +1,6 @@
# Embedded server doesn't support binlog
-- source include/not_embedded.inc
+-- source include/have_log_bin.inc
# Check if a partly-completed INSERT SELECT in a MyISAM table goes into the
# binlog
diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test
index bbc51be6dc9..bf6dae96847 100644
--- a/mysql-test/t/insert_select.test
+++ b/mysql-test/t/insert_select.test
@@ -233,7 +233,9 @@ drop table t1,t2;
CREATE TABLE t1 (a int PRIMARY KEY);
INSERT INTO t1 values (1), (2);
+flush status;
INSERT INTO t1 SELECT a + 2 FROM t1 LIMIT 1;
+show status like 'Handler_read%';
DROP TABLE t1;
@@ -332,3 +334,26 @@ INSERT INTO t2 (d)
SELECT * FROM t2;
DROP TABLE t1,t2;
+
+#
+# Bug #29095: incorrect pushing of LIMIT into the temporary
+# table ignoring ORDER BY clause
+#
+
+CREATE TABLE t1 (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ prev_id INT,
+ join_id INT DEFAULT 0);
+
+INSERT INTO t1 (prev_id) VALUES (NULL), (1), (2);
+SELECT * FROM t1;
+
+CREATE TABLE t2 (join_id INT);
+INSERT INTO t2 (join_id) VALUES (0);
+
+INSERT INTO t1 (prev_id) SELECT id
+ FROM t2 LEFT JOIN t1 ON t1.join_id = t2.join_id
+ ORDER BY id DESC LIMIT 1;
+SELECT * FROM t1;
+
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/insert_update.test b/mysql-test/t/insert_update.test
index 725fbdb25d7..67108744ec6 100644
--- a/mysql-test/t/insert_update.test
+++ b/mysql-test/t/insert_update.test
@@ -290,3 +290,19 @@ INSERT IGNORE INTO t1 (id,c1) SELECT * FROM t2
SELECT * FROM t1;
DROP TABLE t1;
+
+#
+# Bug#28904: INSERT .. ON DUPLICATE was silently updating rows when it
+# shouldn't.
+#
+create table t1(f1 int primary key,
+ f2 timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP);
+insert into t1(f1) values(1);
+--replace_column 1 #
+select @stamp1:=f2 from t1;
+--sleep 2
+insert into t1(f1) values(1) on duplicate key update f1=1;
+--replace_column 1 #
+select @stamp2:=f2 from t1;
+select if( @stamp1 = @stamp2, "correct", "wrong");
+drop table t1;
diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test
index 68b97854c3b..5b599c3dad7 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -512,10 +512,12 @@ select * from v1a join (t3 natural join t4) on a = y;
#--------------------------------------------------------------------
# Negative tests (tests for errors)
#--------------------------------------------------------------------
+# works in Oracle - bug
-- error 1052
-select * from t1 natural join (t3 cross join t4); -- works in Oracle - bug
+select * from t1 natural join (t3 cross join t4);
+# works in Oracle - bug
-- error 1052
-select * from (t3 cross join t4) natural join t1; -- works in Oracle - bug
+select * from (t3 cross join t4) natural join t1;
-- error 1052
select * from t1 join (t2, t3) using (b);
-- error 1052
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index 51e79a20d65..1a59dbf8fc2 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -845,3 +845,19 @@ SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL;
show status like 'Handler_read%';
DROP TABLE t1,t2;
+
+#
+# Bug 28571: outer join with false on condition over constant tables
+#
+
+CREATE TABLE t1 (c int PRIMARY KEY, e int NOT NULL);
+INSERT INTO t1 VALUES (1,0), (2,1);
+CREATE TABLE t2 (d int PRIMARY KEY);
+INSERT INTO t2 VALUES (1), (2), (3);
+
+EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WHERE c=1 AND d IS NULL;
+SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WHERE c=1 AND d IS NULL;
+SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WHERE c=1 AND d<=>NULL;
+
+DROP TABLE t1,t2;
+
diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test
index e84b2071ab1..3d0e68dc0f3 100644
--- a/mysql-test/t/key.test
+++ b/mysql-test/t/key.test
@@ -432,3 +432,15 @@ ORDER BY c.b, c.d
;
DROP TABLE t1, t2;
+
+
+#
+# Bug #20604: Test for disabled keys with aggregate functions and FORCE INDEX.
+#
+CREATE TABLE t1( a TINYINT, KEY(a) ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES( 1 );
+ALTER TABLE t1 DISABLE KEYS;
+EXPLAIN SELECT MAX(a) FROM t1 FORCE INDEX(a);
+DROP TABLE t1;
+
+--echo End of 5.0 tests.
diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test
index 3044964ebc3..4c14dc96aaa 100644
--- a/mysql-test/t/key_cache.test
+++ b/mysql-test/t/key_cache.test
@@ -219,4 +219,31 @@ set global key_cache_block_size= @my_key_cache_block_size;
set @@global.key_buffer_size=0;
select @@global.key_buffer_size;
+#
+# Bug#28478 - Improper key_cache_block_size corrupts MyISAM tables
+#
+SET @bug28478_key_cache_block_size= @@global.key_cache_block_size;
+SET GLOBAL key_cache_block_size= 1536;
+CREATE TABLE t1 (
+ id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ c1 CHAR(150),
+ c2 CHAR(150),
+ c3 CHAR(150),
+ KEY(c1, c2, c3)
+ ) ENGINE= MyISAM;
+INSERT INTO t1 (c1, c2, c3) VALUES
+ ('a', 'b', 'c'), ('b', 'c', 'd'), ('c', 'd', 'e'), ('d', 'e', 'f'),
+ ('e', 'f', 'g'), ('f', 'g', 'h'), ('g', 'h', 'i'), ('h', 'i', 'j'),
+ ('i', 'j', 'k'), ('j', 'k', 'l'), ('k', 'l', 'm'), ('l', 'm', 'n'),
+ ('m', 'n', 'o'), ('n', 'o', 'p'), ('o', 'p', 'q'), ('p', 'q', 'r'),
+ ('q', 'r', 's'), ('r', 's', 't'), ('s', 't', 'u'), ('t', 'u', 'v'),
+ ('u', 'v', 'w'), ('v', 'w', 'x'), ('w', 'x', 'y'), ('x', 'y', 'z');
+INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1;
+INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1;
+INSERT INTO t1 (c1, c2, c3) SELECT c1, c2, c3 from t1;
+CHECK TABLE t1;
+SHOW VARIABLES LIKE 'key_cache_block_size';
+SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size;
+DROP TABLE t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test
index 1e99911a7e3..cedca9db3da 100644
--- a/mysql-test/t/kill.test
+++ b/mysql-test/t/kill.test
@@ -81,7 +81,9 @@ connection conn2;
connection conn1;
-- disable_result_log
-send select id from t1 where id in (select distinct id from t2);
+# This is a very long running query. If this test start failing, it may
+# be necessary to change to an even longer query.
+send select id from t1 where id in (select distinct a.id from t2 a, t2 b, t2 c, t2 d group by a.id, b.id, c.id, d.id having a.id between 10 and 20);
-- enable_result_log
connection conn2;
@@ -117,3 +119,188 @@ reap;
select 1;
connection con1;
select RELEASE_LOCK("a");
+
+#
+# Bug#27563: Stored functions and triggers wasn't throwing an error when killed.
+#
+create table t1(f1 int);
+delimiter |;
+create function bug27563() returns int(11)
+deterministic
+begin
+ declare continue handler for sqlstate '70100' set @a:= 'killed';
+ declare continue handler for sqlexception set @a:= 'exception';
+ set @a= get_lock("lock27563", 10);
+ return 1;
+end|
+delimiter ;|
+# Test stored functions
+# Test INSERT
+connection con1;
+select get_lock("lock27563",10);
+connection con2;
+let $ID= `select connection_id()`;
+send insert into t1 values (bug27563());
+real_sleep 2;
+connection con1;
+disable_query_log;
+eval kill query $ID;
+enable_query_log;
+connection con2;
+--error 1317
+reap;
+select @a;
+connection con1;
+select * from t1;
+
+# Test UPDATE
+insert into t1 values(0);
+connection con2;
+send update t1 set f1= bug27563();
+real_sleep 2;
+connection con1;
+disable_query_log;
+eval kill query $ID;
+enable_query_log;
+connection con2;
+--error 1317
+reap;
+select @a;
+connection con1;
+select * from t1;
+
+# Test DELETE
+insert into t1 values(1);
+connection con2;
+send delete from t1 where bug27563() is null;
+real_sleep 2;
+connection con1;
+disable_query_log;
+eval kill query $ID;
+enable_query_log;
+connection con2;
+--error 1317
+reap;
+select @a;
+connection con1;
+select * from t1;
+
+# Test SELECT
+connection con2;
+send select * from t1 where f1= bug27563();
+real_sleep 2;
+connection con1;
+disable_query_log;
+eval kill query $ID;
+enable_query_log;
+connection con2;
+--error 1317
+reap;
+select @a;
+
+# Test PROCEDURE
+connection con2;
+delimiter |;
+create procedure proc27563()
+begin
+ declare continue handler for sqlstate '70100' set @a:= 'killed';
+ declare continue handler for sqlexception set @a:= 'exception';
+ select get_lock("lock27563",10);
+ select "shouldn't be selected";
+end|
+delimiter ;|
+send call proc27563();
+real_sleep 2;
+connection con1;
+disable_query_log;
+eval kill query $ID;
+enable_query_log;
+connection con2;
+--error 1317
+reap;
+select @a;
+
+# Test TRIGGERS
+connection con2;
+create table t2 (f2 int);
+delimiter |;
+create trigger trg27563 before insert on t1 for each row
+begin
+ declare continue handler for sqlstate '70100' set @a:= 'killed';
+ declare continue handler for sqlexception set @a:= 'exception';
+ set @a:= get_lock("lock27563",10);
+ insert into t2 values(1);
+end|
+delimiter ;|
+send insert into t1 values(2),(3);
+real_sleep 2;
+connection con1;
+disable_query_log;
+eval kill query $ID;
+enable_query_log;
+connection con2;
+--error 1317
+reap;
+select @a;
+connection con1;
+select * from t1;
+select * from t2;
+
+# Cleanup
+select release_lock("lock27563");
+drop table t1, t2;
+drop function bug27563;
+drop procedure proc27563;
+
+#
+# Bug#28598: mysqld crash when killing a long-running explain query.
+#
+--disable_query_log
+connection con1;
+let $ID= `select connection_id()`;
+let $tab_count= 40;
+
+let $i= $tab_count;
+while ($i)
+{
+ eval CREATE TABLE t$i (a$i int, KEY(a$i));
+ eval INSERT INTO t$i VALUES (1),(2),(3),(4),(5),(6),(7);
+ dec $i ;
+}
+set session optimizer_search_depth=0;
+
+let $i=$tab_count;
+while ($i)
+{
+ let $a= a$i;
+ let $t= t$i;
+ dec $i;
+ if ($i)
+ {
+ let $comma=,;
+ let $from=$comma$t$from;
+ let $where=a$i=$a $and $where;
+ }
+ if (!$i)
+ {
+ let $from=FROM $t$from;
+ let $where=WHERE $where;
+ }
+ let $and=AND;
+}
+
+--enable_query_log
+eval PREPARE stmt FROM 'EXPLAIN SELECT * $from $where';
+send EXECUTE stmt;
+--disable_query_log
+
+connection con2;
+real_sleep 2;
+eval kill query $ID;
+let $i= $tab_count;
+while ($i)
+{
+ eval DROP TABLE t$i;
+ dec $i ;
+}
+--enable_query_log
diff --git a/mysql-test/t/limit.test b/mysql-test/t/limit.test
index bc599b20d36..286c04785ff 100644
--- a/mysql-test/t/limit.test
+++ b/mysql-test/t/limit.test
@@ -71,3 +71,20 @@ explain select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3;
select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3;
drop table t1;
# End of 4.1 tests
+
+#
+# Bug #28464: a string argument to 'limit ?' PS
+#
+
+prepare s from "select 1 limit ?";
+set @a='qwe';
+--error 1210
+execute s using @a;
+prepare s from "select 1 limit 1, ?";
+--error 1210
+execute s using @a;
+prepare s from "select 1 limit ?, ?";
+--error 1210
+execute s using @a, @a;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/long_tmpdir-master.opt b/mysql-test/t/long_tmpdir-master.opt
new file mode 100644
index 00000000000..398abfc4632
--- /dev/null
+++ b/mysql-test/t/long_tmpdir-master.opt
@@ -0,0 +1 @@
+--tmpdir=$MYSQLTEST_VARDIR/tmp/long_temporary_directory_path_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
diff --git a/mysql-test/t/long_tmpdir-master.sh b/mysql-test/t/long_tmpdir-master.sh
new file mode 100644
index 00000000000..318955fbcca
--- /dev/null
+++ b/mysql-test/t/long_tmpdir-master.sh
@@ -0,0 +1,3 @@
+d="$MYSQLTEST_VARDIR/tmp/long_temporary_directory_path_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789"
+test -d "$d" || mkdir "$d"
+rm -f "$d"/*
diff --git a/mysql-test/t/long_tmpdir.test b/mysql-test/t/long_tmpdir.test
new file mode 100644
index 00000000000..cf0bed29918
--- /dev/null
+++ b/mysql-test/t/long_tmpdir.test
@@ -0,0 +1,9 @@
+#
+# Bug #29015: Stack overflow in processing temporary table name when tmpdir path
+# is long
+#
+
+create view v1 as select table_name from information_schema.tables;
+drop view v1;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index b3944416adc..c3e5cef5e63 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -486,4 +486,25 @@ insert into t1 values (1);
drop table t2;
drop table t1;
+#
+# BUG#26976 - Missing table in merge not noted in related error msg + SHOW
+# CREATE TABLE fails
+#
+CREATE TABLE tm1(a INT) ENGINE=MERGE UNION=(t1, t2);
+--error 1168
+SELECT * FROM tm1;
+CHECK TABLE tm1;
+CREATE TABLE t1(a INT);
+--error 1168
+SELECT * FROM tm1;
+CHECK TABLE tm1;
+CREATE TABLE t2(a BLOB);
+--error 1168
+SELECT * FROM tm1;
+CHECK TABLE tm1;
+ALTER TABLE t2 MODIFY a INT;
+SELECT * FROM tm1;
+CHECK TABLE tm1;
+DROP TABLE tm1, t1, t2;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/metadata.test b/mysql-test/t/metadata.test
index a6ebfdc14c1..65c062399b7 100644
--- a/mysql-test/t/metadata.test
+++ b/mysql-test/t/metadata.test
@@ -81,3 +81,35 @@ drop view v1,v2,v3;
--disable_metadata
# End of 4.1 tests
+
+#
+# Bug #28492: subselect returns LONG in >5.0.24a and LONGLONG in <=5.0.24a
+#
+--enable_metadata
+select a.* from (select 2147483648 as v_large) a;
+select a.* from (select 214748364 as v_small) a;
+--disable_metadata
+
+#
+# Bug #28898: table alias and database name of VIEW columns is empty in the
+# metadata of # SELECT statement where join is executed via temporary table.
+#
+
+CREATE TABLE t1 (c1 CHAR(1));
+CREATE TABLE t2 (c2 CHAR(1));
+CREATE VIEW v1 AS SELECT t1.c1 FROM t1;
+CREATE VIEW v2 AS SELECT t2.c2 FROM t2;
+INSERT INTO t1 VALUES ('1'), ('2'), ('3');
+INSERT INTO t2 VALUES ('1'), ('2'), ('3'), ('2');
+
+--enable_metadata
+SELECT v1.c1 FROM v1 JOIN t2 ON c1=c2 ORDER BY 1;
+SELECT v1.c1, v2.c2 FROM v1 JOIN v2 ON c1=c2;
+SELECT v1.c1, v2.c2 FROM v1 JOIN v2 ON c1=c2 GROUP BY v1.c1;
+SELECT v1.c1, v2.c2 FROM v1 JOIN v2 ON c1=c2 GROUP BY v1.c1 ORDER BY v2.c2;
+--disable_metadata
+
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/mix_innodb_myisam_binlog.test b/mysql-test/t/mix_innodb_myisam_binlog.test
index 8bced9f069c..428aba92342 100644
--- a/mysql-test/t/mix_innodb_myisam_binlog.test
+++ b/mysql-test/t/mix_innodb_myisam_binlog.test
@@ -5,9 +5,7 @@
# did some tests manually on a slave; tables are replicated fine and
# Exec_Master_Log_Pos advances as expected.
-# Embedded server doesn't support binlogging
--- source include/not_embedded.inc
-
+-- source include/have_log_bin.inc
-- source include/have_innodb.inc
--disable_warnings
@@ -28,9 +26,7 @@ insert into t1 values(1);
insert into t2 select * from t1;
commit;
---replace_column 5 #
---replace_result "xid=14" "xid=8"
-show binlog events from 98;
+source include/show_binlog_events.inc;
delete from t1;
delete from t2;
@@ -42,8 +38,7 @@ insert into t2 select * from t1;
# should say some changes to non-transact1onal tables couldn't be rolled back
rollback;
---replace_column 5 #
-show binlog events from 98;
+source include/show_binlog_events.inc;
delete from t1;
delete from t2;
@@ -57,9 +52,7 @@ insert into t2 select * from t1;
rollback to savepoint my_savepoint;
commit;
---replace_column 5 #
---replace_result "xid=47" "xid=25"
-show binlog events from 98;
+source include/show_binlog_events.inc;
delete from t1;
delete from t2;
@@ -75,9 +68,7 @@ insert into t1 values(7);
commit;
select a from t1 order by a; # check that savepoints work :)
---replace_column 5 #
---replace_result "xid=69" "xid=37"
-show binlog events from 98;
+source include/show_binlog_events.inc;
# and when ROLLBACK is not explicit?
delete from t1;
@@ -97,8 +88,7 @@ connection con2;
# so SHOW BINLOG EVENTS may come before con1 does the loggin. To be sure that
# logging has been done, we use a user lock.
select get_lock("a",10);
---replace_column 5 #
-show binlog events from 98;
+source include/show_binlog_events.inc;
# and when not in a transact1on?
delete from t1;
@@ -108,9 +98,7 @@ reset master;
insert into t1 values(9);
insert into t2 select * from t1;
---replace_column 5 #
---replace_result "xid=117" "xid=60"
-show binlog events from 98;
+source include/show_binlog_events.inc;
# Check that when the query updat1ng the MyISAM table is the first in the
# transaction, we log it immediately.
@@ -121,16 +109,11 @@ reset master;
insert into t1 values(10); # first make t1 non-empty
begin;
insert into t2 select * from t1;
---replace_column 5 #
---replace_result "xid=131" "xid=66"
-show binlog events from 98;
+source include/show_binlog_events.inc;
insert into t1 values(11);
commit;
---replace_column 5 #
---replace_result "xid=131" "xid=66" "xid=134" "xid=68"
-show binlog events from 98;
-
+source include/show_binlog_events.inc;
# Check that things work like before this BEGIN/ROLLBACK code was added,
# when t2 is INNODB
@@ -146,9 +129,7 @@ insert into t1 values(12);
insert into t2 select * from t1;
commit;
---replace_column 5 #
---replace_result "xid=153" "xid=78"
-show binlog events from 98;
+source include/show_binlog_events.inc;
delete from t1;
delete from t2;
@@ -159,8 +140,7 @@ insert into t1 values(13);
insert into t2 select * from t1;
rollback;
---replace_column 5 #
-show binlog events from 98;
+source include/show_binlog_events.inc;
delete from t1;
delete from t2;
@@ -174,9 +154,7 @@ insert into t2 select * from t1;
rollback to savepoint my_savepoint;
commit;
---replace_column 5 #
---replace_result "xid=185" "xid=94"
-show binlog events from 98;
+source include/show_binlog_events.inc;
delete from t1;
delete from t2;
@@ -192,9 +170,7 @@ insert into t1 values(18);
commit;
select a from t1 order by a; # check that savepoints work :)
---replace_column 5 #
---replace_result "xid=206" "xid=105"
-show binlog events from 98;
+source include/show_binlog_events.inc;
# Test for BUG#5714, where a MyISAM update in the transaction used to
# release row-level locks in InnoDB
@@ -253,9 +229,7 @@ insert into t2 values (3);
disconnect con2;
connection con3;
select get_lock("lock1",60);
---replace_column 5 #
---replace_result "xid=206" "xid=105" "xid=224" "xid=114" "xid=227" "xid=115" "xid=231" "xid=117" "xid=258" "xid=132"
-show binlog events from 98;
+source include/show_binlog_events.inc;
do release_lock("lock1");
drop table t0,t2;
diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test
index da19a18c73a..84e6a444d47 100644
--- a/mysql-test/t/multi_update.test
+++ b/mysql-test/t/multi_update.test
@@ -534,3 +534,44 @@ select * from t1;
select * from t2;
drop view v1;
drop table t1, t2;
+
+#
+# Bug#27716 multi-update did partially and has not binlogged
+#
+
+CREATE TABLE `t1` (
+ `a` int(11) NOT NULL auto_increment,
+ `b` int(11) default NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
+
+CREATE TABLE `t2` (
+ `a` int(11) NOT NULL auto_increment,
+ `b` int(11) default NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
+
+# A. testing multi_update::send_eof() execution branch
+insert into t1 values (1,1),(2,2);
+insert into t2 values (1,1),(4,4);
+reset master;
+--error ER_DUP_ENTRY
+UPDATE t2,t1 SET t2.a=t1.a+2;
+# check
+select * from t2 /* must be (3,1), (4,4) */;
+show master status /* there must be the UPDATE query event */;
+
+# B. testing multi_update::send_error() execution branch
+delete from t1;
+delete from t2;
+insert into t1 values (1,2),(3,4),(4,4);
+insert into t2 values (1,2),(3,4),(4,4);
+reset master;
+--error ER_DUP_ENTRY
+UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
+show master status /* there must be the UPDATE query event */;
+
+# cleanup bug#27716
+drop table t1, t2;
+
+--echo end of tests
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index 82d10059c65..12b9423be21 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -1145,4 +1145,20 @@ create table t3 (c1 int) engine=myisam pack_keys=default;
create table t4 (c1 int) engine=myisam pack_keys=2;
drop table t1, t2, t3;
+#
+# Bug#28476: force index on a disabled myisam index gives error 124
+#
+CREATE TABLE t1(a INT, b INT, KEY inx (a), UNIQUE KEY uinx (b)) ENGINE=MyISAM;
+INSERT INTO t1(a,b) VALUES (1,1),(2,2),(3,3),(4,4),(5,5);
+SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
+ALTER TABLE t1 DISABLE KEYS;
+SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
+SELECT a FROM t1 USE INDEX (inx) WHERE a=1;
+SELECT b FROM t1 FORCE INDEX (uinx) WHERE b=1;
+SELECT b FROM t1 USE INDEX (uinx) WHERE b=1;
+SELECT a FROM t1 FORCE INDEX (inx,uinx) WHERE a=1;
+ALTER TABLE t1 ENABLE KEYS;
+SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
+DROP TABLE t1;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index 0732559e7e1..37bbca77d9f 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -262,7 +262,7 @@ EOF
--exec $MYSQL test -e "show status" 2>&1 > /dev/null
--exec $MYSQL --help 2>&1 > /dev/null
--exec $MYSQL --version 2>&1 > /dev/null
---enable_quary_log
+--enable_query_log
#
# bug #26851: Mysql Client --pager Buffer Overflow
diff --git a/mysql-test/t/mysql_upgrade.test b/mysql-test/t/mysql_upgrade.test
index 3f9626fcc42..233e8c7c256 100644
--- a/mysql-test/t/mysql_upgrade.test
+++ b/mysql-test/t/mysql_upgrade.test
@@ -55,3 +55,16 @@ DROP USER mysqltest1@'%';
--replace_regex /.*mysqlcheck.*: Got/mysqlcheck: Got/ /\([0-9]*\)/(errno)/
--error 1
--exec $MYSQL_UPGRADE --skip-verbose --force --host=not_existing_host 2>&1
+
+#
+# Bug #28401 mysql_upgrade Failed with STRICT_ALL_TABLES, ANSI_QUOTES and NO_ZERO_DATE
+#
+
+# The SQL commands used by mysql_upgrade are written to be run
+# with sql_mode set to '' - thus the scripts should change sql_mode
+# for the session to make sure the SQL is legal.
+
+# Test by setting sql_mode before running mysql_upgrade
+set GLOBAL sql_mode='STRICT_ALL_TABLES,ANSI_QUOTES,NO_ZERO_DATE';
+--exec $MYSQL_UPGRADE --skip-verbose --force 2>&1
+eval set GLOBAL sql_mode=default;
diff --git a/mysql-test/t/mysqlbinlog-cp932.test b/mysql-test/t/mysqlbinlog-cp932.test
index 1487606a6c2..1c9f91fd9a8 100644
--- a/mysql-test/t/mysqlbinlog-cp932.test
+++ b/mysql-test/t/mysqlbinlog-cp932.test
@@ -1,6 +1,7 @@
# disabled in embedded until tools running is fixed with embedded
---source include/not_embedded.inc
+-- source include/not_embedded.inc
-- source include/have_cp932.inc
+-- source include/have_log_bin.inc
# Bug#16217 (mysql client did not know how not switch its internal charset)
flush logs;
diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test
index a7b3f413f23..bd90dcfb930 100644
--- a/mysql-test/t/mysqlbinlog.test
+++ b/mysql-test/t/mysqlbinlog.test
@@ -1,7 +1,6 @@
# We are using .opt file since we need small binlog size
-# Embedded server doesn't support binlogging
--- source include/not_embedded.inc
+-- source include/have_log_bin.inc
# we need this for getting fixed timestamps inside of this test
set timestamp=1000000000;
@@ -204,4 +203,17 @@ flush logs;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000009
+#
+# Bug#28293 missed '#' sign in the hex dump when the dump length
+# is divisible by 16.
+#
+
+CREATE TABLE t1 (c1 CHAR(10));
+# we need this for getting fixed timestamps inside of this test
+flush logs;
+INSERT INTO t1 VALUES ('0123456789');
+flush logs;
+DROP TABLE t1;
+--exec $MYSQL_BINLOG --hexdump --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000011 | grep 'Query' | sed 's/[0-9]\{1,\}/REMOVED/g'
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/mysqlbinlog2.test b/mysql-test/t/mysqlbinlog2.test
index 14b213cd9cc..c6869d67da1 100644
--- a/mysql-test/t/mysqlbinlog2.test
+++ b/mysql-test/t/mysqlbinlog2.test
@@ -1,8 +1,7 @@
# Test for the new options --start-datetime, stop-datetime,
# and a few others.
-# Embedded server doesn't support binlogging
--- source include/not_embedded.inc
+-- source include/have_log_bin.inc
--disable_warnings
drop table if exists t1;
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 4c4690520c6..30c241d4096 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -1,5 +1,9 @@
# Embedded server doesn't support external clients
--source include/not_embedded.inc
+--source include/have_log_bin.inc
+
+# Binlog is required
+--source include/have_log_bin.inc
--disable_warnings
DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa, t3;
@@ -1528,7 +1532,14 @@ drop user user2;
drop database mysqldump_test_db;
+--echo #
+--echo # Bug #28522: buffer overrun by '\0' byte using --hex-blob.
+--echo #
+CREATE TABLE t1 (c1 INT, c2 LONGBLOB);
+INSERT INTO t1 SET c1=11, c2=REPEAT('q',509);
+--exec $MYSQL_DUMP --skip-create --compact --hex-blob test t1
+DROP TABLE t1;
--echo #
--echo # End of 5.0 tests
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index 328206626df..aa0e2f89382 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -1,3 +1,5 @@
+-- source include/have_log_bin.inc
+
# This test should work in embedded server after mysqltest is fixed
-- source include/not_embedded.inc
@@ -46,11 +48,6 @@ select otto from (select 1 as otto) as t1;
--error 0
select otto from (select 1 as otto) as t1;
-# expectation <> response
--- // --error 1054
--- // select otto from (select 1 as otto) as t1;
-
-
# ----------------------------------------------------------------------------
# Negative case(statement):
# The derived table t1 does not contain a column named 'friedrich' .
@@ -331,9 +328,9 @@ select 3 from t1 ;
# This is a comment
# This is a ; comment
# This is a -- comment
--- This is also a comment
--- # This is also a comment
--- This is also a ; comment
+# -- This is also a comment
+# -- # This is also a comment
+# -- This is also a ; comment
# ----------------------------------------------------------------------------
# Test comments with embedded command
@@ -840,6 +837,10 @@ while ($num)
}
--enable_abort_on_error
--enable_query_log
+
+# Test source $variable/<filename>
+--source $MYSQLTEST_VARDIR/tmp/sourced.inc
+
--remove_file $MYSQLTEST_VARDIR/tmp/sourced.inc
# ----------------------------------------------------------------------------
@@ -1227,11 +1228,9 @@ select "a" as col1, "c" as col2;
# Test sync_with_master
# ----------------------------------------------------------------------------
--error 1
---exec echo "save_master_pos; sync_with_master 10!;" | $MYSQL_TEST 2>&1
+--exec echo "sync_with_master 10!;" | $MYSQL_TEST 2>&1
--error 1
---exec echo "save_master_pos; sync_with_master 10 !;" | $MYSQL_TEST 2>&1
---error 1
---exec echo "save_master_pos; sync_with_master a;" | $MYSQL_TEST 2>&1
+--exec echo "sync_with_master a;" | $MYSQL_TEST 2>&1
# ----------------------------------------------------------------------------
# Test connect
@@ -1740,23 +1739,130 @@ EOF
--exec echo "echo Some output; exit; echo Not this;" | $MYSQL_TEST 2>&1
# ----------------------------------------------------------------------------
-# test for query_sorted
+# test for sorted_result
# ----------------------------------------------------------------------------
create table t1( a int, b char(255), c timestamp);
insert into t1 values(1, 'Line 1', '2007-04-05'), (2, "Part 2", '2007-04-05');
insert into t1 values(1, 'Line 1', '2007-04-05'), (2, "Part 3", '2007-04-05');
select * from t1;
-query_sorted select * from t1;
+--sorted_result
+select * from t1;
+# Should not be sorted
+select * from t1;
disable_result_log;
-query_sorted select * from t1;
+sorted_result;
+select * from t1;
enable_result_log;
-query_sorted select '';
-query_sorted select "h";
-query_sorted select "he";
-query_sorted select "hep";
-query_sorted select "hepp";
+--sorted_result
+select '';
+sorted_result;
+select "h";
+--sorted_result
+select "he";
+--sorted_result
+select "hep";
+--sorted_result
+select "hepp";
+drop table t1;
+
+# 1. Assignment of result set sorting
+sorted_result;
+ SELECT 2 as "my_col"
+UNION
+SELECT 1;
+#
+--sorted_result
+SELECT 2 as "my_col" UNION SELECT 1;
+--sorted_result
+SELECT 2 as "my_col"
+UNION
+SELECT 1;
+
+# 2. Ensure that the table header will be not sorted into the result
+--sorted_result
+SELECT '2' as "3"
+UNION
+SELECT '1';
+
+# 3. Ensure that an empty result set does not cause problems
+CREATE TABLE t1( a CHAR);
+--sorted_result
+SELECT * FROM t1;
+DROP TABLE t1;
+
+# 4. Ensure that NULL values within the result set do not cause problems
+SELECT NULL as "my_col1",2 AS "my_col2"
+UNION
+SELECT NULL,1;
+--sorted_result
+SELECT NULL as "my_col1",2 AS "my_col2"
+UNION
+SELECT NULL,1;
+#
+SELECT 2 as "my_col1",NULL AS "my_col2"
+UNION
+SELECT 1,NULL;
+--sorted_result
+SELECT 2 as "my_col1",NULL AS "my_col2"
+UNION
+SELECT 1,NULL;
+
+# 5. "sorted_result" changes nothing when applied to a non query statement.
+sorted_result;
+ SET @a = 17;
+#
+# 6. Show that "sorted_result;" before the "SET @a = 17;" above does not affect
+# the now following query.
+SELECT 2 as "my_col"
+UNION
+SELECT 1;
+
+# 7. Ensure that "sorted_result" in combination with $variables works
+let $my_stmt=SELECT 2 as "my_col"
+UNION
+SELECT 1;
+--sorted_result
+eval $my_stmt;
+
+# 8. Ensure that "sorted_result " does not change the semantics of
+# "--error ...." or the protocol output after such an expected failure
+--sorted_result
+--error 1146
+SELECT '2' as "my_col1",2 as "my_col2"
+UNION
+SELECT '1',1 from t2;
+
+# 9. Ensure that several result formatting options including "sorted_result"
+# - have all an effect
+# - "--sorted_result" does not need to be direct before the statement
+# - Row sorting is applied after modification of the column content
+--sorted_result
+--replace_column 1 #
+SELECT '1' as "my_col1",2 as "my_col2"
+UNION
+SELECT '2',1;
+
+# 10. Ensure that at least 1024 rows within a result set do not cause problems
+#
+CREATE TABLE t1 (f1 INT);
+INSERT INTO t1 SET f1 = 1024;
+INSERT INTO t1 SELECT f1 - 1 FROM t1;
+INSERT INTO t1 SELECT f1 - 2 FROM t1;
+INSERT INTO t1 SELECT f1 - 4 FROM t1;
+INSERT INTO t1 SELECT f1 - 8 FROM t1;
+INSERT INTO t1 SELECT f1 - 16 FROM t1;
+INSERT INTO t1 SELECT f1 - 32 FROM t1;
+INSERT INTO t1 SELECT f1 - 64 FROM t1;
+INSERT INTO t1 SELECT f1 - 128 FROM t1;
+INSERT INTO t1 SELECT f1 - 256 FROM t1;
+INSERT INTO t1 SELECT f1 - 512 FROM t1;
+--disable_result_log
+--sorted_result
+SELECT * FROM t1;
+--enable_result_log
+DROP TABLE t1;
# ----------------------------------------------------------------------------
# Some coverage tests
# ----------------------------------------------------------------------------
@@ -1764,10 +1870,132 @@ query_sorted select "hepp";
--disable_query_log
--exec $MYSQL_TEST --help 2>&1 > /dev/null
--exec $MYSQL_TEST --version 2>&1 > /dev/null
---enable_quary_log
+--enable_query_log
--disable_abort_on_error
--error 1
--exec $MYSQL_TEST a b c 2>&1 > /dev/null
--enable_abort_on_error
+--enable_query_log
+
+# ----------------------------------------------------------------------------
+# test for query_get_value
+# ----------------------------------------------------------------------------
+
+CREATE TABLE t1(
+ a int, b varchar(255), c datetime
+);
+SHOW COLUMNS FROM t1;
+
+#------------ Positive tests ------------
+# 1. constant parameters
+# value is simple string without spaces
+let $value= query_get_value(SHOW COLUMNS FROM t1, Type, 1);
+--echo statement=SHOW COLUMNS FROM t1 row_number=1, column_name="Type", Value=$value
+let $value= query_get_value("SHOW COLUMNS FROM t1", Type, 1);
+--echo statement="SHOW COLUMNS FROM t1" row_number=1, column_name="Type", Value=$value
+#
+# 2. $variables as parameters
+# value IS NULL
+let $my_show= SHOW COLUMNS FROM t1;
+let $column_name= Default;
+let $row_number= 1;
+let $value= query_get_value($my_show, $column_name, $row_number);
+--echo statement=$my_show row_number=$row_number, column_name=$column_name, Value=$value
+#
+# 3. result set of a SELECT (not recommended, because projection and
+# selection could be done much better by pure SELECT functionality)
+# value is string with space in the middle
+let $value= query_get_value(SELECT 'A B' AS "MyColumn", MyColumn, 1);
+--echo value= ->$value<-
+#
+# 4. column name with space
+let $value= query_get_value(SELECT 1 AS "My Column", My Column, 1);
+--echo value= $value
+#
+#------------ Negative tests ------------
+# 5. Incomplete statement including missing parameters
+# 5.1 incomplete statement
+--error 1
+--exec echo "let \$value= query_get_value(SHOW;" | $MYSQL_TEST 2>&1
+# 5.2 missing query
+--error 1
+--exec echo "let \$value= query_get_value;" | $MYSQL_TEST 2>&1
+# 5.3 missing column name
+--error 1
+--exec echo "let \$value= query_get_value(SHOW COLUMNS FROM t1);" | $MYSQL_TEST 2>&1
+# 5.4 missing row number
+--error 1
+--exec echo "let \$value= query_get_value(SHOW COLUMNS FROM t1, Field);" | $MYSQL_TEST 2>&1
+#
+# 6. Somehow "wrong" value of parameters
+# 6.1 row parameter
+# 6.1.1 non sense number 0
+let $value= initialized;
+let $value= query_get_value(SHOW COLUMNS FROM t1, Field, 0);
+--echo value= $value
+# 6.1.2 after the last row
+let $value= initialized;
+let $value= query_get_value(SHOW COLUMNS FROM t1, Field, 10);
+--echo value= $value
+# 6.1.3 invalid row number
+--error 1
+--exec echo "let \$value= query_get_value(SHOW COLUMNS FROM t1, Field, notnumber);" | $MYSQL_TEST 2>&1
+# 6.2 column name parameter, name of not existing column
+--error 1
+--exec echo "let \$value= query_get_value(SHOW COLUMNS FROM t1, column_not_exists, 1);" | $MYSQL_TEST 2>&1
+# 6.3. statement which never gives a result set
+--error 1
+--exec echo "let \$value= query_get_value(SET @A = 1, Field, 1);" | $MYSQL_TEST 2>&1
+# 6.4. statement contains a ","
+# Note: There is no need to improve this, because we need query_get_value
+# for SHOW commands only.
+--error 1
+--exec echo "let \$value= query_get_value(SELECT 1 AS "A", 1 AS "B", 1);" | $MYSQL_TEST 2>&1
+#
+# 7. empty result set
+let $value= initialized;
+let $value= query_get_value(SELECT a FROM t1, a, 1);
+--echo value= $value
+#
+# 9. failing statement
+--error 1
+--exec echo "let \$value= query_get_value(SHOW COLNS FROM t1, Field, 1);" | $MYSQL_TEST 2>&1
+#
+# 10. Artificial example how to process a complete SHOW result set:
+let $show_statement= SHOW COLUMNS FROM t1;
+let $rowno= 1;
+let $run=1;
+let $count= 0;
+--echo
+--echo Field Type Null Key Default Extra
+while ($run)
+{
+ let $Field= query_get_value($show_statement, Field, $rowno);
+ if (`SELECT '$Field' = 'No such row'`)
+ {
+ let $run= 0;
+ }
+ if (`SELECT '$Field' <> 'No such row'`)
+ {
+ let $Type= query_get_value($show_statement, Type, $rowno);
+ let $Null= query_get_value($show_statement, Null, $rowno);
+ if (`SELECT '$Null' = 'YES'`)
+ {
+ inc $count;
+ }
+ let $Key= query_get_value($show_statement, Key, $rowno);
+ let $Default= query_get_value($show_statement, Default, $rowno);
+ let $Extra= query_get_value($show_statement, Extra, $rowno);
+ --echo $Field $Type $Null ->$Key<- $Default $Extra
+ inc $rowno;
+ }
+}
+--echo
+--echo Number of columns with Default NULL: $count
+--echo
+eval $show_statement;
+
+drop table t1;
--echo End of tests
+
diff --git a/mysql-test/t/ndb_backup_print.test b/mysql-test/t/ndb_backup_print.test
new file mode 100644
index 00000000000..1e516f03ae6
--- /dev/null
+++ b/mysql-test/t/ndb_backup_print.test
@@ -0,0 +1,66 @@
+-- source include/have_ndb.inc
+-- source include/ndb_default_cluster.inc
+-- source include/not_embedded.inc
+
+--disable_warnings
+use test;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
+--enable_warnings
+
+#NO.1 test output of backup
+--exec $NDB_MGM --no-defaults -e "start backup" |sed -e 's/[0-9]//g' |sed -e 's/localhost//g' |sed -e 's/\.\.\.*//g'
+
+create table t1
+ (pk int key
+ ,a1 BIT(1), a2 BIT(5), a3 BIT(33), a4 BIT(63), a5 BIT(64)
+ ,b1 TINYINT, b2 TINYINT UNSIGNED
+ ,c1 SMALLINT, c2 SMALLINT UNSIGNED
+ ,d1 INT, d2 INT UNSIGNED
+ ,e1 BIGINT, e2 BIGINT UNSIGNED
+ ,f1 CHAR(1) BINARY, f2 CHAR(32) BINARY, f3 CHAR(255) BINARY
+ ,g1 VARCHAR(32) BINARY, g2 VARCHAR(255) BINARY, g3 VARCHAR(1000) BINARY
+ ,h1 BINARY(1), h2 BINARY(8), h3 BINARY(255)
+ ,i1 VARBINARY(32), i2 VARBINARY(255), i3 VARBINARY(1000)
+ ) engine ndb;
+
+insert into t1 values
+ (1
+ ,0x1, 0x17, 0x789a, 0x789abcde, 0xfedc0001
+ ,127, 255
+ ,32767, 65535
+ ,2147483647, 4294967295
+ ,9223372036854775807, 18446744073709551615
+ ,'1','12345678901234567890123456789012','123456789'
+ ,'1','12345678901234567890123456789012','123456789'
+ ,0x12,0x123456789abcdef0, 0x012345
+ ,0x12,0x123456789abcdef0, 0x00123450
+ );
+
+insert into t1 values
+ (2
+ ,0, 0, 0, 0, 0
+ ,-128, 0
+ ,-32768, 0
+ ,-2147483648, 0
+ ,-9223372036854775808, 0
+ ,'','',''
+ ,'','',''
+ ,0x0,0x0,0x0
+ ,0x0,0x0,0x0
+ );
+
+insert into t1 values
+ (3
+ ,NULL,NULL,NULL,NULL,NULL
+ ,NULL,NULL
+ ,NULL,NULL
+ ,NULL,NULL
+ ,NULL,NULL
+ ,NULL,NULL,NULL
+ ,NULL,NULL,NULL
+ ,NULL,NULL,NULL
+ ,NULL,NULL,NULL
+ );
+
+#NO.2 test output of backup after some simple SQL operations
+--exec $NDB_MGM --no-defaults -e "start backup" |sed -e 's/[0-9]//g' |sed -e 's/localhost//g' |sed -e 's/\.\.\.*//g'
diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test
index 70fbfbfe733..80c8942348c 100644
--- a/mysql-test/t/ndb_basic.test
+++ b/mysql-test/t/ndb_basic.test
@@ -740,6 +740,46 @@ INSERT INTO t1 VALUES
SELECT * FROM t1 ORDER BY a;
DROP TABLE t1;
+# delete
+create table t1 (a int not null primary key, b int not null) engine=ndb;
+create table t2 (a int not null primary key, b int not null) engine=ndb;
+insert into t1 values (1,10), (2,20), (3,30);
+insert into t2 values (1,10), (2,20), (3,30);
+select * from t1 order by a;
+delete from t1 where a > 0 order by a desc limit 1;
+select * from t1 order by a;
+delete from t1,t2 using t1,t2 where t1.a = t2.a;
+select * from t2 order by a;
+drop table t1,t2;
+
+# insert ignore
+create table t1 (a int not null primary key, b int not null) engine=ndb;
+insert into t1 values (1,10), (2,20), (3,30);
+--error ER_DUP_ENTRY
+insert into t1 set a=1, b=100;
+insert ignore into t1 set a=1, b=100;
+select * from t1 order by a;
+insert into t1 set a=1, b=1000 on duplicate key update b=b+1;
+select * from t1 order by a;
+drop table t1;
+
+# update
+create table t1 (a int not null primary key, b int not null) engine=ndb;
+create table t2 (c int not null primary key, d int not null) engine=ndb;
+insert into t1 values (1,10), (2,10), (3,30), (4, 30);
+insert into t2 values (1,10), (2,10), (3,30), (4, 30);
+--error ER_DUP_ENTRY
+update t1 set a = 1 where a = 3;
+select * from t1 order by a;
+update t1 set b = 1 where a > 1 order by a desc limit 1;
+select * from t1 order by a;
+--error ER_DUP_ENTRY
+update t1,t2 set a = 1, c = 1 where a = 3 and c = 3;
+select * from t1 order by a;
+update ignore t1,t2 set a = 1, c = 1 where a = 3 and c = 3;
+select * from t1 order by a;
+drop table t1,t2;
+
# End of 5.0 tests
--echo End of 5.0 tests
diff --git a/mysql-test/t/ndb_index_ordered.test b/mysql-test/t/ndb_index_ordered.test
index 19b024a043f..31385fd56b2 100644
--- a/mysql-test/t/ndb_index_ordered.test
+++ b/mysql-test/t/ndb_index_ordered.test
@@ -50,7 +50,7 @@ update t1 set c = 13 where b <= 3;
select * from t1 order by a;
update t1 set b = b + 1 where b > 4 and b < 7;
select * from t1 order by a;
--- Update primary key
+# Update primary key
update t1 set a = a + 10 where b > 1 and b < 7;
select * from t1 order by a;
diff --git a/mysql-test/t/ndb_insert.test b/mysql-test/t/ndb_insert.test
index f346b7dc4ab..b8f00d6f6aa 100644
--- a/mysql-test/t/ndb_insert.test
+++ b/mysql-test/t/ndb_insert.test
@@ -639,4 +639,141 @@ insert ignore into t1 values (1,0), (2,0), (2,null), (3,null);
select * from t1 order by a;
drop table t1;
+# Bug#26342 auto_increment_increment AND auto_increment_offset REALLY REALLY anger NDB cluster
+
+CREATE TABLE t1 (
+ pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ b INT NOT NULL,
+ c INT NOT NULL UNIQUE
+) ENGINE=NDBCLUSTER;
+
+CREATE TABLE t2 (
+ pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ b INT NOT NULL,
+ c INT NOT NULL UNIQUE
+) ENGINE=MYISAM;
+
+SET @@session.auto_increment_increment=10;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+SELECT * FROM t1 ORDER BY pk;
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+TRUNCATE t1;
+TRUNCATE t2;
+SET @@session.auto_increment_offset=5;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t1 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (pk,b,c) VALUES (27,4,3),(NULL,5,4),(99,6,5),(NULL,7,6);
+SELECT * FROM t1 ORDER BY pk;
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+TRUNCATE t1;
+TRUNCATE t2;
+SET @@session.auto_increment_increment=2;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+SELECT * FROM t1 ORDER BY pk;
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+DROP TABLE t1, t2;
+
+CREATE TABLE t1 (
+ pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ b INT NOT NULL,
+ c INT NOT NULL UNIQUE
+) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7;
+
+CREATE TABLE t2 (
+ pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ b INT NOT NULL,
+ c INT NOT NULL UNIQUE
+) ENGINE=MYISAM AUTO_INCREMENT = 7;
+
+SET @@session.auto_increment_offset=1;
+SET @@session.auto_increment_increment=1;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+SELECT * FROM t1 ORDER BY pk;
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+DROP TABLE t1, t2;
+
+CREATE TABLE t1 (
+ pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ b INT NOT NULL,
+ c INT NOT NULL UNIQUE
+) ENGINE=NDBCLUSTER AUTO_INCREMENT = 3;
+
+CREATE TABLE t2 (
+ pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ b INT NOT NULL,
+ c INT NOT NULL UNIQUE
+) ENGINE=MYISAM AUTO_INCREMENT = 3;
+
+SET @@session.auto_increment_offset=5;
+SET @@session.auto_increment_increment=10;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+SELECT * FROM t1 ORDER BY pk;
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+DROP TABLE t1, t2;
+
+CREATE TABLE t1 (
+ pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ b INT NOT NULL,
+ c INT NOT NULL UNIQUE
+) ENGINE=NDBCLUSTER AUTO_INCREMENT = 7;
+
+CREATE TABLE t2 (
+ pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ b INT NOT NULL,
+ c INT NOT NULL UNIQUE
+) ENGINE=MYISAM AUTO_INCREMENT = 7;
+
+SET @@session.auto_increment_offset=5;
+SET @@session.auto_increment_increment=10;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+SELECT * FROM t1 ORDER BY pk;
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+DROP TABLE t1, t2;
+
+CREATE TABLE t1 (
+ pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ b INT NOT NULL,
+ c INT NOT NULL UNIQUE
+) ENGINE=NDBCLUSTER AUTO_INCREMENT = 5;
+
+CREATE TABLE t2 (
+ pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ b INT NOT NULL,
+ c INT NOT NULL UNIQUE
+) ENGINE=MYISAM AUTO_INCREMENT = 5;
+
+SET @@session.auto_increment_offset=5;
+SET @@session.auto_increment_increment=10;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+SELECT * FROM t1 ORDER BY pk;
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+DROP TABLE t1, t2;
+
+CREATE TABLE t1 (
+ pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ b INT NOT NULL,
+ c INT NOT NULL UNIQUE
+) ENGINE=NDBCLUSTER AUTO_INCREMENT = 100;
+
+CREATE TABLE t2 (
+ pk INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ b INT NOT NULL,
+ c INT NOT NULL UNIQUE
+) ENGINE=MYISAM AUTO_INCREMENT = 100;
+
+SET @@session.auto_increment_offset=5;
+SET @@session.auto_increment_increment=10;
+INSERT INTO t1 (b,c) VALUES (1,0),(2,1),(3,2);
+INSERT INTO t2 (b,c) VALUES (1,0),(2,1),(3,2);
+SELECT * FROM t1 ORDER BY pk;
+SELECT COUNT(t1.pk) FROM t1, t2 WHERE t1.pk = t2.pk AND t1.b = t2.b AND t1.c = t1.c;
+DROP TABLE t1, t2;
+
# End of 4.1 tests
diff --git a/mysql-test/t/ndb_restore.test b/mysql-test/t/ndb_restore.test
index 5b839a0d3aa..266a0c7fbc1 100644
--- a/mysql-test/t/ndb_restore.test
+++ b/mysql-test/t/ndb_restore.test
@@ -165,10 +165,10 @@ create table t9 engine=myisam as select * from t9_c;
create table t10 engine=myisam as select * from t10_c;
---exec $NDB_MGM --no-defaults -e "start backup" >> $NDB_TOOLS_OUTPUT
+--source include/ndb_backup.inc
drop table t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c, t10_c;
---exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 1 -m -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-1 >> $NDB_TOOLS_OUTPUT
---exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 2 -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-1 >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id -n 1 -m -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id -n 2 -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
show tables;
@@ -251,6 +251,6 @@ drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c, t10_c;
# Test BUG#10287
#
---exec $NDB_TOOLS_DIR/ndb_select_all --no-defaults -d sys -D , SYSTAB_0 | grep 520093696
+--exec $NDB_TOOLS_DIR/ndb_select_all --no-defaults -d sys -D , SYSTAB_0 | grep 520093696, | sed "s/,$the_backup_id/,<the_backup_id>/"
# End of 5.0 tests (4.1 test intermixed to save test time)
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index 3e8fa07dfb7..29a290c7fbf 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -719,10 +719,10 @@ CREATE TABLE t1 (a INT UNSIGNED NOT NULL, b TIME);
INSERT INTO t1 (a) VALUES (100000), (0), (100), (1000000),(10000), (1000), (10);
UPDATE t1 SET b = SEC_TO_TIME(a);
--- Correct ORDER
+# Correct ORDER
SELECT a, b FROM t1 ORDER BY b DESC;
--- must be ordered as the above
+# must be ordered as the above
SELECT a, b FROM t1 ORDER BY SEC_TO_TIME(a) DESC;
DROP TABLE t1;
diff --git a/mysql-test/t/outfile.test b/mysql-test/t/outfile.test
index f285407efd4..2b80b0b9d93 100644
--- a/mysql-test/t/outfile.test
+++ b/mysql-test/t/outfile.test
@@ -41,9 +41,9 @@ eval select * into dumpfile "../tmp/outfile-test.2" from t1;
eval select * into dumpfile "../tmp/outfile-test.3" from t1;
enable_query_log;
select load_file(concat(@tmpdir,"/outfile-test.not-exist"));
---exec rm $MYSQLTEST_VARDIR/tmp/outfile-test.1
---exec rm $MYSQLTEST_VARDIR/tmp/outfile-test.2
---exec rm $MYSQLTEST_VARDIR/tmp/outfile-test.3
+--remove_file $MYSQLTEST_VARDIR/tmp/outfile-test.1
+--remove_file $MYSQLTEST_VARDIR/tmp/outfile-test.2
+--remove_file $MYSQLTEST_VARDIR/tmp/outfile-test.3
drop table t1;
# Bug#8191
@@ -51,7 +51,7 @@ disable_query_log;
eval select 1 into outfile "../tmp/outfile-test.4";
enable_query_log;
select load_file(concat(@tmpdir,"/outfile-test.4"));
---exec rm $MYSQLTEST_VARDIR/tmp/outfile-test.4
+--remove_file $MYSQLTEST_VARDIR/tmp/outfile-test.4
#
# Bug #5382: 'explain select into outfile' crashes the server
@@ -75,7 +75,7 @@ eval SELECT * INTO OUTFILE "../tmp/outfile-test.4"
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
FROM information_schema.schemata LIMIT 0, 5;
# enable_query_log;
---exec rm $MYSQLTEST_VARDIR/tmp/outfile-test.4
+--remove_file $MYSQLTEST_VARDIR/tmp/outfile-test.4
use information_schema;
# disable_query_log;
@@ -83,7 +83,7 @@ eval SELECT * INTO OUTFILE "../tmp/outfile-test.4"
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
FROM schemata LIMIT 0, 5;
enable_query_log;
---exec rm $MYSQLTEST_VARDIR/tmp/outfile-test.4
+--remove_file $MYSQLTEST_VARDIR/tmp/outfile-test.4
use test;
#
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 5b7adc40755..93a89c2b275 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -1791,5 +1791,13 @@ execute stmt;
deallocate prepare stmt;
drop tables t1;
+#
+# Bug #28509: strange behaviour: passing a decimal value to PS
+#
+prepare stmt from "create table t1 select ?";
+set @a=1.0;
+execute stmt using @a;
+show create table t1;
+drop table t1;
--echo End of 5.0 tests.
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index 1ef104f820b..965ebf5df62 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -89,7 +89,11 @@ show status like "Qcache_queries_in_cache";
select sql_cache * from t1 union select * from t1;
set query_cache_type=2;
select sql_cache * from t1 union select * from t1;
+
+# all sql_cache statements, except for the first select, are ignored.
select * from t1 union select sql_cache * from t1;
+select * from t1 where a IN (select sql_cache a from t1);
+select * from t1 where a IN (select a from t1 union select sql_cache a from t1);
show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
set query_cache_type=on;
@@ -102,6 +106,15 @@ show status like "Qcache_queries_in_cache";
# SELECT SQL_NO_CACHE
#
select sql_no_cache * from t1;
+# sql_no_cache can occur in any nested select to turn on cacheing for the whole
+# expression and it will always override a sql_cache statement.
+select * from t1 union select sql_no_cache * from t1;
+select * from t1 where a IN (select sql_no_cache a from t1);
+select * from t1 where a IN (select a from t1 union select sql_no_cache a from t1);
+select sql_cache sql_no_cache * from t1;
+select sql_cache * from t1 union select sql_no_cache * from t1;
+select sql_cache * from t1 where a IN (select sql_no_cache a from t1);
+select sql_cache * from t1 where a IN (select a from t1 union select sql_no_cache a from t1);
show status like "Qcache_queries_in_cache";
drop table t1;
#
@@ -965,9 +978,54 @@ delimiter ;|
select *, change_global() from t1;
drop function change_global;
+drop table t1;
+
set GLOBAL query_cache_type=default;
set GLOBAL query_cache_limit=default;
set GLOBAL query_cache_min_res_unit=default;
set GLOBAL query_cache_size= default;
+
+#
+# Bug #28897 UUID() returns non-unique values when query cache is enabled
+#
+
+set GLOBAL query_cache_size=1000000;
+
+create table t1 (a char);
+insert into t1 values ('c');
+
+let $q1= `select UUID(), a from t1`;
+let $q2= `select UUID(), a from t1`;
+
+# disabling the logging of the query because the UUIDs are different each run.
+--disable_query_log
+eval select a from t1 where "$q1" = "$q2";
+--enable_query_log
+
+drop table t1;
+
+set GLOBAL query_cache_size= default;
+
+#
+# Bug #29053 SQL_CACHE in UNION causes non-deterministic functions to be cached
+#
+
+set GLOBAL query_cache_size=1000000;
+
+create table t1 (a char);
+insert into t1 values ('c');
+
+let $q1= `select RAND() from t1 union select sql_cache 1 from t1;`;
+let $q2= `select RAND() from t1 union select sql_cache 1 from t1;`;
+
+# disabling the logging of the query because the times are different each run.
+--disable_query_log
+eval select a from t1 where "$q1" = "$q2";
+--enable_query_log
+
+drop table t1;
+
+set GLOBAL query_cache_size= default;
+
# End of 5.0 tests
diff --git a/mysql-test/t/row.test b/mysql-test/t/row.test
index d2750fecbac..20d044306a6 100644
--- a/mysql-test/t/row.test
+++ b/mysql-test/t/row.test
@@ -7,10 +7,8 @@ select (1,2,3) IN ((3,2,3), (1,2,3), (1,3,3));
select row(10,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3));
select row(1,2,3) IN (row(3,NULL,3), row(1,2,3), row(1,3,3));
select row(10,2,3) IN (row(3,NULL,3), row(1,2,3), row(1,3,3));
---disable_ps_warnings
select row('a',1.5,3) IN (row(1,2,3), row('a',1.5,3), row('a','a','a'));
select row('a',0,3) IN (row(3,2,3), row('a','a','3'), row(1,3,3));
---enable_ps_warnings
select row('a',0,3) IN (row(3,2,3), row('a','0','3'), row(1,3,3));
select row('a',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3));
select row('b',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3));
diff --git a/mysql-test/t/rpl000015.test b/mysql-test/t/rpl000015.test
index d05e4df66b1..e103d40943f 100644
--- a/mysql-test/t/rpl000015.test
+++ b/mysql-test/t/rpl000015.test
@@ -1,3 +1,5 @@
+-- source include/have_log_bin.inc
+
connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
connect (slave,localhost,root,,test,$SLAVE_MYPORT,$SLAVE_MYSOCK);
connection master;
diff --git a/mysql-test/t/rpl000017.test b/mysql-test/t/rpl000017.test
index c1d36d53501..4488cbad230 100644
--- a/mysql-test/t/rpl000017.test
+++ b/mysql-test/t/rpl000017.test
@@ -1,3 +1,5 @@
+-- source include/have_log_bin.inc
+
connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
connect (slave,localhost,root,,test,$SLAVE_MYPORT,$SLAVE_MYSOCK);
connection master;
diff --git a/mysql-test/t/rpl_change_master.test b/mysql-test/t/rpl_change_master.test
index 6c055a81ceb..9dd1505af90 100644
--- a/mysql-test/t/rpl_change_master.test
+++ b/mysql-test/t/rpl_change_master.test
@@ -20,11 +20,11 @@ connection slave;
stop slave;
--replace_result $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 8 # 9 # 23 # 33 #
-show slave status;
+query_vertical show slave status;
change master to master_user='root';
--replace_result $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 8 # 9 # 23 # 33 #
-show slave status;
+query_vertical show slave status;
start slave;
sync_with_master;
select * from t1;
diff --git a/mysql-test/t/rpl_grant.test b/mysql-test/t/rpl_grant.test
new file mode 100644
index 00000000000..71e36342584
--- /dev/null
+++ b/mysql-test/t/rpl_grant.test
@@ -0,0 +1,42 @@
+# Tests of grants and users
+
+source include/master-slave.inc;
+source include/not_embedded.inc;
+
+--echo **** On Master ****
+connection master;
+
+CREATE USER dummy@localhost;
+CREATE USER dummy1@localhost, dummy2@localhost;
+
+SELECT user, host FROM mysql.user WHERE user != 'root'; # root host non-determ
+SELECT COUNT(*) FROM mysql.user;
+sync_slave_with_master;
+--echo **** On Slave ****
+SELECT user,host FROM mysql.user WHERE user != 'root'; # root host non-determ
+SELECT COUNT(*) FROM mysql.user;
+
+--echo **** On Master ****
+connection master;
+
+# No user exists
+error ER_CANNOT_USER;
+DROP USER nonexisting@localhost;
+
+# At least one user exists, but not all
+error ER_CANNOT_USER;
+DROP USER nonexisting@localhost, dummy@localhost;
+
+# All users exist
+DROP USER dummy1@localhost, dummy2@localhost;
+
+SELECT user, host FROM mysql.user WHERE user != 'root'; # root host non-determ
+SELECT COUNT(*) FROM mysql.user;
+sync_slave_with_master;
+--echo **** On Slave ****
+SELECT user,host FROM mysql.user WHERE user != 'root'; # root host non-determ
+SELECT COUNT(*) FROM mysql.user;
+
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 1 # 8 # 9 # 23 # 33 #
+query_vertical SHOW SLAVE STATUS;
diff --git a/mysql-test/t/rpl_loaddata.test b/mysql-test/t/rpl_loaddata.test
index 5ebdec6f761..a4781ed4faa 100644
--- a/mysql-test/t/rpl_loaddata.test
+++ b/mysql-test/t/rpl_loaddata.test
@@ -12,6 +12,7 @@
# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986)
source include/master-slave.inc;
+source include/have_innodb.inc;
connection slave;
reset master;
@@ -150,5 +151,14 @@ drop table t2;
connection master;
drop table t2;
drop table t1;
+
+# BUG#17233 LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed
+CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB;
+
+--error 1062
+LOAD DATA INFILE "../std_data_ln/words.dat" INTO TABLE t1;
+
+DROP TABLE t1;
+
sync_with_master;
# End of 4.1 tests
diff --git a/mysql-test/t/rpl_log_pos.test b/mysql-test/t/rpl_log_pos.test
index 979b146bb22..ee8da494f86 100644
--- a/mysql-test/t/rpl_log_pos.test
+++ b/mysql-test/t/rpl_log_pos.test
@@ -4,31 +4,29 @@
source include/master-slave.inc;
show master status;
sync_slave_with_master;
---replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
-show slave status;
-stop slave;
-change master to master_log_pos=73;
-start slave;
-sleep 5;
+
stop slave;
+--source include/wait_for_slave_to_stop.inc
change master to master_log_pos=73;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 8 # 9 # 23 # 33 #
-show slave status;
+query_vertical show slave status;
+
start slave;
-sleep 5;
---replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
-show slave status;
+let $slave_param= Slave_SQL_Running;
+let $slave_param_value= Yes;
+--source include/wait_for_slave_param.inc
+let $slave_param= Slave_IO_Running;
+let $slave_param_value= No;
+--source include/wait_for_slave_param.inc
stop slave;
-change master to master_log_pos=173;
-start slave;
-sleep 2;
+--source include/wait_for_slave_to_stop.inc
+
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 8 # 9 # 23 # 33 #
-show slave status;
+query_vertical show slave status;
+
connection master;
show master status;
create table if not exists t1 (n int);
@@ -37,7 +35,6 @@ create table t1 (n int);
insert into t1 values (1),(2),(3);
save_master_pos;
connection slave;
-stop slave;
change master to master_log_pos=98;
start slave;
sync_with_master;
@@ -46,4 +43,4 @@ connection master;
drop table t1;
sync_slave_with_master;
-# End of 4.1 tests
+--echo End of 5.0 tests
diff --git a/mysql-test/t/rpl_packet.test b/mysql-test/t/rpl_packet.test
index db6f475dc94..f410b561663 100644
--- a/mysql-test/t/rpl_packet.test
+++ b/mysql-test/t/rpl_packet.test
@@ -56,7 +56,7 @@ START SLAVE;
# Reconnect to master for new setting to take effect
disconnect master;
-connect (master, localhost, root)
+connect (master, localhost, root);
connection master;
CREATE TABLe `t1` (`f1` LONGTEXT) ENGINE=MyISAM;
diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test
index 5d9f1c29fe2..69614b45693 100644
--- a/mysql-test/t/rpl_rotate_logs.test
+++ b/mysql-test/t/rpl_rotate_logs.test
@@ -1,6 +1,8 @@
# This test uses chmod, can't be run with root permissions
-- source include/not_as_root.inc
+-- source include/have_log_bin.inc
+
#
# Test is run with max_binlog_size=2048 to force automatic rotation of the
# binary log
@@ -107,9 +109,18 @@ show master logs;
# we just tests if synonyms are accepted
purge binary logs to 'master-bin.000002';
show binary logs;
-# sleeping 10 seconds or more would make the slave believe connection is down
---real_sleep 1
-purge master logs before now();
+
+# Calculate time to use in "purge master logs before" by taking
+# last modification time of t2 and adding 1 second
+# This is donw in order to handle the case where file system
+# time differs from mysqld's time
+--disable_result_log
+select @time_for_purge:=DATE_ADD(UPDATE_TIME, INTERVAL 1 SECOND)
+ from information_schema.tables
+ where TABLE_SCHEMA="test" and TABLE_NAME="t2";
+--enable_result_log
+
+purge master logs before (@time_for_purge);
show binary logs;
insert into t2 values (65);
sync_slave_with_master;
diff --git a/mysql-test/t/rpl_skip_error.test b/mysql-test/t/rpl_skip_error.test
index f6fc73f58f2..baa7a88b8bb 100644
--- a/mysql-test/t/rpl_skip_error.test
+++ b/mysql-test/t/rpl_skip_error.test
@@ -17,3 +17,24 @@ connection master;
drop table t1;
sync_with_master;
# End of 4.1 tests
+
+#
+# #28839 Errors in strict mode silently stop SQL thread if --slave-skip-errors exists
+#
+create table t1(a int primary key);
+insert into t1 values (1),(2);
+delete from t1 where @@server_id=1;
+set sql_mode=strict_trans_tables;
+select @@server_id;
+insert into t1 values (1),(2),(3);
+sync_slave_with_master;
+connection slave;
+select @@server_id;
+select * from t1;
+--replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_result $MASTER_MYPORT MASTER_PORT
+show slave status;
+connection master;
+drop table t1;
+sync_with_master;
+# End of 5.0 tests
diff --git a/mysql-test/t/rpl_ssl.test b/mysql-test/t/rpl_ssl.test
index f83f8b983b2..d08004cb00b 100644
--- a/mysql-test/t/rpl_ssl.test
+++ b/mysql-test/t/rpl_ssl.test
@@ -56,6 +56,9 @@ enable_query_log;
connection master;
insert into t1 values (NULL);
sync_slave_with_master;
+--source include/wait_for_slave_to_start.inc
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 #
query_vertical show slave status;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/rpl_user_variables.test b/mysql-test/t/rpl_user_variables.test
index b2f4bfbb29d..8f8f0accbd1 100644
--- a/mysql-test/t/rpl_user_variables.test
+++ b/mysql-test/t/rpl_user_variables.test
@@ -296,13 +296,48 @@ SELECT * from t1;
SELECT * from t2;
connection master;
+drop table t1, t2;
---echo End of 5.0 tests.
+#
+# Bug #26842: master binary log contains invalid queries - replication fails
+#
+save_master_pos;
+connection slave;
+sync_with_master;
+reset master;
-# Cleanup
+connection master;
+create table t1 (a int);
+prepare s from "insert into t1 values (@a),(?)";
+set @a=98; execute s using @a;
+prepare s from "insert into t1 values (?)";
+set @a=99; execute s using @a;
+prepare s from "insert into t1 select 100 limit ?";
+set @a=100; execute s using @a;
-DROP TABLE t1;
-DROP TABLE t2;
+save_master_pos;
+connection slave;
+sync_with_master;
+show binlog events from 98;
+select * from t1;
+connection master;
+drop table t1;
+
+#
+# Bug #12826: Possible to get inconsistent slave using SQL syntax Prepared Statements
+#
+connection master;
+create table t1(a int, b int);
+prepare s1 from 'insert into t1 values (@x:=@x+1, ?)';
+set @x=1; execute s1 using @x;
+select * from t1;
+sync_slave_with_master;
+connection slave;
+select * from t1;
+connection master;
+drop table t1;
+
+--echo End of 5.0 tests.
# This test uses a stored function that uses user-defined variables to return data
# The test ensures the value of the user-defined variable is replicated correctly
@@ -310,7 +345,6 @@ DROP TABLE t2;
# This test was constructed for BUG#20141
--disable_warnings
-DROP TABLE IF EXISTS t1;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
--enable_warnings
@@ -358,4 +392,3 @@ DROP TABLE t1;
sync_slave_with_master;
stop slave;
-
diff --git a/mysql-test/t/rpl_view.test b/mysql-test/t/rpl_view.test
index 812e5d44d58..21748586130 100644
--- a/mysql-test/t/rpl_view.test
+++ b/mysql-test/t/rpl_view.test
@@ -149,4 +149,16 @@ drop view v1;
sync_slave_with_master;
+#
+# BUG#28244 CREATE VIEW breaks replication when view exists
+#
+connection master;
+CREATE TABLE t1(a INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+--error ER_TABLE_EXISTS_ERROR
+CREATE VIEW v1 AS SELECT * FROM t1;
+DROP VIEW v1;
+DROP TABLE t1;
+sync_slave_with_master;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/sp-code.test b/mysql-test/t/sp-code.test
index 0f249c95172..10755f2bf8a 100644
--- a/mysql-test/t/sp-code.test
+++ b/mysql-test/t/sp-code.test
@@ -2,7 +2,7 @@
# Test the debugging feature "show procedure/function code <name>"
#
--- source include/is_debug_build.inc
+-- source include/have_debug.inc
--disable_warnings
drop procedure if exists empty;
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index 9e5c795d586..ec91be13ba0 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -1454,7 +1454,7 @@ select bug12329();
# Until we implement proper mechanism for invalidation of PS/SP when table
# or SP's are changed the following statement will fail with 'Table ... was
# not locked' error (this mechanism should be based on the new TDC).
---error 1100
+--error ER_NO_SUCH_TABLE
execute stmt1;
deallocate prepare stmt1;
drop function bug12329;
@@ -1639,13 +1639,13 @@ create trigger t1_ai after insert on t1 for each row insert into t2 values (new.
create view v1 as select * from t1;
drop table t2;
# Limitation, the desired error is ER_VIEW_INVALID
---error ER_TABLE_NOT_LOCKED
+--error ER_NO_SUCH_TABLE
insert into v1 values (1);
drop trigger t1_ai;
create function bug11555_1() returns int return (select max(i) from t2);
create trigger t1_ai after insert on t1 for each row set @a:=bug11555_1();
# Limitation, the desired error is ER_VIEW_INVALID
---error ER_TABLE_NOT_LOCKED
+--error ER_NO_SUCH_TABLE
insert into v1 values (2);
drop function bug11555_1;
drop table t1;
diff --git a/mysql-test/t/sp-prelocking.test b/mysql-test/t/sp-prelocking.test
index cc3e3b93e06..ec5b7fbad7c 100644
--- a/mysql-test/t/sp-prelocking.test
+++ b/mysql-test/t/sp-prelocking.test
@@ -301,5 +301,36 @@ deallocate prepare stmt;
drop function bug19634;
drop table t1, t2, t3;
+#
+# Bug #27907 Misleading error message when opening/locking tables
+#
+
+--disable_warnings
+drop table if exists bug_27907_logs;
+drop table if exists bug_27907_t1;
+--enable_warnings
+
+create table bug_27907_logs (a int);
+create table bug_27907_t1 (a int);
+
+delimiter |;
+
+create trigger bug_27907_t1_ai after insert on bug_27907_t1
+for each row
+begin
+ insert into bug_27907_logs (a) values (1);
+end|
+
+delimiter ;|
+
+drop table bug_27907_logs;
+
+#
+# was failing before with error ER_NOT_LOCKED
+#
+--error ER_NO_SUCH_TABLE
+insert into bug_27907_t1(a) values (1);
+
+drop table bug_27907_t1;
--echo End of 5.0 tests
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index ff203a85ef7..0de416cdffa 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -6975,7 +6975,7 @@ use test|
--disable_warnings
drop function if exists bug20777|
drop table if exists examplebug20777|
---enabled_warnings
+--enable_warnings
create function bug20777(f1 bigint unsigned) returns bigint unsigned
begin
set f1 = (f1 - 10); set f1 = (f1 + 10);
@@ -7112,3 +7112,23 @@ select count(*) from t1 /* must be 3 */;
drop table t1,t2;
drop function bug27354;
+
+#
+# Bug #28605: SHOW CREATE VIEW with views using stored_procedures no longer
+# showing SP names.
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE FUNCTION metered(a INT) RETURNS INT RETURN 12;
+
+CREATE VIEW v1 AS SELECT test.metered(a) as metered FROM t1;
+
+SHOW CREATE VIEW v1;
+
+DROP VIEW v1;
+DROP FUNCTION metered;
+DROP TABLE t1;
+
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/sp_trans.test b/mysql-test/t/sp_trans.test
index 8eccaafcf0e..60f7e3326b4 100644
--- a/mysql-test/t/sp_trans.test
+++ b/mysql-test/t/sp_trans.test
@@ -2,6 +2,7 @@
# tests that require InnoDB...
#
+-- source include/have_log_bin.inc
-- source include/have_innodb.inc
--disable_warnings
@@ -554,34 +555,6 @@ set @@session.max_heap_table_size=default|
#
-# Bug #13270 INSERT,UPDATE,etc that calls func with side-effect does not binlog
-# Bug #23333 stored function + non-transac table + transac table =
-# breaks stmt-based binlog
-# Bug #27395 OPTION_STATUS_NO_TRANS_UPDATE is not preserved at the end of SF()
-#
-CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM|
-CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB|
-
-insert into t2 values (1,1)|
-
-create function bug23333()
-RETURNS int(11)
-DETERMINISTIC
-begin
- insert into t1 values (null);
- select count(*) from t1 into @a;
- return @a;
-end|
-
-reset master|
---error ER_DUP_ENTRY
-insert into t2 values (bug23333(),1)|
---replace_column 2 # 5 # 6 #
-show binlog events from 98 /* with fixes for #23333 will show there is the query */|
-select count(*),@a from t1 /* must be 1,1 */|
-drop table t1, t2|
-
-#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
diff --git a/mysql-test/t/sp_trans_log.test b/mysql-test/t/sp_trans_log.test
new file mode 100644
index 00000000000..3e440b3ccc1
--- /dev/null
+++ b/mysql-test/t/sp_trans_log.test
@@ -0,0 +1,33 @@
+-- source include/have_innodb.inc
+-- source include/have_log_bin.inc
+
+delimiter |;
+
+#
+# Bug #13270 INSERT,UPDATE,etc that calls func with side-effect does not binlog
+# Bug #23333 stored function + non-transac table + transac table =
+# breaks stmt-based binlog
+# Bug #27395 OPTION_STATUS_NO_TRANS_UPDATE is not preserved at the end of SF()
+#
+CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM|
+CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB|
+
+insert into t2 values (1,1)|
+
+create function bug23333()
+RETURNS int(11)
+DETERMINISTIC
+begin
+ insert into t1 values (null);
+ select count(*) from t1 into @a;
+ return @a;
+end|
+
+reset master|
+--error ER_DUP_ENTRY
+insert into t2 values (bug23333(),1)|
+--replace_column 2 # 5 # 6 #
+show binlog events from 98 /* with fixes for #23333 will show there is the query */|
+select count(*),@a from t1 /* must be 1,1 */|
+drop table t1, t2|
+
diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test
index fc663853174..2b71bf1093c 100644
--- a/mysql-test/t/strict.test
+++ b/mysql-test/t/strict.test
@@ -890,11 +890,11 @@ INSERT INTO t1 (col1,col2,col3) VALUES (NULL, '', '2004-01-01');
INSERT INTO t1 (col1,col2,col3) VALUES (102, NULL, '2004-01-01');
--error 1048
INSERT INTO t1 VALUES (103,'',NULL);
---error 1263
+--error 1048
UPDATE t1 SET col1=NULL WHERE col1 =100;
---error 1263
+--error 1048
UPDATE t1 SET col2 =NULL WHERE col2 ='hello';
---error 1263
+--error 1048
UPDATE t1 SET col2 =NULL where col3 IS NOT NULL;
INSERT IGNORE INTO t1 values (NULL,NULL,NULL);
SELECT * FROM t1;
@@ -914,7 +914,7 @@ INSERT INTO t1 (col1) VALUES (2);
INSERT INTO t1 VALUES(default(col1),default(col2));
--error 1364
INSERT INTO t1 (col1) SELECT 1;
---error 1263
+--error 1048
INSERT INTO t1 SELECT 1,NULL;
INSERT IGNORE INTO t1 values (NULL,NULL);
INSERT IGNORE INTO t1 (col1) values (3);
@@ -975,9 +975,7 @@ select * from t1;
# Check that select don't abort even in strict mode (for now)
set sql_mode='traditional';
---disable_ps_warnings
select count(*) from t1 where STR_TO_DATE('2004.12.12 10:22:61','%Y.%m.%d %T') IS NULL;
---enable_ps_warnings
drop table t1;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 5840e434b64..12688fa4cf4 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -1822,13 +1822,6 @@ SELECT * FROM t1
DROP TABLE t1,t2,t3;
#
-# BUG #10308: purge log with subselect
-#
-
-purge master logs before (select adddate(current_timestamp(), interval -4 day));
-
-
-#
# Bug#18503: Queries with a quantified subquery returning empty set may
# return a wrong result.
#
@@ -2906,4 +2899,50 @@ SELECT id, st FROM t1
DROP TABLE t1,t2;
+#
+# Bug #28728: crash with EXPLAIN EXTENDED for a query with a derived table
+# over a grouping subselect
+#
+
+CREATE TABLE t1 (a int);
+
+INSERT INTO t1 VALUES (1), (2);
+
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT count(*) FROM t1 GROUP BY a) as res;
+
+DROP TABLE t1;
+
+#
+# Bug #28811: crash for query containing subquery with ORDER BY and LIMIT 1
+#
+
+CREATE TABLE t1 (
+ a varchar(255) default NULL,
+ b timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ INDEX idx(a,b)
+);
+CREATE TABLE t2 (
+ a varchar(255) default NULL
+);
+
+INSERT INTO t1 VALUES ('abcdefghijk','2007-05-07 06:00:24');
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26');
+INSERT INTO `t2` VALUES ('abcdefghijk');
+INSERT INTO `t2` VALUES ('asdf');
+
+SET session sort_buffer_size=8192;
+
+SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2;
+
+DROP TABLE t1,t2;
+
--echo End of 5.0 tests.
diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test
index 0302e2cede6..2f844c9cc21 100644
--- a/mysql-test/t/subselect3.test
+++ b/mysql-test/t/subselect3.test
@@ -260,11 +260,11 @@ insert into t2 values
('dd', 1, NULL);
alter table t1 add index idx(ie1,ie2);
---cc 3 NULL NULL
+# cc 3 NULL NULL
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=3 and b is null ;
insert into t2 values ('new1', 10,10);
insert into t1 values ('new1', 1234, 10, NULL);
--- new1, 10, 10, NULL,
+# new1, 10, 10, NULL,
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=10 and b=10;
explain extended
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=10 and b=10;
diff --git a/mysql-test/t/subselect_notembedded.test b/mysql-test/t/subselect_notembedded.test
index c5b23f6dac8..c112272e8ad 100644
--- a/mysql-test/t/subselect_notembedded.test
+++ b/mysql-test/t/subselect_notembedded.test
@@ -1,8 +1,9 @@
-- source include/not_embedded.inc
#
-# BUG #10308: purge log with subselect
+# BUG#10308: purge log with subselect
+# Bug#28553: mysqld crash in "purge master log before(select time from information_schema)"
#
-
+--error 1064
purge master logs before (select adddate(current_timestamp(), interval -4 day));
-
+purge master logs before adddate(current_timestamp(), interval -4 day);
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index 82de4dac111..7158d02956e 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -1000,9 +1000,9 @@ create trigger t1_bi after insert on t1 for each row insert into t3 values (new.
# Until we implement proper mechanism for invalidation of PS/SP when table
# or SP's are changed these two statements will fail with 'Table ... was
# not locked' error (this mechanism should be based on the new TDC).
---error 1100 #ER_TABLE_NOT_LOCKED
+--error ER_NO_SUCH_TABLE
execute stmt1;
---error 1100 #ER_TABLE_NOT_LOCKED
+--error ER_NO_SUCH_TABLE
call p1();
deallocate prepare stmt1;
drop procedure p1;
@@ -1763,4 +1763,70 @@ select * from t1;
select * from t3;
drop table t1, t2, t3;
+disconnect addconroot1;
+disconnect addconroot2;
+disconnect addconwithoutdb;
+#
+# Bug #26162: Trigger DML ignores low_priority_updates setting
+#
+CREATE TABLE t1 (id INTEGER);
+CREATE TABLE t2 (id INTEGER);
+
+INSERT INTO t2 VALUES (1),(2);
+
+# trigger that produces the high priority insert, but should be low, adding
+# LOW_PRIORITY fixes this
+CREATE TRIGGER t1_test AFTER INSERT ON t1 FOR EACH ROW
+ INSERT INTO t2 VALUES (new.id);
+
+CONNECT (rl_holder, localhost, root,,);
+CONNECT (rl_acquirer, localhost, root,,);
+CONNECT (wl_acquirer, localhost, root,,);
+CONNECT (rl_contender, localhost, root,,);
+
+CONNECTION rl_holder;
+SELECT GET_LOCK('B26162',120);
+
+CONNECTION rl_acquirer;
+--send
+SELECT 'rl_acquirer', GET_LOCK('B26162',120), id FROM t2 WHERE id = 1;
+
+CONNECTION wl_acquirer;
+SET SESSION LOW_PRIORITY_UPDATES=1;
+SET GLOBAL LOW_PRIORITY_UPDATES=1;
+#need to wait for rl_acquirer to lock on the B26162 lock
+sleep 2;
+--send
+INSERT INTO t1 VALUES (5);
+
+CONNECTION rl_contender;
+# must not "see" the row inserted by the INSERT (as it must run before the
+# INSERT)
+--send
+SELECT 'rl_contender', id FROM t2 WHERE id > 1;
+
+CONNECTION rl_holder;
+#need to wait for wl_acquirer and rl_contender to lock on t2
+sleep 2;
+SELECT RELEASE_LOCK('B26162');
+
+CONNECTION rl_acquirer;
+--reap
+SELECT RELEASE_LOCK('B26162');
+CONNECTION wl_acquirer;
+--reap
+CONNECTION rl_contender;
+--reap
+
+CONNECTION default;
+DISCONNECT rl_acquirer;
+DISCONNECT wl_acquirer;
+DISCONNECT rl_contender;
+DISCONNECT rl_holder;
+
+DROP TRIGGER t1_test;
+DROP TABLE t1,t2;
+SET SESSION LOW_PRIORITY_UPDATES=DEFAULT;
+SET GLOBAL LOW_PRIORITY_UPDATES=DEFAULT;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test
index c6050753943..02cd07e3c16 100644
--- a/mysql-test/t/type_date.test
+++ b/mysql-test/t/type_date.test
@@ -123,3 +123,16 @@ insert into t1 values ('2000-01-01','2000-01-02');
select 1 from t1 where cast('2000-01-01 12:01:01' as datetime) between start_date and end_date;
drop table t1;
# End of 4.1 tests
+
+#
+# Bug #23093: Implicit conversion of 9912101 to date does not match
+# cast(9912101 as date)
+#
+select @d:=1111, year(@d), month(@d), day(@d), cast(@d as date);
+select @d:=011111, year(@d), month(@d), day(@d), cast(@d as date);
+select @d:=1311, year(@d), month(@d), day(@d), cast(@d as date);
+create table t1 (d date , dt datetime , ts timestamp);
+insert into t1 values (9912101,9912101,9912101);
+insert into t1 values (11111,11111,11111);
+select * from t1;
+drop table t1;
diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test
index cf512aa3649..ffda593f320 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -141,6 +141,31 @@ SELECT CAST(CAST('2006-08-10 10:11:12' AS DATETIME) AS DECIMAL(20,6));
SELECT CAST(CAST('2006-08-10 10:11:12' AS DATETIME) + INTERVAL 14 MICROSECOND AS DECIMAL(20,6));
SELECT CAST(CAST('10:11:12.098700' AS TIME) AS DECIMAL(20,6));
+
+#
+# Test of storing datetime into date fields
+#
+
+set @org_mode=@@sql_mode;
+create table t1 (da date default '1962-03-03 23:33:34', dt datetime default '1962-03-03');
+show create table t1;
+insert into t1 values ();
+insert into t1 values ('2007-03-23 13:49:38','2007-03-23 13:49:38');
+set @@sql_mode='ansi,traditional';
+insert into t1 values ('2007-03-23 13:49:38','2007-03-23 13:49:38');
+insert into t1 set dt='2007-03-23 13:49:38',da=dt;
+# Test error handling
+--error 1292
+insert into t1 values ('2007-03-32','2007-03-23 13:49:38');
+select * from t1;
+drop table t1;
+--error 1067
+create table t1 (da date default '1962-03-32 23:33:34', dt datetime default '1962-03-03');
+--error 1067
+create table t1 (t time default '916:00:00 a');
+set @@sql_mode= @org_mode;
+
+
#
# Bug#27590: Wrong DATE/DATETIME comparison.
#
@@ -246,3 +271,14 @@ select if(@bug28261 = f1, '', @bug28261:= f1) from t1;
select if(@bug28261 = f1, '', @bug28261:= f1) from t1;
select if(@bug28261 = f1, '', @bug28261:= f1) from t1;
drop table t1;
+
+#
+# Bug#28778: Wrong result of BETWEEN when comparing a DATETIME field with an
+# integer constants.
+#
+create table t1(f1 datetime);
+insert into t1 values('2001-01-01'),('2002-02-02');
+select * from t1 where f1 between 20020101 and 20070101000000;
+select * from t1 where f1 between 2002010 and 20070101000000;
+select * from t1 where f1 between 20020101 and 2007010100000;
+drop table t1;
diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test
index 4fdb0c8458f..5538f19f5f9 100644
--- a/mysql-test/t/type_decimal.test
+++ b/mysql-test/t/type_decimal.test
@@ -394,3 +394,17 @@ create table t1 as
from (select 1 as s,'t' as t union select null, null ) as sub1;
select group_concat(t) from t1 group by week(date)/10;
drop table t1;
+
+#
+# Bug#28980: ROUND(<dec expr>, <int col>) returned double values
+#
+
+CREATE TABLE t1 (
+ qty decimal(16,6) default NULL,
+ dps tinyint(3) unsigned default NULL
+);
+INSERT INTO t1 VALUES (1.1325,3);
+
+SELECT ROUND(qty,3), dps, ROUND(qty,dps) FROM t1;
+
+DROP TABLE t1;
diff --git a/mysql-test/t/type_enum.test b/mysql-test/t/type_enum.test
index 4b3429d9ea0..45da469cf2d 100644
--- a/mysql-test/t/type_enum.test
+++ b/mysql-test/t/type_enum.test
@@ -157,3 +157,11 @@ create table t1(exhausting_charset enum('ABCDEFGHIJKLMNOPQRSTUVWXYZ','
 !"','#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~','xx\','yy\€','zz‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'));
--echo End of 4.1 tests
+
+#
+# Bug#28729: Field_enum wrongly reported an error while storing an empty string.
+#
+create table t1(f1 set('a','b'), index(f1));
+insert into t1 values(''),(''),('a'),('b');
+select * from t1 where f1='';
+drop table t1;
diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test
index f790bcf6daa..a55200c8853 100644
--- a/mysql-test/t/type_float.test
+++ b/mysql-test/t/type_float.test
@@ -222,3 +222,23 @@ drop table t1;
create table t1 (s1 float(0,2));
--error 1427
create table t1 (s1 float(1,2));
+
+#
+# Bug #28121 "INSERT or UPDATE into DOUBLE(200,0) field being truncated to 31 digits"
+#
+
+create table t1 (f1 double(200, 0));
+insert into t1 values (1e199), (-1e199);
+insert into t1 values (1e200), (-1e200);
+insert into t1 values (2e200), (-2e200);
+select f1 + 0e0 from t1;
+drop table t1;
+
+create table t1 (f1 float(30, 0));
+insert into t1 values (1e29), (-1e29);
+insert into t1 values (1e30), (-1e30);
+insert into t1 values (2e30), (-2e30);
+select f1 + 0e0 from t1;
+drop table t1;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test
index 0b582dc61b6..75af1f4be4b 100644
--- a/mysql-test/t/udf.test
+++ b/mysql-test/t/udf.test
@@ -288,4 +288,28 @@ drop function metaphon;
drop function myfunc_double;
drop function myfunc_int;
+#
+# Bug #28921: Queries containing UDF functions are cached
+#
+
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
+eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
+create table t1 (a char);
+
+set GLOBAL query_cache_size=1355776;
+reset query cache;
+
+select metaphon('MySQL') from t1;
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+
+select metaphon('MySQL') from t1;
+show status like "Qcache_hits";
+show status like "Qcache_queries_in_cache";
+
+drop table t1;
+drop function metaphon;
+set GLOBAL query_cache_size=default;
+
+
--echo End of 5.0 tests.
diff --git a/mysql-test/t/user_var-binlog.test b/mysql-test/t/user_var-binlog.test
index 12a5e616fa2..57bf9df2fb0 100644
--- a/mysql-test/t/user_var-binlog.test
+++ b/mysql-test/t/user_var-binlog.test
@@ -1,5 +1,4 @@
-# Embedded server does not support binlogging
---source include/not_embedded.inc
+-- source include/have_log_bin.inc
# Check that user variables are binlogged correctly (BUG#3875)
create table t1 (a varchar(50));
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index 70f57fdf283..3a3e8f88f83 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -222,3 +222,18 @@ drop table t1,t2;
insert into city 'blah';
SHOW COUNT(*) WARNINGS;
SHOW COUNT(*) ERRORS;
+
+#
+# Bug#28494: Grouping by Item_func_set_user_var produces incorrect result.
+#
+create table t1(f1 int, f2 varchar(2), f3 float, f4 decimal(2,1));
+insert into t1 values
+ (1, "a", 1.5, 1.6), (1, "a", 1.5, 1.6), (2, "b", 2.5, 2.6),
+ (3, "c", 3.5, 3.6), (4, "d", 4.5, 4.6), (1, "a", 1.5, 1.6),
+ (3, "c", 3.5, 3.6), (1, "a", 1.5, 1.6);
+select @a:=f1, count(f1) from t1 group by 1 desc;
+select @a:=f1, count(f1) from t1 group by 1 asc;
+select @a:=f2, count(f2) from t1 group by 1 desc;
+select @a:=f3, count(f3) from t1 group by 1 desc;
+select @a:=f4, count(f4) from t1 group by 1 desc;
+drop table t1;
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 3275ba0a687..f670ac8a49d 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -32,6 +32,7 @@ create view v1 (c,d) as select a,b from t1
# simple view
create view v1 (c) as select b+1 from t1;
select c from v1;
+select is_updatable from information_schema.views where table_name='v1';
# temporary table should not hide table of view
create temporary table t1 (a int, b int);
@@ -228,6 +229,8 @@ create table t1 (a int, b int, primary key(a));
insert into t1 values (10,2), (20,3), (30,4), (40,5), (50,10);
create view v1 (a,c) as select a, b+1 from t1;
create algorithm=temptable view v2 (a,c) as select a, b+1 from t1;
+select is_updatable from information_schema.views where table_name='v2';
+select is_updatable from information_schema.views where table_name='v1';
# try to update expression
-- error 1348
update v1 set c=a+c;
@@ -497,6 +500,7 @@ insert into t1 values(5,'Hello, world of views');
create view v1 as select * from t1;
create view v2 as select * from v1;
update v2 set col2='Hello, view world';
+select is_updatable from information_schema.views;
select * from t1;
drop view v2, v1;
drop table t1;
@@ -3233,4 +3237,115 @@ CREATE VIEW v1 AS SELECT CAST(1.23456789 AS DECIMAL(8,0)) AS col;
SHOW CREATE VIEW v1;
DROP VIEW v1;
+#
+# Bug #28716: CHECK OPTION expression is evaluated over expired record buffers
+# when VIEW is updated via temporary tables
+#
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b INT, c INT DEFAULT 0);
+INSERT INTO t1 (a) VALUES (1), (2);
+INSERT INTO t2 (b) VALUES (1), (2);
+CREATE VIEW v1 AS SELECT t2.b,t2.c FROM t1, t2
+ WHERE t1.a=t2.b AND t2.b < 3 WITH CHECK OPTION;
+SELECT * FROM v1;
+UPDATE v1 SET c=1 WHERE b=1;
+SELECT * FROM v1;
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+#
+# Bug #28561: update on multi-table view with CHECK OPTION and
+# a subquery in WHERE condition
+#
+
+CREATE TABLE t1 (id int);
+CREATE TABLE t2 (id int, c int DEFAULT 0);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+
+CREATE VIEW v1 AS
+ SELECT t2.c FROM t1, t2
+ WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+
+UPDATE v1 SET c=1;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+#
+# Bug #27827: CHECK OPTION ignores ON conditions when updating
+# a multi-table view with CHECK OPTION.
+#
+
+CREATE TABLE t1 (a1 INT, c INT DEFAULT 0);
+CREATE TABLE t2 (a2 INT);
+CREATE TABLE t3 (a3 INT);
+CREATE TABLE t4 (a4 INT);
+INSERT INTO t1 (a1) VALUES (1),(2);
+INSERT INTO t2 (a2) VALUES (1),(2);
+INSERT INTO t3 (a3) VALUES (1),(2);
+INSERT INTO t4 (a4) VALUES (1),(2);
+
+CREATE VIEW v1 AS
+ SELECT t1.a1, t1.c FROM t1 JOIN t2 ON t1.a1=t2.a2 AND t1.c < 3
+ WITH CHECK OPTION;
+SELECT * FROM v1;
+--error 1369
+UPDATE v1 SET c=3;
+PREPARE t FROM 'UPDATE v1 SET c=3';
+--error 1369
+EXECUTE t;
+--error 1369
+EXECUTE t;
+--error 1369
+INSERT INTO v1(a1, c) VALUES (3, 3);
+UPDATE v1 SET c=1 WHERE a1=1;
+SELECT * FROM v1;
+SELECT * FROM t1;
+
+CREATE VIEW v2 AS SELECT t1.a1, t1.c
+ FROM (t1 JOIN t2 ON t1.a1=t2.a2 AND t1.c < 3)
+ JOIN (t3 JOIN t4 ON t3.a3=t4.a4)
+ ON t2.a2=t3.a3 WITH CHECK OPTION;
+SELECT * FROM v2;
+--error 1369
+UPDATE v2 SET c=3;
+PREPARE t FROM 'UPDATE v2 SET c=3';
+--error 1369
+EXECUTE t;
+--error 1369
+EXECUTE t;
+--error 1369
+INSERT INTO v2(a1, c) VALUES (3, 3);
+UPDATE v2 SET c=2 WHERE a1=1;
+SELECT * FROM v2;
+SELECT * FROM t1;
+
+DROP VIEW v1,v2;
+DROP TABLE t1,t2,t3,t4;
+
+#
+# Bug #29104: assertion abort for a query with a view column reference
+# in the GROUP BY list and a condition requiring the value
+# of another view column to be equal to a constant
+#
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (1,2), (2,2), (1,3), (1,2);
+
+CREATE VIEW v1 AS SELECT a, b+1 as b FROM t1;
+
+
+SELECT b, SUM(a) FROM v1 WHERE b=3 GROUP BY b;
+EXPLAIN SELECT b, SUM(a) FROM v1 WHERE b=3 GROUP BY b;
+
+SELECT a, SUM(b) FROM v1 WHERE b=3 GROUP BY a;
+EXPLAIN SELECT a, SUM(b) FROM v1 WHERE b=3 GROUP BY a;
+
+SELECT a, SUM(b) FROM v1 WHERE a=1 GROUP BY a;
+EXPLAIN SELECT a, SUM(b) FROM v1 WHERE a=1 GROUP BY a;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
--echo End of 5.0 tests.
diff --git a/mysys/charset-def.c b/mysys/charset-def.c
index 394fe6de1f3..36ff4139d9c 100644
--- a/mysys/charset-def.c
+++ b/mysys/charset-def.c
@@ -24,7 +24,6 @@
#ifdef HAVE_UCA_COLLATIONS
#ifdef HAVE_CHARSET_ucs2
-extern CHARSET_INFO my_charset_ucs2_general_uca;
extern CHARSET_INFO my_charset_ucs2_icelandic_uca_ci;
extern CHARSET_INFO my_charset_ucs2_latvian_uca_ci;
extern CHARSET_INFO my_charset_ucs2_romanian_uca_ci;
@@ -46,7 +45,6 @@ extern CHARSET_INFO my_charset_ucs2_hungarian_uca_ci;
#endif
#ifdef HAVE_CHARSET_utf8
-extern CHARSET_INFO my_charset_utf8_general_uca_ci;
extern CHARSET_INFO my_charset_utf8_icelandic_uca_ci;
extern CHARSET_INFO my_charset_utf8_latvian_uca_ci;
extern CHARSET_INFO my_charset_utf8_romanian_uca_ci;
@@ -134,7 +132,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused)))
add_compiled_collation(&my_charset_ucs2_general_ci);
add_compiled_collation(&my_charset_ucs2_bin);
#ifdef HAVE_UCA_COLLATIONS
- add_compiled_collation(&my_charset_ucs2_general_uca);
+ add_compiled_collation(&my_charset_ucs2_unicode_ci);
add_compiled_collation(&my_charset_ucs2_icelandic_uca_ci);
add_compiled_collation(&my_charset_ucs2_latvian_uca_ci);
add_compiled_collation(&my_charset_ucs2_romanian_uca_ci);
@@ -168,7 +166,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused)))
add_compiled_collation(&my_charset_utf8_general_cs);
#endif
#ifdef HAVE_UCA_COLLATIONS
- add_compiled_collation(&my_charset_utf8_general_uca_ci);
+ add_compiled_collation(&my_charset_utf8_unicode_ci);
add_compiled_collation(&my_charset_utf8_icelandic_uca_ci);
add_compiled_collation(&my_charset_utf8_latvian_uca_ci);
add_compiled_collation(&my_charset_utf8_romanian_uca_ci);
diff --git a/mysys/charset.c b/mysys/charset.c
index cce97677b14..9ea17c6515c 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -202,6 +202,19 @@ static my_bool simple_cs_is_full(CHARSET_INFO *cs)
}
+static void
+copy_uca_collation(CHARSET_INFO *to, CHARSET_INFO *from)
+{
+ to->cset= from->cset;
+ to->coll= from->coll;
+ to->strxfrm_multiply= from->strxfrm_multiply;
+ to->min_sort_char= from->min_sort_char;
+ to->max_sort_char= from->max_sort_char;
+ to->mbminlen= from->mbminlen;
+ to->mbmaxlen= from->mbmaxlen;
+}
+
+
static int add_collation(CHARSET_INFO *cs)
{
if (cs->name && (cs->number ||
@@ -225,29 +238,30 @@ static int add_collation(CHARSET_INFO *cs)
if (!(all_charsets[cs->number]->state & MY_CS_COMPILED))
{
- CHARSET_INFO *new= all_charsets[cs->number];
+ CHARSET_INFO *newcs= all_charsets[cs->number];
if (cs_copy_data(all_charsets[cs->number],cs))
return MY_XML_ERROR;
if (!strcmp(cs->csname,"ucs2") )
{
#if defined(HAVE_CHARSET_ucs2) && defined(HAVE_UCA_COLLATIONS)
- new->cset= my_charset_ucs2_general_uca.cset;
- new->coll= my_charset_ucs2_general_uca.coll;
- new->strxfrm_multiply= my_charset_ucs2_general_uca.strxfrm_multiply;
- new->min_sort_char= my_charset_ucs2_general_uca.min_sort_char;
- new->max_sort_char= my_charset_ucs2_general_uca.max_sort_char;
- new->mbminlen= 2;
- new->mbmaxlen= 2;
- new->state |= MY_CS_AVAILABLE | MY_CS_LOADED;
+ copy_uca_collation(newcs, &my_charset_ucs2_unicode_ci);
+ newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED;
#endif
}
+ else if (!strcmp(cs->csname, "utf8"))
+ {
+#if defined (HAVE_CHARSET_utf8) && defined(HAVE_UCA_COLLATIONS)
+ copy_uca_collation(newcs, &my_charset_utf8_unicode_ci);
+ newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED;
+#endif
+ }
else
{
uchar *sort_order= all_charsets[cs->number]->sort_order;
simple_cs_init_functions(all_charsets[cs->number]);
- new->mbminlen= 1;
- new->mbmaxlen= 1;
+ newcs->mbminlen= 1;
+ newcs->mbmaxlen= 1;
if (simple_cs_is_full(all_charsets[cs->number]))
{
all_charsets[cs->number]->state |= MY_CS_LOADED;
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index 87f136dbf81..af910678a1f 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -173,7 +173,7 @@ static void test_key_cache(KEY_CACHE *keycache,
#endif
#define KEYCACHE_HASH(f, pos) \
-(((ulong) ((pos) >> keycache->key_cache_shift)+ \
+(((ulong) ((pos) / keycache->key_cache_block_size) + \
(ulong) (f)) & (keycache->hash_entries-1))
#define FILE_HASH(f) ((uint) (f) & (CHANGED_BLOCKS_HASH-1))
@@ -329,7 +329,6 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
keycache->key_cache_mem_size= use_mem;
keycache->key_cache_block_size= key_cache_block_size;
- keycache->key_cache_shift= my_bit_log2(key_cache_block_size);
DBUG_PRINT("info", ("key_cache_block_size: %u",
key_cache_block_size));
@@ -352,7 +351,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
ALIGN_SIZE(hash_links * sizeof(HASH_LINK)) +
ALIGN_SIZE(sizeof(HASH_LINK*) *
keycache->hash_entries))) +
- ((ulong) blocks << keycache->key_cache_shift) > use_mem)
+ ((ulong) blocks * keycache->key_cache_block_size) > use_mem)
blocks--;
/* Allocate memory for cache page buffers */
if ((keycache->block_mem=
@@ -1807,7 +1806,7 @@ byte *key_cache_read(KEY_CACHE *keycache,
uint status;
int page_st;
- offset= (uint) (filepos & (keycache->key_cache_block_size-1));
+ offset= (uint) (filepos % keycache->key_cache_block_size);
/* Read data in key_cache_block_size increments */
do
{
@@ -1946,7 +1945,7 @@ int key_cache_insert(KEY_CACHE *keycache,
int error;
uint offset;
- offset= (uint) (filepos & (keycache->key_cache_block_size-1));
+ offset= (uint) (filepos % keycache->key_cache_block_size);
do
{
keycache_pthread_mutex_lock(&keycache->cache_lock);
@@ -2081,7 +2080,7 @@ int key_cache_write(KEY_CACHE *keycache,
int page_st;
uint offset;
- offset= (uint) (filepos & (keycache->key_cache_block_size-1));
+ offset= (uint) (filepos % keycache->key_cache_block_size);
do
{
keycache_pthread_mutex_lock(&keycache->cache_lock);
diff --git a/mysys/my_init.c b/mysys/my_init.c
index 2bcf5f44c4d..32d3f07fd31 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -262,6 +262,34 @@ void my_parameter_handler(const wchar_t * expression, const wchar_t * function,
}
+#ifdef __MSVC_RUNTIME_CHECKS
+#include <rtcapi.h>
+
+/* Turn off runtime checks for 'handle_rtc_failure' */
+#pragma runtime_checks("", off)
+
+/*
+ handle_rtc_failure
+ Catch the RTC error and dump it to stderr
+*/
+
+int handle_rtc_failure(int err_type, const char *file, int line,
+ const char* module, const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ fprintf(stderr, "Error:");
+ vfprintf(stderr, format, args);
+ fprintf(stderr, " At %s:%d\n", file, line);
+ va_end(args);
+ (void) fflush(stderr);
+
+ return 0; /* Error is handled */
+}
+#pragma runtime_checks("", on)
+#endif
+
+
static void my_win_init(void)
{
HKEY hSoftMysql ;
@@ -292,6 +320,14 @@ static void my_win_init(void)
_set_invalid_parameter_handler(my_parameter_handler);
#endif
#endif
+#ifdef __MSVC_RUNTIME_CHECKS
+ /*
+ Install handler to send RTC (Runtime Error Check) warnings
+ to log file
+ */
+ _RTC_SetErrorFunc(handle_rtc_failure);
+#endif
+
_tzset();
/* apre la chiave HKEY_LOCAL_MACHINES\software\MySQL */
diff --git a/mysys/my_seek.c b/mysys/my_seek.c
index 2be4812a2bd..5c1a6c44b6f 100644
--- a/mysys/my_seek.c
+++ b/mysys/my_seek.c
@@ -23,7 +23,9 @@
my_off_t pos The expected position (absolute or relative)
int whence A direction parameter and one of
{SEEK_SET, SEEK_CUR, SEEK_END}
- myf MyFlags Not used.
+ myf MyFlags MY_THREADSAFE must be set in case my_seek may be mixed
+ with my_pread/my_pwrite calls and fd is shared among
+ threads.
DESCRIPTION
The my_seek function is a wrapper around the system call lseek and
@@ -54,9 +56,16 @@ my_off_t my_seek(File fd, my_off_t pos, int whence,
Make sure we are using a valid file descriptor!
*/
DBUG_ASSERT(fd != -1);
-
- newpos= lseek(fd, pos, whence);
-
+#if defined(THREAD) && !defined(HAVE_PREAD)
+ if (MyFlags & MY_THREADSAFE)
+ {
+ pthread_mutex_lock(&my_file_info[fd].mutex);
+ newpos= lseek(fd, pos, whence);
+ pthread_mutex_unlock(&my_file_info[fd].mutex);
+ }
+ else
+#endif
+ newpos= lseek(fd, pos, whence);
if (newpos == (os_off_t) -1)
{
my_errno=errno;
@@ -79,6 +88,7 @@ my_off_t my_tell(File fd, myf MyFlags __attribute__((unused)))
os_off_t pos;
DBUG_ENTER("my_tell");
DBUG_PRINT("my",("Fd: %d MyFlags: %d",fd, MyFlags));
+ DBUG_ASSERT(fd >= 0);
#ifdef HAVE_TELL
pos=tell(fd);
#else
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 07a92e34dd3..cf7ea0a800f 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -87,27 +87,31 @@ my_bool my_thread_global_init(void)
fprintf(stderr,"Can't initialize threads: error %d\n", pth_ret);
return 1;
}
-
-#ifdef NPTL_PTHREAD_EXIT_BUG
-
-/*
- BUG#24507: Race conditions inside current NPTL pthread_exit() implementation.
- To avoid a possible segmentation fault during concurrent executions of
- pthread_exit(), a dummy thread is spawned which initializes internal variables
- of pthread lib. See bug description for thoroughfull explanation.
-
- TODO: Remove this code when fixed versions of glibc6 are in common use.
-*/
+#ifdef NPTL_PTHREAD_EXIT_BUG
+ /*
+ BUG#24507: Race conditions inside current NPTL pthread_exit()
+ implementation.
- pthread_t dummy_thread;
- pthread_attr_t dummy_thread_attr;
+ To avoid a possible segmentation fault during concurrent
+ executions of pthread_exit(), a dummy thread is spawned which
+ initializes internal variables of pthread lib. See bug description
+ for a full explanation.
- pthread_attr_init(&dummy_thread_attr);
- pthread_attr_setdetachstate(&dummy_thread_attr,PTHREAD_CREATE_DETACHED);
+ TODO: Remove this code when fixed versions of glibc6 are in common
+ use.
+ */
+ if (thd_lib_detected == THD_LIB_NPTL)
+ {
+ pthread_t dummy_thread;
+ pthread_attr_t dummy_thread_attr;
- pthread_create(&dummy_thread,&dummy_thread_attr,nptl_pthread_exit_hack_handler,NULL);
+ pthread_attr_init(&dummy_thread_attr);
+ pthread_attr_setdetachstate(&dummy_thread_attr, PTHREAD_CREATE_DETACHED);
+ pthread_create(&dummy_thread,&dummy_thread_attr,
+ nptl_pthread_exit_hack_handler, NULL);
+ }
#endif
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
diff --git a/ndb/include/debugger/EventLogger.hpp b/ndb/include/debugger/EventLogger.hpp
index 11df3f513fc..f6762743df0 100644
--- a/ndb/include/debugger/EventLogger.hpp
+++ b/ndb/include/debugger/EventLogger.hpp
@@ -175,5 +175,5 @@ private:
char m_text[MAX_TEXT_LENGTH];
};
-
+extern void getRestartAction(Uint32 action, BaseString &str);
#endif
diff --git a/ndb/include/mgmapi/ndbd_exit_codes.h b/ndb/include/mgmapi/ndbd_exit_codes.h
index 874bf0aa253..1051fd9e394 100644
--- a/ndb/include/mgmapi/ndbd_exit_codes.h
+++ b/ndb/include/mgmapi/ndbd_exit_codes.h
@@ -79,6 +79,8 @@ typedef ndbd_exit_classification_enum ndbd_exit_classification;
#define NDBD_EXIT_NO_MORE_UNDOLOG 2312
#define NDBD_EXIT_SR_UNDOLOG 2313
#define NDBD_EXIT_SINGLE_USER_MODE 2314
+#define NDBD_EXIT_NODE_DECLARED_DEAD 2315
+#define NDBD_EXIT_SR_SCHEMAFILE 2316
#define NDBD_EXIT_MEMALLOC 2327
#define NDBD_EXIT_BLOCK_JBUFCONGESTION 2334
#define NDBD_EXIT_TIME_QUEUE_SHORT 2335
diff --git a/ndb/include/ndbapi/Ndb.hpp b/ndb/include/ndbapi/Ndb.hpp
index b3c9acd4e20..f83db77739e 100644
--- a/ndb/include/ndbapi/Ndb.hpp
+++ b/ndb/include/ndbapi/Ndb.hpp
@@ -1388,9 +1388,11 @@ public:
* @return 0 or -1 on error, and tupleId in out parameter
*/
int getAutoIncrementValue(const char* aTableName,
- Uint64 & tupleId, Uint32 cacheSize);
+ Uint64 & tupleId, Uint32 cacheSize,
+ Uint64 step = 1, Uint64 start = 1);
int getAutoIncrementValue(const NdbDictionary::Table * aTable,
- Uint64 & tupleId, Uint32 cacheSize);
+ Uint64 & tupleId, Uint32 cacheSize,
+ Uint64 step = 1, Uint64 start = 1);
int readAutoIncrementValue(const char* aTableName,
Uint64 & tupleId);
int readAutoIncrementValue(const NdbDictionary::Table * aTable,
@@ -1401,7 +1403,8 @@ public:
Uint64 tupleId, bool increase);
private:
int getTupleIdFromNdb(Ndb_local_table_info* info,
- Uint64 & tupleId, Uint32 cacheSize);
+ Uint64 & tupleId, Uint32 cacheSize,
+ Uint64 step = 1, Uint64 start = 1 );
int readTupleIdFromNdb(Ndb_local_table_info* info,
Uint64 & tupleId);
int setTupleIdInNdb(Ndb_local_table_info* info,
diff --git a/ndb/src/common/transporter/Packer.cpp b/ndb/src/common/transporter/Packer.cpp
index 66c00b0af89..d471167b0e7 100644
--- a/ndb/src/common/transporter/Packer.cpp
+++ b/ndb/src/common/transporter/Packer.cpp
@@ -20,7 +20,12 @@
#include <TransporterCallback.hpp>
#include <RefConvert.hpp>
+#ifdef ERROR_INSERT
+Uint32 MAX_RECEIVED_SIGNALS = 1024;
+#else
#define MAX_RECEIVED_SIGNALS 1024
+#endif
+
Uint32
TransporterRegistry::unpack(Uint32 * readPtr,
Uint32 sizeOfData,
diff --git a/ndb/src/common/transporter/SCI_Transporter.cpp b/ndb/src/common/transporter/SCI_Transporter.cpp
index 138b79acb51..0720fe84973 100644
--- a/ndb/src/common/transporter/SCI_Transporter.cpp
+++ b/ndb/src/common/transporter/SCI_Transporter.cpp
@@ -65,13 +65,10 @@ SCI_Transporter::SCI_Transporter(TransporterRegistry &t_reg,
m_initLocal=false;
- m_swapCounter=0;
m_failCounter=0;
m_remoteNodes[0]=remoteSciNodeId0;
m_remoteNodes[1]=remoteSciNodeId1;
m_adapters = nAdapters;
- // The maximum number of times to try and create,
- // start and destroy a sequence
m_ActiveAdapterId=0;
m_StandbyAdapterId=1;
@@ -102,8 +99,6 @@ SCI_Transporter::SCI_Transporter(TransporterRegistry &t_reg,
DBUG_VOID_RETURN;
}
-
-
void SCI_Transporter::disconnectImpl()
{
DBUG_ENTER("SCI_Transporter::disconnectImpl");
@@ -129,7 +124,8 @@ void SCI_Transporter::disconnectImpl()
if(err != SCI_ERR_OK) {
report_error(TE_SCI_UNABLE_TO_CLOSE_CHANNEL);
- DBUG_PRINT("error", ("Cannot close channel to the driver. Error code 0x%x",
+ DBUG_PRINT("error",
+ ("Cannot close channel to the driver. Error code 0x%x",
err));
}
}
@@ -164,19 +160,18 @@ bool SCI_Transporter::initTransporter() {
m_sendBuffer.m_buffer = new Uint32[m_sendBuffer.m_sendBufferSize / 4];
m_sendBuffer.m_dataSize = 0;
- DBUG_PRINT("info", ("Created SCI Send Buffer with buffer size %d and packet size %d",
+ DBUG_PRINT("info",
+ ("Created SCI Send Buffer with buffer size %d and packet size %d",
m_sendBuffer.m_sendBufferSize, m_PacketSize * 4));
if(!getLinkStatus(m_ActiveAdapterId) ||
(m_adapters > 1 &&
!getLinkStatus(m_StandbyAdapterId))) {
- DBUG_PRINT("error", ("The link is not fully operational. Check the cables and the switches"));
- //reportDisconnect(remoteNodeId, 0);
- //doDisconnect();
+ DBUG_PRINT("error",
+ ("The link is not fully operational. Check the cables and the switches"));
//NDB should terminate
report_error(TE_SCI_LINK_ERROR);
DBUG_RETURN(false);
}
-
DBUG_RETURN(true);
} // initTransporter()
@@ -235,7 +230,8 @@ sci_error_t SCI_Transporter::initLocalSegment() {
DBUG_PRINT("info", ("SCInode iD %d adapter %d\n",
sciAdapters[i].localSciNodeId, i));
if(err != SCI_ERR_OK) {
- DBUG_PRINT("error", ("Cannot open an SCI virtual device. Error code 0x%x",
+ DBUG_PRINT("error",
+ ("Cannot open an SCI virtual device. Error code 0x%x",
err));
DBUG_RETURN(err);
}
@@ -269,7 +265,8 @@ sci_error_t SCI_Transporter::initLocalSegment() {
&err);
if(err != SCI_ERR_OK) {
- DBUG_PRINT("error", ("Local Segment is not accessible by an SCI adapter. Error code 0x%x\n",
+ DBUG_PRINT("error",
+ ("Local Segment is not accessible by an SCI adapter. Error code 0x%x\n",
err));
DBUG_RETURN(err);
}
@@ -303,15 +300,13 @@ sci_error_t SCI_Transporter::initLocalSegment() {
&err);
if(err != SCI_ERR_OK) {
- DBUG_PRINT("error", ("Local Segment is not available for remote connections. Error code 0x%x\n",
+ DBUG_PRINT("error",
+ ("Local Segment is not available for remote connections. Error code 0x%x\n",
err));
DBUG_RETURN(err);
}
}
-
-
setupLocalSegment();
-
DBUG_RETURN(err);
} // initLocalSegment()
@@ -343,12 +338,6 @@ bool SCI_Transporter::doSend() {
if(sizeToSend==4097)
i4097++;
#endif
- if(startSequence(m_ActiveAdapterId)!=SCI_ERR_OK) {
- DBUG_PRINT("error", ("Start sequence failed"));
- report_error(TE_SCI_UNABLE_TO_START_SEQUENCE);
- return false;
- }
-
tryagain:
retry++;
@@ -374,119 +363,36 @@ bool SCI_Transporter::doSend() {
SCI_FLAG_ERROR_CHECK,
&err);
-
if (err != SCI_ERR_OK) {
- if(err == SCI_ERR_OUT_OF_RANGE) {
- DBUG_PRINT("error", ("Data transfer : out of range error"));
- goto tryagain;
- }
- if(err == SCI_ERR_SIZE_ALIGNMENT) {
- DBUG_PRINT("error", ("Data transfer : alignment error"));
- DBUG_PRINT("info", ("sendPtr 0x%x, sizeToSend = %d", sendPtr, sizeToSend));
- goto tryagain;
- }
- if(err == SCI_ERR_OFFSET_ALIGNMENT) {
- DBUG_PRINT("error", ("Data transfer : offset alignment"));
- goto tryagain;
- }
- if(err == SCI_ERR_TRANSFER_FAILED) {
- //(m_TargetSegm[m_StandbyAdapterId].writer)->heavyLock();
- if(getLinkStatus(m_ActiveAdapterId)) {
- goto tryagain;
- }
- if (m_adapters == 1) {
- DBUG_PRINT("error", ("SCI Transfer failed"));
+ if (err == SCI_ERR_OUT_OF_RANGE ||
+ err == SCI_ERR_SIZE_ALIGNMENT ||
+ err == SCI_ERR_OFFSET_ALIGNMENT) {
+ DBUG_PRINT("error", ("Data transfer error = %d", err));
report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
return false;
- }
- m_failCounter++;
- Uint32 temp=m_ActiveAdapterId;
- switch(m_swapCounter) {
- case 0:
- /**swap from active (0) to standby (1)*/
- if(getLinkStatus(m_StandbyAdapterId)) {
- DBUG_PRINT("error", ("Swapping from adapter 0 to 1"));
+ }
+ if(err == SCI_ERR_TRANSFER_FAILED) {
+ if(getLinkStatus(m_ActiveAdapterId))
+ goto tryagain;
+ if (m_adapters == 1) {
+ DBUG_PRINT("error", ("SCI Transfer failed"));
+ report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
+ return false;
+ }
+ m_failCounter++;
+ Uint32 temp=m_ActiveAdapterId;
+ if (getLinkStatus(m_StandbyAdapterId)) {
failoverShmWriter();
SCIStoreBarrier(m_TargetSegm[m_StandbyAdapterId].sequence,0);
m_ActiveAdapterId=m_StandbyAdapterId;
m_StandbyAdapterId=temp;
- SCIRemoveSequence((m_TargetSegm[m_StandbyAdapterId].sequence),
- FLAGS,
- &err);
- if(err!=SCI_ERR_OK) {
- report_error(TE_SCI_UNABLE_TO_REMOVE_SEQUENCE);
- DBUG_PRINT("error", ("Unable to remove sequence"));
- return false;
- }
- if(startSequence(m_ActiveAdapterId)!=SCI_ERR_OK) {
- DBUG_PRINT("error", ("Start sequence failed"));
- report_error(TE_SCI_UNABLE_TO_START_SEQUENCE);
- return false;
- }
- m_swapCounter++;
- DBUG_PRINT("info", ("failover complete"));
- goto tryagain;
- } else {
- report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
- DBUG_PRINT("error", ("SCI Transfer failed"));
- return false;
- }
- return false;
- break;
- case 1:
- /** swap back from 1 to 0
- must check that the link is up */
-
- if(getLinkStatus(m_StandbyAdapterId)) {
- failoverShmWriter();
- m_ActiveAdapterId=m_StandbyAdapterId;
- m_StandbyAdapterId=temp;
- DBUG_PRINT("info", ("Swapping from 1 to 0"));
- if(createSequence(m_ActiveAdapterId)!=SCI_ERR_OK) {
- DBUG_PRINT("error", ("Unable to create sequence"));
- report_error(TE_SCI_UNABLE_TO_CREATE_SEQUENCE);
- return false;
- }
- if(startSequence(m_ActiveAdapterId)!=SCI_ERR_OK) {
- DBUG_PRINT("error", ("startSequence failed... disconnecting"));
- report_error(TE_SCI_UNABLE_TO_START_SEQUENCE);
- return false;
- }
-
- SCIRemoveSequence((m_TargetSegm[m_StandbyAdapterId].sequence)
- , FLAGS,
- &err);
- if(err!=SCI_ERR_OK) {
- DBUG_PRINT("error", ("Unable to remove sequence"));
- report_error(TE_SCI_UNABLE_TO_REMOVE_SEQUENCE);
- return false;
- }
-
- if(createSequence(m_StandbyAdapterId)!=SCI_ERR_OK) {
- DBUG_PRINT("error", ("Unable to create sequence on standby"));
- report_error(TE_SCI_UNABLE_TO_CREATE_SEQUENCE);
- return false;
- }
-
- m_swapCounter=0;
-
- DBUG_PRINT("info", ("failover complete.."));
- goto tryagain;
-
+ DBUG_PRINT("error", ("Swapping from adapter %u to %u",
+ m_StandbyAdapterId, m_ActiveAdapterId));
} else {
- DBUG_PRINT("error", ("Unrecoverable data transfer error"));
report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
- return false;
+ DBUG_PRINT("error", ("SCI Transfer failed"));
}
-
- break;
- default:
- DBUG_PRINT("error", ("Unrecoverable data transfer error"));
- report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
- return false;
- break;
- }
- }
+ }
} else {
SHM_Writer * writer = (m_TargetSegm[m_ActiveAdapterId].writer);
writer->updateWritePtr(sizeToSend);
@@ -497,7 +403,6 @@ bool SCI_Transporter::doSend() {
m_sendBuffer.m_dataSize = 0;
m_sendBuffer.m_forceSendLimit = sendLimit;
}
-
} else {
/**
* If we end up here, the SCI segment is full.
@@ -552,15 +457,12 @@ void SCI_Transporter::setupLocalSegment()
DBUG_VOID_RETURN;
} //setupLocalSegment
-
-
void SCI_Transporter::setupRemoteSegment()
{
DBUG_ENTER("SCI_Transporter::setupRemoteSegment");
Uint32 sharedSize = 0;
sharedSize =4096; //start of the buffer is page aligned
-
Uint32 sizeOfBuffer = m_BufferSize;
const Uint32 slack = MAX_MESSAGE_SIZE;
sizeOfBuffer -= sharedSize;
@@ -666,7 +568,6 @@ SCI_Transporter::init_remote()
DBUG_PRINT("error", ("Error connecting segment, err 0x%x", err));
DBUG_RETURN(false);
}
-
}
// Map the remote memory segment into program space
for(Uint32 i=0; i < m_adapters ; i++) {
@@ -679,13 +580,14 @@ SCI_Transporter::init_remote()
FLAGS,
&err);
-
- if(err!= SCI_ERR_OK) {
- DBUG_PRINT("error", ("Cannot map a segment to the remote node %d. Error code 0x%x",m_RemoteSciNodeId, err));
- //NDB SHOULD TERMINATE AND COMPUTER REBOOTED!
- report_error(TE_SCI_CANNOT_MAP_REMOTESEGMENT);
- DBUG_RETURN(false);
- }
+ if(err!= SCI_ERR_OK) {
+ DBUG_PRINT("error",
+ ("Cannot map a segment to the remote node %d. Error code 0x%x",
+ m_RemoteSciNodeId, err));
+ //NDB SHOULD TERMINATE AND COMPUTER REBOOTED!
+ report_error(TE_SCI_CANNOT_MAP_REMOTESEGMENT);
+ DBUG_RETURN(false);
+ }
}
m_mapped=true;
setupRemoteSegment();
@@ -713,7 +615,6 @@ SCI_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd)
NDB_CLOSE_SOCKET(sockfd);
DBUG_RETURN(false);
}
-
if (!init_local()) {
NDB_CLOSE_SOCKET(sockfd);
DBUG_RETURN(false);
@@ -788,29 +689,9 @@ sci_error_t SCI_Transporter::createSequence(Uint32 adapterid) {
&(m_TargetSegm[adapterid].sequence),
SCI_FLAG_FAST_BARRIER,
&err);
-
-
return err;
} // createSequence()
-
-sci_error_t SCI_Transporter::startSequence(Uint32 adapterid) {
-
- sci_error_t err;
- /** Perform preliminary error check on an SCI adapter before starting a
- * sequence of read and write operations on the mapped segment.
- */
- m_SequenceStatus = SCIStartSequence(
- (m_TargetSegm[adapterid].sequence),
- FLAGS, &err);
-
-
- // If there still is an error then data cannot be safely send
- return err;
-} // startSequence()
-
-
-
bool SCI_Transporter::disconnectLocal()
{
DBUG_ENTER("SCI_Transporter::disconnectLocal");
@@ -878,9 +759,6 @@ SCI_Transporter::~SCI_Transporter() {
DBUG_VOID_RETURN;
} // ~SCI_Transporter()
-
-
-
void SCI_Transporter::closeSCI() {
// Termination of SCI
sci_error_t err;
@@ -897,8 +775,9 @@ void SCI_Transporter::closeSCI() {
SCIClose(activeSCIDescriptor, FLAGS, &err);
if(err != SCI_ERR_OK) {
- DBUG_PRINT("error", ("Cannot close SCI channel to the driver. Error code 0x%x",
- err));
+ DBUG_PRINT("error",
+ ("Cannot close SCI channel to the driver. Error code 0x%x",
+ err));
}
SCITerminate();
DBUG_VOID_RETURN;
@@ -973,7 +852,6 @@ SCI_Transporter::getConnectionStatus() {
return false;
}
-
void
SCI_Transporter::setConnected() {
*m_remoteStatusFlag = SCICONNECTED;
@@ -983,7 +861,6 @@ SCI_Transporter::setConnected() {
*m_localStatusFlag = SCICONNECTED;
}
-
void
SCI_Transporter::setDisconnect() {
if(getLinkStatus(m_ActiveAdapterId))
@@ -994,7 +871,6 @@ SCI_Transporter::setDisconnect() {
}
}
-
bool
SCI_Transporter::checkConnected() {
if (*m_localStatusFlag == SCIDISCONNECT) {
@@ -1015,8 +891,9 @@ SCI_Transporter::initSCI() {
SCIInitialize(0, &error);
if(error != SCI_ERR_OK) {
DBUG_PRINT("error", ("Cannot initialize SISCI library."));
- DBUG_PRINT("error", ("Inconsistency between SISCI library and SISCI driver. Error code 0x%x",
- error));
+ DBUG_PRINT("error",
+ ("Inconsistency between SISCI library and SISCI driver. Error code 0x%x",
+ error));
DBUG_RETURN(false);
}
init = true;
@@ -1029,3 +906,4 @@ SCI_Transporter::get_free_buffer() const
{
return (m_TargetSegm[m_ActiveAdapterId].writer)->get_free_buffer();
}
+
diff --git a/ndb/src/common/transporter/SCI_Transporter.hpp b/ndb/src/common/transporter/SCI_Transporter.hpp
index fbba2ac4516..f774186f238 100644
--- a/ndb/src/common/transporter/SCI_Transporter.hpp
+++ b/ndb/src/common/transporter/SCI_Transporter.hpp
@@ -54,12 +54,12 @@
* local segment, the SCI transporter connects to a segment created by another
* transporter at a remote node, and the maps the remote segment into its
* virtual address space. However, since NDB Cluster relies on redundancy
- * at the network level, by using dual SCI adapters communica
- *
+ * at the network level, by using dual SCI adapters communication can be
+ * maintained even if one of the adapter cards fails (or anything on the
+ * network this adapter card exists in e.g. an SCI switch failure).
*
*/
-
/**
* class SCITransporter
* @brief - main class for the SCI transporter.
@@ -84,16 +84,6 @@ public:
sci_error_t createSequence(Uint32 adapterid);
- /**
- * starts a sequence for error checking.
- * The actual checking that a sequence is correct is done implicitly
- * in SCIMemCpy (in doSend).
- * @param adapterid the adapter on which to start the sequence.
- * @return SCI_ERR_OK if ok, otherwize something else.
- */
- sci_error_t startSequence(Uint32 adapterid);
-
-
/** Initiate Local Segment: create a memory segment,
* prepare a memory segment, map the local segment
* into memory space and make segment available.
@@ -159,7 +149,6 @@ private:
bool m_mapped;
bool m_initLocal;
bool m_sciinit;
- Uint32 m_swapCounter;
Uint32 m_failCounter;
/**
* For statistics on transfered packets
@@ -195,7 +184,6 @@ private:
*/
Uint32 m_reportFreq;
-
Uint32 m_adapters;
Uint32 m_numberOfRemoteNodes;
diff --git a/ndb/src/common/transporter/TCP_Transporter.hpp b/ndb/src/common/transporter/TCP_Transporter.hpp
index 4e0de15bdbe..7b6fd0b2323 100644
--- a/ndb/src/common/transporter/TCP_Transporter.hpp
+++ b/ndb/src/common/transporter/TCP_Transporter.hpp
@@ -102,6 +102,10 @@ private:
virtual void updateReceiveDataPtr(Uint32 bytesRead);
virtual Uint32 get_free_buffer() const;
+
+ inline bool hasReceiveData () const {
+ return receiveBuffer.sizeOfData > 0;
+ }
protected:
/**
* Setup client/server and perform connect/accept
diff --git a/ndb/src/common/transporter/TransporterRegistry.cpp b/ndb/src/common/transporter/TransporterRegistry.cpp
index bd2ff0d3062..68454c672fd 100644
--- a/ndb/src/common/transporter/TransporterRegistry.cpp
+++ b/ndb/src/common/transporter/TransporterRegistry.cpp
@@ -841,28 +841,13 @@ TransporterRegistry::poll_OSE(Uint32 timeOutMillis)
Uint32
TransporterRegistry::poll_TCP(Uint32 timeOutMillis)
{
+ bool hasdata = false;
if (false && nTCPTransporters == 0)
{
tcpReadSelectReply = 0;
return 0;
}
- struct timeval timeout;
-#ifdef NDB_OSE
- // Return directly if there are no TCP transporters configured
-
- if(timeOutMillis <= 1){
- timeout.tv_sec = 0;
- timeout.tv_usec = 1025;
- } else {
- timeout.tv_sec = timeOutMillis / 1000;
- timeout.tv_usec = (timeOutMillis % 1000) * 1000;
- }
-#else
- timeout.tv_sec = timeOutMillis / 1000;
- timeout.tv_usec = (timeOutMillis % 1000) * 1000;
-#endif
-
NDB_SOCKET_TYPE maxSocketValue = -1;
// Needed for TCP/IP connections
@@ -885,8 +870,27 @@ TransporterRegistry::poll_TCP(Uint32 timeOutMillis)
// Put the connected transporters in the socket read-set
FD_SET(socket, &tcpReadset);
}
+ hasdata |= t->hasReceiveData();
}
+ timeOutMillis = hasdata ? 0 : timeOutMillis;
+
+ struct timeval timeout;
+#ifdef NDB_OSE
+ // Return directly if there are no TCP transporters configured
+
+ if(timeOutMillis <= 1){
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 1025;
+ } else {
+ timeout.tv_sec = timeOutMillis / 1000;
+ timeout.tv_usec = (timeOutMillis % 1000) * 1000;
+ }
+#else
+ timeout.tv_sec = timeOutMillis / 1000;
+ timeout.tv_usec = (timeOutMillis % 1000) * 1000;
+#endif
+
// The highest socket value plus one
maxSocketValue++;
@@ -901,7 +905,7 @@ TransporterRegistry::poll_TCP(Uint32 timeOutMillis)
}
#endif
- return tcpReadSelectReply;
+ return tcpReadSelectReply || hasdata;
}
#endif
@@ -937,26 +941,27 @@ TransporterRegistry::performReceive()
#endif
#ifdef NDB_TCP_TRANSPORTER
- if(tcpReadSelectReply > 0)
+ for (int i=0; i<nTCPTransporters; i++)
{
- for (int i=0; i<nTCPTransporters; i++)
- {
- checkJobBuffer();
- TCP_Transporter *t = theTCPTransporters[i];
- const NodeId nodeId = t->getRemoteNodeId();
- const NDB_SOCKET_TYPE socket = t->getSocket();
- if(is_connected(nodeId)){
- if(t->isConnected() && FD_ISSET(socket, &tcpReadset))
+ checkJobBuffer();
+ TCP_Transporter *t = theTCPTransporters[i];
+ const NodeId nodeId = t->getRemoteNodeId();
+ const NDB_SOCKET_TYPE socket = t->getSocket();
+ if(is_connected(nodeId)){
+ if(t->isConnected())
+ {
+ if (FD_ISSET(socket, &tcpReadset))
{
- const int receiveSize = t->doReceive();
- if(receiveSize > 0)
- {
- Uint32 * ptr;
- Uint32 sz = t->getReceiveData(&ptr);
- transporter_recv_from(callbackObj, nodeId);
- Uint32 szUsed = unpack(ptr, sz, nodeId, ioStates[nodeId]);
- t->updateReceiveDataPtr(szUsed);
- }
+ t->doReceive();
+ }
+
+ if (t->hasReceiveData())
+ {
+ Uint32 * ptr;
+ Uint32 sz = t->getReceiveData(&ptr);
+ transporter_recv_from(callbackObj, nodeId);
+ Uint32 szUsed = unpack(ptr, sz, nodeId, ioStates[nodeId]);
+ t->updateReceiveDataPtr(szUsed);
}
}
}
diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt
index 9c2b441e7be..17f2c35624a 100644
--- a/ndb/src/kernel/blocks/ERROR_codes.txt
+++ b/ndb/src/kernel/blocks/ERROR_codes.txt
@@ -1,5 +1,5 @@
Next QMGR 1
-Next NDBCNTR 1000
+Next NDBCNTR 1002
Next NDBFS 2000
Next DBACC 3002
Next DBTUP 4014
@@ -501,3 +501,4 @@ TUP:
NDBCNTR:
1000: Crash insertion on SystemError::CopyFragRef
+1001: Delay sending NODE_FAILREP (to own node), until error is cleared
diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
index 9579700663b..1b5e7a27a0c 100644
--- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
+++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
@@ -132,6 +132,7 @@ Cmvmi::~Cmvmi()
#ifdef ERROR_INSERT
NodeBitmask c_error_9000_nodes_mask;
+extern Uint32 MAX_RECEIVED_SIGNALS;
#endif
void Cmvmi::execNDB_TAMPER(Signal* signal)
@@ -161,6 +162,22 @@ void Cmvmi::execNDB_TAMPER(Signal* signal)
kill(getpid(), SIGABRT);
}
#endif
+
+#ifdef ERROR_INSERT
+ if (signal->theData[0] == 9003)
+ {
+ if (MAX_RECEIVED_SIGNALS < 1024)
+ {
+ MAX_RECEIVED_SIGNALS = 1024;
+ }
+ else
+ {
+ MAX_RECEIVED_SIGNALS = 1 + (rand() % 128);
+ }
+ ndbout_c("MAX_RECEIVED_SIGNALS: %d", MAX_RECEIVED_SIGNALS);
+ CLEAR_ERROR_INSERT_VALUE;
+ }
+#endif
}//execNDB_TAMPER()
void Cmvmi::execSET_LOGLEVELORD(Signal* signal)
diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
index a039c1bdbe7..fed40d0a904 100644
--- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
@@ -79,6 +79,9 @@
#include <NdbSleep.h>
#include <signaldata/ApiBroadcast.hpp>
+#include <EventLogger.hpp>
+extern EventLogger g_eventLogger;
+
#define ZNOT_FOUND 626
#define ZALREADYEXIST 630
@@ -401,6 +404,9 @@ void Dbdict::execFSCLOSECONF(Signal* signal)
case FsConnectRecord::OPEN_READ_SCHEMA2:
openSchemaFile(signal, 1, fsPtr.i, false, false);
break;
+ case FsConnectRecord::OPEN_READ_TAB_FILE2:
+ openTableFile(signal, 1, fsPtr.i, c_readTableRecord.tableId, false);
+ break;
default:
jamLine((fsPtr.p->fsState & 0xFFF));
ndbrequire(false);
@@ -780,8 +786,11 @@ void Dbdict::readTableConf(Signal* signal,
void Dbdict::readTableRef(Signal* signal,
FsConnectRecordPtr fsPtr)
{
+ /**
+ * First close corrupt file
+ */
fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE2;
- openTableFile(signal, 1, fsPtr.i, c_readTableRecord.tableId, false);
+ closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
return;
}//Dbdict::readTableRef()
@@ -1069,17 +1078,36 @@ void Dbdict::readSchemaConf(Signal* signal,
for (Uint32 n = 0; n < xsf->noOfPages; n++) {
SchemaFile * sf = &xsf->schemaPage[n];
- bool ok =
- memcmp(sf->Magic, NDB_SF_MAGIC, sizeof(sf->Magic)) == 0 &&
- sf->FileSize != 0 &&
- sf->FileSize % NDB_SF_PAGE_SIZE == 0 &&
- sf->FileSize == sf0->FileSize &&
- sf->PageNumber == n &&
- computeChecksum((Uint32*)sf, NDB_SF_PAGE_SIZE_IN_WORDS) == 0;
- ndbrequire(ok || !crashInd);
- if (! ok) {
+ bool ok = false;
+ const char *reason;
+ if (memcmp(sf->Magic, NDB_SF_MAGIC, sizeof(sf->Magic)) != 0)
+ { jam(); reason = "magic code"; }
+ else if (sf->FileSize == 0)
+ { jam(); reason = "file size == 0"; }
+ else if (sf->FileSize % NDB_SF_PAGE_SIZE != 0)
+ { jam(); reason = "invalid size multiple"; }
+ else if (sf->FileSize != sf0->FileSize)
+ { jam(); reason = "invalid size"; }
+ else if (sf->PageNumber != n)
+ { jam(); reason = "invalid page number"; }
+ else if (computeChecksum((Uint32*)sf, NDB_SF_PAGE_SIZE_IN_WORDS) != 0)
+ { jam(); reason = "invalid checksum"; }
+ else
+ ok = true;
+
+ if (!ok)
+ {
+ char reason_msg[128];
+ snprintf(reason_msg, sizeof(reason_msg),
+ "schema file corrupt, page %u (%s, "
+ "sz=%u sz0=%u pn=%u)",
+ n, reason, sf->FileSize, sf0->FileSize, sf->PageNumber);
+ if (crashInd)
+ progError(__LINE__, NDBD_EXIT_SR_SCHEMAFILE, reason_msg);
+ ndbrequireErr(fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1,
+ NDBD_EXIT_SR_SCHEMAFILE);
jam();
- ndbrequire(fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1);
+ infoEvent("primary %s, trying backup", reason_msg);
readSchemaRef(signal, fsPtr);
return;
}
diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
index cebf350021f..9191bb3fb9b 100644
--- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
+++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
@@ -4459,12 +4459,18 @@ void Dbdih::failedNodeLcpHandling(Signal* signal, NodeRecordPtr failedNodePtr)
jam();
const Uint32 nodeId = failedNodePtr.i;
- if (c_lcpState.m_participatingLQH.get(failedNodePtr.i)){
+ if (isMaster() && c_lcpState.m_participatingLQH.get(failedNodePtr.i))
+ {
/*----------------------------------------------------*/
/* THE NODE WAS INVOLVED IN A LOCAL CHECKPOINT. WE */
/* MUST UPDATE THE ACTIVE STATUS TO INDICATE THAT */
/* THE NODE HAVE MISSED A LOCAL CHECKPOINT. */
/*----------------------------------------------------*/
+
+ /**
+ * Bug#28717, Only master should do this, as this status is copied
+ * to other nodes
+ */
switch (failedNodePtr.p->activeStatus) {
case Sysfile::NS_Active:
jam();
diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
index 4474d226a27..2ed08db527c 100644
--- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
+++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
@@ -2668,7 +2668,8 @@ private:
UintR cfirstfreeLogFile;
UintR clogFileFileSize;
-#define ZLFO_FILE_SIZE 256 /* MAX 256 OUTSTANDING FILE OPERATIONS */
+#define ZLFO_MIN_FILE_SIZE 256
+// RedoBuffer/32K minimum ZLFO_MIN_FILE_SIZE
LogFileOperationRecord *logFileOperationRecord;
LogFileOperationRecordPtr lfoPtr;
UintR cfirstfreeLfo;
@@ -2685,7 +2686,7 @@ private:
UintR cfirstfreePageRef;
UintR cpageRefFileSize;
-#define ZSCANREC_FILE_SIZE 100
+// Configurable
ArrayPool<ScanRecord> c_scanRecordPool;
ScanRecordPtr scanptr;
UintR cscanNoFreeRec;
diff --git a/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp b/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
index 3452269be51..adeed3e1e8b 100644
--- a/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
+++ b/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
@@ -32,11 +32,11 @@ void Dblqh::initData()
chostFileSize = MAX_NDB_NODES;
clcpFileSize = ZNO_CONCURRENT_LCP;
clcpLocrecFileSize = ZLCP_LOCREC_FILE_SIZE;
- clfoFileSize = ZLFO_FILE_SIZE;
+ clfoFileSize = 0;
clogFileFileSize = 0;
clogPartFileSize = ZLOG_PART_FILE_SIZE;
cpageRefFileSize = ZPAGE_REF_FILE_SIZE;
- cscanrecFileSize = ZSCANREC_FILE_SIZE;
+ cscanrecFileSize = 0;
ctabrecFileSize = 0;
ctcConnectrecFileSize = 0;
ctcNodeFailrecFileSize = MAX_NDB_NODES;
@@ -338,6 +338,11 @@ Dblqh::Dblqh(const class Configuration & conf):
initData();
+ /* maximum number of log file operations */
+ clfoFileSize = clogPageFileSize;
+ if (clfoFileSize < ZLFO_MIN_FILE_SIZE)
+ clfoFileSize = ZLFO_MIN_FILE_SIZE;
+
#ifdef VM_TRACE
{
void* tmp[] = {
diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
index 69bd6329ff1..32827c18802 100644
--- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
+++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
@@ -1375,6 +1375,13 @@ void Ndbcntr::execNODE_FAILREP(Signal* signal)
{
jamEntry();
+ if (ERROR_INSERTED(1001))
+ {
+ sendSignalWithDelay(reference(), GSN_NODE_FAILREP, signal, 100,
+ signal->getLength());
+ return;
+ }
+
const NodeFailRep * nodeFail = (NodeFailRep *)&signal->theData[0];
NdbNodeBitmask allFailed;
allFailed.assign(NdbNodeBitmask::Size, nodeFail->theNodes);
diff --git a/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp b/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp
index 353330929e5..55b0a8c4d39 100644
--- a/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp
+++ b/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp
@@ -569,7 +569,7 @@ AsyncFile*
Ndbfs::createAsyncFile(){
// Check limit of open files
- if (theFiles.size()+1 == m_maxFiles) {
+ if (theFiles.size() == m_maxFiles) {
// Print info about all open files
for (unsigned i = 0; i < theFiles.size(); i++){
AsyncFile* file = theFiles[i];
diff --git a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
index a0a19620a05..a76838f7007 100644
--- a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
+++ b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
@@ -2816,7 +2816,7 @@ void Qmgr::failReportLab(Signal* signal, Uint16 aFailedNode,
if (failedNodePtr.i == getOwnNodeId()) {
jam();
- Uint32 code = 0;
+ Uint32 code = NDBD_EXIT_NODE_DECLARED_DEAD;
const char * msg = 0;
char extra[100];
switch(aFailCause){
diff --git a/ndb/src/kernel/error/ndbd_exit_codes.c b/ndb/src/kernel/error/ndbd_exit_codes.c
index 37a54e33350..92bee522d24 100644
--- a/ndb/src/kernel/error/ndbd_exit_codes.c
+++ b/ndb/src/kernel/error/ndbd_exit_codes.c
@@ -57,12 +57,15 @@ static const ErrStruct errArray[] =
"error(s) on other node(s)"},
{NDBD_EXIT_PARTITIONED_SHUTDOWN, XAE, "Partitioned cluster detected. "
"Please check if cluster is already running"},
+ {NDBD_EXIT_NODE_DECLARED_DEAD, XAE,
+ "Node declared dead. See error log for details"},
{NDBD_EXIT_POINTER_NOTINRANGE, XIE, "Pointer too large"},
{NDBD_EXIT_SR_OTHERNODEFAILED, XRE, "Another node failed during system "
"restart, please investigate error(s) on other node(s)"},
{NDBD_EXIT_NODE_NOT_DEAD, XRE, "Internal node state conflict, "
"most probably resolved by restarting node again"},
{NDBD_EXIT_SR_REDOLOG, XFI, "Error while reading the REDO log"},
+ {NDBD_EXIT_SR_SCHEMAFILE, XFI, "Error while reading the schema file"},
/* Currently unused? */
{2311, XIE, "Conflict when selecting restart type"},
{NDBD_EXIT_NO_MORE_UNDOLOG, XCR,
diff --git a/ndb/src/kernel/vm/WatchDog.cpp b/ndb/src/kernel/vm/WatchDog.cpp
index d1abb709b1e..2e24a5eaa6c 100644
--- a/ndb/src/kernel/vm/WatchDog.cpp
+++ b/ndb/src/kernel/vm/WatchDog.cpp
@@ -16,6 +16,7 @@
#include <ndb_global.h>
#include <my_pthread.h>
+#include <sys/times.h>
#include "WatchDog.hpp"
#include "GlobalData.hpp"
@@ -129,6 +130,13 @@ WatchDog::run(){
break;
}//switch
g_eventLogger.warning("Ndb kernel is stuck in: %s", last_stuck_action);
+ {
+ struct tms my_tms;
+ times(&my_tms);
+ g_eventLogger.info("User time: %llu System time: %llu",
+ (Uint64)my_tms.tms_utime,
+ (Uint64)my_tms.tms_stime);
+ }
if(alerts == 3){
shutdownSystem(last_stuck_action);
}
diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp
index 2265579ad1e..8abce4f9cc4 100644
--- a/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -25,6 +25,7 @@
#include <mgmapi.h>
#include <util/BaseString.hpp>
+#include <ndbd_exit_codes.h>
class MgmtSrvr;
@@ -125,7 +126,7 @@ public:
int executeStatus(int processId, const char* parameters, bool all);
int executeEventReporting(int processId, const char* parameters, bool all);
int executeDumpState(int processId, const char* parameters, bool all);
- int executeStartBackup(char * parameters);
+ int executeStartBackup(char * parameters, bool interactive);
int executeAbortBackup(char * parameters);
int executeStop(Vector<BaseString> &command_list, unsigned command_pos,
int *node_ids, int no_of_nodes);
@@ -768,6 +769,133 @@ CommandInterpreter::printError()
}
}
+/*
+ * print log event from mgmsrv to console screen
+ */
+#define make_uint64(a,b) (((Uint64)(a)) + (((Uint64)(b)) << 32))
+#define Q64(a) make_uint64(event->EVENT.a ## _lo, event->EVENT.a ## _hi)
+#define R event->source_nodeid
+#define Q(a) event->EVENT.a
+#define QVERSION getMajor(Q(version)), getMinor(Q(version)), getBuild(Q(version))
+#define NDB_LE_(a) NDB_LE_ ## a
+static void
+printLogEvent(struct ndb_logevent* event)
+{
+ switch (event->type) {
+ /**
+ * NDB_MGM_EVENT_CATEGORY_BACKUP
+ */
+#undef EVENT
+#define EVENT BackupStarted
+ case NDB_LE_BackupStarted:
+ ndbout_c("Node %u: Backup %d started from node %d",
+ R, Q(backup_id), Q(starting_node));
+ break;
+#undef EVENT
+#define EVENT BackupFailedToStart
+ case NDB_LE_BackupFailedToStart:
+ ndbout_c("Node %u: Backup request from %d failed to start. Error: %d",
+ R, Q(starting_node), Q(error));
+ break;
+#undef EVENT
+#define EVENT BackupCompleted
+ case NDB_LE_BackupCompleted:
+ ndbout_c("Node %u: Backup %u started from node %u completed\n"
+ " StartGCP: %u StopGCP: %u\n"
+ " #Records: %u #LogRecords: %u\n"
+ " Data: %u bytes Log: %u bytes", R,
+ Q(backup_id), Q(starting_node),
+ Q(start_gci), Q(stop_gci),
+ Q(n_records), Q(n_log_records),
+ Q(n_bytes), Q(n_log_bytes));
+ break;
+#undef EVENT
+#define EVENT BackupAborted
+ case NDB_LE_BackupAborted:
+ ndbout_c("Node %u: Backup %d started from %d has been aborted. Error: %d",
+ R, Q(backup_id), Q(starting_node), Q(error));
+ break;
+ /**
+ * NDB_MGM_EVENT_CATEGORY_STARTUP
+ */
+#undef EVENT
+#define EVENT NDBStartStarted
+ case NDB_LE_NDBStartStarted:
+ ndbout_c("Node %u: Start initiated (version %d.%d.%d)",
+ R, QVERSION);
+ break;
+#undef EVENT
+#define EVENT NDBStartCompleted
+ case NDB_LE_NDBStartCompleted:
+ ndbout_c("Node %u: Started (version %d.%d.%d)",
+ R, QVERSION);
+ break;
+#undef EVENT
+#define EVENT NDBStopStarted
+ case NDB_LE_NDBStopStarted:
+ ndbout_c("Node %u: %s shutdown initiated", R,
+ (Q(stoptype) == 1 ? "Cluster" : "Node"));
+ break;
+#undef EVENT
+#define EVENT NDBStopCompleted
+ case NDB_LE_NDBStopCompleted:
+ {
+ BaseString action_str("");
+ BaseString signum_str("");
+ getRestartAction(Q(action), action_str);
+ if (Q(signum))
+ signum_str.appfmt(" Initiated by signal %d.",
+ Q(signum));
+ ndbout_c("Node %u: Node shutdown completed%s.%s",
+ R, action_str.c_str(), signum_str.c_str());
+ }
+ break;
+#undef EVENT
+#define EVENT NDBStopForced
+ case NDB_LE_NDBStopForced:
+ {
+ BaseString action_str("");
+ BaseString reason_str("");
+ BaseString sphase_str("");
+ int signum = Q(signum);
+ int error = Q(error);
+ int sphase = Q(sphase);
+ int extra = Q(extra);
+ getRestartAction(Q(action), action_str);
+ if (signum)
+ reason_str.appfmt(" Initiated by signal %d.", signum);
+ if (error)
+ {
+ ndbd_exit_classification cl;
+ ndbd_exit_status st;
+ const char *msg = ndbd_exit_message(error, &cl);
+ const char *cl_msg = ndbd_exit_classification_message(cl, &st);
+ const char *st_msg = ndbd_exit_status_message(st);
+ reason_str.appfmt(" Caused by error %d: \'%s(%s). %s\'.",
+ error, msg, cl_msg, st_msg);
+ if (extra != 0)
+ reason_str.appfmt(" (extra info %d)", extra);
+ }
+ if (sphase < 255)
+ sphase_str.appfmt(" Occured during startphase %u.", sphase);
+ ndbout_c("Node %u: Forced node shutdown completed%s.%s%s",
+ R, action_str.c_str(), sphase_str.c_str(),
+ reason_str.c_str());
+ }
+ break;
+#undef EVENT
+#define EVENT StopAborted
+ case NDB_LE_NDBStopAborted:
+ ndbout_c("Node %u: Node shutdown aborted", R);
+ break;
+ /**
+ * default nothing to print
+ */
+ default:
+ break;
+ }
+}
+
//*****************************************************************************
//*****************************************************************************
@@ -784,27 +912,21 @@ event_thread_run(void* p)
int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP,
1, NDB_MGM_EVENT_CATEGORY_STARTUP,
0 };
- int fd = ndb_mgm_listen_event(handle, filter);
- if (fd != NDB_INVALID_SOCKET)
+
+ NdbLogEventHandle log_handle= NULL;
+ struct ndb_logevent log_event;
+
+ log_handle= ndb_mgm_create_logevent_handle(handle, filter);
+ if (log_handle)
{
do_event_thread= 1;
- char *tmp= 0;
- char buf[1024];
- SocketInputStream in(fd,10);
do {
- if (tmp == 0) NdbSleep_MilliSleep(10);
- if((tmp = in.gets(buf, 1024)))
- {
- const char ping_token[]= "<PING>";
- if (memcmp(ping_token,tmp,sizeof(ping_token)-1))
- if(tmp && strlen(tmp))
- {
- Guard g(printmutex);
- ndbout << tmp;
- }
- }
+ if (ndb_logevent_get_next(log_handle, &log_event, 2000) <= 0)
+ continue;
+ Guard g(printmutex);
+ printLogEvent(&log_event);
} while(do_event_thread);
- NDB_CLOSE_SOCKET(fd);
+ ndb_mgm_destroy_logevent_handle(&log_handle);
}
else
{
@@ -1054,7 +1176,7 @@ CommandInterpreter::execute_impl(const char *_line, bool interactive)
else if(strcasecmp(firstToken, "START") == 0 &&
allAfterFirstToken != NULL &&
strncasecmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){
- m_error= executeStartBackup(allAfterFirstToken);
+ m_error= executeStartBackup(allAfterFirstToken, interactive);
DBUG_RETURN(true);
}
else if(strcasecmp(firstToken, "ABORT") == 0 &&
@@ -2531,20 +2653,11 @@ CommandInterpreter::executeEventReporting(int processId,
* Backup
*****************************************************************************/
int
-CommandInterpreter::executeStartBackup(char* parameters)
+CommandInterpreter::executeStartBackup(char* parameters, bool interactive)
{
struct ndb_mgm_reply reply;
unsigned int backupId;
-#if 0
- int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0 };
- int fd = ndb_mgm_listen_event(m_mgmsrv, filter);
- if (fd < 0)
- {
- ndbout << "Initializing start of backup failed" << endl;
- printError();
- return fd;
- }
-#endif
+
Vector<BaseString> args;
{
BaseString(parameters).split(args);
@@ -2557,25 +2670,20 @@ CommandInterpreter::executeStartBackup(char* parameters)
int sz= args.size();
int result;
- if (sz == 2 &&
- args[1] == "NOWAIT")
+ int flags = 2;
+ if (sz == 2 && args[1] == "NOWAIT")
{
- result = ndb_mgm_start_backup(m_mgmsrv, 0, &backupId, &reply);
+ flags = 0;
}
- else if (sz == 1 ||
- (sz == 3 &&
- args[1] == "WAIT" &&
- args[2] == "COMPLETED"))
+ else if (sz == 1 || (sz == 3 && args[1] == "WAIT" && args[2] == "COMPLETED"))
{
+ flags = 2;
ndbout_c("Waiting for completed, this may take several minutes");
- result = ndb_mgm_start_backup(m_mgmsrv, 2, &backupId, &reply);
}
- else if (sz == 3 &&
- args[1] == "WAIT" &&
- args[2] == "STARTED")
+ else if (sz == 3 && args[1] == "WAIT" && args[2] == "STARTED")
{
ndbout_c("Waiting for started, this may take several minutes");
- result = ndb_mgm_start_backup(m_mgmsrv, 1, &backupId, &reply);
+ flags = 1;
}
else
{
@@ -2583,48 +2691,80 @@ CommandInterpreter::executeStartBackup(char* parameters)
return -1;
}
+ NdbLogEventHandle log_handle= NULL;
+ struct ndb_logevent log_event;
+ if (flags == 2 && !interactive)
+ {
+ int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0, 0 };
+ log_handle = ndb_mgm_create_logevent_handle(m_mgmsrv, filter);
+ if (!log_handle)
+ {
+ ndbout << "Initializing start of backup failed" << endl;
+ printError();
+ return -1;
+ }
+ }
+ result = ndb_mgm_start_backup(m_mgmsrv, flags, &backupId, &reply);
+
if (result != 0) {
ndbout << "Backup failed" << endl;
printError();
-#if 0
- close(fd);
-#endif
+
+ if (log_handle)
+ ndb_mgm_destroy_logevent_handle(&log_handle);
return result;
}
-#if 0
- ndbout_c("Waiting for completed, this may take several minutes");
- char *tmp;
- char buf[1024];
+
+ /**
+ * If interactive, event listner thread is already running
+ */
+ if (log_handle && !interactive)
{
- SocketInputStream in(fd);
int count = 0;
+ int retry = 0;
do {
- tmp = in.gets(buf, 1024);
- if(tmp)
+ if (ndb_logevent_get_next(log_handle, &log_event, 60000) > 0)
{
- ndbout << tmp;
- unsigned int id;
- if(sscanf(tmp, "%*[^:]: Backup %d ", &id) == 1 && id == backupId){
- count++;
- }
+ int print = 0;
+ switch (log_event.type) {
+ case NDB_LE_BackupStarted:
+ if (log_event.BackupStarted.backup_id == backupId)
+ print = 1;
+ break;
+ case NDB_LE_BackupCompleted:
+ if (log_event.BackupCompleted.backup_id == backupId)
+ print = 1;
+ break;
+ case NDB_LE_BackupAborted:
+ if (log_event.BackupAborted.backup_id == backupId)
+ print = 1;
+ break;
+ default:
+ break;
+ }
+ if (print)
+ {
+ Guard g(m_print_mutex);
+ printLogEvent(&log_event);
+ count++;
+ }
}
- } while(count < 2);
- }
+ else
+ {
+ retry++;
+ }
+ } while(count < 2 && retry < 3);
- SocketInputStream in(fd, 10);
- do {
- tmp = in.gets(buf, 1024);
- if(tmp && tmp[0] != 0)
- {
- ndbout << tmp;
- }
- } while(tmp && tmp[0] != 0);
+ if (retry >= 3)
+ ndbout << "get backup event failed for " << retry << " times" << endl;
+
+ ndb_mgm_destroy_logevent_handle(&log_handle);
+ }
- close(fd);
-#endif
return 0;
}
+
int
CommandInterpreter::executeAbortBackup(char* parameters)
{
diff --git a/ndb/src/mgmclient/Makefile.am b/ndb/src/mgmclient/Makefile.am
index 8ce8bf4da45..99540160341 100644
--- a/ndb/src/mgmclient/Makefile.am
+++ b/ndb/src/mgmclient/Makefile.am
@@ -21,7 +21,8 @@ libndbmgmclient_la_LIBADD = ../mgmapi/libmgmapi.la \
../common/logger/liblogger.la \
../common/portlib/libportlib.la \
../common/util/libgeneral.la \
- ../common/portlib/libportlib.la
+ ../common/portlib/libportlib.la \
+ ../common/debugger/libtrace.la
ndb_mgm_SOURCES = main.cpp
diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp
index 449f287dc1d..dcdee3d4ea1 100644
--- a/ndb/src/ndbapi/Ndb.cpp
+++ b/ndb/src/ndbapi/Ndb.cpp
@@ -767,17 +767,27 @@ Ndb::getNodeId()
}
/****************************************************************************
-Uint64 getTupleIdFromNdb( Uint32 aTableId, Uint32 cacheSize );
-
-Parameters: aTableId : The TableId.
- cacheSize: Prefetch this many values
-Remark: Returns a new TupleId to the application.
- The TupleId comes from SYSTAB_0 where SYSKEY_0 = TableId.
- It is initialized to (TableId << 48) + 1 in NdbcntrMain.cpp.
+Uint64 getAutoIncrementValue( const char* aTableName,
+ Uint64 & tupleId,
+ Uint32 cacheSize,
+ Uint64 step,
+ Uint64 start);
+
+Parameters: aTableName (IN) : The table name.
+ autoValue (OUT) : Returns new autoincrement value
+ cacheSize (IN) : Prefetch this many values
+ step (IN) : Specifies the step between the
+ autoincrement values.
+ start (IN) : Start value for first value
+Remark: Returns a new autoincrement value to the application.
+ The autoincrement values can be increased by steps
+ (default 1) and a number of values can be prefetched
+ by specifying cacheSize (default 10).
****************************************************************************/
int
Ndb::getAutoIncrementValue(const char* aTableName,
- Uint64 & tupleId, Uint32 cacheSize)
+ Uint64 & autoValue, Uint32 cacheSize,
+ Uint64 step, Uint64 start)
{
DBUG_ENTER("Ndb::getAutoIncrementValue");
BaseString internal_tabname(internalize_table_name(aTableName));
@@ -788,15 +798,17 @@ Ndb::getAutoIncrementValue(const char* aTableName,
theError.code = theDictionary->getNdbError().code;
DBUG_RETURN(-1);
}
- if (getTupleIdFromNdb(info, tupleId, cacheSize) == -1)
+ DBUG_PRINT("info", ("step %lu", (ulong) step));
+ if (getTupleIdFromNdb(info, autoValue, cacheSize, step, start) == -1)
DBUG_RETURN(-1);
- DBUG_PRINT("info", ("value %lu", (ulong) tupleId));
+ DBUG_PRINT("info", ("value %lu", (ulong) autoValue));
DBUG_RETURN(0);
}
int
Ndb::getAutoIncrementValue(const NdbDictionary::Table * aTable,
- Uint64 & tupleId, Uint32 cacheSize)
+ Uint64 & autoValue, Uint32 cacheSize,
+ Uint64 step, Uint64 start)
{
DBUG_ENTER("Ndb::getAutoIncrementValue");
assert(aTable != 0);
@@ -809,36 +821,73 @@ Ndb::getAutoIncrementValue(const NdbDictionary::Table * aTable,
theError.code = theDictionary->getNdbError().code;
DBUG_RETURN(-1);
}
- if (getTupleIdFromNdb(info, tupleId, cacheSize) == -1)
+ DBUG_PRINT("info", ("step %lu", (ulong) step));
+ if (getTupleIdFromNdb(info, autoValue, cacheSize, step, start) == -1)
DBUG_RETURN(-1);
- DBUG_PRINT("info", ("value %lu", (ulong)tupleId));
+ DBUG_PRINT("info", ("value %lu", (ulong) autoValue));
DBUG_RETURN(0);
}
int
Ndb::getTupleIdFromNdb(Ndb_local_table_info* info,
- Uint64 & tupleId, Uint32 cacheSize)
+ Uint64 & tupleId, Uint32 cacheSize,
+ Uint64 step, Uint64 start)
{
+/*
+ Returns a new TupleId to the application.
+ The TupleId comes from SYSTAB_0 where SYSKEY_0 = TableId.
+ It is initialized to (TableId << 48) + 1 in NdbcntrMain.cpp.
+ In most cases step= start= 1, in which case we get:
+ 1,2,3,4,5,...
+ If step=10 and start=5 and first number is 1, we get:
+ 5,15,25,35,...
+*/
DBUG_ENTER("Ndb::getTupleIdFromNdb");
- if (info->m_first_tuple_id != info->m_last_tuple_id)
+ DBUG_PRINT("info", ("Step %lu (%lu,%lu)", (ulong) step, (ulong) info->m_first_tuple_id, (ulong) info->m_last_tuple_id));
+ /*
+ Check if the next value can be taken from the pre-fetched
+ sequence.
+ */
+ if (info->m_first_tuple_id != info->m_last_tuple_id &&
+ info->m_first_tuple_id + step <= info->m_last_tuple_id)
{
assert(info->m_first_tuple_id < info->m_last_tuple_id);
- tupleId = ++info->m_first_tuple_id;
- DBUG_PRINT("info", ("next cached value %lu", (ulong)tupleId));
+ info->m_first_tuple_id += step;
+ tupleId = info->m_first_tuple_id;
+ DBUG_PRINT("info", ("Next cached value %lu", (ulong) tupleId));
}
else
{
+ /*
+ If start value is greater than step it is ignored
+ */
+ Uint64 offset = (start > step) ? 1 : start;
+
+ /*
+ Pre-fetch a number of values depending on cacheSize
+ */
if (cacheSize == 0)
cacheSize = 1;
- DBUG_PRINT("info", ("reading %u values from database", (uint)cacheSize));
+
+ DBUG_PRINT("info", ("Reading %u values from database", (uint)cacheSize));
/*
* reserve next cacheSize entries in db. adds cacheSize to NEXTID
- * and returns first tupleId in the new range.
+ * and returns first tupleId in the new range. If tupleId's are
+ * incremented in steps then multiply the cacheSize with step size.
*/
- Uint64 opValue = cacheSize;
+ Uint64 opValue = cacheSize * step;
+
if (opTupleIdOnNdb(info, opValue, 0) == -1)
DBUG_RETURN(-1);
- tupleId = opValue;
+ DBUG_PRINT("info", ("Next value fetched from database %lu", (ulong) opValue));
+ DBUG_PRINT("info", ("Increasing %lu by offset %lu, increment is %lu", (ulong) (ulong) opValue, (ulong) offset, (ulong) step));
+ Uint64 current, next;
+ Uint64 div = ((Uint64) (opValue + step - offset)) / step;
+ next = div * step + offset;
+ current = (next < step) ? next : next - step;
+ tupleId = (opValue <= current) ? current : next;
+ DBUG_PRINT("info", ("Returning %lu", (ulong) tupleId));
+ info->m_first_tuple_id = tupleId;
}
DBUG_RETURN(0);
}
@@ -1065,9 +1114,9 @@ Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op)
}
else
{
- DBUG_PRINT("info",
- ("Setting next auto increment value (db) to %lu",
- (ulong)opValue));
+ DBUG_PRINT("info",
+ ("Setting next auto increment value (db) to %lu",
+ (ulong)opValue));
info->m_first_tuple_id = info->m_last_tuple_id = opValue - 1;
}
break;
diff --git a/ndb/test/include/NdbRestarter.hpp b/ndb/test/include/NdbRestarter.hpp
index 3307cf3e424..15da0218a16 100644
--- a/ndb/test/include/NdbRestarter.hpp
+++ b/ndb/test/include/NdbRestarter.hpp
@@ -67,6 +67,8 @@ public:
int getRandomNodeOtherNodeGroup(int nodeId, int randomNumber);
int getRandomNotMasterNodeId(int randomNumber);
+ NdbMgmHandle handle;
+
protected:
int waitClusterState(ndb_mgm_node_status _status,
@@ -89,7 +91,6 @@ protected:
bool connected;
BaseString addr;
- NdbMgmHandle handle;
ndb_mgm_configuration * m_config;
protected:
ndb_mgm_configuration * getConfig();
diff --git a/ndb/test/ndbapi/testNdbApi.cpp b/ndb/test/ndbapi/testNdbApi.cpp
index aee668039fe..5307a5bcd1c 100644
--- a/ndb/test/ndbapi/testNdbApi.cpp
+++ b/ndb/test/ndbapi/testNdbApi.cpp
@@ -1306,6 +1306,36 @@ int runTestExecuteAsynch(NDBT_Context* ctx, NDBT_Step* step){
template class Vector<NdbScanOperation*>;
+int
+runBug28443(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int result = NDBT_OK;
+ int records = ctx->getNumRecords();
+
+ NdbRestarter restarter;
+
+ restarter.insertErrorInAllNodes(9003);
+
+ for (Uint32 i = 0; i<ctx->getNumLoops(); i++)
+ {
+ HugoTransactions hugoTrans(*ctx->getTab());
+ if (hugoTrans.loadTable(GETNDB(step), records, 2048) != 0)
+ {
+ result = NDBT_FAILED;
+ goto done;
+ }
+ if (runClearTable(ctx, step) != 0)
+ {
+ result = NDBT_FAILED;
+ goto done;
+ }
+ }
+
+done:
+ restarter.insertErrorInAllNodes(9003);
+
+ return result;
+}
NDBT_TESTSUITE(testNdbApi);
TESTCASE("MaxNdb",
@@ -1392,10 +1422,18 @@ TESTCASE("Scan_4006",
INITIALIZER(runScan_4006);
FINALIZER(runClearTable);
}
+TESTCASE("Bug28443",
+ ""){
+ INITIALIZER(runBug28443);
+}
TESTCASE("ExecuteAsynch",
"Check that executeAsync() works (BUG#27495)\n"){
INITIALIZER(runTestExecuteAsynch);
}
+TESTCASE("Bug28443",
+ ""){
+ INITIALIZER(runBug28443);
+}
NDBT_TESTSUITE_END(testNdbApi);
int main(int argc, const char** argv){
diff --git a/ndb/test/ndbapi/testNodeRestart.cpp b/ndb/test/ndbapi/testNodeRestart.cpp
index fd5d6f15e71..8c76efec3b3 100644
--- a/ndb/test/ndbapi/testNodeRestart.cpp
+++ b/ndb/test/ndbapi/testNodeRestart.cpp
@@ -1215,6 +1215,84 @@ runBug27283(NDBT_Context* ctx, NDBT_Step* step)
}
pos = 0;
}
+
+ return NDBT_OK;
+}
+
+int
+runBug28717(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int result = NDBT_OK;
+ int loops = ctx->getNumLoops();
+ int records = ctx->getNumRecords();
+ Ndb* pNdb = GETNDB(step);
+ NdbRestarter res;
+
+ if (res.getNumDbNodes() < 4)
+ {
+ return NDBT_OK;
+ }
+
+ int master = res.getMasterNodeId();
+ int node0 = res.getRandomNodeOtherNodeGroup(master, rand());
+ int node1 = res.getRandomNodeSameNodeGroup(node0, rand());
+
+ ndbout_c("master: %d node0: %d node1: %d", master, node0, node1);
+
+ if (res.restartOneDbNode(node0, false, true, true))
+ {
+ return NDBT_FAILED;
+ }
+
+ {
+ int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_CHECKPOINT, 0 };
+ NdbLogEventHandle handle =
+ ndb_mgm_create_logevent_handle(res.handle, filter);
+
+
+ int dump[] = { DumpStateOrd::DihStartLcpImmediately };
+ struct ndb_logevent event;
+
+ for (Uint32 i = 0; i<3; i++)
+ {
+ res.dumpStateOneNode(master, dump, 1);
+ while(ndb_logevent_get_next(handle, &event, 0) >= 0 &&
+ event.type != NDB_LE_LocalCheckpointStarted);
+ while(ndb_logevent_get_next(handle, &event, 0) >= 0 &&
+ event.type != NDB_LE_LocalCheckpointCompleted);
+ }
+ }
+
+ if (res.waitNodesNoStart(&node0, 1))
+ return NDBT_FAILED;
+
+ int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
+
+ if (res.dumpStateOneNode(node0, val2, 2))
+ return NDBT_FAILED;
+
+ if (res.insertErrorInNode(node0, 5010))
+ return NDBT_FAILED;
+
+ if (res.insertErrorInNode(node1, 1001))
+ return NDBT_FAILED;
+
+ if (res.startNodes(&node0, 1))
+ return NDBT_FAILED;
+
+ NdbSleep_SecSleep(3);
+
+ if (res.insertErrorInNode(node1, 0))
+ return NDBT_FAILED;
+
+ if (res.waitNodesNoStart(&node0, 1))
+ return NDBT_FAILED;
+
+ if (res.startNodes(&node0, 1))
+ return NDBT_FAILED;
+
+ if (res.waitClusterStarted())
+ return NDBT_FAILED;
return NDBT_OK;
}
@@ -1552,6 +1630,9 @@ TESTCASE("Bug27003", ""){
TESTCASE("Bug27283", ""){
INITIALIZER(runBug27283);
}
+TESTCASE("Bug28717", ""){
+ INITIALIZER(runBug28717);
+}
NDBT_TESTSUITE_END(testNodeRestart);
int main(int argc, const char** argv){
diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt
index e1a69d923cb..56c2bccfd8c 100644
--- a/ndb/test/run-test/daily-basic-tests.txt
+++ b/ndb/test/run-test/daily-basic-tests.txt
@@ -508,6 +508,10 @@ max-time: 1500
cmd: testDict
args: -n CreateAndDrop
+max-time: 1000
+cmd: testNodeRestart
+args: -n Bug28717 T1
+
max-time: 1500
cmd: testDict
args: -n CreateAndDropAtRandom -l 200 T1
@@ -629,6 +633,10 @@ max-time: 500
cmd: testNdbApi
args: -n ExecuteAsynch T1
+max-time: 1000
+cmd: testNdbApi
+args: -n BugBug28443
+
#max-time: 500
#cmd: testInterpreter
#args: T1
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
index bca0581ecbc..e9113b098da 100755
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -13,20 +13,30 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+# Build mysql_fix_privilege_tables.sql
+ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/scripts/mysql_fix_privilege_tables.sql
+ COMMAND copy /b
+ mysql_system_tables.sql + mysql_system_tables_fix.sql
+ mysql_fix_privilege_tables.sql
+ DEPENDS
+ ${PROJECT_SOURCE_DIR}/scripts/mysql_system_tables.sql
+ ${PROJECT_SOURCE_DIR}/scripts/mysql_system_tables_fix.sql)
+# Build comp_sql - used for embedding SQL in C or C++ programs
ADD_EXECUTABLE(comp_sql comp_sql.c)
TARGET_LINK_LIBRARIES(comp_sql dbug mysys strings)
-# Build comp_sql - used for embedding SQL in C or C++ programs
+# Use comp_sql to build mysql_fix_privilege_tables_sql.c
GET_TARGET_PROPERTY(COMP_SQL_EXE comp_sql LOCATION)
ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/scripts/mysql_fix_privilege_tables_sql.c
COMMAND ${COMP_SQL_EXE}
mysql_fix_privilege_tables
mysql_fix_privilege_tables.sql
- mysql_fix_privilege_tables_sql.c
+ mysql_fix_privilege_tables_sql.c
DEPENDS comp_sql ${PROJECT_SOURCE_DIR}/scripts/mysql_fix_privilege_tables.sql)
+# Add dummy target for the above to be built
ADD_CUSTOM_TARGET(GenFixPrivs
ALL
DEPENDS ${PROJECT_SOURCE_DIR}/scripts/mysql_fix_privilege_tables_sql.c)
diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh
index e8bf39bd016..77f51c51c19 100644
--- a/scripts/make_binary_distribution.sh
+++ b/scripts/make_binary_distribution.sh
@@ -102,11 +102,41 @@ case $system in
;;
esac
+# This is needed to prefer GNU tar over platform tar because that can't
+# always handle long filenames
+
+PATH_DIRS=`echo $PATH | \
+ sed -e 's/^:/. /' -e 's/:$/ ./' -e 's/::/ . /g' -e 's/:/ /g' `
+
+which_1 ()
+{
+ for cmd
+ do
+ for d in $PATH_DIRS
+ do
+ for file in $d/$cmd
+ do
+ if [ -x $file -a ! -d $file ] ; then
+ echo $file
+ exit 0
+ fi
+ done
+ done
+ done
+ exit 1
+}
+
+tar=`which_1 gnutar gtar`
+if [ "$?" = "1" -o x"$tar" = x"" ] ; then
+ tar=tar
+fi
+
mkdir $BASE $BASE/bin $BASE/docs \
$BASE/include $BASE/lib $BASE/support-files $BASE/share $BASE/scripts \
$BASE/mysql-test $BASE/mysql-test/t $BASE/mysql-test/r \
- $BASE/mysql-test/include $BASE/mysql-test/std_data $BASE/mysql-test/lib
+ $BASE/mysql-test/include $BASE/mysql-test/std_data $BASE/mysql-test/lib \
+ $BASE/mysql-test/suite
if [ $BASE_SYSTEM != "netware" ] ; then
mkdir $BASE/share/mysql $BASE/tests $BASE/sql-bench $BASE/man \
@@ -117,8 +147,8 @@ fi
# Copy files if they exists, warn for those that don't.
# Note that when listing files to copy, we might list the file name
-# twice, once in the directory location where it is build, and a
-# second time in the ".libs" location. In the case the firs one
+# twice, once in the directory location where it is built, and a
+# second time in the ".libs" location. In the case the first one
# is a wrapper script, the second one will overwrite it with the
# binary file.
copyfileto()
@@ -274,6 +304,13 @@ $CP mysql-test/t/*.test mysql-test/t/*.imtest \
$CP mysql-test/r/*.result mysql-test/r/*.require \
$BASE/mysql-test/r
+# Copy the additional suites "as is", they are in flux
+$tar cf - mysql-test/suite | ( cd $BASE ; $tar xf - )
+# Clean up if we did this from a bk tree
+if [ -d mysql-test/SCCS ] ; then
+ find $BASE/mysql-test -name SCCS -print | xargs rm -rf
+fi
+
if [ $BASE_SYSTEM != "netware" ] ; then
chmod a+x $BASE/bin/*
copyfileto $BASE/bin scripts/*
@@ -374,41 +411,12 @@ if [ x$DEBUG = x1 ] ; then
exit
fi
-# This is needed to prefere gnu tar instead of tar because tar can't
-# always handle long filenames
-
-PATH_DIRS=`echo $PATH | \
- sed -e 's/^:/. /' -e 's/:$/ ./' -e 's/::/ . /g' -e 's/:/ /g' `
-
-which_1 ()
-{
- for cmd
- do
- for d in $PATH_DIRS
- do
- for file in $d/$cmd
- do
- if [ -x $file -a ! -d $file ] ; then
- echo $file
- exit 0
- fi
- done
- done
- done
- exit 1
-}
-
if [ $BASE_SYSTEM != "netware" ] ; then
#
# Create the result tar file
#
- tar=`which_1 gnutar gtar`
- if [ "$?" = "1" -o x"$tar" = x"" ] ; then
- tar=tar
- fi
-
echo "Using $tar to create archive"
OPT=cvf
diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist
index 30127b0043f..beb274ca1a3 100755
--- a/scripts/make_win_bin_dist
+++ b/scripts/make_win_bin_dist
@@ -239,25 +239,45 @@ if [ x"$PACK_EMBEDDED" = x"" -a \
fi
# ----------------------------------------------------------------------
-# FIXME why not copy it all in "include"?!
+# Note: Make sure to sync with include/Makefile.am and WiX installer
+# XML specifications
# ----------------------------------------------------------------------
mkdir -p $DESTDIR/include
-cp include/conf*.h \
- include/mysql*.h \
- include/errmsg.h \
- include/my_alloc.h \
- include/my_getopt.h \
- include/my_sys.h \
+cp include/mysql.h \
+ include/mysql_com.h \
+ include/mysql_time.h \
include/my_list.h \
- include/my_pthread.h \
+ include/my_alloc.h \
+ include/typelib.h \
include/my_dbug.h \
include/m_string.h \
- include/m_ctype.h \
- include/my_global.h \
+ include/my_sys.h \
+ include/my_xml.h \
+ include/mysql_embed.h \
+ include/my_pthread.h \
+ include/my_no_pthread.h \
include/raid.h \
- include/typelib.h $DESTDIR/include/
-cp libmysql/libmysql.def $DESTDIR/include/
+ include/decimal.h \
+ include/errmsg.h \
+ include/my_global.h \
+ include/my_net.h \
+ include/my_getopt.h \
+ include/sslopt-longopts.h \
+ include/my_dir.h \
+ include/sslopt-vars.h \
+ include/sslopt-case.h \
+ include/sql_common.h \
+ include/keycache.h \
+ include/m_ctype.h \
+ include/my_attribute.h \
+ include/mysqld_error.h \
+ include/sql_state.h \
+ include/mysqld_ername.h \
+ include/mysql_version.h \
+ include/config-win.h \
+ libmysql/libmysql.def \
+ $DESTDIR/include/
# ----------------------------------------------------------------------
# Client libraries, and other libraries
diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql
index 205bc93efea..c8334339b32 100644
--- a/scripts/mysql_system_tables_fix.sql
+++ b/scripts/mysql_system_tables_fix.sql
@@ -9,6 +9,7 @@
# this sql script.
# On windows you should do 'mysql --force mysql < mysql_fix_privilege_tables.sql'
+set sql_mode='';
set storage_engine=MyISAM;
ALTER TABLE user add File_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL;
diff --git a/server-tools/instance-manager/mysql_connection.cc b/server-tools/instance-manager/mysql_connection.cc
index 3e1694e24ee..2b377d60ad0 100644
--- a/server-tools/instance-manager/mysql_connection.cc
+++ b/server-tools/instance-manager/mysql_connection.cc
@@ -112,8 +112,8 @@ C_MODE_START
void my_net_local_init(NET *net)
{
net->max_packet= net_buffer_length;
- net->read_timeout= net_read_timeout;
- net->write_timeout= net_write_timeout;
+ my_net_set_read_timeout(net, (uint)net_read_timeout);
+ my_net_set_write_timeout(net, (uint)net_write_timeout);
net->retry_count= net_retry_count;
net->max_packet_size= max_allowed_packet;
}
diff --git a/sql-common/client.c b/sql-common/client.c
index 3342db4bcfe..f8d52e02196 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -402,7 +402,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
HANDLE handle_file_map = NULL;
ulong connect_number;
char connect_number_char[22], *p;
- char tmp[64];
+ char *tmp= NULL;
char *suffix_pos;
DWORD error_allow = 0;
DWORD error_code = 0;
@@ -410,13 +410,19 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
char *shared_memory_base_name = mysql->options.shared_memory_base_name;
/*
+ get enough space base-name + '_' + longest suffix we might ever send
+ */
+ if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L, MYF(MY_FAE))))
+ goto err;
+
+ /*
The name of event and file-mapping events create agree next rule:
shared_memory_base_name+unique_part
Where:
shared_memory_base_name is unique value for each server
unique_part is uniquel value for each object (events and file-mapping)
*/
- suffix_pos = strxmov(tmp,shared_memory_base_name,"_",NullS);
+ suffix_pos = strxmov(tmp, "Global\\", shared_memory_base_name, "_", NullS);
strmov(suffix_pos, "CONNECT_REQUEST");
if (!(event_connect_request= OpenEvent(event_access_rights, FALSE, tmp)))
{
@@ -470,8 +476,8 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
unique_part is uniquel value for each object (events and file-mapping)
number_of_connection is number of connection between server and client
*/
- suffix_pos = strxmov(tmp,shared_memory_base_name,"_",connect_number_char,
- "_",NullS);
+ suffix_pos = strxmov(tmp, "Global\\", shared_memory_base_name, "_", connect_number_char,
+ "_", NullS);
strmov(suffix_pos, "DATA");
if ((handle_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL)
{
@@ -551,6 +557,8 @@ err2:
CloseHandle(handle_file_map);
}
err:
+ if (tmp)
+ my_free(tmp, MYF(0));
if (error_allow)
error_code = GetLastError();
if (event_connect_request)
@@ -2047,13 +2055,11 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
/* If user set read_timeout, let it override the default */
if (mysql->options.read_timeout)
- net->read_timeout= mysql->options.read_timeout;
- vio_timeout(net->vio, 0, net->read_timeout);
+ my_net_set_read_timeout(net, mysql->options.read_timeout);
/* If user set write_timeout, let it override the default */
if (mysql->options.write_timeout)
- net->write_timeout= mysql->options.write_timeout;
- vio_timeout(net->vio, 1, net->write_timeout);
+ my_net_set_write_timeout(net, mysql->options.write_timeout);
if (mysql->options.max_allowed_packet)
net->max_packet_size= mysql->options.max_allowed_packet;
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index 4032c273e35..f5d5828e024 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -727,7 +727,39 @@ void init_time(void)
}
- /* Calculate nr of day since year 0 in new date-system (from 1615) */
+/*
+ Handle 2 digit year conversions
+
+ SYNOPSIS
+ year_2000_handling()
+ year 2 digit year
+
+ RETURN
+ Year between 1970-2069
+*/
+
+uint year_2000_handling(uint year)
+{
+ if ((year=year+1900) < 1900+YY_PART_YEAR)
+ year+=100;
+ return year;
+}
+
+
+/*
+ Calculate nr of day since year 0 in new date-system (from 1615)
+
+ SYNOPSIS
+ calc_daynr()
+ year Year (exact 4 digit year, no year conversions)
+ month Month
+ day Day
+
+ NOTES: 0000-00-00 is a valid date, and will return 0
+
+ RETURN
+ Days since 0000-00-00
+*/
long calc_daynr(uint year,uint month,uint day)
{
@@ -1120,6 +1152,7 @@ longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
ok:
part1=(long) (nr/LL(1000000));
part2=(long) (nr - (longlong) part1*LL(1000000));
+ bzero((char*) time_res, sizeof(*time_res));
time_res->year= (int) (part1/10000L); part1%=10000L;
time_res->month= (int) part1 / 100;
time_res->day= (int) part1 % 100;
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index e77b4c5765e..1f02e3afc67 100755
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -86,7 +86,7 @@ TARGET_LINK_LIBRARIES(mysqld heap myisam myisammrg mysys yassl zlib dbug yassl
taocrypt strings vio regex wsock32)
IF(EMBED_MANIFESTS)
- MYSQL_EMBED_MANIFEST("mysqld" "requireAdministrator")
+ MYSQL_EMBED_MANIFEST("mysqld" "asInvoker")
ENDIF(EMBED_MANIFESTS)
IF(WITH_EXAMPLE_STORAGE_ENGINE)
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 9be3bf93746..fae35222128 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -43,7 +43,8 @@ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \
@innodb_system_libs@ \
@ndbcluster_libs@ @ndbcluster_system_libs@ \
$(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \
- $(yassl_libs) $(openssl_libs)
+ $(yassl_libs) $(openssl_libs) \
+ @MYSQLD_EXTRA_LIBS@
noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
item_strfunc.h item_timefunc.h item_uniq.h \
diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc
index 00f927aa7b7..2c5226222e2 100644
--- a/sql/examples/ha_tina.cc
+++ b/sql/examples/ha_tina.cc
@@ -301,7 +301,7 @@ ha_tina::ha_tina(TABLE *table_arg)
chain_size(DEFAULT_CHAIN_LENGTH), records_is_known(0)
{
/* Set our original buffers from pre-allocated memory */
- buffer.set(byte_buffer, IO_SIZE, system_charset_info);
+ buffer.set(byte_buffer, IO_SIZE, &my_charset_bin);
chain= chain_buffer;
}
@@ -447,7 +447,7 @@ int ha_tina::find_current_row(byte *buf)
else
buffer.append(*mapped_ptr);
}
- (*field)->store(buffer.ptr(), buffer.length(), system_charset_info);
+ (*field)->store(buffer.ptr(), buffer.length(), buffer.charset());
}
next_position= (end_ptr - share->mapped_file)+1;
/* Maybe use \N for null? */
diff --git a/sql/field.cc b/sql/field.cc
index d2e72371bc1..f81b1c33fa7 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1550,7 +1550,7 @@ uint Field::fill_cache_field(CACHE_FIELD *copy)
}
-bool Field::get_date(TIME *ltime,uint fuzzydate)
+bool Field::get_date(MYSQL_TIME *ltime,uint fuzzydate)
{
char buff[40];
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
@@ -1561,7 +1561,7 @@ bool Field::get_date(TIME *ltime,uint fuzzydate)
return 0;
}
-bool Field::get_time(TIME *ltime)
+bool Field::get_time(MYSQL_TIME *ltime)
{
char buff[40];
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
@@ -1578,7 +1578,7 @@ bool Field::get_time(TIME *ltime)
Needs to be changed if/when we want to support different time formats
*/
-int Field::store_time(TIME *ltime, timestamp_type type_arg)
+int Field::store_time(MYSQL_TIME *ltime, timestamp_type type_arg)
{
char buff[MAX_DATE_STRING_REP_LENGTH];
uint length= (uint) my_TIME_to_str(ltime, buff);
@@ -2504,7 +2504,7 @@ int Field_new_decimal::store_decimal(const my_decimal *decimal_value)
}
-int Field_new_decimal::store_time(TIME *ltime, timestamp_type t_type)
+int Field_new_decimal::store_time(MYSQL_TIME *ltime, timestamp_type t_type)
{
my_decimal decimal_value;
return store_value(date2my_decimal(ltime, &decimal_value));
@@ -3675,56 +3675,9 @@ int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
int Field_float::store(double nr)
{
- float j;
- int error= 0;
+ int error= truncate(&nr, FLT_MAX);
+ float j= (float)nr;
- if (isnan(nr))
- {
- j= 0;
- set_null();
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- error= 1;
- }
- else if (unsigned_flag && nr < 0)
- {
- j= 0;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- error= 1;
- }
- else
- {
- double max_value;
- if (dec >= NOT_FIXED_DEC)
- {
- max_value= FLT_MAX;
- }
- else
- {
- uint tmp=min(field_length,array_elements(log_10)-1);
- max_value= (log_10[tmp]-1)/log_10[dec];
- /*
- The following comparison is needed to not get an overflow if nr
- is close to FLT_MAX
- */
- if (fabs(nr) < FLT_MAX/10.0e+32)
- nr= floor(nr*log_10[dec]+0.5)/log_10[dec];
- }
- if (nr < -max_value)
- {
- j= (float)-max_value;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- error= 1;
- }
- else if (nr > max_value)
- {
- j= (float)max_value;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- error= 1;
- }
- else
- j= (float) nr;
- }
-
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
{
@@ -3963,48 +3916,7 @@ int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
int Field_double::store(double nr)
{
- int error= 0;
-
- if (isnan(nr))
- {
- nr= 0;
- set_null();
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- error= 1;
- }
- else if (unsigned_flag && nr < 0)
- {
- nr= 0;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- error= 1;
- }
- else
- {
- double max_value;
- if (not_fixed)
- {
- max_value= DBL_MAX;
- }
- else
- {
- uint tmp=min(field_length,array_elements(log_10)-1);
- max_value= (log_10[tmp]-1)/log_10[dec];
- if (fabs(nr) < DBL_MAX/10.0e+32)
- nr= floor(nr*log_10[dec]+0.5)/log_10[dec];
- }
- if (nr < -max_value)
- {
- nr= -max_value;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- error= 1;
- }
- else if (nr > max_value)
- {
- nr= max_value;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- error= 1;
- }
- }
+ int error= truncate(&nr, DBL_MAX);
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
@@ -4023,6 +3935,63 @@ int Field_double::store(longlong nr, bool unsigned_val)
return store(unsigned_val ? ulonglong2double((ulonglong) nr) : (double) nr);
}
+/*
+ If a field has fixed length, truncate the double argument pointed to by 'nr'
+ appropriately.
+ Also ensure that the argument is within [-max_value; max_value] range.
+*/
+
+int Field_real::truncate(double *nr, double max_value)
+{
+ int error= 1;
+ double res= *nr;
+
+ if (isnan(res))
+ {
+ res= 0;
+ set_null();
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ goto end;
+ }
+ else if (unsigned_flag && res < 0)
+ {
+ res= 0;
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ goto end;
+ }
+
+ if (!not_fixed)
+ {
+ uint order= field_length - dec;
+ uint step= array_elements(log_10) - 1;
+ max_value= 1.0;
+ for (; order > step; order-= step)
+ max_value*= log_10[step];
+ max_value*= log_10[order];
+ max_value-= 1.0 / log_10[dec];
+
+ double tmp= rint((res - floor(res)) * log_10[dec]) / log_10[dec];
+ res= floor(res) + tmp;
+ }
+
+ if (res < -max_value)
+ {
+ res= -max_value;
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ }
+ else if (res > max_value)
+ {
+ res= max_value;
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ }
+ else
+ error= 0;
+
+end:
+ *nr= res;
+ return error;
+}
+
int Field_real::store_decimal(const my_decimal *dm)
{
@@ -4285,7 +4254,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg,
const char *field_name_arg,
struct st_table *table_arg,
CHARSET_INFO *cs)
- :Field_str(ptr_arg, 19, null_ptr_arg, null_bit_arg,
+ :Field_str(ptr_arg, MAX_DATETIME_WIDTH, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg, cs)
{
/* For 4.0 MYD and 4.0 InnoDB compatibility */
@@ -4303,7 +4272,8 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg,
Field_timestamp::Field_timestamp(bool maybe_null_arg,
const char *field_name_arg,
struct st_table *table_arg, CHARSET_INFO *cs)
- :Field_str((char*) 0, 19, maybe_null_arg ? (uchar*) "": 0, 0,
+ :Field_str((char*) 0, MAX_DATETIME_WIDTH,
+ maybe_null_arg ? (uchar*) "": 0, 0,
NONE, field_name_arg, table_arg, cs)
{
/* For 4.0 MYD and 4.0 InnoDB compatibility */
@@ -4359,7 +4329,8 @@ timestamp_auto_set_type Field_timestamp::get_auto_set_type() const
int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
{
- TIME l_time;
+
+ MYSQL_TIME l_time;
my_time_t tmp= 0;
int error;
bool have_smth_to_conv;
@@ -4429,7 +4400,7 @@ int Field_timestamp::store(double nr)
int Field_timestamp::store(longlong nr, bool unsigned_val)
{
- TIME l_time;
+ MYSQL_TIME l_time;
my_time_t timestamp= 0;
int error;
my_bool in_dst_time_gap;
@@ -4486,7 +4457,7 @@ double Field_timestamp::val_real(void)
longlong Field_timestamp::val_int(void)
{
uint32 temp;
- TIME time_tmp;
+ MYSQL_TIME time_tmp;
THD *thd= table ? table->in_use : current_thd;
#ifdef WORDS_BIGENDIAN
@@ -4511,7 +4482,7 @@ longlong Field_timestamp::val_int(void)
String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
{
uint32 temp, temp2;
- TIME time_tmp;
+ MYSQL_TIME time_tmp;
THD *thd= table ? table->in_use : current_thd;
char *to;
@@ -4580,7 +4551,7 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
}
-bool Field_timestamp::get_date(TIME *ltime, uint fuzzydate)
+bool Field_timestamp::get_date(MYSQL_TIME *ltime, uint fuzzydate)
{
long temp;
THD *thd= table ? table->in_use : current_thd;
@@ -4604,7 +4575,7 @@ bool Field_timestamp::get_date(TIME *ltime, uint fuzzydate)
return 0;
}
-bool Field_timestamp::get_time(TIME *ltime)
+bool Field_timestamp::get_time(MYSQL_TIME *ltime)
{
return Field_timestamp::get_date(ltime,0);
}
@@ -4612,7 +4583,7 @@ bool Field_timestamp::get_time(TIME *ltime)
bool Field_timestamp::send_binary(Protocol *protocol)
{
- TIME tm;
+ MYSQL_TIME tm;
Field_timestamp::get_date(&tm, 0);
return protocol->store(&tm);
}
@@ -4688,7 +4659,7 @@ void Field_timestamp::set_time()
int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
{
- TIME ltime;
+ MYSQL_TIME ltime;
long tmp;
int error= 0;
int warning;
@@ -4703,9 +4674,12 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
else
{
if (warning & MYSQL_TIME_WARN_TRUNCATED)
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
+ {
+ set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED,
from, len, MYSQL_TIMESTAMP_TIME, 1);
+ error= 1;
+ }
if (warning & MYSQL_TIME_WARN_OUT_OF_RANGE)
{
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
@@ -4716,8 +4690,6 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
if (ltime.month)
ltime.day=0;
tmp=(ltime.day*24L+ltime.hour)*10000L+(ltime.minute*100+ltime.second);
- if (error > 1)
- error= 2;
}
if (ltime.neg)
@@ -4727,7 +4699,7 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
}
-int Field_time::store_time(TIME *ltime, timestamp_type time_type)
+int Field_time::store_time(MYSQL_TIME *ltime, timestamp_type time_type)
{
long tmp= ((ltime->month ? 0 : ltime->day * 24L) + ltime->hour) * 10000L +
(ltime->minute * 100 + ltime->second);
@@ -4831,8 +4803,8 @@ longlong Field_time::val_int(void)
String *Field_time::val_str(String *val_buffer,
String *val_ptr __attribute__((unused)))
{
- TIME ltime;
- val_buffer->alloc(19);
+ MYSQL_TIME ltime;
+ val_buffer->alloc(MAX_DATE_STRING_REP_LENGTH);
long tmp=(long) sint3korr(ptr);
ltime.neg= 0;
if (tmp < 0)
@@ -4855,7 +4827,7 @@ String *Field_time::val_str(String *val_buffer,
DATE_FORMAT(time, "%l.%i %p")
*/
-bool Field_time::get_date(TIME *ltime, uint fuzzydate)
+bool Field_time::get_date(MYSQL_TIME *ltime, uint fuzzydate)
{
long tmp;
THD *thd= table ? table->in_use : current_thd;
@@ -4883,7 +4855,7 @@ bool Field_time::get_date(TIME *ltime, uint fuzzydate)
}
-bool Field_time::get_time(TIME *ltime)
+bool Field_time::get_time(MYSQL_TIME *ltime)
{
long tmp=(long) sint3korr(ptr);
ltime->neg=0;
@@ -4905,7 +4877,7 @@ bool Field_time::get_time(TIME *ltime)
bool Field_time::send_binary(Protocol *protocol)
{
- TIME tm;
+ MYSQL_TIME tm;
Field_time::get_time(&tm);
tm.day= tm.hour/24; // Move hours to days
tm.hour-= tm.day*24;
@@ -5058,7 +5030,7 @@ void Field_year::sql_type(String &res) const
int Field_date::store(const char *from, uint len,CHARSET_INFO *cs)
{
- TIME l_time;
+ MYSQL_TIME l_time;
uint32 tmp;
int error;
THD *thd= table ? table->in_use : current_thd;
@@ -5114,7 +5086,7 @@ int Field_date::store(double nr)
int Field_date::store(longlong nr, bool unsigned_val)
{
- TIME not_used;
+ MYSQL_TIME not_used;
int error;
longlong initial_nr= nr;
THD *thd= table ? table->in_use : current_thd;
@@ -5155,7 +5127,7 @@ int Field_date::store(longlong nr, bool unsigned_val)
bool Field_date::send_binary(Protocol *protocol)
{
longlong tmp= Field_date::val_int();
- TIME tm;
+ MYSQL_TIME tm;
tm.year= (uint32) tmp/10000L % 10000;
tm.month= (uint32) tmp/100 % 100;
tm.day= (uint32) tmp % 100;
@@ -5192,7 +5164,7 @@ longlong Field_date::val_int(void)
String *Field_date::val_str(String *val_buffer,
String *val_ptr __attribute__((unused)))
{
- TIME ltime;
+ MYSQL_TIME ltime;
val_buffer->alloc(field_length);
int32 tmp;
#ifdef WORDS_BIGENDIAN
@@ -5261,9 +5233,26 @@ void Field_date::sql_type(String &res) const
** In number context: YYYYMMDD
****************************************************************************/
+/*
+ Store string into a date field
+
+ SYNOPSIS
+ Field_newdate::store()
+ from Date string
+ len Length of date field
+ cs Character set (not used)
+
+ RETURN
+ 0 ok
+ 1 Value was cut during conversion
+ 2 Wrong date string
+ 3 Datetime value that was cut (warning level NOTE)
+*/
+
int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
{
- TIME l_time;
+ long tmp;
+ MYSQL_TIME l_time;
int error;
THD *thd= table ? table->in_use : current_thd;
enum enum_mysql_timestamp_type ret;
@@ -5274,20 +5263,23 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
MODE_INVALID_DATES))),
&error)) <= MYSQL_TIMESTAMP_ERROR)
{
- int3store(ptr,0L);
+ tmp= 0;
error= 2;
}
else
{
- int3store(ptr, l_time.day + l_time.month*32 + l_time.year*16*32);
- if(!error && (ret != MYSQL_TIMESTAMP_DATE))
- return 2;
+ tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
+ if (!error && (ret != MYSQL_TIMESTAMP_DATE))
+ error= 3; // Datetime was cut (note)
}
if (error)
- set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
+ set_datetime_warning(error == 3 ? MYSQL_ERROR::WARN_LEVEL_NOTE :
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ WARN_DATA_TRUNCATED,
from, len, MYSQL_TIMESTAMP_DATE, 1);
+ int3store(ptr, tmp);
return error;
}
@@ -5307,7 +5299,7 @@ int Field_newdate::store(double nr)
int Field_newdate::store(longlong nr, bool unsigned_val)
{
- TIME l_time;
+ MYSQL_TIME l_time;
longlong tmp;
int error;
THD *thd= table ? table->in_use : current_thd;
@@ -5334,7 +5326,7 @@ int Field_newdate::store(longlong nr, bool unsigned_val)
}
-int Field_newdate::store_time(TIME *ltime, timestamp_type time_type)
+int Field_newdate::store_time(MYSQL_TIME *ltime, timestamp_type time_type)
{
long tmp;
int error= 0;
@@ -5348,7 +5340,7 @@ int Field_newdate::store_time(TIME *ltime, timestamp_type time_type)
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
MODE_INVALID_DATES))), &error))
{
- char buff[12];
+ char buff[MAX_DATE_STRING_REP_LENGTH];
String str(buff, sizeof(buff), &my_charset_latin1);
make_date((DATE_TIME_FORMAT *) 0, ltime, &str);
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
@@ -5368,7 +5360,7 @@ int Field_newdate::store_time(TIME *ltime, timestamp_type time_type)
bool Field_newdate::send_binary(Protocol *protocol)
{
- TIME tm;
+ MYSQL_TIME tm;
Field_newdate::get_date(&tm,0);
return protocol->store_date(&tm);
}
@@ -5416,7 +5408,7 @@ String *Field_newdate::val_str(String *val_buffer,
}
-bool Field_newdate::get_date(TIME *ltime,uint fuzzydate)
+bool Field_newdate::get_date(MYSQL_TIME *ltime,uint fuzzydate)
{
uint32 tmp=(uint32) uint3korr(ptr);
ltime->day= tmp & 31;
@@ -5429,7 +5421,7 @@ bool Field_newdate::get_date(TIME *ltime,uint fuzzydate)
}
-bool Field_newdate::get_time(TIME *ltime)
+bool Field_newdate::get_time(MYSQL_TIME *ltime)
{
return Field_newdate::get_date(ltime,0);
}
@@ -5467,7 +5459,7 @@ void Field_newdate::sql_type(String &res) const
int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs)
{
- TIME time_tmp;
+ MYSQL_TIME time_tmp;
int error;
ulonglong tmp= 0;
enum enum_mysql_timestamp_type func_res;
@@ -5519,7 +5511,7 @@ int Field_datetime::store(double nr)
int Field_datetime::store(longlong nr, bool unsigned_val)
{
- TIME not_used;
+ MYSQL_TIME not_used;
int error;
longlong initial_nr= nr;
THD *thd= table ? table->in_use : current_thd;
@@ -5554,12 +5546,12 @@ int Field_datetime::store(longlong nr, bool unsigned_val)
}
-int Field_datetime::store_time(TIME *ltime,timestamp_type time_type)
+int Field_datetime::store_time(MYSQL_TIME *ltime,timestamp_type time_type)
{
longlong tmp;
int error= 0;
/*
- We don't perform range checking here since values stored in TIME
+ We don't perform range checking here since values stored in MYSQL_TIME
structure always fit into DATETIME range.
*/
if (time_type == MYSQL_TIMESTAMP_DATE ||
@@ -5573,7 +5565,7 @@ int Field_datetime::store_time(TIME *ltime,timestamp_type time_type)
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
MODE_INVALID_DATES))), &error))
{
- char buff[19];
+ char buff[MAX_DATE_STRING_REP_LENGTH];
String str(buff, sizeof(buff), &my_charset_latin1);
make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str);
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
@@ -5599,7 +5591,7 @@ int Field_datetime::store_time(TIME *ltime,timestamp_type time_type)
bool Field_datetime::send_binary(Protocol *protocol)
{
- TIME tm;
+ MYSQL_TIME tm;
Field_datetime::get_date(&tm, TIME_FUZZY_DATE);
return protocol->store(&tm);
}
@@ -5647,7 +5639,7 @@ String *Field_datetime::val_str(String *val_buffer,
part1=(long) (tmp/LL(1000000));
part2=(long) (tmp - (ulonglong) part1*LL(1000000));
- pos=(char*) val_buffer->ptr()+19;
+ pos= (char*) val_buffer->ptr() + MAX_DATETIME_WIDTH;
*pos--=0;
*pos--= (char) ('0'+(char) (part2%10)); part2/=10;
*pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
@@ -5671,7 +5663,7 @@ String *Field_datetime::val_str(String *val_buffer,
return val_buffer;
}
-bool Field_datetime::get_date(TIME *ltime, uint fuzzydate)
+bool Field_datetime::get_date(MYSQL_TIME *ltime, uint fuzzydate)
{
longlong tmp=Field_datetime::val_int();
uint32 part1,part2;
@@ -5690,7 +5682,7 @@ bool Field_datetime::get_date(TIME *ltime, uint fuzzydate)
return (!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ? 1 : 0;
}
-bool Field_datetime::get_time(TIME *ltime)
+bool Field_datetime::get_time(MYSQL_TIME *ltime)
{
return Field_datetime::get_date(ltime,0);
}
@@ -6227,7 +6219,8 @@ uint Field_string::get_key_image(char *buff, uint length, imagetype type_arg)
length / field_charset->mbmaxlen);
memcpy(buff, ptr, bytes);
if (bytes < length)
- bzero(buff + bytes, length - bytes);
+ field_charset->cset->fill(field_charset, buff + bytes, length - bytes,
+ field_charset->pad_char);
return bytes;
}
@@ -7621,6 +7614,8 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
tmp=0;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
}
+ if (!table->in_use->count_cuted_fields)
+ err= 0;
}
else
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
@@ -8543,15 +8538,18 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
break;
case FIELD_TYPE_TIMESTAMP:
if (!fld_length)
- length= 14; /* Full date YYYYMMDDHHMMSS */
- else if (length != 19)
+ {
+ /* Compressed date YYYYMMDDHHMMSS */
+ length= MAX_DATETIME_COMPRESSED_WIDTH;
+ }
+ else if (length != MAX_DATETIME_WIDTH)
{
/*
We support only even TIMESTAMP lengths less or equal than 14
and 19 as length of 4.1 compatible representation.
*/
length= ((length+1)/2)*2; /* purecov: inspected */
- length= min(length,14); /* purecov: inspected */
+ length= min(length, MAX_DATETIME_COMPRESSED_WIDTH); /* purecov: inspected */
}
flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
if (fld_default_value)
@@ -8604,7 +8602,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
length= 10;
break;
case FIELD_TYPE_DATETIME:
- length= 19;
+ length= MAX_DATETIME_WIDTH;
break;
case FIELD_TYPE_SET:
{
@@ -9059,10 +9057,13 @@ uint32 Field_blob::max_display_length()
NOTE
This function won't produce warning and increase cut fields counter
- if count_cuted_fields == FIELD_CHECK_IGNORE for current thread.
+ if count_cuted_fields == CHECK_FIELD_IGNORE for current thread.
+
+ if count_cuted_fields == CHECK_FIELD_IGNORE then we ignore notes.
+ This allows us to avoid notes in optimisation, like convert_constant_item().
RETURN VALUE
- 1 if count_cuted_fields == FIELD_CHECK_IGNORE
+ 1 if count_cuted_fields == CHECK_FIELD_IGNORE and error level is not NOTE
0 otherwise
*/
@@ -9082,7 +9083,7 @@ Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code,
thd->row_count);
return 0;
}
- return 1;
+ return level >= MYSQL_ERROR::WARN_LEVEL_WARN;
}
@@ -9110,9 +9111,10 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
timestamp_type ts_type, int cuted_increment)
{
THD *thd= table ? table->in_use : current_thd;
- if (thd->really_abort_on_warning() ||
+ if ((thd->really_abort_on_warning() &&
+ level >= MYSQL_ERROR::WARN_LEVEL_WARN) ||
set_warning(level, code, cuted_increment))
- make_truncated_value_warning(thd, str, str_length, ts_type,
+ make_truncated_value_warning(thd, level, str, str_length, ts_type,
field_name);
}
@@ -9145,7 +9147,7 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
{
char str_nr[22];
char *str_end= longlong10_to_str(nr, str_nr, -10);
- make_truncated_value_warning(thd, str_nr, (uint) (str_end - str_nr),
+ make_truncated_value_warning(thd, level, str_nr, (uint) (str_end - str_nr),
ts_type, field_name);
}
}
@@ -9178,7 +9180,7 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
/* DBL_DIG is enough to print '-[digits].E+###' */
char str_nr[DBL_DIG + 8];
uint str_len= my_sprintf(str_nr, (str_nr, "%g", nr));
- make_truncated_value_warning(thd, str_nr, str_len, ts_type,
+ make_truncated_value_warning(thd, level, str_nr, str_len, ts_type,
field_name);
}
}
diff --git a/sql/field.h b/sql/field.h
index 47f61c1fe8b..fb6534b7b55 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -98,7 +98,7 @@ public:
virtual int store(double nr)=0;
virtual int store(longlong nr, bool unsigned_val)=0;
virtual int store_decimal(const my_decimal *d)=0;
- virtual int store_time(TIME *ltime, timestamp_type t_type);
+ virtual int store_time(MYSQL_TIME *ltime, timestamp_type t_type);
virtual double val_real(void)=0;
virtual longlong val_int(void)=0;
virtual my_decimal *val_decimal(my_decimal *);
@@ -326,8 +326,8 @@ public:
uint offset(); // Should be inline ...
void copy_from_tmp(int offset);
uint fill_cache_field(struct st_cache_field *copy);
- virtual bool get_date(TIME *ltime,uint fuzzydate);
- virtual bool get_time(TIME *ltime);
+ virtual bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
+ virtual bool get_time(MYSQL_TIME *ltime);
virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; }
virtual CHARSET_INFO *sort_charset(void) const { return charset(); }
virtual bool has_charset(void) const { return FALSE; }
@@ -360,7 +360,12 @@ public:
{
return field_length / charset()->mbmaxlen;
}
-
+ virtual geometry_type get_geometry_type()
+ {
+ /* shouldn't get here. */
+ DBUG_ASSERT(0);
+ return GEOM_GEOMETRY;
+ }
friend bool reopen_table(THD *,struct st_table *,bool);
friend int cre_myisam(my_string name, register TABLE *form, uint options,
ulonglong auto_increment_value);
@@ -453,6 +458,7 @@ public:
/* base class for float and double and decimal (old one) */
class Field_real :public Field_num {
public:
+ my_bool not_fixed;
Field_real(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
@@ -460,13 +466,16 @@ public:
struct st_table *table_arg,
uint8 dec_arg, bool zero_arg, bool unsigned_arg)
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
- field_name_arg, table_arg, dec_arg, zero_arg, unsigned_arg)
+ field_name_arg, table_arg, dec_arg, zero_arg, unsigned_arg),
+ not_fixed(dec_arg >= NOT_FIXED_DEC)
{}
int store_decimal(const my_decimal *);
my_decimal *val_decimal(my_decimal *);
+ int truncate(double *nr, double max_length);
uint32 max_display_length() { return field_length; }
+ uint size_of() const { return sizeof(*this); }
};
@@ -529,7 +538,7 @@ public:
int store(const char *to, uint length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
- int store_time(TIME *ltime, timestamp_type t_type);
+ int store_time(MYSQL_TIME *ltime, timestamp_type t_type);
int store_decimal(const my_decimal *);
double val_real(void);
longlong val_int(void);
@@ -675,7 +684,7 @@ public:
void sort_string(char *buff,uint length);
uint32 pack_length() const { return 4; }
void sql_type(String &str) const;
- uint32 max_display_length() { return 11; }
+ uint32 max_display_length() { return MY_INT32_NUM_DECIMAL_DIGITS; }
};
@@ -758,7 +767,6 @@ public:
class Field_double :public Field_real {
public:
- my_bool not_fixed;
Field_double(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
@@ -766,21 +774,18 @@ public:
uint8 dec_arg,bool zero_arg,bool unsigned_arg)
:Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg,
- dec_arg, zero_arg, unsigned_arg),
- not_fixed(dec_arg >= NOT_FIXED_DEC)
+ dec_arg, zero_arg, unsigned_arg)
{}
Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
struct st_table *table_arg, uint8 dec_arg)
:Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0,
- NONE, field_name_arg, table_arg, dec_arg, 0, 0),
- not_fixed(dec_arg >= NOT_FIXED_DEC)
+ NONE, field_name_arg, table_arg, dec_arg, 0, 0)
{}
Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
- struct st_table *table_arg, uint8 dec_arg, my_bool not_fixed_srg)
+ struct st_table *table_arg, uint8 dec_arg, my_bool not_fixed_arg)
:Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0,
- NONE, field_name_arg, table_arg, dec_arg, 0, 0),
- not_fixed(not_fixed_srg)
- {}
+ NONE, field_name_arg, table_arg, dec_arg, 0, 0)
+ {not_fixed= not_fixed_arg; }
enum_field_types type() const { return FIELD_TYPE_DOUBLE;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; }
int store(const char *to,uint length,CHARSET_INFO *charset);
@@ -795,7 +800,6 @@ public:
void sort_string(char *buff,uint length);
uint32 pack_length() const { return sizeof(double); }
void sql_type(String &str) const;
- uint size_of() const { return sizeof(*this); }
};
@@ -879,8 +883,8 @@ public:
longget(tmp,ptr);
return tmp;
}
- bool get_date(TIME *ltime,uint fuzzydate);
- bool get_time(TIME *ltime);
+ bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
+ bool get_time(MYSQL_TIME *ltime);
timestamp_auto_set_type get_auto_set_type() const;
};
@@ -953,7 +957,7 @@ public:
int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
- int store_time(TIME *ltime, timestamp_type type);
+ int store_time(MYSQL_TIME *ltime, timestamp_type type);
int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
double val_real(void);
longlong val_int(void);
@@ -965,8 +969,8 @@ public:
void sql_type(String &str) const;
bool can_be_compared_as_longlong() const { return TRUE; }
bool zero_pack() const { return 1; }
- bool get_date(TIME *ltime,uint fuzzydate);
- bool get_time(TIME *ltime);
+ bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
+ bool get_time(MYSQL_TIME *ltime);
};
@@ -985,7 +989,7 @@ public:
enum_field_types type() const { return FIELD_TYPE_TIME;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
enum Item_result cmp_type () const { return INT_RESULT; }
- int store_time(TIME *ltime, timestamp_type type);
+ int store_time(MYSQL_TIME *ltime, timestamp_type type);
int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
@@ -993,9 +997,9 @@ public:
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
- bool get_date(TIME *ltime, uint fuzzydate);
+ bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
bool send_binary(Protocol *protocol);
- bool get_time(TIME *ltime);
+ bool get_time(MYSQL_TIME *ltime);
int cmp(const char *,const char*);
void sort_string(char *buff,uint length);
uint32 pack_length() const { return 3; }
@@ -1026,7 +1030,7 @@ public:
int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
- int store_time(TIME *ltime, timestamp_type type);
+ int store_time(MYSQL_TIME *ltime, timestamp_type type);
int reset(void)
{
ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0;
@@ -1042,8 +1046,8 @@ public:
void sql_type(String &str) const;
bool can_be_compared_as_longlong() const { return TRUE; }
bool zero_pack() const { return 1; }
- bool get_date(TIME *ltime,uint fuzzydate);
- bool get_time(TIME *ltime);
+ bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
+ bool get_time(MYSQL_TIME *ltime);
};
@@ -1108,6 +1112,11 @@ public:
class Field_varstring :public Field_longstr {
public:
+ /*
+ The maximum space available in a Field_varstring, in bytes. See
+ length_bytes.
+ */
+ static const uint MAX_SIZE= UINT_MAX16;
/* Store number of bytes used to store length (1 or 2) */
uint32 length_bytes;
Field_varstring(char *ptr_arg,
@@ -1320,6 +1329,7 @@ public:
uint get_key_image(char *buff,uint length,imagetype type);
uint size_of() const { return sizeof(*this); }
int reset(void) { return !maybe_null() || Field_blob::reset(); }
+ geometry_type get_geometry_type() { return geom_type; };
};
#endif /*HAVE_SPATIAL*/
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 5670b1e0676..410db357510 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -177,8 +177,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions)
}
if (current_thd->count_cuted_fields == CHECK_FIELD_WARN)
{
- field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_NULL_TO_NOTNULL, 1);
+ field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_BAD_NULL_ERROR, 1);
return 0;
}
if (!current_thd->no_errors)
@@ -530,7 +529,21 @@ void Copy_field::set(char *to,Field *from)
}
+/*
+ To do:
+
+ If 'save\ is set to true and the 'from' is a blob field, do_copy is set to
+ do_save_blob rather than do_conv_blob. The only differences between them
+ appears to be:
+ - do_save_blob allocates and uses an intermediate buffer before calling
+ Field_blob::store. Is this in order to trigger the call to
+ well_formed_copy_nchars, by changing the pointer copy->tmp.ptr()?
+ That call will take place anyway in all known cases.
+
+ - The above causes a truncation to MAX_FIELD_WIDTH. Is this the intended
+ effect? Truncation is handled by well_formed_copy_nchars anyway.
+ */
void Copy_field::set(Field *to,Field *from,bool save)
{
if (to->type() == FIELD_TYPE_NULL)
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 23d652cb8cc..d518ddbb117 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -35,7 +35,8 @@ if (my_b_write((file),(byte*) (from),param->ref_length)) \
/* functions defined in this file */
-static char **make_char_array(register uint fields, uint length, myf my_flag);
+static char **make_char_array(char **old_pos, register uint fields,
+ uint length, myf my_flag);
static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffer_file, uint count);
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
uchar * *sort_keys, IO_CACHE *buffer_file,
@@ -202,9 +203,9 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
ulong old_memavl;
ulong keys= memavl/(param.rec_length+sizeof(char*));
param.keys=(uint) min(records+1, keys);
- if (table_sort.sort_keys ||
- (table_sort.sort_keys= (uchar **) make_char_array(param.keys, param.rec_length,
- MYF(0))))
+ if ((table_sort.sort_keys=
+ (uchar **) make_char_array((char **) table_sort.sort_keys,
+ param.keys, param.rec_length, MYF(0))))
break;
old_memavl=memavl;
if ((memavl=memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
@@ -249,7 +250,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
MYF(MY_WME)))
goto err;
- reinit_io_cache(outfile,WRITE_CACHE,0L,0,0);
+ if (reinit_io_cache(outfile,WRITE_CACHE,0L,0,0))
+ goto err;
/*
Use also the space previously used by string pointers in sort_buffer
@@ -345,14 +347,16 @@ void filesort_free_buffers(TABLE *table, bool full)
/* Make a array of string pointers */
-static char **make_char_array(register uint fields, uint length, myf my_flag)
+static char **make_char_array(char **old_pos, register uint fields,
+ uint length, myf my_flag)
{
register char **pos;
- char **old_pos,*char_pos;
+ char *char_pos;
DBUG_ENTER("make_char_array");
- if ((old_pos= (char**) my_malloc((uint) fields*(length+sizeof(char*)),
- my_flag)))
+ if (old_pos ||
+ (old_pos= (char**) my_malloc((uint) fields*(length+sizeof(char*)),
+ my_flag)))
{
pos=old_pos; char_pos=((char*) (pos+fields)) -length;
while (fields--) *(pos++) = (char_pos+= length);
@@ -369,6 +373,8 @@ static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
ulong length;
BUFFPEK *tmp;
DBUG_ENTER("read_buffpek_from_file");
+ if (count > UINT_MAX/sizeof(BUFFPEK))
+ return 0; /* sizeof(BUFFPEK)*count will overflow */
tmp=(BUFFPEK*) my_malloc(length=sizeof(BUFFPEK)*count, MYF(MY_WME));
if (tmp)
{
@@ -600,6 +606,9 @@ write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
MYF(MY_WME)))
goto err; /* purecov: inspected */
+ /* check we won't have more buffpeks than we can possibly keep in memory */
+ if (my_b_tell(buffpek_pointers) + sizeof(BUFFPEK) > (ulonglong)UINT_MAX)
+ goto err;
buffpek.file_pos= my_b_tell(tempfile);
if ((ha_rows) count > param->max_rows)
count=(uint) param->max_rows; /* purecov: inspected */
@@ -907,7 +916,7 @@ static bool save_index(SORTPARAM *param, uchar **sort_keys, uint count,
int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
{
- register int i;
+ register uint i;
IO_CACHE t_file2,*from_file,*to_file,*temp;
BUFFPEK *lastbuff;
DBUG_ENTER("merge_many_buff");
@@ -922,14 +931,16 @@ int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
from_file= t_file ; to_file= &t_file2;
while (*maxbuffer >= MERGEBUFF2)
{
- reinit_io_cache(from_file,READ_CACHE,0L,0,0);
- reinit_io_cache(to_file,WRITE_CACHE,0L,0,0);
+ if (reinit_io_cache(from_file,READ_CACHE,0L,0,0))
+ goto cleanup;
+ if (reinit_io_cache(to_file,WRITE_CACHE,0L,0,0))
+ goto cleanup;
lastbuff=buffpek;
- for (i=0 ; i <= (int) *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF)
+ for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF)
{
if (merge_buffers(param,from_file,to_file,sort_buffer,lastbuff++,
buffpek+i,buffpek+i+MERGEBUFF-1,0))
- break; /* purecov: inspected */
+ goto cleanup;
}
if (merge_buffers(param,from_file,to_file,sort_buffer,lastbuff++,
buffpek+i,buffpek+ *maxbuffer,0))
@@ -941,6 +952,7 @@ int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
setup_io_cache(to_file);
*maxbuffer= (uint) (lastbuff-buffpek)-1;
}
+cleanup:
close_cached_file(to_file); // This holds old result
if (to_file == t_file)
{
diff --git a/sql/ha_blackhole.h b/sql/ha_blackhole.h
index 0046a57d10a..4dcb37c637d 100644
--- a/sql/ha_blackhole.h
+++ b/sql/ha_blackhole.h
@@ -43,8 +43,7 @@ public:
{
return(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
HA_DUPP_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
- HA_FILE_BASED | HA_CAN_GEOMETRY | HA_READ_RND_SAME |
- HA_CAN_INSERT_DELAYED);
+ HA_FILE_BASED | HA_CAN_GEOMETRY | HA_READ_RND_SAME);
}
ulong index_flags(uint inx, uint part, bool all_parts) const
{
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 6d8a770175d..5e953092436 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -109,6 +109,14 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
}
length=(uint) (strxmov(name, param->db_name,".",param->table_name,NullS) -
name);
+ /*
+ TODO: switch from protocol to push_warning here. The main reason we didn't
+ it yet is parallel repair. Due to following trace:
+ mi_check_print_msg/push_warning/sql_alloc/my_pthread_getspecific_ptr.
+
+ Also we likely need to lock mutex here (in both cases with protocol and
+ push_warning).
+ */
protocol->prepare_for_resend();
protocol->store(name, length, system_charset_info);
protocol->store(param->op_name, system_charset_info);
@@ -956,8 +964,8 @@ int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt)
param.sort_buffer_length= check_opt->sort_buffer_size;
if ((error= repair(thd,param,1)) && param.retry_repair)
{
- sql_print_warning("Warning: Optimize table got errno %d, retrying",
- my_errno);
+ sql_print_warning("Warning: Optimize table got errno %d on %s.%s, retrying",
+ my_errno, param.db_name, param.table_name);
param.testflag&= ~T_REP_BY_SORT;
error= repair(thd,param,1);
}
@@ -1138,11 +1146,7 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt)
/* We only come here when the user did specify an index map */
key_map kmap;
if (get_key_map_from_key_list(&kmap, table, table_list->use_index))
- {
- errmsg= thd->net.last_error;
- error= HA_ADMIN_FAILED;
- goto err;
- }
+ DBUG_RETURN(HA_ADMIN_FAILED);
map= kmap.to_ulonglong();
}
@@ -1155,7 +1159,6 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt)
error= HA_ADMIN_CORRUPT;
}
- err:
if (error != HA_ADMIN_OK)
{
/* Send error to user */
@@ -1192,11 +1195,7 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt)
key_map kmap;
get_key_map_from_key_list(&kmap, table, table_list->use_index);
if (kmap.is_set_all())
- {
- errmsg= thd->net.last_error;
- error= HA_ADMIN_FAILED;
- goto err;
- }
+ DBUG_RETURN(HA_ADMIN_FAILED);
if (!kmap.is_clear_all())
map= kmap.to_ulonglong();
}
@@ -1347,8 +1346,8 @@ int ha_myisam::enable_indexes(uint mode)
param.tmpdir=&mysql_tmpdir_list;
if ((error= (repair(thd,param,0) != HA_ADMIN_OK)) && param.retry_repair)
{
- sql_print_warning("Warning: Enabling keys got errno %d, retrying",
- my_errno);
+ sql_print_warning("Warning: Enabling keys got errno %d on %s.%s, retrying",
+ my_errno, param.db_name, param.table_name);
/* Repairing by sort failed. Now try standard repair method. */
param.testflag&= ~(T_REP_BY_SORT | T_QUICK);
error= (repair(thd,param,0) != HA_ADMIN_OK);
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index 1202a733a16..60aa4bd6adc 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -72,6 +72,24 @@ extern int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
uint t1_keys, uint t1_recs,
MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo,
uint t2_keys, uint t2_recs, bool strict);
+static void split_file_name(const char *file_name,
+ LEX_STRING *db, LEX_STRING *name);
+
+
+extern "C" void myrg_print_wrong_table(const char *table_name)
+{
+ LEX_STRING db, name;
+ char buf[FN_REFLEN];
+ split_file_name(table_name, &db, &name);
+ memcpy(buf, db.str, db.length);
+ buf[db.length]= '.';
+ memcpy(buf + db.length + 1, name.str, name.length);
+ buf[db.length + name.length + 1]= 0;
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_ADMIN_WRONG_MRG_TABLE, ER(ER_ADMIN_WRONG_MRG_TABLE),
+ buf);
+}
+
const char **ha_myisammrg::bas_ext() const
{
@@ -121,6 +139,8 @@ int ha_myisammrg::open(const char *name, int mode, uint test_if_locked)
{
DBUG_PRINT("error",("reclength: %lu mean_rec_length: %lu",
table->s->reclength, mean_rec_length));
+ if (test_if_locked & HA_OPEN_FOR_REPAIR)
+ myrg_print_wrong_table(file->open_tables->table->filename);
error= HA_ERR_WRONG_MRG_TABLE_DEF;
goto err;
}
@@ -139,12 +159,19 @@ int ha_myisammrg::open(const char *name, int mode, uint test_if_locked)
u_table->table->s->base.keys,
u_table->table->s->base.fields, false))
{
- my_free((gptr) recinfo, MYF(0));
error= HA_ERR_WRONG_MRG_TABLE_DEF;
- goto err;
+ if (test_if_locked & HA_OPEN_FOR_REPAIR)
+ myrg_print_wrong_table(u_table->table->filename);
+ else
+ {
+ my_free((gptr) recinfo, MYF(0));
+ goto err;
+ }
}
}
my_free((gptr) recinfo, MYF(0));
+ if (error == HA_ERR_WRONG_MRG_TABLE_DEF)
+ goto err;
#if !defined(BIG_TABLES) || SIZEOF_OFF_T == 4
/* Merge table has more than 2G rows */
if (table->s->crashed)
@@ -597,3 +624,9 @@ void ha_myisammrg::append_create_info(String *packet)
}
packet->append(')');
}
+
+
+int ha_myisammrg::check(THD* thd, HA_CHECK_OPT* check_opt)
+{
+ return HA_ADMIN_OK;
+}
diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h
index 16c734e2682..2ba5b6b551e 100644
--- a/sql/ha_myisammrg.h
+++ b/sql/ha_myisammrg.h
@@ -81,4 +81,5 @@ class ha_myisammrg: public handler
void update_create_info(HA_CREATE_INFO *create_info);
void append_create_info(String *packet);
MYRG_INFO *myrg_info() { return file; }
+ int check(THD* thd, HA_CHECK_OPT* check_opt);
};
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 9b48e0d4f38..357b797ec75 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -234,11 +234,6 @@ inline
int execute_no_commit(ha_ndbcluster *h, NdbTransaction *trans,
bool force_release)
{
-#ifdef NOT_USED
- int m_batch_execute= 0;
- if (m_batch_execute)
- return 0;
-#endif
h->release_completed_operations(trans, force_release);
return trans->execute(NdbTransaction::NoCommit,
NdbTransaction::AbortOnError,
@@ -248,11 +243,6 @@ int execute_no_commit(ha_ndbcluster *h, NdbTransaction *trans,
inline
int execute_commit(ha_ndbcluster *h, NdbTransaction *trans)
{
-#ifdef NOT_USED
- int m_batch_execute= 0;
- if (m_batch_execute)
- return 0;
-#endif
return trans->execute(NdbTransaction::Commit,
NdbTransaction::AbortOnError,
h->m_force_send);
@@ -261,11 +251,6 @@ int execute_commit(ha_ndbcluster *h, NdbTransaction *trans)
inline
int execute_commit(THD *thd, NdbTransaction *trans)
{
-#ifdef NOT_USED
- int m_batch_execute= 0;
- if (m_batch_execute)
- return 0;
-#endif
return trans->execute(NdbTransaction::Commit,
NdbTransaction::AbortOnError,
thd->variables.ndb_force_send);
@@ -275,11 +260,6 @@ inline
int execute_no_commit_ie(ha_ndbcluster *h, NdbTransaction *trans,
bool force_release)
{
-#ifdef NOT_USED
- int m_batch_execute= 0;
- if (m_batch_execute)
- return 0;
-#endif
h->release_completed_operations(trans, force_release);
return trans->execute(NdbTransaction::NoCommit,
NdbTransaction::AO_IgnoreError,
@@ -2264,12 +2244,10 @@ int ha_ndbcluster::write_row(byte *record)
if (has_auto_increment)
{
int error;
-
+
m_skip_auto_increment= FALSE;
if ((error= update_auto_increment()))
DBUG_RETURN(error);
- /* Ensure that handler is always called for auto_increment values */
- thd->next_insert_id= 0;
m_skip_auto_increment= !auto_increment_column_changed;
}
}
@@ -2309,20 +2287,28 @@ int ha_ndbcluster::write_row(byte *record)
{
// Table has hidden primary key
Ndb *ndb= get_ndb();
- int ret;
Uint64 auto_value;
uint retries= NDB_AUTO_INCREMENT_RETRIES;
- do {
- ret= ndb->getAutoIncrementValue((const NDBTAB *) m_table, auto_value, 1);
- } while (ret == -1 &&
- --retries &&
- ndb->getNdbError().status == NdbError::TemporaryError);
- if (ret == -1)
- ERR_RETURN(ndb->getNdbError());
+ int retry_sleep= 30; /* 30 milliseconds, transaction */
+ for (;;)
+ {
+ if (ndb->getAutoIncrementValue((const NDBTAB *) m_table,
+ auto_value, 1) == -1)
+ {
+ if (--retries &&
+ ndb->getNdbError().status == NdbError::TemporaryError);
+ {
+ my_sleep(retry_sleep);
+ continue;
+ }
+ ERR_RETURN(ndb->getNdbError());
+ }
+ break;
+ }
if (set_hidden_key(op, table->s->fields, (const byte*)&auto_value))
ERR_RETURN(op->getNdbError());
}
- else
+ else
{
if ((res= set_primary_key_from_record(op, record)))
return res;
@@ -2461,7 +2447,8 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data)
* If IGNORE the ignore constraint violations on primary and unique keys,
* but check that it is not part of INSERT ... ON DUPLICATE KEY UPDATE
*/
- if (m_ignore_dup_key && thd->lex->sql_command == SQLCOM_UPDATE)
+ if (m_ignore_dup_key && (thd->lex->sql_command == SQLCOM_UPDATE ||
+ thd->lex->sql_command == SQLCOM_UPDATE_MULTI))
{
int peek_res= peek_indexed_rows(new_data, pk_update);
@@ -4841,6 +4828,8 @@ ulonglong ha_ndbcluster::get_auto_increment()
{
int cache_size;
Uint64 auto_value;
+ Uint64 step= current_thd->variables.auto_increment_increment;
+ Uint64 start= current_thd->variables.auto_increment_offset;
DBUG_ENTER("get_auto_increment");
DBUG_PRINT("enter", ("m_tabname: %s", m_tabname));
Ndb *ndb= get_ndb();
@@ -4855,22 +4844,27 @@ ulonglong ha_ndbcluster::get_auto_increment()
m_rows_to_insert - m_rows_inserted :
((m_rows_to_insert > m_autoincrement_prefetch) ?
m_rows_to_insert : m_autoincrement_prefetch));
- int ret;
uint retries= NDB_AUTO_INCREMENT_RETRIES;
- do {
- ret=
- m_skip_auto_increment ?
- ndb->readAutoIncrementValue((const NDBTAB *) m_table, auto_value) :
- ndb->getAutoIncrementValue((const NDBTAB *) m_table, auto_value, cache_size);
- } while (ret == -1 &&
- --retries &&
- ndb->getNdbError().status == NdbError::TemporaryError);
- if (ret == -1)
- {
- const NdbError err= ndb->getNdbError();
- sql_print_error("Error %lu in ::get_auto_increment(): %s",
- (ulong) err.code, err.message);
- DBUG_RETURN(~(ulonglong) 0);
+ int retry_sleep= 30; /* 30 milliseconds, transaction */
+ for (;;)
+ {
+ if (m_skip_auto_increment &&
+ ndb->readAutoIncrementValue((const NDBTAB *) m_table, auto_value) ||
+ ndb->getAutoIncrementValue((const NDBTAB *) m_table,
+ auto_value, cache_size, step, start))
+ {
+ if (--retries &&
+ ndb->getNdbError().status == NdbError::TemporaryError);
+ {
+ my_sleep(retry_sleep);
+ continue;
+ }
+ const NdbError err= ndb->getNdbError();
+ sql_print_error("Error %lu in ::get_auto_increment(): %s",
+ (ulong) err.code, err.message);
+ DBUG_RETURN(~(ulonglong) 0);
+ }
+ break;
}
DBUG_RETURN((longlong)auto_value);
}
@@ -4894,7 +4888,8 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
HA_NEED_READ_RANGE_BUFFER |
HA_CAN_GEOMETRY |
HA_CAN_BIT_FIELD |
- HA_PARTIAL_COLUMN_READ),
+ HA_PARTIAL_COLUMN_READ |
+ HA_EXTERNAL_AUTO_INCREMENT),
m_share(0),
m_use_write(FALSE),
m_ignore_dup_key(FALSE),
@@ -5011,27 +5006,36 @@ int ha_ndbcluster::open(const char *name, int mode, uint test_if_locked)
set_dbname(name);
set_tabname(name);
- if (check_ndb_connection()) {
- free_share(m_share); m_share= 0;
- DBUG_RETURN(HA_ERR_NO_CONNECTION);
+ if ((res= check_ndb_connection()) ||
+ (res= get_metadata(name)))
+ {
+ free_share(m_share);
+ m_share= 0;
+ DBUG_RETURN(res);
}
-
- res= get_metadata(name);
- if (!res)
+ while (1)
{
Ndb *ndb= get_ndb();
if (ndb->setDatabaseName(m_dbname))
{
- ERR_RETURN(ndb->getNdbError());
+ res= ndb_to_mysql_error(&ndb->getNdbError());
+ break;
}
struct Ndb_statistics stat;
res= ndb_get_table_statistics(NULL, false, ndb, m_tabname, &stat);
records= stat.row_count;
if(!res)
res= info(HA_STATUS_CONST);
+ break;
}
-
- DBUG_RETURN(res);
+ if (res)
+ {
+ free_share(m_share);
+ m_share= 0;
+ release_metadata();
+ DBUG_RETURN(res);
+ }
+ DBUG_RETURN(0);
}
diff --git a/sql/handler.cc b/sql/handler.cc
index 867ac7ff778..37b81b58cfe 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1598,6 +1598,8 @@ int handler::update_auto_increment()
ulonglong nr;
THD *thd= table->in_use;
struct system_variables *variables= &thd->variables;
+ bool external_auto_increment=
+ table->file->table_flags() & HA_EXTERNAL_AUTO_INCREMENT;
DBUG_ENTER("handler::update_auto_increment");
/*
@@ -1615,12 +1617,12 @@ int handler::update_auto_increment()
adjust_next_insert_id_after_explicit_value(nr);
DBUG_RETURN(0);
}
- if (!(nr= thd->next_insert_id))
+ if (external_auto_increment || !(nr= thd->next_insert_id))
{
if ((nr= get_auto_increment()) == ~(ulonglong) 0)
DBUG_RETURN(HA_ERR_AUTOINC_READ_FAILED); // Mark failure
- if (variables->auto_increment_increment != 1)
+ if (!external_auto_increment && variables->auto_increment_increment != 1)
nr= next_insert_id(nr-1, variables);
/*
Update next row based on the found value. This way we don't have to
diff --git a/sql/handler.h b/sql/handler.h
index 9863d541b5f..2680c9859f6 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -93,7 +93,8 @@
#define HA_CAN_BIT_FIELD (1 << 28) /* supports bit fields */
#define HA_NEED_READ_RANGE_BUFFER (1 << 29) /* for read_multi_range */
#define HA_ANY_INDEX_MAY_BE_UNIQUE (1 << 30)
-
+/* The storage engine manages auto_increment itself */
+#define HA_EXTERNAL_AUTO_INCREMENT (1 << 31)
/* bits in index_flags(index_number) for what you can do with index */
#define HA_READ_NEXT 1 /* TODO really use this flag */
@@ -162,6 +163,7 @@
#define HA_LEX_CREATE_TMP_TABLE 1
#define HA_LEX_CREATE_IF_NOT_EXISTS 2
+#define HA_LEX_CREATE_TABLE_LIKE 4
#define HA_OPTION_NO_CHECKSUM (1L << 17)
#define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18)
#define HA_MAX_REC_LENGTH 65535
diff --git a/sql/init.cc b/sql/init.cc
index ad55a2a8b24..b3b68926683 100644
--- a/sql/init.cc
+++ b/sql/init.cc
@@ -21,8 +21,6 @@
void unireg_init(ulong options)
{
- uint i;
- double nr;
DBUG_ENTER("unireg_init");
MYSYS_PROGRAM_DONT_USE_CURSES();
@@ -39,16 +37,5 @@ void unireg_init(ulong options)
VOID(strmov(reg_ext,".frm"));
specialflag=SPECIAL_SAME_DB_NAME | options; /* Set options from argv */
- /* Make a tab of powers of 10 */
- for (i=0,nr=1.0; i < array_elements(log_10) ; i++)
- { /* It's used by filesort... */
- log_10[i]= nr ; nr*= 10.0;
- }
- /* Make a tab of powers of 0.1 */
- for (i= 0, nr= 0.1; i < array_elements(log_01); i++)
- {
- log_01[i]= nr;
- nr*= 0.1;
- }
DBUG_VOID_RETURN;
}
diff --git a/sql/item.cc b/sql/item.cc
index 651ab826484..a334028fd64 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -270,7 +270,7 @@ my_decimal *Item::val_decimal_from_string(my_decimal *decimal_value)
my_decimal *Item::val_decimal_from_date(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_date(&ltime, TIME_FUZZY_DATE))
{
my_decimal_set_zero(decimal_value);
@@ -283,7 +283,7 @@ my_decimal *Item::val_decimal_from_date(my_decimal *decimal_value)
my_decimal *Item::val_decimal_from_time(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_time(&ltime))
{
my_decimal_set_zero(decimal_value);
@@ -318,7 +318,7 @@ longlong Item::val_int_from_decimal()
int Item::save_time_in_field(Field *field)
{
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_time(&ltime))
return set_field_to_null(field);
field->set_notnull();
@@ -328,7 +328,7 @@ int Item::save_time_in_field(Field *field)
int Item::save_date_in_field(Field *field)
{
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_date(&ltime, TIME_FUZZY_DATE))
return set_field_to_null(field);
field->set_notnull();
@@ -836,22 +836,40 @@ bool Item_string::eq(const Item *item, bool binary_cmp) const
/*
- Get the value of the function as a TIME structure.
+ Get the value of the function as a MYSQL_TIME structure.
As a extra convenience the time structure is reset on error!
*/
-bool Item::get_date(TIME *ltime,uint fuzzydate)
+bool Item::get_date(MYSQL_TIME *ltime,uint fuzzydate)
{
- char buff[40];
- String tmp(buff,sizeof(buff), &my_charset_bin),*res;
- if (!(res=val_str(&tmp)) ||
- str_to_datetime_with_warn(res->ptr(), res->length(),
- ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR)
+ if (result_type() == STRING_RESULT)
{
- bzero((char*) ltime,sizeof(*ltime));
- return 1;
+ char buff[40];
+ String tmp(buff,sizeof(buff), &my_charset_bin),*res;
+ if (!(res=val_str(&tmp)) ||
+ str_to_datetime_with_warn(res->ptr(), res->length(),
+ ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR)
+ goto err;
+ }
+ else
+ {
+ longlong value= val_int();
+ int was_cut;
+ if (number_to_datetime(value, ltime, fuzzydate, &was_cut) == LL(-1))
+ {
+ char buff[22], *end;
+ end= longlong10_to_str(value, buff, -10);
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ buff, (int) (end-buff), MYSQL_TIMESTAMP_NONE,
+ NullS);
+ goto err;
+ }
}
return 0;
+
+err:
+ bzero((char*) ltime,sizeof(*ltime));
+ return 1;
}
/*
@@ -859,7 +877,7 @@ bool Item::get_date(TIME *ltime,uint fuzzydate)
As a extra convenience the time structure is reset on error!
*/
-bool Item::get_time(TIME *ltime)
+bool Item::get_time(MYSQL_TIME *ltime)
{
char buff[40];
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
@@ -1838,7 +1856,7 @@ String *Item_field::str_result(String *str)
return result_field->val_str(str,&str_value);
}
-bool Item_field::get_date(TIME *ltime,uint fuzzydate)
+bool Item_field::get_date(MYSQL_TIME *ltime,uint fuzzydate)
{
if ((null_value=field->is_null()) || field->get_date(ltime,fuzzydate))
{
@@ -1848,7 +1866,7 @@ bool Item_field::get_date(TIME *ltime,uint fuzzydate)
return 0;
}
-bool Item_field::get_date_result(TIME *ltime,uint fuzzydate)
+bool Item_field::get_date_result(MYSQL_TIME *ltime,uint fuzzydate)
{
if ((null_value=result_field->is_null()) ||
result_field->get_date(ltime,fuzzydate))
@@ -1859,7 +1877,7 @@ bool Item_field::get_date_result(TIME *ltime,uint fuzzydate)
return 0;
}
-bool Item_field::get_time(TIME *ltime)
+bool Item_field::get_time(MYSQL_TIME *ltime)
{
if ((null_value=field->is_null()) || field->get_time(ltime))
{
@@ -1920,10 +1938,11 @@ bool Item_field::val_bool_result()
bool Item_field::eq(const Item *item, bool binary_cmp) const
{
- if (item->type() != FIELD_ITEM)
+ Item *real_item= ((Item *) item)->real_item();
+ if (real_item->type() != FIELD_ITEM)
return 0;
- Item_field *item_field= (Item_field*) item;
+ Item_field *item_field= (Item_field*) real_item;
if (item_field->field && field)
return item_field->field == field;
/*
@@ -2295,6 +2314,7 @@ default_set_param_func(Item_param *param,
Item_param::Item_param(unsigned pos_in_query_arg) :
+ strict_type(FALSE),
state(NO_VALUE),
item_result_type(STRING_RESULT),
/* Don't pretend to be a literal unless value for this item is set. */
@@ -2386,7 +2406,7 @@ void Item_param::set_decimal(const char *str, ulong length)
/*
- Set parameter value from TIME value.
+ Set parameter value from MYSQL_TIME value.
SYNOPSIS
set_time()
@@ -2400,7 +2420,7 @@ void Item_param::set_decimal(const char *str, ulong length)
the fact that even wrong value sent over binary protocol fits into
MAX_DATE_STRING_REP_LENGTH buffer.
*/
-void Item_param::set_time(TIME *tm, timestamp_type time_type,
+void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type,
uint32 max_length_arg)
{
DBUG_ENTER("Item_param::set_time");
@@ -2415,7 +2435,8 @@ void Item_param::set_time(TIME *tm, timestamp_type time_type,
{
char buff[MAX_DATE_STRING_REP_LENGTH];
uint length= my_TIME_to_str(&value.time, buff);
- make_truncated_value_warning(current_thd, buff, length, time_type, 0);
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ buff, length, time_type, 0);
set_zero_time(&value.time, MYSQL_TIMESTAMP_ERROR);
}
@@ -2488,16 +2509,16 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
if (entry && entry->value)
{
item_result_type= entry->type;
- switch (entry->type) {
+ if (strict_type && required_result_type != item_result_type)
+ DBUG_RETURN(1);
+ switch (item_result_type) {
case REAL_RESULT:
set_double(*(double*)entry->value);
item_type= Item::REAL_ITEM;
- item_result_type= REAL_RESULT;
break;
case INT_RESULT:
set_int(*(longlong*)entry->value, MY_INT64_NUM_DECIMAL_DIGITS);
item_type= Item::INT_ITEM;
- item_result_type= INT_RESULT;
break;
case STRING_RESULT:
{
@@ -2519,7 +2540,6 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
charset of connection, so we have to set it later.
*/
item_type= Item::STRING_ITEM;
- item_result_type= STRING_RESULT;
if (set_str((const char *)entry->value, entry->length))
DBUG_RETURN(1);
@@ -2533,6 +2553,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
decimals= ent_value->frac;
max_length= my_decimal_precision_to_length(ent_value->precision(),
decimals, unsigned_flag);
+ item_type= Item::DECIMAL_ITEM;
break;
}
default:
@@ -2616,7 +2637,7 @@ int Item_param::save_in_field(Field *field, bool no_conversions)
}
-bool Item_param::get_time(TIME *res)
+bool Item_param::get_time(MYSQL_TIME *res)
{
if (state == TIME_VALUE)
{
@@ -2631,7 +2652,7 @@ bool Item_param::get_time(TIME *res)
}
-bool Item_param::get_date(TIME *res, uint fuzzydate)
+bool Item_param::get_date(MYSQL_TIME *res, uint fuzzydate)
{
if (state == TIME_VALUE)
{
@@ -3057,7 +3078,7 @@ String* Item_ref_null_helper::val_str(String* s)
}
-bool Item_ref_null_helper::get_date(TIME *ltime, uint fuzzydate)
+bool Item_ref_null_helper::get_date(MYSQL_TIME *ltime, uint fuzzydate)
{
return (owner->was_null|= null_value= (*ref)->get_date(ltime, fuzzydate));
}
@@ -4298,7 +4319,9 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table)
case MYSQL_TYPE_GEOMETRY:
return new Field_geom(max_length, maybe_null, name, table,
(Field::geometry_type)
- ((Item_geometry_func *)this)->get_geometry_type());
+ ((type() == Item::TYPE_HOLDER) ?
+ ((Item_type_holder *)this)->get_geometry_type() :
+ ((Item_geometry_func *)this)->get_geometry_type()));
}
}
@@ -4852,7 +4875,7 @@ bool Item::send(Protocol *protocol, String *buffer)
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_TIMESTAMP:
{
- TIME tm;
+ MYSQL_TIME tm;
get_date(&tm, TIME_FUZZY_DATE);
if (!null_value)
{
@@ -4865,7 +4888,7 @@ bool Item::send(Protocol *protocol, String *buffer)
}
case MYSQL_TYPE_TIME:
{
- TIME tm;
+ MYSQL_TIME tm;
get_time(&tm);
if (!null_value)
result= protocol->store_time(&tm);
@@ -5437,7 +5460,7 @@ bool Item_ref::is_null()
}
-bool Item_ref::get_date(TIME *ltime,uint fuzzydate)
+bool Item_ref::get_date(MYSQL_TIME *ltime,uint fuzzydate)
{
return (null_value=(*ref)->get_date_result(ltime,fuzzydate));
}
@@ -5479,6 +5502,21 @@ void Item_ref::make_field(Send_field *field)
}
+Item *Item_ref::get_tmp_table_item(THD *thd)
+{
+ if (!result_field)
+ return (*ref)->get_tmp_table_item(thd);
+
+ Item_field *item= new Item_field(result_field);
+ if (item)
+ {
+ item->table_name= table_name;
+ item->db_name= db_name;
+ }
+ return item;
+}
+
+
void Item_ref_null_helper::print(String *str)
{
str->append(STRING_WITH_LEN("<ref_null_helper>("));
@@ -5536,7 +5574,7 @@ bool Item_direct_ref::is_null()
}
-bool Item_direct_ref::get_date(TIME *ltime,uint fuzzydate)
+bool Item_direct_ref::get_date(MYSQL_TIME *ltime,uint fuzzydate)
{
return (null_value=(*ref)->get_date(ltime,fuzzydate));
}
@@ -5605,8 +5643,7 @@ bool Item_outer_ref::fix_fields(THD *thd, Item **reference)
DESCRIPTION
A view column reference is considered equal to another column
reference if the second one is a view column and if both column
- references resolve to the same item. It is assumed that both
- items are of the same type.
+ references resolve to the same item.
RETURN
TRUE Referenced item is equal to given item
@@ -5622,8 +5659,6 @@ bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const
if (item_ref->ref_type() == VIEW_REF)
{
Item *item_ref_ref= *(item_ref->ref);
- DBUG_ASSERT((*ref)->real_item()->type() ==
- item_ref_ref->real_item()->type());
return ((*ref)->real_item() == item_ref_ref->real_item());
}
}
@@ -6403,6 +6438,10 @@ Item_type_holder::Item_type_holder(THD *thd, Item *item)
if (Field::result_merge_type(fld_type) == INT_RESULT)
decimals= 0;
prev_decimal_int_part= item->decimal_int_part();
+ if (item->field_type() == MYSQL_TYPE_GEOMETRY)
+ geometry_type= (item->type() == Item::FIELD_ITEM) ?
+ ((Item_field *)item)->get_geometry_type() :
+ (Field::geometry_type)((Item_geometry_func *)item)->get_geometry_type();
}
diff --git a/sql/item.h b/sql/item.h
index 18a05b0b4ad..3478095351a 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -689,9 +689,9 @@ public:
/* Called for items that really have to be split */
void split_sum_func2(THD *thd, Item **ref_pointer_array, List<Item> &fields,
Item **ref, bool skip_registered);
- virtual bool get_date(TIME *ltime,uint fuzzydate);
- virtual bool get_time(TIME *ltime);
- virtual bool get_date_result(TIME *ltime,uint fuzzydate)
+ virtual bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
+ virtual bool get_time(MYSQL_TIME *ltime);
+ virtual bool get_date_result(MYSQL_TIME *ltime,uint fuzzydate)
{ return get_date(ltime,fuzzydate); }
/*
The method allows to determine nullness of a complex expression
@@ -1273,9 +1273,9 @@ public:
}
Field *get_tmp_table_field() { return result_field; }
Field *tmp_table_field(TABLE *t_arg) { return result_field; }
- bool get_date(TIME *ltime,uint fuzzydate);
- bool get_date_result(TIME *ltime,uint fuzzydate);
- bool get_time(TIME *ltime);
+ bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
+ bool get_date_result(MYSQL_TIME *ltime,uint fuzzydate);
+ bool get_time(MYSQL_TIME *ltime);
bool is_null() { return field->is_null(); }
void update_null_value();
Item *get_tmp_table_item(THD *thd);
@@ -1304,6 +1304,11 @@ public:
int fix_outer_field(THD *thd, Field **field, Item **reference);
virtual Item *update_value_transformer(byte *select_arg);
void print(String *str);
+ Field::geometry_type get_geometry_type()
+ {
+ DBUG_ASSERT(field_type() == MYSQL_TYPE_GEOMETRY);
+ return field->get_geometry_type();
+ }
friend class Item_default_value;
friend class Item_insert_value;
friend class st_select_lex_unit;
@@ -1359,8 +1364,10 @@ class Item_param :public Item
char cnvbuf[MAX_FIELD_WIDTH];
String cnvstr;
Item *cnvitem;
-public:
+ bool strict_type;
+ enum Item_result required_result_type;
+public:
enum enum_item_param_state
{
NO_VALUE, NULL_VALUE, INT_VALUE, REAL_VALUE,
@@ -1402,7 +1409,7 @@ public:
*/
CHARSET_INFO *final_character_set_of_str_value;
} cs_info;
- TIME time;
+ MYSQL_TIME time;
} value;
/* Cached values for virtual methods to save us one switch. */
@@ -1434,8 +1441,8 @@ public:
longlong val_int();
my_decimal *val_decimal(my_decimal*);
String *val_str(String*);
- bool get_time(TIME *tm);
- bool get_date(TIME *tm, uint fuzzydate);
+ bool get_time(MYSQL_TIME *tm);
+ bool get_date(MYSQL_TIME *tm, uint fuzzydate);
int save_in_field(Field *field, bool no_conversions);
void set_null();
@@ -1444,7 +1451,7 @@ public:
void set_decimal(const char *str, ulong length);
bool set_str(const char *str, ulong length);
bool set_longdata(const char *str, ulong length);
- void set_time(TIME *tm, timestamp_type type, uint32 max_length_arg);
+ void set_time(MYSQL_TIME *tm, timestamp_type type, uint32 max_length_arg);
bool set_from_user_var(THD *thd, const user_var_entry *entry);
void reset();
/*
@@ -1488,6 +1495,11 @@ public:
Otherwise return FALSE.
*/
bool eq(const Item *item, bool binary_cmp) const;
+ void set_strict_type(enum Item_result result_type_arg)
+ {
+ strict_type= TRUE;
+ required_result_type= result_type_arg;
+ }
};
@@ -1877,7 +1889,7 @@ public:
bool val_bool();
String *val_str(String* tmp);
bool is_null();
- bool get_date(TIME *ltime,uint fuzzydate);
+ bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
double val_result();
longlong val_int_result();
String *str_result(String* tmp);
@@ -1892,11 +1904,7 @@ public:
enum_field_types field_type() const { return (*ref)->field_type(); }
Field *get_tmp_table_field()
{ return result_field ? result_field : (*ref)->get_tmp_table_field(); }
- Item *get_tmp_table_item(THD *thd)
- {
- return (result_field ? new Item_field(result_field) :
- (*ref)->get_tmp_table_item(thd));
- }
+ Item *get_tmp_table_item(THD *thd);
table_map used_tables() const
{
return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables();
@@ -1954,7 +1962,7 @@ public:
my_decimal *val_decimal(my_decimal *);
bool val_bool();
bool is_null();
- bool get_date(TIME *ltime,uint fuzzydate);
+ bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
virtual Ref_Type ref_type() { return DIRECT_REF; }
};
@@ -2059,7 +2067,7 @@ public:
String* val_str(String* s);
my_decimal *val_decimal(my_decimal *);
bool val_bool();
- bool get_date(TIME *ltime, uint fuzzydate);
+ bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
void print(String *str);
/*
we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
@@ -2563,6 +2571,7 @@ class Item_type_holder: public Item
protected:
TYPELIB *enum_set_typelib;
enum_field_types fld_type;
+ Field::geometry_type geometry_type;
void get_full_info(Item *item);
@@ -2582,6 +2591,7 @@ public:
Field *make_field_by_type(TABLE *table);
static uint32 display_length(Item *item);
static enum_field_types get_real_type(Item *);
+ Field::geometry_type get_geometry_type() { return geometry_type; };
};
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 3a79940b571..ed0c09f0b32 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -316,8 +316,10 @@ static bool convert_constant_item(THD *thd, Field *field, Item **item)
{
/* For comparison purposes allow invalid dates like 2000-01-32 */
ulong orig_sql_mode= thd->variables.sql_mode;
+ enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
MODE_INVALID_DATES;
+ thd->count_cuted_fields= CHECK_FIELD_IGNORE;
if (!(*item)->save_in_field(field, 1) && !((*item)->null_value))
{
Item *tmp=new Item_int_with_ref(field->val_int(), *item,
@@ -328,6 +330,7 @@ static bool convert_constant_item(THD *thd, Field *field, Item **item)
return 1; // Item was replaced
}
thd->variables.sql_mode= orig_sql_mode;
+ thd->count_cuted_fields= orig_count_cuted_fields;
}
return 0;
}
@@ -504,7 +507,7 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
{
if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
{
- precision= 5 * log_01[max((*a)->decimals, (*b)->decimals)];
+ precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
if (func == &Arg_comparator::compare_real)
func= &Arg_comparator::compare_real_fixed;
else if (func == &Arg_comparator::compare_e_real)
@@ -564,8 +567,9 @@ get_date_from_str(THD *thd, String *str, timestamp_type warn_type,
if (error || *error_arg)
{
- make_truncated_value_warning(thd, str->ptr(), str->length(), warn_type,
- warn_name);
+ make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ str->ptr(), str->length(),
+ warn_type, warn_name);
*error_arg= TRUE;
}
return value;
@@ -762,7 +766,12 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
{
value= item->val_int();
*is_null= item->null_value;
- if (item->field_type() == MYSQL_TYPE_DATE)
+ /*
+ Item_date_add_interval may return MYSQL_TYPE_STRING as the result
+ field type. To detect that the DATE value has been returned we
+ compare it with 1000000L - any DATE value should be less than it.
+ */
+ if (item->field_type() == MYSQL_TYPE_DATE || value < 100000000L)
value*= 1000000L;
}
else
@@ -1746,6 +1755,23 @@ void Item_func_between::fix_length_and_dec()
ge_cmp.set_datetime_cmp_func(args, args + 1);
le_cmp.set_datetime_cmp_func(args, args + 2);
}
+ else if (args[0]->real_item()->type() == FIELD_ITEM &&
+ thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
+ thd->lex->sql_command != SQLCOM_SHOW_CREATE)
+ {
+ Field *field=((Item_field*) (args[0]->real_item()))->field;
+ if (field->can_be_compared_as_longlong())
+ {
+ /*
+ The following can't be recoded with || as convert_constant_item
+ changes the argument
+ */
+ if (convert_constant_item(thd, field,&args[1]))
+ cmp_type=INT_RESULT; // Works for all types.
+ if (convert_constant_item(thd, field,&args[2]))
+ cmp_type=INT_RESULT; // Works for all types.
+ }
+ }
}
diff --git a/sql/item_create.cc b/sql/item_create.cc
index c4008d36aae..42cbdc8c280 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -418,6 +418,7 @@ Item *create_func_unhex(Item* a)
Item *create_func_uuid(void)
{
+ current_thd->lex->safe_to_cache_query= 0;
return new Item_func_uuid();
}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 1bd41cf87a4..b256ce4624a 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -996,6 +996,8 @@ longlong Item_func_unsigned::val_int()
my_decimal tmp, *dec= args[0]->val_decimal(&tmp);
if (!(null_value= args[0]->null_value))
my_decimal2int(E_DEC_FATAL_ERROR, dec, 1, &value);
+ else
+ value= 0;
return value;
}
else if (args[0]->cast_to_int_type() != STRING_RESULT ||
@@ -1521,16 +1523,20 @@ void Item_func_neg::fix_length_and_dec()
Use val() to get value as arg_type doesn't mean that item is
Item_int or Item_real due to existence of Item_param.
*/
- if (hybrid_type == INT_RESULT &&
- args[0]->type() == INT_ITEM &&
- ((ulonglong) args[0]->val_int() >= (ulonglong) LONGLONG_MIN))
+ if (hybrid_type == INT_RESULT && args[0]->const_item())
{
- /*
- Ensure that result is converted to DECIMAL, as longlong can't hold
- the negated number
- */
- hybrid_type= DECIMAL_RESULT;
- DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT"));
+ longlong val= args[0]->val_int();
+ if ((ulonglong) val >= (ulonglong) LONGLONG_MIN &&
+ ((ulonglong) val != (ulonglong) LONGLONG_MIN ||
+ args[0]->type() != INT_ITEM))
+ {
+ /*
+ Ensure that result is converted to DECIMAL, as longlong can't hold
+ the negated number
+ */
+ hybrid_type= DECIMAL_RESULT;
+ DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT"));
+ }
}
unsigned_flag= 0;
DBUG_VOID_RETURN;
@@ -1955,7 +1961,13 @@ void Item_func_round::fix_length_and_dec()
{
max_length= args[0]->max_length;
decimals= args[0]->decimals;
- hybrid_type= REAL_RESULT;
+ if (args[0]->result_type() == DECIMAL_RESULT)
+ {
+ max_length++;
+ hybrid_type= DECIMAL_RESULT;
+ }
+ else
+ hybrid_type= REAL_RESULT;
return;
}
@@ -2025,9 +2037,9 @@ double my_double_round(double value, longlong dec, bool dec_unsigned,
tmp=(abs_dec < array_elements(log_10) ?
log_10[abs_dec] : pow(10.0,(double) abs_dec));
- if (dec_negative && isinf(tmp))
+ if (dec_negative && my_isinf(tmp))
tmp2= 0;
- else if (!dec_negative && isinf(value * tmp))
+ else if (!dec_negative && my_isinf(value * tmp))
tmp2= value;
else if (truncate)
{
@@ -2499,7 +2511,6 @@ longlong Item_func_coercibility::val_int()
void Item_func_locate::fix_length_and_dec()
{
- maybe_null= 0;
max_length= MY_INT32_NUM_DECIMAL_DIGITS;
agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1);
}
@@ -3447,6 +3458,7 @@ longlong Item_func_get_lock::val_int()
THD *thd=current_thd;
User_level_lock *ull;
int error;
+ DBUG_ENTER("Item_func_get_lock::val_int");
/*
In slave thread no need to get locks, everything is serialized. Anyway
@@ -3456,7 +3468,7 @@ longlong Item_func_get_lock::val_int()
it's not guaranteed to be same as on master.
*/
if (thd->slave_thread)
- return 1;
+ DBUG_RETURN(1);
pthread_mutex_lock(&LOCK_user_locks);
@@ -3464,8 +3476,10 @@ longlong Item_func_get_lock::val_int()
{
pthread_mutex_unlock(&LOCK_user_locks);
null_value=1;
- return 0;
+ DBUG_RETURN(0);
}
+ DBUG_PRINT("info", ("lock %.*s, thd=%ld", res->length(), res->ptr(),
+ (long) thd->real_id));
null_value=0;
if (thd->ull)
@@ -3484,14 +3498,17 @@ longlong Item_func_get_lock::val_int()
delete ull;
pthread_mutex_unlock(&LOCK_user_locks);
null_value=1; // Probably out of memory
- return 0;
+ DBUG_RETURN(0);
}
ull->thread=thd->real_id;
+ ull->thread_id=thd->thread_id;
thd->ull=ull;
pthread_mutex_unlock(&LOCK_user_locks);
- return 1; // Got new lock
+ DBUG_PRINT("info", ("made new lock"));
+ DBUG_RETURN(1); // Got new lock
}
ull->count++;
+ DBUG_PRINT("info", ("ull->count=%d", ull->count));
/*
Structure is now initialized. Try to get the lock.
@@ -3505,9 +3522,13 @@ longlong Item_func_get_lock::val_int()
error= 0;
while (ull->locked && !thd->killed)
{
+ DBUG_PRINT("info", ("waiting on lock"));
error= pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime);
if (error == ETIMEDOUT || error == ETIME)
+ {
+ DBUG_PRINT("info", ("lock wait timeout"));
break;
+ }
error= 0;
}
@@ -3531,6 +3552,7 @@ longlong Item_func_get_lock::val_int()
ull->thread_id= thd->thread_id;
thd->ull=ull;
error=0;
+ DBUG_PRINT("info", ("got the lock"));
}
pthread_mutex_unlock(&LOCK_user_locks);
@@ -3540,7 +3562,7 @@ longlong Item_func_get_lock::val_int()
thd->mysys_var->current_cond= 0;
pthread_mutex_unlock(&thd->mysys_var->mutex);
- return !error ? 1 : 0;
+ DBUG_RETURN(!error ? 1 : 0);
}
@@ -3558,11 +3580,14 @@ longlong Item_func_release_lock::val_int()
String *res=args[0]->val_str(&value);
User_level_lock *ull;
longlong result;
+ THD *thd=current_thd;
+ DBUG_ENTER("Item_func_release_lock::val_int");
if (!res || !res->length())
{
null_value=1;
- return 0;
+ DBUG_RETURN(0);
}
+ DBUG_PRINT("info", ("lock %.*s", res->length(), res->ptr()));
null_value=0;
result=0;
@@ -3575,19 +3600,20 @@ longlong Item_func_release_lock::val_int()
}
else
{
-#ifdef EMBEDDED_LIBRARY
- if (ull->locked && pthread_equal(current_thd->real_id,ull->thread))
-#else
- if (ull->locked && pthread_equal(pthread_self(),ull->thread))
-#endif
+ DBUG_PRINT("info", ("ull->locked=%d ull->thread=%ld thd=%ld",
+ (int) ull->locked,
+ (long)ull->thread,
+ (long)thd->real_id));
+ if (ull->locked && pthread_equal(thd->real_id,ull->thread))
{
+ DBUG_PRINT("info", ("release lock"));
result=1; // Release is ok
item_user_lock_release(ull);
- current_thd->ull=0;
+ thd->ull=0;
}
}
pthread_mutex_unlock(&LOCK_user_locks);
- return result;
+ DBUG_RETURN(result);
}
@@ -4061,8 +4087,8 @@ bool
Item_func_set_user_var::check(bool use_result_field)
{
DBUG_ENTER("Item_func_set_user_var::check");
- if (use_result_field)
- DBUG_ASSERT(result_field);
+ if (use_result_field && !result_field)
+ use_result_field= FALSE;
switch (cached_result_type) {
case REAL_RESULT:
@@ -4206,6 +4232,40 @@ my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val)
}
+double Item_func_set_user_var::val_result()
+{
+ DBUG_ASSERT(fixed == 1);
+ check(TRUE);
+ update(); // Store expression
+ return entry->val_real(&null_value);
+}
+
+longlong Item_func_set_user_var::val_int_result()
+{
+ DBUG_ASSERT(fixed == 1);
+ check(TRUE);
+ update(); // Store expression
+ return entry->val_int(&null_value);
+}
+
+String *Item_func_set_user_var::str_result(String *str)
+{
+ DBUG_ASSERT(fixed == 1);
+ check(TRUE);
+ update(); // Store expression
+ return entry->val_str(&null_value, str, decimals);
+}
+
+
+my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val)
+{
+ DBUG_ASSERT(fixed == 1);
+ check(TRUE);
+ update(); // Store expression
+ return entry->val_decimal(&null_value, val);
+}
+
+
void Item_func_set_user_var::print(String *str)
{
str->append(STRING_WITH_LEN("(@"));
@@ -4288,9 +4348,11 @@ void Item_func_set_user_var::make_field(Send_field *tmp_field)
TRUE Error
*/
-int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions)
+int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions,
+ bool can_use_result_field)
{
- bool use_result_field= (result_field && result_field != field);
+ bool use_result_field= (!can_use_result_field ? 0 :
+ (result_field && result_field != field));
int error;
/* Update the value of the user variable */
@@ -5213,10 +5275,11 @@ Item_func_sp::func_name() const
{
THD *thd= current_thd;
/* Calculate length to avoid reallocation of string for sure */
- uint len= ((m_name->m_explicit_name ? m_name->m_db.length : 0 +
+ uint len= (((m_name->m_explicit_name ? m_name->m_db.length : 0) +
m_name->m_name.length)*2 + //characters*quoting
2 + // ` and `
- 1 + // .
+ (m_name->m_explicit_name ?
+ 3 : 0) + // '`', '`' and '.' for the db
1 + // end of string
ALIGN_SIZE(1)); // to avoid String reallocation
String qname((char *)alloc_root(thd->mem_root, len), len,
@@ -5347,6 +5410,8 @@ Item_func_sp::execute()
{
null_value= 1;
context->process_error(thd);
+ if (thd->killed)
+ thd->send_kill_message();
return TRUE;
}
diff --git a/sql/item_func.h b/sql/item_func.h
index 7ec3c0b00c4..9a0201cb28b 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -147,11 +147,11 @@ public:
void count_only_length();
void count_real_length();
void count_decimal_length();
- inline bool get_arg0_date(TIME *ltime, uint fuzzy_date)
+ inline bool get_arg0_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
return (null_value=args[0]->get_date(ltime, fuzzy_date));
}
- inline bool get_arg0_time(TIME *ltime)
+ inline bool get_arg0_time(MYSQL_TIME *ltime)
{
return (null_value=args[0]->get_time(ltime));
}
@@ -1208,6 +1208,10 @@ public:
longlong val_int();
String *val_str(String *str);
my_decimal *val_decimal(my_decimal *);
+ double val_result();
+ longlong val_int_result();
+ String *str_result(String *str);
+ my_decimal *val_decimal_result(my_decimal *);
bool update_hash(void *ptr, uint length, enum Item_result type,
CHARSET_INFO *cs, Derivation dv, bool unsigned_arg);
bool send(Protocol *protocol, String *str_arg);
@@ -1220,7 +1224,13 @@ public:
void print(String *str);
void print_as_stmt(String *str);
const char *func_name() const { return "set_user_var"; }
- int save_in_field(Field *field, bool no_conversions);
+ int save_in_field(Field *field, bool no_conversions,
+ bool can_use_result_field);
+ int save_in_field(Field *field, bool no_conversions)
+ {
+ return save_in_field(field, no_conversions, 1);
+ }
+ void save_org_in_field(Field *field) { (void)save_in_field(field, 1, 0); }
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index f9a0f715985..0c24f14c8fe 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1145,8 +1145,9 @@ String *Item_func_substr::val_str(String *str)
(arg_count == 3 && args[2]->null_value))))
return 0; /* purecov: inspected */
- /* Negative length, will return empty string. */
- if ((arg_count == 3) && (length <= 0) && !args[2]->unsigned_flag)
+ /* Negative or zero length, will return empty string. */
+ if ((arg_count == 3) && (length <= 0) &&
+ (length == 0 || !args[2]->unsigned_flag))
return &my_empty_string;
/* Assumes that the maximum length of a String is < INT_MAX32. */
@@ -3334,7 +3335,7 @@ String *Item_func_uuid::val_str(String *str)
*--s=_dig_vec_lower[mac[i] >> 4];
}
randominit(&uuid_rand, tmp + (ulong) server_start_time,
- tmp + thd->status_var.bytes_sent);
+ tmp + (ulong) thd->status_var.bytes_sent);
set_clock_seq_str();
}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index d6b31d43389..ea2a14ffb63 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -432,7 +432,7 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table,
2-byte lenght.
*/
if (max_length/collation.collation->mbmaxlen > 255 &&
- convert_blob_length < UINT_MAX16 && convert_blob_length)
+ convert_blob_length <= Field_varstring::MAX_SIZE && convert_blob_length)
return new Field_varstring(convert_blob_length, maybe_null,
name, table,
collation.collation);
@@ -3269,14 +3269,20 @@ bool Item_func_group_concat::setup(THD *thd)
tmp_table_param->force_copy_fields= force_copy_fields;
DBUG_ASSERT(table == 0);
/*
+ Currently we have to force conversion of BLOB values to VARCHAR's
+ if we are to store them in TREE objects used for ORDER BY and
+ DISTINCT. This leads to truncation if the BLOB's size exceeds
+ Field_varstring::MAX_SIZE.
+ */
+ if (arg_count_order > 0 || distinct)
+ set_if_smaller(tmp_table_param->convert_blob_length,
+ Field_varstring::MAX_SIZE);
+ /*
We have to create a temporary table to get descriptions of fields
(types, sizes and so on).
Note that in the table, we first have the ORDER BY fields, then the
field list.
-
- We need to set set_sum_field in true for storing value of blob in buffer
- of a record instead of a pointer of one.
*/
if (!(table= create_tmp_table(thd, tmp_table_param, all_fields,
(ORDER*) 0, 0, TRUE,
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 194fb6445fa..9795ec5f413 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -46,12 +46,12 @@
the microseconds twice.
*/
-static bool make_datetime(date_time_format_types format, TIME *ltime,
+static bool make_datetime(date_time_format_types format, MYSQL_TIME *ltime,
String *str)
{
char *buff;
CHARSET_INFO *cs= &my_charset_bin;
- uint length= 30;
+ uint length= MAX_DATE_STRING_REP_LENGTH;
if (str->alloc(length))
return 1;
@@ -95,7 +95,7 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
/*
- Wrapper over make_datetime() with validation of the input TIME value
+ Wrapper over make_datetime() with validation of the input MYSQL_TIME value
NOTE
see make_datetime() for more information
@@ -105,7 +105,7 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
0 otherwise
*/
-static bool make_datetime_with_warn(date_time_format_types format, TIME *ltime,
+static bool make_datetime_with_warn(date_time_format_types format, MYSQL_TIME *ltime,
String *str)
{
int warning= 0;
@@ -117,14 +117,15 @@ static bool make_datetime_with_warn(date_time_format_types format, TIME *ltime,
if (!warning)
return 0;
- make_truncated_value_warning(current_thd, str->ptr(), str->length(),
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ str->ptr(), str->length(),
MYSQL_TIMESTAMP_TIME, NullS);
return make_datetime(format, ltime, str);
}
/*
- Wrapper over make_time() with validation of the input TIME value
+ Wrapper over make_time() with validation of the input MYSQL_TIME value
NOTE
see make_time() for more info
@@ -135,7 +136,7 @@ static bool make_datetime_with_warn(date_time_format_types format, TIME *ltime,
*/
static bool make_time_with_warn(const DATE_TIME_FORMAT *format,
- TIME *l_time, String *str)
+ MYSQL_TIME *l_time, String *str)
{
int warning= 0;
make_time(format, l_time, str);
@@ -143,7 +144,8 @@ static bool make_time_with_warn(const DATE_TIME_FORMAT *format,
return 1;
if (warning)
{
- make_truncated_value_warning(current_thd, str->ptr(), str->length(),
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ str->ptr(), str->length(),
MYSQL_TIMESTAMP_TIME, NullS);
make_time(format, l_time, str);
}
@@ -153,16 +155,16 @@ static bool make_time_with_warn(const DATE_TIME_FORMAT *format,
/*
- Convert seconds to TIME value with overflow checking
+ Convert seconds to MYSQL_TIME value with overflow checking
SYNOPSIS:
sec_to_time()
seconds number of seconds
unsigned_flag 1, if 'seconds' is unsigned, 0, otherwise
- ltime output TIME value
+ ltime output MYSQL_TIME value
DESCRIPTION
- If the 'seconds' argument is inside TIME data range, convert it to a
+ If the 'seconds' argument is inside MYSQL_TIME data range, convert it to a
corresponding value.
Otherwise, truncate the resulting value to the nearest endpoint, and
produce a warning message.
@@ -172,7 +174,7 @@ static bool make_time_with_warn(const DATE_TIME_FORMAT *format,
0 otherwise
*/
-static bool sec_to_time(longlong seconds, bool unsigned_flag, TIME *ltime)
+static bool sec_to_time(longlong seconds, bool unsigned_flag, MYSQL_TIME *ltime)
{
uint sec;
@@ -205,7 +207,8 @@ overflow:
char buf[22];
int len= (int)(longlong10_to_str(seconds, buf, unsigned_flag ? 10 : -10)
- buf);
- make_truncated_value_warning(current_thd, buf, len, MYSQL_TIMESTAMP_TIME,
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ buf, len, MYSQL_TIMESTAMP_TIME,
NullS);
return 1;
@@ -224,7 +227,7 @@ static DATE_TIME_FORMAT time_24hrs_format= {{0}, '\0', 0,
{(char *)"%H:%i:%S", 8}};
/*
- Extract datetime value to TIME struct from string value
+ Extract datetime value to MYSQL_TIME struct from string value
according to format string.
SYNOPSIS
@@ -257,7 +260,7 @@ static DATE_TIME_FORMAT time_24hrs_format= {{0}, '\0', 0,
*/
static bool extract_date_time(DATE_TIME_FORMAT *format,
- const char *val, uint length, TIME *l_time,
+ const char *val, uint length, MYSQL_TIME *l_time,
timestamp_type cached_timestamp_type,
const char **sub_pattern_end,
const char *date_time_type)
@@ -305,13 +308,15 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
case 'Y':
tmp= (char*) val + min(4, val_len);
l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ if ((int) (tmp-val) <= 2)
+ l_time->year= year_2000_handling(l_time->year);
val= tmp;
break;
case 'y':
tmp= (char*) val + min(2, val_len);
l_time->year= (int) my_strtoll10(val, &tmp, &error);
val= tmp;
- l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900);
+ l_time->year= year_2000_handling(l_time->year);
break;
/* Month */
@@ -514,7 +519,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
if (yearday > 0)
{
- uint days= calc_daynr(l_time->year,1,1) + yearday - 1;
+ uint days;
+ days= calc_daynr(l_time->year,1,1) + yearday - 1;
if (days <= 0 || days > MAX_DAY_NUMBER)
goto err;
get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day);
@@ -576,7 +582,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
{
if (!my_isspace(&my_charset_latin1,*val))
{
- make_truncated_value_warning(current_thd, val_begin, length,
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ val_begin, length,
cached_timestamp_type, NullS);
break;
}
@@ -600,7 +607,7 @@ err:
Create a formated date/time value in a string
*/
-bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
+bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
timestamp_type type, String *str)
{
char intbuff[15];
@@ -915,8 +922,8 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
*/
-static bool calc_time_diff(TIME *l_time1, TIME *l_time2, int l_sign,
- longlong *seconds_out, long *microseconds_out)
+bool calc_time_diff(MYSQL_TIME *l_time1, MYSQL_TIME *l_time2, int l_sign,
+ longlong *seconds_out, long *microseconds_out)
{
long days;
bool neg;
@@ -996,7 +1003,7 @@ longlong Item_func_period_diff::val_int()
longlong Item_func_to_days::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_arg0_date(&ltime, TIME_NO_ZERO_DATE))
return 0;
return (longlong) calc_daynr(ltime.year,ltime.month,ltime.day);
@@ -1005,7 +1012,7 @@ longlong Item_func_to_days::val_int()
longlong Item_func_dayofyear::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_arg0_date(&ltime,TIME_NO_ZERO_DATE))
return 0;
return (longlong) calc_daynr(ltime.year,ltime.month,ltime.day) -
@@ -1015,7 +1022,7 @@ longlong Item_func_dayofyear::val_int()
longlong Item_func_dayofmonth::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
(void) get_arg0_date(&ltime, TIME_FUZZY_DATE);
return (longlong) ltime.day;
}
@@ -1023,7 +1030,7 @@ longlong Item_func_dayofmonth::val_int()
longlong Item_func_month::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
(void) get_arg0_date(&ltime, TIME_FUZZY_DATE);
return (longlong) ltime.month;
}
@@ -1053,7 +1060,7 @@ String* Item_func_monthname::val_str(String* str)
longlong Item_func_quarter::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_arg0_date(&ltime, TIME_FUZZY_DATE))
return 0;
return (longlong) ((ltime.month+2)/3);
@@ -1062,7 +1069,7 @@ longlong Item_func_quarter::val_int()
longlong Item_func_hour::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
(void) get_arg0_time(&ltime);
return ltime.hour;
}
@@ -1070,7 +1077,7 @@ longlong Item_func_hour::val_int()
longlong Item_func_minute::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
(void) get_arg0_time(&ltime);
return ltime.minute;
}
@@ -1079,7 +1086,7 @@ longlong Item_func_minute::val_int()
longlong Item_func_second::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
(void) get_arg0_time(&ltime);
return ltime.second;
}
@@ -1126,7 +1133,7 @@ longlong Item_func_week::val_int()
{
DBUG_ASSERT(fixed == 1);
uint year;
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_arg0_date(&ltime, TIME_NO_ZERO_DATE))
return 0;
return (longlong) calc_week(&ltime,
@@ -1139,7 +1146,7 @@ longlong Item_func_yearweek::val_int()
{
DBUG_ASSERT(fixed == 1);
uint year,week;
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_arg0_date(&ltime, TIME_NO_ZERO_DATE))
return 0;
week= calc_week(&ltime,
@@ -1152,7 +1159,7 @@ longlong Item_func_yearweek::val_int()
longlong Item_func_weekday::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_arg0_date(&ltime, TIME_NO_ZERO_DATE))
return 0;
@@ -1182,7 +1189,7 @@ String* Item_func_dayname::val_str(String* str)
longlong Item_func_year::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
(void) get_arg0_date(&ltime, TIME_FUZZY_DATE);
return (longlong) ltime.year;
}
@@ -1190,7 +1197,7 @@ longlong Item_func_year::val_int()
longlong Item_func_unix_timestamp::val_int()
{
- TIME ltime;
+ MYSQL_TIME ltime;
my_bool not_used;
DBUG_ASSERT(fixed == 1);
@@ -1221,7 +1228,7 @@ longlong Item_func_unix_timestamp::val_int()
longlong Item_func_time_to_sec::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
longlong seconds;
(void) get_arg0_time(&ltime);
seconds=ltime.hour*3600L+ltime.minute*60+ltime.second;
@@ -1390,10 +1397,10 @@ static bool get_interval_value(Item *args,interval_type int_type,
String *Item_date::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_date(&ltime, TIME_FUZZY_DATE))
return (String *) 0;
- if (str->alloc(11))
+ if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
{
null_value= 1;
return (String *) 0;
@@ -1406,19 +1413,19 @@ String *Item_date::val_str(String *str)
longlong Item_date::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_date(&ltime, TIME_FUZZY_DATE))
return 0;
return (longlong) (ltime.year*10000L+ltime.month*100+ltime.day);
}
-bool Item_func_from_days::get_date(TIME *ltime, uint fuzzy_date)
+bool Item_func_from_days::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
longlong value=args[0]->val_int();
if ((null_value=args[0]->null_value))
return 1;
- bzero(ltime, sizeof(TIME));
+ bzero(ltime, sizeof(MYSQL_TIME));
get_date_from_daynr((long) value, &ltime->year, &ltime->month, &ltime->day);
ltime->time_type= MYSQL_TIMESTAMP_DATE;
return 0;
@@ -1442,7 +1449,7 @@ void Item_func_curdate::fix_length_and_dec()
String *Item_func_curdate::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- if (str->alloc(11))
+ if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
{
null_value= 1;
return (String *) 0;
@@ -1452,10 +1459,10 @@ String *Item_func_curdate::val_str(String *str)
}
/*
- Converts current time in my_time_t to TIME represenatation for local
+ Converts current time in my_time_t to MYSQL_TIME represenatation for local
time zone. Defines time zone (local) used for whole CURDATE function.
*/
-void Item_func_curdate_local::store_now_in_TIME(TIME *now_time)
+void Item_func_curdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
{
THD *thd= current_thd;
thd->variables.time_zone->gmt_sec_to_TIME(now_time,
@@ -1465,10 +1472,10 @@ void Item_func_curdate_local::store_now_in_TIME(TIME *now_time)
/*
- Converts current time in my_time_t to TIME represenatation for UTC
+ Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
time zone. Defines time zone (UTC) used for whole UTC_DATE function.
*/
-void Item_func_curdate_utc::store_now_in_TIME(TIME *now_time)
+void Item_func_curdate_utc::store_now_in_TIME(MYSQL_TIME *now_time)
{
my_tz_UTC->gmt_sec_to_TIME(now_time,
(my_time_t)(current_thd->query_start()));
@@ -1479,7 +1486,7 @@ void Item_func_curdate_utc::store_now_in_TIME(TIME *now_time)
}
-bool Item_func_curdate::get_date(TIME *res,
+bool Item_func_curdate::get_date(MYSQL_TIME *res,
uint fuzzy_date __attribute__((unused)))
{
*res=ltime;
@@ -1497,7 +1504,7 @@ String *Item_func_curtime::val_str(String *str)
void Item_func_curtime::fix_length_and_dec()
{
- TIME ltime;
+ MYSQL_TIME ltime;
decimals= DATETIME_DEC;
collation.set(&my_charset_bin);
@@ -1509,10 +1516,10 @@ void Item_func_curtime::fix_length_and_dec()
/*
- Converts current time in my_time_t to TIME represenatation for local
+ Converts current time in my_time_t to MYSQL_TIME represenatation for local
time zone. Defines time zone (local) used for whole CURTIME function.
*/
-void Item_func_curtime_local::store_now_in_TIME(TIME *now_time)
+void Item_func_curtime_local::store_now_in_TIME(MYSQL_TIME *now_time)
{
THD *thd= current_thd;
thd->variables.time_zone->gmt_sec_to_TIME(now_time,
@@ -1522,10 +1529,10 @@ void Item_func_curtime_local::store_now_in_TIME(TIME *now_time)
/*
- Converts current time in my_time_t to TIME represenatation for UTC
+ Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
time zone. Defines time zone (UTC) used for whole UTC_TIME function.
*/
-void Item_func_curtime_utc::store_now_in_TIME(TIME *now_time)
+void Item_func_curtime_utc::store_now_in_TIME(MYSQL_TIME *now_time)
{
my_tz_UTC->gmt_sec_to_TIME(now_time,
(my_time_t)(current_thd->query_start()));
@@ -1558,10 +1565,10 @@ void Item_func_now::fix_length_and_dec()
/*
- Converts current time in my_time_t to TIME represenatation for local
+ Converts current time in my_time_t to MYSQL_TIME represenatation for local
time zone. Defines time zone (local) used for whole NOW function.
*/
-void Item_func_now_local::store_now_in_TIME(TIME *now_time)
+void Item_func_now_local::store_now_in_TIME(MYSQL_TIME *now_time)
{
THD *thd= current_thd;
thd->variables.time_zone->gmt_sec_to_TIME(now_time,
@@ -1571,10 +1578,10 @@ void Item_func_now_local::store_now_in_TIME(TIME *now_time)
/*
- Converts current time in my_time_t to TIME represenatation for UTC
+ Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
time zone. Defines time zone (UTC) used for whole UTC_TIMESTAMP function.
*/
-void Item_func_now_utc::store_now_in_TIME(TIME *now_time)
+void Item_func_now_utc::store_now_in_TIME(MYSQL_TIME *now_time)
{
my_tz_UTC->gmt_sec_to_TIME(now_time,
(my_time_t)(current_thd->query_start()));
@@ -1585,7 +1592,7 @@ void Item_func_now_utc::store_now_in_TIME(TIME *now_time)
}
-bool Item_func_now::get_date(TIME *res,
+bool Item_func_now::get_date(MYSQL_TIME *res,
uint fuzzy_date __attribute__((unused)))
{
*res= ltime;
@@ -1602,10 +1609,10 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions)
/*
- Converts current time in my_time_t to TIME represenatation for local
+ Converts current time in my_time_t to MYSQL_TIME represenatation for local
time zone. Defines time zone (local) used for whole SYSDATE function.
*/
-void Item_func_sysdate_local::store_now_in_TIME(TIME *now_time)
+void Item_func_sysdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
{
THD *thd= current_thd;
thd->variables.time_zone->gmt_sec_to_TIME(now_time, (my_time_t) time(NULL));
@@ -1647,7 +1654,7 @@ void Item_func_sysdate_local::fix_length_and_dec()
}
-bool Item_func_sysdate_local::get_date(TIME *res,
+bool Item_func_sysdate_local::get_date(MYSQL_TIME *res,
uint fuzzy_date __attribute__((unused)))
{
store_now_in_TIME(&ltime);
@@ -1668,10 +1675,11 @@ int Item_func_sysdate_local::save_in_field(Field *to, bool no_conversions)
String *Item_func_sec_to_time::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
longlong arg_val= args[0]->val_int();
- if ((null_value=args[0]->null_value) || str->alloc(19))
+ if ((null_value=args[0]->null_value) ||
+ str->alloc(MAX_DATE_STRING_REP_LENGTH))
{
null_value= 1;
return (String*) 0;
@@ -1687,7 +1695,7 @@ String *Item_func_sec_to_time::val_str(String *str)
longlong Item_func_sec_to_time::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
longlong arg_val= args[0]->val_int();
if ((null_value=args[0]->null_value))
@@ -1829,7 +1837,7 @@ uint Item_func_date_format::format_length(const String *format)
String *Item_func_date_format::val_str(String *str)
{
String *format;
- TIME l_time;
+ MYSQL_TIME l_time;
uint size;
DBUG_ASSERT(fixed == 1);
@@ -1856,6 +1864,10 @@ String *Item_func_date_format::val_str(String *str)
size=max_length;
else
size=format_length(format);
+
+ if (size < MAX_DATE_STRING_REP_LENGTH)
+ size= MAX_DATE_STRING_REP_LENGTH;
+
if (format == str)
str= &value; // Save result here
if (str->alloc(size))
@@ -1892,27 +1904,28 @@ void Item_func_from_unixtime::fix_length_and_dec()
String *Item_func_from_unixtime::val_str(String *str)
{
- TIME time_tmp;
+ MYSQL_TIME time_tmp;
DBUG_ASSERT(fixed == 1);
if (get_date(&time_tmp, 0))
return 0;
- if (str->alloc(20*MY_CHARSET_BIN_MB_MAXLEN))
+ if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
{
null_value= 1;
return 0;
}
make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str);
+
return str;
}
longlong Item_func_from_unixtime::val_int()
{
- TIME time_tmp;
+ MYSQL_TIME time_tmp;
DBUG_ASSERT(fixed == 1);
@@ -1922,7 +1935,7 @@ longlong Item_func_from_unixtime::val_int()
return (longlong) TIME_to_ulonglong_datetime(&time_tmp);
}
-bool Item_func_from_unixtime::get_date(TIME *ltime,
+bool Item_func_from_unixtime::get_date(MYSQL_TIME *ltime,
uint fuzzy_date __attribute__((unused)))
{
ulonglong tmp= (ulonglong)(args[0]->val_int());
@@ -1963,25 +1976,26 @@ Item_func_convert_tz::fix_fields(THD *thd_arg, Item **ref)
String *Item_func_convert_tz::val_str(String *str)
{
- TIME time_tmp;
+ MYSQL_TIME time_tmp;
if (get_date(&time_tmp, 0))
return 0;
-
- if (str->alloc(20*MY_CHARSET_BIN_MB_MAXLEN))
+
+ if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
{
null_value= 1;
return 0;
}
-
+
make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str);
+
return str;
}
longlong Item_func_convert_tz::val_int()
{
- TIME time_tmp;
+ MYSQL_TIME time_tmp;
if (get_date(&time_tmp, 0))
return 0;
@@ -1990,7 +2004,7 @@ longlong Item_func_convert_tz::val_int()
}
-bool Item_func_convert_tz::get_date(TIME *ltime,
+bool Item_func_convert_tz::get_date(MYSQL_TIME *ltime,
uint fuzzy_date __attribute__((unused)))
{
my_time_t my_time_tmp;
@@ -2051,7 +2065,7 @@ void Item_date_add_interval::fix_length_and_dec()
- If first arg is a MYSQL_TYPE_DATE and the interval type uses hours,
minutes or seconds then type is MYSQL_TYPE_DATETIME.
- Otherwise the result is MYSQL_TYPE_STRING
- (This is because you can't know if the string contains a DATE, TIME or
+ (This is because you can't know if the string contains a DATE, MYSQL_TIME or
DATETIME argument)
*/
cached_field_type= MYSQL_TYPE_STRING;
@@ -2071,7 +2085,7 @@ void Item_date_add_interval::fix_length_and_dec()
/* Here arg[1] is a Item_interval object */
-bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
+bool Item_date_add_interval::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
long period,sign;
INTERVAL interval;
@@ -2173,27 +2187,6 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
default:
goto null_date;
}
-
- /* Adjust cached_field_type according to the detected type. */
- if (cached_field_type == MYSQL_TYPE_STRING)
- {
- switch (ltime->time_type)
- {
- case MYSQL_TIMESTAMP_DATE:
- cached_field_type= MYSQL_TYPE_DATE;
- break;
- case MYSQL_TIMESTAMP_DATETIME:
- cached_field_type= MYSQL_TYPE_DATETIME;
- break;
- case MYSQL_TIMESTAMP_TIME:
- cached_field_type= MYSQL_TYPE_TIME;
- break;
- default:
- /* Shouldn't get here. */
- DBUG_ASSERT(0);
- break;
- }
- }
return 0; // Ok
invalid_date:
@@ -2209,7 +2202,7 @@ invalid_date:
String *Item_date_add_interval::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
enum date_time_format_types format;
if (Item_date_add_interval::get_date(&ltime, TIME_NO_ZERO_DATE))
@@ -2233,7 +2226,7 @@ String *Item_date_add_interval::val_str(String *str)
longlong Item_date_add_interval::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
longlong date;
if (Item_date_add_interval::get_date(&ltime, TIME_NO_ZERO_DATE))
return (longlong) 0;
@@ -2322,7 +2315,7 @@ void Item_extract::fix_length_and_dec()
longlong Item_extract::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
uint year;
ulong week_format;
long neg;
@@ -2574,7 +2567,8 @@ void Item_char_typecast::fix_length_and_dec()
String *Item_datetime_typecast::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
+
if (!get_arg0_date(&ltime, TIME_FUZZY_DATE) &&
!make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME,
&ltime, str))
@@ -2588,7 +2582,7 @@ String *Item_datetime_typecast::val_str(String *str)
longlong Item_datetime_typecast::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_arg0_date(&ltime,1))
{
null_value= 1;
@@ -2599,7 +2593,7 @@ longlong Item_datetime_typecast::val_int()
}
-bool Item_time_typecast::get_time(TIME *ltime)
+bool Item_time_typecast::get_time(MYSQL_TIME *ltime)
{
bool res= get_arg0_time(ltime);
/*
@@ -2615,7 +2609,7 @@ bool Item_time_typecast::get_time(TIME *ltime)
longlong Item_time_typecast::val_int()
{
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_time(&ltime))
{
null_value= 1;
@@ -2627,7 +2621,7 @@ longlong Item_time_typecast::val_int()
String *Item_time_typecast::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (!get_arg0_time(&ltime) &&
!make_datetime(ltime.second_part ? TIME_MICROSECOND : TIME_ONLY,
@@ -2639,7 +2633,7 @@ String *Item_time_typecast::val_str(String *str)
}
-bool Item_date_typecast::get_date(TIME *ltime, uint fuzzy_date)
+bool Item_date_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
bool res= get_arg0_date(ltime, TIME_FUZZY_DATE);
ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
@@ -2651,9 +2645,10 @@ bool Item_date_typecast::get_date(TIME *ltime, uint fuzzy_date)
String *Item_date_typecast::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
- if (!get_arg0_date(&ltime, TIME_FUZZY_DATE) && !str->alloc(11))
+ if (!get_arg0_date(&ltime, TIME_FUZZY_DATE) &&
+ !str->alloc(MAX_DATE_STRING_REP_LENGTH))
{
make_date((DATE_TIME_FORMAT *) 0, &ltime, str);
return str;
@@ -2666,7 +2661,7 @@ String *Item_date_typecast::val_str(String *str)
longlong Item_date_typecast::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (args[0]->get_date(&ltime, TIME_FUZZY_DATE))
{
null_value= 1;
@@ -2678,27 +2673,35 @@ longlong Item_date_typecast::val_int()
/*
MAKEDATE(a,b) is a date function that creates a date value
from a year and day value.
+
+ NOTES:
+ As arguments are integers, we can't know if the year is a 2 digit or 4 digit year.
+ In this case we treat all years < 100 as 2 digit years. Ie, this is not safe
+ for dates between 0000-01-01 and 0099-12-31
*/
String *Item_func_makedate::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- TIME l_time;
+ MYSQL_TIME l_time;
long daynr= (long) args[1]->val_int();
- long yearnr= (long) args[0]->val_int();
+ long year= (long) args[0]->val_int();
long days;
if (args[0]->null_value || args[1]->null_value ||
- yearnr < 0 || daynr <= 0)
+ year < 0 || daynr <= 0)
goto err;
- days= calc_daynr(yearnr,1,1) + daynr - 1;
+ if (year < 100)
+ year= year_2000_handling(year);
+
+ days= calc_daynr(year,1,1) + daynr - 1;
/* Day number from year 0 to 9999-12-31 */
if (days >= 0 && days <= MAX_DAY_NUMBER)
{
null_value=0;
get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day);
- if (str->alloc(11))
+ if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
goto err;
make_date((DATE_TIME_FORMAT *) 0, &l_time, str);
return str;
@@ -2710,19 +2713,32 @@ err:
}
+/*
+ MAKEDATE(a,b) is a date function that creates a date value
+ from a year and day value.
+
+ NOTES:
+ As arguments are integers, we can't know if the year is a 2 digit or 4 digit year.
+ In this case we treat all years < 100 as 2 digit years. Ie, this is not safe
+ for dates between 0000-01-01 and 0099-12-31
+*/
+
longlong Item_func_makedate::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME l_time;
+ MYSQL_TIME l_time;
long daynr= (long) args[1]->val_int();
- long yearnr= (long) args[0]->val_int();
+ long year= (long) args[0]->val_int();
long days;
if (args[0]->null_value || args[1]->null_value ||
- yearnr < 0 || daynr <= 0)
+ year < 0 || daynr <= 0)
goto err;
- days= calc_daynr(yearnr,1,1) + daynr - 1;
+ if (year < 100)
+ year= year_2000_handling(year);
+
+ days= calc_daynr(year,1,1) + daynr - 1;
/* Day number from year 0 to 9999-12-31 */
if (days >= 0 && days < MAX_DAY_NUMBER)
{
@@ -2777,7 +2793,7 @@ void Item_func_add_time::fix_length_and_dec()
String *Item_func_add_time::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- TIME l_time1, l_time2, l_time3;
+ MYSQL_TIME l_time1, l_time2, l_time3;
bool is_time= 0;
long days, microseconds;
longlong seconds;
@@ -2821,6 +2837,7 @@ String *Item_func_add_time::val_str(String *str)
days= (long)(seconds/86400L);
calc_time_from_sec(&l_time3, (long)(seconds%86400L), microseconds);
+
if (!is_time)
{
get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day);
@@ -2879,7 +2896,7 @@ String *Item_func_timediff::val_str(String *str)
longlong seconds;
long microseconds;
int l_sign= 1;
- TIME l_time1 ,l_time2, l_time3;
+ MYSQL_TIME l_time1 ,l_time2, l_time3;
null_value= 0;
if (args[0]->get_time(&l_time1) ||
@@ -2924,7 +2941,7 @@ null_date:
String *Item_func_maketime::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
bool overflow= 0;
longlong hour= args[0]->val_int();
@@ -2936,7 +2953,7 @@ String *Item_func_maketime::val_str(String *str)
args[2]->null_value ||
minute < 0 || minute > 59 ||
second < 0 || second > 59 ||
- str->alloc(19))))
+ str->alloc(MAX_DATE_STRING_REP_LENGTH))))
return 0;
bzero((char *)&ltime, sizeof(ltime));
@@ -2968,7 +2985,8 @@ String *Item_func_maketime::val_str(String *str)
char *ptr= longlong10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10);
int len = (int)(ptr - buf) +
my_sprintf(ptr, (ptr, ":%02u:%02u", (uint)minute, (uint)second));
- make_truncated_value_warning(current_thd, buf, len, MYSQL_TIMESTAMP_TIME,
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ buf, len, MYSQL_TIMESTAMP_TIME,
NullS);
}
@@ -2992,7 +3010,7 @@ String *Item_func_maketime::val_str(String *str)
longlong Item_func_microsecond::val_int()
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (!get_arg0_time(&ltime))
return ltime.second_part;
return 0;
@@ -3001,7 +3019,7 @@ longlong Item_func_microsecond::val_int()
longlong Item_func_timestamp_diff::val_int()
{
- TIME ltime1, ltime2;
+ MYSQL_TIME ltime1, ltime2;
longlong seconds;
long microseconds;
long months= 0;
@@ -3319,7 +3337,7 @@ void Item_func_str_to_date::fix_length_and_dec()
}
}
-bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date)
+bool Item_func_str_to_date::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
DATE_TIME_FORMAT date_time_format;
char val_buff[64], format_buff[64];
@@ -3360,7 +3378,7 @@ null_date:
String *Item_func_str_to_date::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (Item_func_str_to_date::get_date(&ltime, TIME_FUZZY_DATE))
return 0;
@@ -3373,7 +3391,7 @@ String *Item_func_str_to_date::val_str(String *str)
}
-bool Item_func_last_day::get_date(TIME *ltime, uint fuzzy_date)
+bool Item_func_last_day::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
{
if (get_arg0_date(ltime, fuzzy_date & ~TIME_FUZZY_DATE) ||
(ltime->month == 0))
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 14ceb8dcb28..8e925a0156f 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -432,9 +432,9 @@ public:
/*
Abstract method that defines which time zone is used for conversion.
Converts time current time in my_time_t representation to broken-down
- TIME representation using UTC-SYSTEM or per-thread time zone.
+ MYSQL_TIME representation using UTC-SYSTEM or per-thread time zone.
*/
- virtual void store_now_in_TIME(TIME *now_time)=0;
+ virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
bool result_as_longlong() { return TRUE; }
};
@@ -445,7 +445,7 @@ public:
Item_func_curtime_local() :Item_func_curtime() {}
Item_func_curtime_local(Item *a) :Item_func_curtime(a) {}
const char *func_name() const { return "curtime"; }
- virtual void store_now_in_TIME(TIME *now_time);
+ virtual void store_now_in_TIME(MYSQL_TIME *now_time);
};
@@ -455,7 +455,7 @@ public:
Item_func_curtime_utc() :Item_func_curtime() {}
Item_func_curtime_utc(Item *a) :Item_func_curtime(a) {}
const char *func_name() const { return "utc_time"; }
- virtual void store_now_in_TIME(TIME *now_time);
+ virtual void store_now_in_TIME(MYSQL_TIME *now_time);
};
@@ -464,14 +464,14 @@ public:
class Item_func_curdate :public Item_date
{
longlong value;
- TIME ltime;
+ MYSQL_TIME ltime;
public:
Item_func_curdate() :Item_date() {}
longlong val_int() { DBUG_ASSERT(fixed == 1); return (value) ; }
String *val_str(String *str);
void fix_length_and_dec();
- bool get_date(TIME *res, uint fuzzy_date);
- virtual void store_now_in_TIME(TIME *now_time)=0;
+ bool get_date(MYSQL_TIME *res, uint fuzzy_date);
+ virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
};
@@ -480,7 +480,7 @@ class Item_func_curdate_local :public Item_func_curdate
public:
Item_func_curdate_local() :Item_func_curdate() {}
const char *func_name() const { return "curdate"; }
- void store_now_in_TIME(TIME *now_time);
+ void store_now_in_TIME(MYSQL_TIME *now_time);
};
@@ -489,7 +489,7 @@ class Item_func_curdate_utc :public Item_func_curdate
public:
Item_func_curdate_utc() :Item_func_curdate() {}
const char *func_name() const { return "utc_date"; }
- void store_now_in_TIME(TIME *now_time);
+ void store_now_in_TIME(MYSQL_TIME *now_time);
};
@@ -501,7 +501,7 @@ protected:
longlong value;
char buff[20*2+32]; // +32 to make my_snprintf_{8bit|ucs2} happy
uint buff_length;
- TIME ltime;
+ MYSQL_TIME ltime;
public:
Item_func_now() :Item_date_func() {}
Item_func_now(Item *a) :Item_date_func(a) {}
@@ -510,8 +510,8 @@ public:
int save_in_field(Field *to, bool no_conversions);
String *val_str(String *str);
void fix_length_and_dec();
- bool get_date(TIME *res, uint fuzzy_date);
- virtual void store_now_in_TIME(TIME *now_time)=0;
+ bool get_date(MYSQL_TIME *res, uint fuzzy_date);
+ virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0;
};
@@ -521,7 +521,7 @@ public:
Item_func_now_local() :Item_func_now() {}
Item_func_now_local(Item *a) :Item_func_now(a) {}
const char *func_name() const { return "now"; }
- virtual void store_now_in_TIME(TIME *now_time);
+ virtual void store_now_in_TIME(MYSQL_TIME *now_time);
virtual enum Functype functype() const { return NOW_FUNC; }
};
@@ -532,7 +532,7 @@ public:
Item_func_now_utc() :Item_func_now() {}
Item_func_now_utc(Item *a) :Item_func_now(a) {}
const char *func_name() const { return "utc_timestamp"; }
- virtual void store_now_in_TIME(TIME *now_time);
+ virtual void store_now_in_TIME(MYSQL_TIME *now_time);
};
@@ -547,13 +547,13 @@ public:
Item_func_sysdate_local(Item *a) :Item_func_now(a) {}
bool const_item() const { return 0; }
const char *func_name() const { return "sysdate"; }
- void store_now_in_TIME(TIME *now_time);
+ void store_now_in_TIME(MYSQL_TIME *now_time);
double val_real();
longlong val_int();
int save_in_field(Field *to, bool no_conversions);
String *val_str(String *str);
void fix_length_and_dec();
- bool get_date(TIME *res, uint fuzzy_date);
+ bool get_date(MYSQL_TIME *res, uint fuzzy_date);
void update_used_tables()
{
Item_func_now::update_used_tables();
@@ -567,7 +567,7 @@ class Item_func_from_days :public Item_date
public:
Item_func_from_days(Item *a) :Item_date(a) {}
const char *func_name() const { return "from_days"; }
- bool get_date(TIME *res, uint fuzzy_date);
+ bool get_date(MYSQL_TIME *res, uint fuzzy_date);
};
@@ -597,7 +597,7 @@ class Item_func_from_unixtime :public Item_date_func
String *val_str(String *str);
const char *func_name() const { return "from_unixtime"; }
void fix_length_and_dec();
- bool get_date(TIME *res, uint fuzzy_date);
+ bool get_date(MYSQL_TIME *res, uint fuzzy_date);
};
@@ -635,7 +635,7 @@ class Item_func_convert_tz :public Item_date_func
const char *func_name() const { return "convert_tz"; }
bool fix_fields(THD *, Item **);
void fix_length_and_dec();
- bool get_date(TIME *res, uint fuzzy_date);
+ bool get_date(MYSQL_TIME *res, uint fuzzy_date);
void cleanup();
};
@@ -694,7 +694,7 @@ public:
void fix_length_and_dec();
enum_field_types field_type() const { return cached_field_type; }
longlong val_int();
- bool get_date(TIME *res, uint fuzzy_date);
+ bool get_date(MYSQL_TIME *res, uint fuzzy_date);
bool eq(const Item *item, bool binary_cmp) const;
void print(String *str);
};
@@ -778,7 +778,7 @@ public:
Item_date_typecast(Item *a) :Item_typecast_maybe_null(a) {}
const char *func_name() const { return "cast_as_date"; }
String *val_str(String *str);
- bool get_date(TIME *ltime, uint fuzzy_date);
+ bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
const char *cast_type() const { return "date"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
Field *tmp_table_field(TABLE *t_arg)
@@ -812,7 +812,7 @@ public:
Item_time_typecast(Item *a) :Item_typecast_maybe_null(a) {}
const char *func_name() const { return "cast_as_time"; }
String *val_str(String *str);
- bool get_time(TIME *ltime);
+ bool get_time(MYSQL_TIME *ltime);
const char *cast_type() const { return "time"; }
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
Field *tmp_table_field(TABLE *t_arg)
@@ -1033,7 +1033,7 @@ public:
:Item_str_func(a, b)
{}
String *val_str(String *str);
- bool get_date(TIME *ltime, uint fuzzy_date);
+ bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
const char *func_name() const { return "str_to_date"; }
enum_field_types field_type() const { return cached_field_type; }
void fix_length_and_dec();
@@ -1046,5 +1046,5 @@ class Item_func_last_day :public Item_date
public:
Item_func_last_day(Item *a) :Item_date(a) {}
const char *func_name() const { return "last_day"; }
- bool get_date(TIME *res, uint fuzzy_date);
+ bool get_date(MYSQL_TIME *res, uint fuzzy_date);
};
diff --git a/sql/lock.cc b/sql/lock.cc
index 9298b33b4d2..93358e56701 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -178,6 +178,13 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
}
else if (rc == 1) /* aborted */
{
+ /*
+ reset_lock_data is required here. If thr_multi_lock fails it
+ resets lock type for tables, which were locked before (and
+ including) one that caused error. Lock type for other tables
+ preserved.
+ */
+ reset_lock_data(sql_lock);
thd->some_tables_deleted=1; // Try again
sql_lock->lock_count= 0; // Locks are already freed
}
diff --git a/sql/log.cc b/sql/log.cc
index 7563d754556..818828f9557 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1784,7 +1784,7 @@ void MYSQL_LOG::rotate_and_purge(uint flags)
#ifdef HAVE_REPLICATION
if (expire_logs_days)
{
- long purge_time= (long) (time(0) - expire_logs_days*24*60*60);
+ time_t purge_time= time(0) - expire_logs_days*24*60*60;
if (purge_time >= 0)
purge_logs_before_date(purge_time);
}
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 173ca6232ee..c37df31ae00 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1001,11 +1001,15 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
}
*c= '\0';
- /* Non-full last line */
if (hex_string[0])
+ {
+ /* Non-full last line */
fprintf(file, "# %8.8lx %-48.48s |%s|\n# ",
(unsigned long) (hexdump_from + (i & 0xfffffff0)),
hex_string, char_string);
+ }
+ else
+ fprintf(file, "# ");
}
}
@@ -1279,20 +1283,31 @@ Query_log_event::Query_log_event()
/*
- Query_log_event::Query_log_event()
+ SYNOPSIS
+ Query_log_event::Query_log_event()
+ thd - thread handle
+ query_arg - array of char representing the query
+ query_length - size of the `query_arg' array
+ using_trans - there is a modified transactional table
+ suppress_use - suppress the generation of 'USE' statements
+ killed_status_arg - an optional with default to THD::KILLED_NO_VALUE
+ if the value is different from the default, the arg
+ is set to the current thd->killed value.
+ A caller might need to masquerade thd->killed with
+ THD::NOT_KILLED.
+ DESCRIPTION
+ Creates an event for binlogging
+ The value for local `killed_status' can be supplied by caller.
*/
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
ulong query_length, bool using_trans,
- bool suppress_use)
+ bool suppress_use, THD::killed_state killed_status_arg)
:Log_event(thd_arg,
((thd_arg->tmp_table_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0)
| (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0)),
using_trans),
data_buf(0), query(query_arg), catalog(thd_arg->catalog),
db(thd_arg->db), q_len((uint32) query_length),
- error_code((thd_arg->killed != THD::NOT_KILLED) ?
- ((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ?
- 0 : thd->killed_errno()) : thd_arg->net.last_errno),
thread_id(thd_arg->thread_id),
/* save the original thread id; we already know the server id */
slave_proxy_id(thd_arg->variables.pseudo_thread_id),
@@ -1304,6 +1319,14 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
charset_database_number(0)
{
time_t end_time;
+
+ if (killed_status_arg == THD::KILLED_NO_VALUE)
+ killed_status_arg= thd_arg->killed;
+ error_code=
+ (killed_status_arg == THD::NOT_KILLED) ? thd_arg->net.last_errno :
+ ((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ? 0 :
+ thd->killed_errno());
+
time(&end_time);
exec_time = (ulong) (end_time - thd->start_time);
catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
@@ -1945,6 +1968,7 @@ Default database: '%s'. Query: '%s'",
{
DBUG_PRINT("info",("error ignored"));
clear_all_errors(thd, rli);
+ thd->killed= THD::NOT_KILLED;
}
/*
Other cases: mostly we expected no error and get one.
@@ -3378,6 +3402,8 @@ int Rotate_log_event::exec_event(struct st_relay_log_info* rli)
memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
rli->notify_group_master_log_name_update();
rli->group_master_log_pos= pos;
+ strmake(rli->group_relay_log_name, rli->event_relay_log_name,
+ sizeof(rli->group_relay_log_name) - 1);
rli->group_relay_log_pos= rli->event_relay_log_pos;
DBUG_PRINT("info", ("group_master_log_name: '%s' group_master_log_pos:\
%lu",
diff --git a/sql/log_event.h b/sql/log_event.h
index a1e7adb6487..04aac5d08fc 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -804,7 +804,8 @@ public:
#ifndef MYSQL_CLIENT
Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length,
- bool using_trans, bool suppress_use);
+ bool using_trans, bool suppress_use,
+ THD::killed_state killed_err_arg= THD::KILLED_NO_VALUE);
const char* get_db() { return db; }
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc
index 0ef1f9794ba..4ef2ae5cf95 100644
--- a/sql/my_decimal.cc
+++ b/sql/my_decimal.cc
@@ -191,7 +191,7 @@ int str2my_decimal(uint mask, const char *from, uint length,
}
-my_decimal *date2my_decimal(TIME *ltime, my_decimal *dec)
+my_decimal *date2my_decimal(MYSQL_TIME *ltime, my_decimal *dec)
{
longlong date;
date = (ltime->year*100L + ltime->month)*100L + ltime->day;
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index 0affa07557e..c661579ea66 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -300,7 +300,7 @@ int string2my_decimal(uint mask, const String *str, my_decimal *d)
}
-my_decimal *date2my_decimal(TIME *ltime, my_decimal *dec);
+my_decimal *date2my_decimal(MYSQL_TIME *ltime, my_decimal *dec);
#endif /*defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY) */
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index f03ef487154..0aaa1744fe1 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -89,9 +89,6 @@ void kill_one_thread(THD *thd, ulong id, bool only_kill_query);
bool net_request_file(NET* net, const char* fname);
char* query_table_status(THD *thd,const char *db,const char *table_name);
-void net_set_write_timeout(NET *net, uint timeout);
-void net_set_read_timeout(NET *net, uint timeout);
-
#define x_free(A) { my_free((gptr) (A),MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); }
#define safeFree(x) { if(x) { my_free((gptr) x,MYF(0)); x = NULL; } }
#define PREV_BITS(type,A) ((type) (((type) 1 << (A)) -1))
@@ -179,7 +176,7 @@ MY_LOCALE *my_locale_by_number(uint number);
#define STACK_MIN_SIZE 12000 // Abort if less stack during eval.
#define STACK_MIN_SIZE_FOR_OPEN 1024*80
-#define STACK_BUFF_ALLOC 256 // For stack overrun checks
+#define STACK_BUFF_ALLOC 352 // For stack overrun checks
#ifndef MYSQLD_NET_RETRY_COUNT
#define MYSQLD_NET_RETRY_COUNT 10 // Abort read after this many int.
#endif
@@ -816,9 +813,8 @@ bool mysql_alter_table(THD *thd, char *new_db, char *new_name,
Alter_info *alter_info,
uint order_num, ORDER *order, bool ignore);
bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list);
-bool mysql_create_like_table(THD *thd, TABLE_LIST *table,
- HA_CREATE_INFO *create_info,
- Table_ident *src_table);
+bool mysql_create_like_table(THD *thd, TABLE_LIST *table, TABLE_LIST *src_table,
+ HA_CREATE_INFO *create_info);
bool mysql_rename_table(enum db_type base,
const char *old_db,
const char * old_name,
@@ -1272,8 +1268,6 @@ extern char language[FN_REFLEN], reg_ext[FN_EXTLEN];
extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file;
extern char log_error_file[FN_REFLEN], *opt_tc_log_file;
-extern double log_10[32];
-extern double log_01[32];
extern ulonglong log_10_int[20];
extern ulonglong keybuff_size;
extern ulonglong thd_startup_options;
@@ -1510,16 +1504,22 @@ ulong convert_period_to_month(ulong period);
ulong convert_month_to_period(ulong month);
void get_date_from_daynr(long daynr,uint *year, uint *month,
uint *day);
-my_time_t TIME_to_timestamp(THD *thd, const TIME *t, my_bool *not_exist);
-bool str_to_time_with_warn(const char *str,uint length,TIME *l_time);
+my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, my_bool *not_exist);
+bool str_to_time_with_warn(const char *str,uint length,MYSQL_TIME *l_time);
timestamp_type str_to_datetime_with_warn(const char *str, uint length,
- TIME *l_time, uint flags);
-void localtime_to_TIME(TIME *to, struct tm *from);
-void calc_time_from_sec(TIME *to, long seconds, long microseconds);
+ MYSQL_TIME *l_time, uint flags);
+void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
+void calc_time_from_sec(MYSQL_TIME *to, long seconds, long microseconds);
+
+void make_truncated_value_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
+ const char *str_val,
+ uint str_length, timestamp_type time_type,
+ const char *field_name);
+
+bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type, INTERVAL interval);
+bool calc_time_diff(MYSQL_TIME *l_time1, MYSQL_TIME *l_time2, int l_sign,
+ longlong *seconds_out, long *microseconds_out);
-void make_truncated_value_warning(THD *thd, const char *str_val,
- uint str_length, timestamp_type time_type,
- const char *field_name);
extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type,
const char *format_str,
uint format_length);
@@ -1527,13 +1527,13 @@ extern DATE_TIME_FORMAT *date_time_format_copy(THD *thd,
DATE_TIME_FORMAT *format);
const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format,
timestamp_type type);
-extern bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
+extern bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
timestamp_type type, String *str);
-void make_datetime(const DATE_TIME_FORMAT *format, const TIME *l_time,
+void make_datetime(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time,
String *str);
-void make_date(const DATE_TIME_FORMAT *format, const TIME *l_time,
+void make_date(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time,
String *str);
-void make_time(const DATE_TIME_FORMAT *format, const TIME *l_time,
+void make_time(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time,
String *str);
ulonglong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
Item *warn_item, bool *is_null);
@@ -1555,7 +1555,7 @@ double my_double_round(double value, longlong dec, bool dec_unsigned,
bool truncate);
int get_quick_record(SQL_SELECT *select);
int calc_weekday(long daynr,bool sunday_first_day_of_week);
-uint calc_week(TIME *l_time, uint week_behaviour, uint *year);
+uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year);
void find_date(char *pos,uint *vek,uint flag);
TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end);
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index e5abef25b62..afeb3b82a01 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -32,6 +32,9 @@
#ifdef HAVE_NDBCLUSTER_DB
#include "ha_ndbcluster.h"
#endif
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
#ifdef HAVE_INNOBASE_DB
#define OPT_INNODB_DEFAULT 1
@@ -346,7 +349,15 @@ bool opt_endinfo, using_udf_functions;
my_bool locked_in_memory;
bool opt_using_transactions, using_update_log;
bool volatile abort_loop;
-bool volatile shutdown_in_progress, grant_option;
+bool volatile shutdown_in_progress;
+/**
+ @brief 'grant_option' is used to indicate if privileges needs
+ to be checked, in which case the lock, LOCK_grant, is used
+ to protect access to the grant table.
+ @note This flag is dropped in 5.1
+ @see grant_init()
+ */
+bool volatile grant_option;
my_bool opt_skip_slave_start = 0; // If set, slave is not autostarted
my_bool opt_reckless_slave = 0;
@@ -434,8 +445,6 @@ ulong slow_launch_threads = 0, sync_binlog_period;
ulong expire_logs_days = 0;
ulong rpl_recovery_rank=0;
-double log_10[32]; /* 10 potences */
-double log_01[32];
time_t server_start_time;
char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
@@ -1365,6 +1374,15 @@ static struct passwd *check_user(const char *user)
err:
sql_print_error("Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user);
unireg_abort(1);
+
+#ifdef PR_SET_DUMPABLE
+ if (test_flags & TEST_CORE_ON_SIGNAL)
+ {
+ /* inform kernel that process is dumpable */
+ (void) prctl(PR_SET_DUMPABLE, 1);
+ }
+#endif
+
#endif
return NULL;
}
@@ -2148,6 +2166,16 @@ later when used with nscd), disable LDAP in your nsswitch.conf, or use a\n\
mysqld that is not statically linked.\n");
#endif
+#ifdef HAVE_NPTL
+ if (thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
+ fprintf(stderr,"\n\
+You are running a statically-linked LinuxThreads binary on an NPTL system.\n\
+This can result in crashes on some distributions due to LT/NPTL conflicts.\n\
+You should either build a dynamically-linked binary, or force LinuxThreads\n\
+to be used with the LD_ASSUME_KERNEL environment variable. Please consult\n\
+the documentation for your distribution on how to do that.\n");
+#endif
+
if (locked_in_memory)
{
fprintf(stderr, "\n\
@@ -3271,7 +3299,7 @@ server.");
#ifdef HAVE_REPLICATION
if (opt_bin_log && expire_logs_days)
{
- long purge_time= (long) (time(0) - expire_logs_days*24*60*60);
+ time_t purge_time= time(0) - expire_logs_days*24*60*60;
if (purge_time >= 0)
mysql_bin_log.purge_logs_before_date(purge_time);
}
@@ -3574,6 +3602,11 @@ we force server id to 2, but this MySQL server will not act as a slave.");
freopen(log_error_file,"a+",stderr);
FreeConsole(); // Remove window
}
+ else
+ {
+ /* Don't show error dialog box when on foreground: it stops the server */
+ SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
+ }
#endif
/*
@@ -4387,7 +4420,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg)
HANDLE event_connect_answer= 0;
ulong smem_buffer_length= shared_memory_buffer_length + 4;
ulong connect_number= 1;
- char tmp[63];
+ char *tmp= NULL;
char *suffix_pos;
char connect_number_char[22], *p;
const char *errmsg= 0;
@@ -4396,6 +4429,12 @@ pthread_handler_t handle_connections_shared_memory(void *arg)
DBUG_ENTER("handle_connections_shared_memorys");
DBUG_PRINT("general",("Waiting for allocated shared memory."));
+ /*
+ get enough space base-name + '_' + longest suffix we might ever send
+ */
+ if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L, MYF(MY_FAE))))
+ goto error;
+
if (my_security_attr_create(&sa_event, &errmsg,
GENERIC_ALL, SYNCHRONIZE | EVENT_MODIFY_STATE))
goto error;
@@ -4583,6 +4622,9 @@ errorconn:
/* End shared memory handling */
error:
+ if (tmp)
+ my_free(tmp, MYF(0));
+
if (errmsg)
{
char buff[180];
@@ -5806,7 +5848,7 @@ log and this option does nothing anymore.",
(gptr*) &dflt_key_cache_var.param_block_size,
(gptr*) 0,
0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
- KEY_CACHE_BLOCK_SIZE , 512, 1024*16, MALLOC_OVERHEAD, 512, 0},
+ KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0},
{"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
"The minimum percentage of warm blocks in key cache",
(gptr*) &dflt_key_cache_var.param_division_limit,
@@ -6177,14 +6219,15 @@ struct show_var_st status_vars[]= {
{"Aborted_connects", (char*) &aborted_connects, SHOW_LONG},
{"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG},
{"Binlog_cache_use", (char*) &binlog_cache_use, SHOW_LONG},
- {"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONG_STATUS},
- {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONG_STATUS},
+ {"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
+ {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
{"Com_admin_commands", (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS},
{"Com_alter_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
{"Com_alter_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
{"Com_analyze", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
{"Com_backup_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BACKUP_TABLE]), SHOW_LONG_STATUS},
{"Com_begin", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BEGIN]), SHOW_LONG_STATUS},
+ {"Com_call_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CALL]), SHOW_LONG_STATUS},
{"Com_change_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_DB]), SHOW_LONG_STATUS},
{"Com_change_master", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_MASTER]), SHOW_LONG_STATUS},
{"Com_check", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECK]), SHOW_LONG_STATUS},
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index a635d058cd5..017a2eb9ecd 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -120,13 +120,13 @@ static my_bool net_write_buff(NET *net,const char *packet,ulong len);
my_bool my_net_init(NET *net, Vio* vio)
{
DBUG_ENTER("my_net_init");
+ net->vio = vio;
my_net_local_init(net); /* Set some limits */
if (!(net->buff=(uchar*) my_malloc((uint32) net->max_packet+
NET_HEADER_SIZE + COMP_HEADER_SIZE,
MYF(MY_WME))))
DBUG_RETURN(1);
net->buff_end=net->buff+net->max_packet;
- net->vio = vio;
net->no_send_ok= net->no_send_eof= net->no_send_error= 0;
net->error=0; net->return_errno=0; net->return_status=0;
net->pkt_nr=net->compress_pkt_nr=0;
@@ -609,10 +609,10 @@ net_real_write(NET *net,const char *packet,ulong len)
#ifndef NO_ALARM
thr_alarm_init(&alarmed);
if (net_blocking)
- thr_alarm(&alarmed,(uint) net->write_timeout,&alarm_buff);
+ thr_alarm(&alarmed, net->write_timeout, &alarm_buff);
#else
alarmed=0;
- /* Write timeout is set in net_set_write_timeout */
+ /* Write timeout is set in my_net_set_write_timeout */
#endif /* NO_ALARM */
pos=(char*) packet; end=pos+len;
@@ -624,7 +624,7 @@ net_real_write(NET *net,const char *packet,ulong len)
#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2))
if ((interrupted || length==0) && !thr_alarm_in_use(&alarmed))
{
- if (!thr_alarm(&alarmed,(uint) net->write_timeout,&alarm_buff))
+ if (!thr_alarm(&alarmed, net->write_timeout, &alarm_buff))
{ /* Always true for client */
my_bool old_mode;
while (vio_blocking(net->vio, TRUE, &old_mode) < 0)
@@ -805,7 +805,7 @@ my_real_read(NET *net, ulong *complen)
if (net_blocking)
thr_alarm(&alarmed,net->read_timeout,&alarm_buff);
#else
- /* Read timeout is set in net_set_read_timeout */
+ /* Read timeout is set in my_net_set_read_timeout */
#endif /* NO_ALARM */
pos = net->buff + net->where_b; /* net->packet -4 */
@@ -1117,25 +1117,27 @@ my_net_read(NET *net)
}
-void net_set_read_timeout(NET *net, uint timeout)
+void my_net_set_read_timeout(NET *net, uint timeout)
{
- DBUG_ENTER("net_set_read_timeout");
+ DBUG_ENTER("my_net_set_read_timeout");
DBUG_PRINT("enter", ("timeout: %d", timeout));
net->read_timeout= timeout;
#ifdef NO_ALARM
- vio_timeout(net->vio, 0, timeout);
+ if (net->vio)
+ vio_timeout(net->vio, 0, timeout);
#endif
DBUG_VOID_RETURN;
}
-void net_set_write_timeout(NET *net, uint timeout)
+void my_net_set_write_timeout(NET *net, uint timeout)
{
- DBUG_ENTER("net_set_write_timeout");
+ DBUG_ENTER("my_net_set_write_timeout");
DBUG_PRINT("enter", ("timeout: %d", timeout));
net->write_timeout= timeout;
#ifdef NO_ALARM
- vio_timeout(net->vio, 1, timeout);
+ if (net->vio)
+ vio_timeout(net->vio, 1, timeout);
#endif
DBUG_VOID_RETURN;
}
diff --git a/sql/protocol.cc b/sql/protocol.cc
index f9ba734a48d..ced6d78519a 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -948,7 +948,7 @@ bool Protocol_simple::store(Field *field)
*/
-bool Protocol_simple::store(TIME *tm)
+bool Protocol_simple::store(MYSQL_TIME *tm)
{
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
@@ -971,7 +971,7 @@ bool Protocol_simple::store(TIME *tm)
}
-bool Protocol_simple::store_date(TIME *tm)
+bool Protocol_simple::store_date(MYSQL_TIME *tm)
{
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
@@ -990,7 +990,7 @@ bool Protocol_simple::store_date(TIME *tm)
we support 0-6 decimals for time.
*/
-bool Protocol_simple::store_time(TIME *tm)
+bool Protocol_simple::store_time(MYSQL_TIME *tm)
{
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
@@ -1162,7 +1162,7 @@ bool Protocol_prep::store(Field *field)
}
-bool Protocol_prep::store(TIME *tm)
+bool Protocol_prep::store(MYSQL_TIME *tm)
{
char buff[12],*pos;
uint length;
@@ -1188,7 +1188,7 @@ bool Protocol_prep::store(TIME *tm)
return packet->append(buff, length+1, PACKET_BUFFER_EXTRA_ALLOC);
}
-bool Protocol_prep::store_date(TIME *tm)
+bool Protocol_prep::store_date(MYSQL_TIME *tm)
{
tm->hour= tm->minute= tm->second=0;
tm->second_part= 0;
@@ -1196,7 +1196,7 @@ bool Protocol_prep::store_date(TIME *tm)
}
-bool Protocol_prep::store_time(TIME *tm)
+bool Protocol_prep::store_time(MYSQL_TIME *tm)
{
char buff[13], *pos;
uint length;
diff --git a/sql/protocol.h b/sql/protocol.h
index 0e00a7c21e0..f8e7f490d1b 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -86,9 +86,9 @@ public:
CHARSET_INFO *fromcs, CHARSET_INFO *tocs)=0;
virtual bool store(float from, uint32 decimals, String *buffer)=0;
virtual bool store(double from, uint32 decimals, String *buffer)=0;
- virtual bool store(TIME *time)=0;
- virtual bool store_date(TIME *time)=0;
- virtual bool store_time(TIME *time)=0;
+ virtual bool store(MYSQL_TIME *time)=0;
+ virtual bool store_date(MYSQL_TIME *time)=0;
+ virtual bool store_time(MYSQL_TIME *time)=0;
virtual bool store(Field *field)=0;
#ifdef EMBEDDED_LIBRARY
int begin_dataset();
@@ -116,9 +116,9 @@ public:
virtual bool store(const char *from, uint length, CHARSET_INFO *cs);
virtual bool store(const char *from, uint length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
- virtual bool store(TIME *time);
- virtual bool store_date(TIME *time);
- virtual bool store_time(TIME *time);
+ virtual bool store(MYSQL_TIME *time);
+ virtual bool store_date(MYSQL_TIME *time);
+ virtual bool store_time(MYSQL_TIME *time);
virtual bool store(float nr, uint32 decimals, String *buffer);
virtual bool store(double from, uint32 decimals, String *buffer);
virtual bool store(Field *field);
@@ -150,9 +150,9 @@ public:
virtual bool store(const char *from,uint length, CHARSET_INFO *cs);
virtual bool store(const char *from, uint length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
- virtual bool store(TIME *time);
- virtual bool store_date(TIME *time);
- virtual bool store_time(TIME *time);
+ virtual bool store(MYSQL_TIME *time);
+ virtual bool store_date(MYSQL_TIME *time);
+ virtual bool store_time(MYSQL_TIME *time);
virtual bool store(float nr, uint32 decimals, String *buffer);
virtual bool store(double from, uint32 decimals, String *buffer);
virtual bool store(Field *field);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 8808327ce0a..09cdc34f803 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1226,7 +1226,11 @@ static void sys_default_ftb_syntax(THD *thd, enum_var_type type)
static void fix_low_priority_updates(THD *thd, enum_var_type type)
{
- if (type != OPT_GLOBAL)
+ if (type == OPT_GLOBAL)
+ thr_upgraded_concurrent_insert_lock=
+ (global_system_variables.low_priority_updates ?
+ TL_WRITE_LOW_PRIORITY : TL_WRITE);
+ else
thd->update_lock_default= (thd->variables.low_priority_updates ?
TL_WRITE_LOW_PRIORITY : TL_WRITE);
}
@@ -1291,14 +1295,14 @@ static int check_completion_type(THD *thd, set_var *var)
static void fix_net_read_timeout(THD *thd, enum_var_type type)
{
if (type != OPT_GLOBAL)
- net_set_read_timeout(&thd->net, thd->variables.net_read_timeout);
+ my_net_set_read_timeout(&thd->net, thd->variables.net_read_timeout);
}
static void fix_net_write_timeout(THD *thd, enum_var_type type)
{
if (type != OPT_GLOBAL)
- net_set_write_timeout(&thd->net, thd->variables.net_write_timeout);
+ my_net_set_write_timeout(&thd->net, thd->variables.net_write_timeout);
}
static void fix_net_retry_count(THD *thd, enum_var_type type)
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 1230287656e..a52ffa8216c 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5633,4 +5633,5 @@ ER_WRONG_STRING_LENGTH
eng "String '%-.70s' is too long for %s (should be no longer than %d)"
ER_NON_INSERTABLE_TABLE
eng "The target table %-.100s of the %s is not insertable-into"
-
+ER_ADMIN_WRONG_MRG_TABLE
+ eng "Table '%-.64s' is differently defined or of non-MyISAM type or doesn't exist"
diff --git a/sql/sp.cc b/sql/sp.cc
index 976bb1911b2..de786a77275 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -757,7 +757,7 @@ print_field_values(THD *thd, TABLE *table,
switch (used_field->field_type) {
case MYSQL_TYPE_TIMESTAMP:
{
- TIME tmp_time;
+ MYSQL_TIME tmp_time;
bzero((char *)&tmp_time, sizeof(tmp_time));
((Field_timestamp *) used_field->field)->get_time(&tmp_time);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 835d8bf038f..a98fe5027c9 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -539,7 +539,7 @@ sp_head::init_strings(THD *thd, LEX *lex)
Trim "garbage" at the end. This is sometimes needed with the
"/ * ! VERSION... * /" wrapper in dump files.
*/
- endp= skip_rear_comments((char*) m_body_begin, (char*) endp);
+ endp= skip_rear_comments(thd->charset(), (char*) m_body_begin, (char*) endp);
m_body.length= endp - m_body_begin;
m_body.str= strmake_root(root, m_body_begin, m_body.length);
@@ -1321,6 +1321,9 @@ err_with_cleanup:
free_root(&call_mem_root, MYF(0));
thd->spcont= octx;
+ if (thd->killed)
+ thd->send_kill_message();
+
DBUG_RETURN(err_status);
}
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index ebf9385d177..f9bd2c6ba0d 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -978,14 +978,15 @@ bool acl_getroot_no_password(Security_context *sctx, char *user, char *host,
*/
for (i=0 ; i < acl_users.elements ; i++)
{
- acl_user= dynamic_element(&acl_users,i,ACL_USER*);
- if ((!acl_user->user && !user[0]) ||
- (acl_user->user && strcmp(user, acl_user->user) == 0))
+ ACL_USER *acl_user_tmp= dynamic_element(&acl_users,i,ACL_USER*);
+ if ((!acl_user_tmp->user && !user[0]) ||
+ (acl_user_tmp->user && strcmp(user, acl_user_tmp->user) == 0))
{
- if (compare_hostname(&acl_user->host, host, ip))
+ if (compare_hostname(&acl_user_tmp->host, host, ip))
{
- res= 0;
- break;
+ acl_user= acl_user_tmp;
+ res= 0;
+ break;
}
}
}
@@ -2995,7 +2996,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
}
}
}
- grant_option=TRUE;
+
thd->mem_root= old_root;
pthread_mutex_unlock(&acl_cache->lock);
@@ -3162,7 +3163,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
continue;
}
}
- grant_option=TRUE;
+
thd->mem_root= old_root;
pthread_mutex_unlock(&acl_cache->lock);
if (!result && !no_error)
@@ -3338,6 +3339,8 @@ my_bool grant_init()
delete thd;
/* Remember that we don't have a THD */
my_pthread_setspecific_ptr(THR_THD, 0);
+ /* Set the grant option flag so we will check grants */
+ grant_option= TRUE;
DBUG_RETURN(return_val);
}
@@ -3367,7 +3370,6 @@ static my_bool grant_load(TABLE_LIST *tables)
THR_MALLOC);
DBUG_ENTER("grant_load");
- grant_option = FALSE;
(void) hash_init(&column_priv_hash,system_charset_info,
0,0,0, (hash_get_key) get_grant_table,
(hash_free_key) free_grant_table,0);
@@ -3478,7 +3480,6 @@ static my_bool grant_load(TABLE_LIST *tables)
}
while (!p_table->file->index_next(p_table->record[0]));
}
- grant_option= TRUE;
return_val=0; // Return ok
end_unlock:
@@ -3511,7 +3512,6 @@ my_bool grant_reload(THD *thd)
{
TABLE_LIST tables[3];
HASH old_column_priv_hash, old_proc_priv_hash, old_func_priv_hash;
- bool old_grant_option;
MEM_ROOT old_mem;
my_bool return_val= 1;
DBUG_ENTER("grant_reload");
@@ -3541,7 +3541,6 @@ my_bool grant_reload(THD *thd)
old_column_priv_hash= column_priv_hash;
old_proc_priv_hash= proc_priv_hash;
old_func_priv_hash= func_priv_hash;
- old_grant_option= grant_option;
old_mem= memex;
if ((return_val= grant_load(tables)))
@@ -3551,7 +3550,6 @@ my_bool grant_reload(THD *thd)
column_priv_hash= old_column_priv_hash; /* purecov: deadcode */
proc_priv_hash= old_proc_priv_hash;
func_priv_hash= old_func_priv_hash;
- grant_option= old_grant_option; /* purecov: deadcode */
memex= old_mem; /* purecov: deadcode */
}
else
@@ -5380,6 +5378,12 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
VOID(pthread_mutex_unlock(&acl_cache->lock));
+ if (result)
+ my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe());
+
+ DBUG_PRINT("info", ("thd->net.last_errno: %d", thd->net.last_errno));
+ DBUG_PRINT("info", ("thd->net.last_error: %s", thd->net.last_error));
+
if (mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
@@ -5388,8 +5392,6 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
- if (result)
- my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe());
DBUG_RETURN(result);
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index ed48ca577fb..ed006714143 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1505,6 +1505,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
HASH_SEARCH_STATE state;
DBUG_ENTER("open_table");
+ DBUG_ASSERT (table_list->lock_type != TL_WRITE_DEFAULT);
/* find a unused table in the open table cache */
if (refresh)
*refresh=0;
@@ -1669,10 +1670,17 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
VOID(pthread_mutex_unlock(&LOCK_open));
}
}
- if ((thd->locked_tables) && (thd->locked_tables->lock_count > 0))
- my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias);
- else
+ /*
+ No table in the locked tables list. In case of explicit LOCK TABLES
+ this can happen if a user did not include the able into the list.
+ In case of pre-locked mode locked tables list is generated automatically,
+ so we may only end up here if the table did not exist when
+ locked tables list was created.
+ */
+ if (thd->prelocked_mode == PRELOCKED)
my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias);
+ else
+ my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias);
DBUG_RETURN(0);
}
@@ -2667,6 +2675,12 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
for (tables= *start; tables ;tables= tables->next_global)
{
safe_to_ignore_table= FALSE; // 'FALSE', as per coding style
+
+ if (tables->lock_type == TL_WRITE_DEFAULT)
+ {
+ tables->lock_type= thd->update_lock_default;
+ DBUG_ASSERT (tables->lock_type >= TL_WRITE_ALLOW_WRITE);
+ }
/*
Ignore placeholders for derived tables. After derived tables
processing, link to created temporary table will be put here.
@@ -5167,7 +5181,12 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
get_key_map_from_key_list(&map, table, table_list->use_index);
if (map.is_set_all())
DBUG_RETURN(1);
- table->keys_in_use_for_query=map;
+ /*
+ Don't introduce keys in keys_in_use_for_query that weren't there
+ before. FORCE/USE INDEX should not add keys, it should only remove
+ all keys except the key(s) specified in the hint.
+ */
+ table->keys_in_use_for_query.intersect(map);
}
if (table_list->ignore_index)
{
@@ -5800,13 +5819,13 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors)
table= (*ptr)->table;
table->auto_increment_field_not_null= FALSE;
}
- while ((field = *ptr++))
+ while ((field = *ptr++) && !thd->net.report_error)
{
value=v++;
table= field->table;
if (field == table->next_number_field)
table->auto_increment_field_not_null= TRUE;
- if (value->save_in_field(field, 0) == -1)
+ if (value->save_in_field(field, 0) < 0)
goto err;
}
DBUG_RETURN(thd->net.report_error);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 010dc101e0d..788026d2f67 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1221,6 +1221,11 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
}
+#define NEED_ESCAPING(x) ((int) (uchar) (x) == escape_char || \
+ (int) (uchar) (x) == field_sep_char || \
+ (int) (uchar) (x) == line_sep_char || \
+ !(x))
+
bool select_export::send_data(List<Item> &items)
{
@@ -1280,14 +1285,20 @@ bool select_export::send_data(List<Item> &items)
used_length=res->length();
if (result_type == STRING_RESULT && escape_char != -1)
{
- char *pos,*start,*end;
-
+ char *pos, *start, *end;
+ CHARSET_INFO *res_charset= res->charset();
+ CHARSET_INFO *character_set_client= thd->variables.
+ character_set_client;
+ bool check_second_byte= (res_charset == &my_charset_bin) &&
+ character_set_client->
+ escape_with_backslash_is_dangerous;
+ DBUG_ASSERT(character_set_client->mbmaxlen == 2 ||
+ !character_set_client->escape_with_backslash_is_dangerous);
for (start=pos=(char*) res->ptr(),end=pos+used_length ;
pos != end ;
pos++)
{
#ifdef USE_MB
- CHARSET_INFO *res_charset=res->charset();
if (use_mb(res_charset))
{
int l;
@@ -1298,9 +1309,45 @@ bool select_export::send_data(List<Item> &items)
}
}
#endif
- if ((int) *pos == escape_char || (int) *pos == field_sep_char ||
- (int) *pos == line_sep_char || !*pos)
- {
+
+ /*
+ Special case when dumping BINARY/VARBINARY/BLOB values
+ for the clients with character sets big5, cp932, gbk and sjis,
+ which can have the escape character (0x5C "\" by default)
+ as the second byte of a multi-byte sequence.
+
+ If
+ - pos[0] is a valid multi-byte head (e.g 0xEE) and
+ - pos[1] is 0x00, which will be escaped as "\0",
+
+ then we'll get "0xEE + 0x5C + 0x30" in the output file.
+
+ If this file is later loaded using this sequence of commands:
+
+ mysql> create table t1 (a varchar(128)) character set big5;
+ mysql> LOAD DATA INFILE 'dump.txt' INTO TABLE t1;
+
+ then 0x5C will be misinterpreted as the second byte
+ of a multi-byte character "0xEE + 0x5C", instead of
+ escape character for 0x00.
+
+ To avoid this confusion, we'll escape the multi-byte
+ head character too, so the sequence "0xEE + 0x00" will be
+ dumped as "0x5C + 0xEE + 0x5C + 0x30".
+
+ Note, in the condition below we only check if
+ mbcharlen is equal to 2, because there are no
+ character sets with mbmaxlen longer than 2
+ and with escape_with_backslash_is_dangerous set.
+ DBUG_ASSERT before the loop makes that sure.
+ */
+
+ if (NEED_ESCAPING(*pos) ||
+ (check_second_byte &&
+ my_mbcharlen(character_set_client, (uchar) *pos) == 2 &&
+ pos + 1 < end &&
+ NEED_ESCAPING(pos[1])))
+ {
char tmp_buff[2];
tmp_buff[0]= escape_char;
tmp_buff[1]= *pos ? *pos : '0';
diff --git a/sql/sql_class.h b/sql/sql_class.h
index ceb50bd669c..b005f956c28 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -594,7 +594,7 @@ struct system_variables
Time_zone *time_zone;
- /* DATE, DATETIME and TIME formats */
+ /* DATE, DATETIME and MYSQL_TIME formats */
DATE_TIME_FORMAT *date_format;
DATE_TIME_FORMAT *datetime_format;
DATE_TIME_FORMAT *time_format;
@@ -606,8 +606,8 @@ struct system_variables
typedef struct system_status_var
{
- ulong bytes_received;
- ulong bytes_sent;
+ ulonglong bytes_received;
+ ulonglong bytes_sent;
ulong com_other;
ulong com_stat[(uint) SQLCOM_END];
ulong created_tmp_disk_tables;
@@ -1397,7 +1397,14 @@ public:
DYNAMIC_ARRAY user_var_events; /* For user variables replication */
MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */
- enum killed_state { NOT_KILLED=0, KILL_BAD_DATA=1, KILL_CONNECTION=ER_SERVER_SHUTDOWN, KILL_QUERY=ER_QUERY_INTERRUPTED };
+ enum killed_state
+ {
+ NOT_KILLED=0,
+ KILL_BAD_DATA=1,
+ KILL_CONNECTION=ER_SERVER_SHUTDOWN,
+ KILL_QUERY=ER_QUERY_INTERRUPTED,
+ KILLED_NO_VALUE /* means neither of the states */
+ };
killed_state volatile killed;
/* scramble - random string sent to client on handshake */
@@ -1670,7 +1677,8 @@ public:
void end_statement();
inline int killed_errno() const
{
- return killed != KILL_BAD_DATA ? killed : 0;
+ killed_state killed_val; /* to cache the volatile 'killed' */
+ return (killed_val= killed) != KILL_BAD_DATA ? killed_val : 0;
}
inline void send_kill_message() const
{
@@ -2284,6 +2292,11 @@ class multi_update :public select_result_interceptor
List <Item> *fields, *values;
List <Item> **fields_for_table, **values_for_table;
uint table_count;
+ /*
+ List of tables referenced in the CHECK OPTION condition of
+ the updated view excluding the updated table.
+ */
+ List <TABLE> unupdated_check_opt_tables;
Copy_field *copy_field;
enum enum_duplicates handle_duplicates;
bool do_update, trans_safe;
diff --git a/sql/sql_client.cc b/sql/sql_client.cc
index d6f1183806e..032a2e26e3a 100644
--- a/sql/sql_client.cc
+++ b/sql/sql_client.cc
@@ -28,8 +28,11 @@ void my_net_local_init(NET *net)
{
#ifndef EMBEDDED_LIBRARY
net->max_packet= (uint) global_system_variables.net_buffer_length;
- net->read_timeout= (uint) global_system_variables.net_read_timeout;
- net->write_timeout=(uint) global_system_variables.net_write_timeout;
+
+ my_net_set_read_timeout(net, (uint)global_system_variables.net_read_timeout);
+ my_net_set_write_timeout(net,
+ (uint)global_system_variables.net_write_timeout);
+
net->retry_count= (uint) global_system_variables.net_retry_count;
net->max_packet_size= max(global_system_variables.net_buffer_length,
global_system_variables.max_allowed_packet);
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index 61a7581908c..a25c82c7721 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -205,8 +205,8 @@ void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
TRUE Error sending data to client
*/
-static const char *warning_level_names[]= {"Note", "Warning", "Error", "?"};
-static int warning_level_length[]= { 4, 7, 5, 1 };
+const char *warning_level_names[]= {"Note", "Warning", "Error", "?"};
+int warning_level_length[]= { 4, 7, 5, 1 };
bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
{
diff --git a/sql/sql_error.h b/sql/sql_error.h
index 28d946f14f8..4dbf3ada8f0 100644
--- a/sql/sql_error.h
+++ b/sql/sql_error.h
@@ -39,3 +39,5 @@ void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
uint code, const char *format, ...);
void mysql_reset_errors(THD *thd, bool force);
bool mysqld_show_warnings(THD *thd, ulong levels_to_show);
+extern const char *warning_level_names[];
+extern int warning_level_length[];
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 02c5012b0c5..9e094c31dce 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -870,9 +870,35 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (mysql_bin_log.is_open())
{
if (error <= 0)
+ {
+ /*
+ [Guilhem wrote] Temporary errors may have filled
+ thd->net.last_error/errno. For example if there has
+ been a disk full error when writing the row, and it was
+ MyISAM, then thd->net.last_error/errno will be set to
+ "disk full"... and the my_pwrite() will wait until free
+ space appears, and so when it finishes then the
+ write_row() was entirely successful
+ */
+ /* todo: consider removing */
thd->clear_error();
+ }
+ /* bug#22725:
+
+ A query which per-row-loop can not be interrupted with
+ KILLED, like INSERT, and that does not invoke stored
+ routines can be binlogged with neglecting the KILLED error.
+
+ If there was no error (error == zero) until after the end of
+ inserting loop the KILLED flag that appeared later can be
+ disregarded since previously possible invocation of stored
+ routines did not result in any error due to the KILLED. In
+ such case the flag is ignored for constructing binlog event.
+ */
Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_table, FALSE);
+ transactional_table, FALSE,
+ (error>0) ? thd->killed : THD::NOT_KILLED);
+ DBUG_ASSERT(thd->killed != THD::KILL_BAD_DATA || error > 0);
if (mysql_bin_log.write(&qinfo) && transactional_table)
error=1;
}
@@ -921,20 +947,24 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (values_list.elements == 1 && (!(thd->options & OPTION_WARNINGS) ||
!thd->cuted_fields))
{
- thd->row_count_func= info.copied+info.deleted+info.updated;
+ thd->row_count_func= info.copied + info.deleted +
+ ((thd->client_capabilities & CLIENT_FOUND_ROWS) ?
+ info.touched : info.updated);
send_ok(thd, (ulong) thd->row_count_func, id);
}
else
{
char buff[160];
+ ha_rows updated=((thd->client_capabilities & CLIENT_FOUND_ROWS) ?
+ info.touched : info.updated);
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);
else
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
- (ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields);
- thd->row_count_func= info.copied+info.deleted+info.updated;
+ (ulong) (info.deleted + updated), (ulong) thd->cuted_fields);
+ thd->row_count_func= info.copied + info.deleted + updated;
::send_ok(thd, (ulong) thd->row_count_func, id, buff);
}
thd->abort_on_warning= 0;
@@ -1374,23 +1404,18 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
goto before_trg_err;
table->file->restore_auto_increment();
- if ((error=table->file->update_row(table->record[1],table->record[0])))
+ if ((table->file->table_flags() & HA_PARTIAL_COLUMN_READ) ||
+ compare_record(table, thd->query_id))
{
- if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore)
+ if ((error=table->file->update_row(table->record[1],table->record[0])))
{
- goto ok_or_after_trg_err;
+ if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore)
+ {
+ goto ok_or_after_trg_err;
+ }
+ goto err;
}
- goto err;
- }
- if (table->next_number_field)
- table->file->adjust_next_insert_id_after_explicit_value(
- table->next_number_field->val_int());
- info->touched++;
-
- if ((table->file->table_flags() & HA_PARTIAL_COLUMN_READ) ||
- compare_record(table, thd->query_id))
- {
info->updated++;
trg_error= (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
@@ -1399,6 +1424,11 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
info->copied++;
}
+ if (table->next_number_field)
+ table->file->adjust_next_insert_id_after_explicit_value(
+ table->next_number_field->val_int());
+ info->touched++;
+
goto ok_or_after_trg_err;
}
else /* DUP_REPLACE */
@@ -2912,7 +2942,9 @@ bool select_insert::send_eof()
else
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
(ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields);
- thd->row_count_func= info.copied+info.deleted+info.updated;
+ thd->row_count_func= info.copied + info.deleted +
+ ((thd->client_capabilities & CLIENT_FOUND_ROWS) ?
+ info.touched : info.updated);
::send_ok(thd, (ulong) thd->row_count_func, last_insert_id, buff);
DBUG_RETURN(0);
}
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 7bcdc499011..cbfba3d4d80 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1098,6 +1098,7 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root)
SYNOPSIS
skip_rear_comments()
+ cs character set
begin pointer to the beginning of statement
end pointer to the end of statement
@@ -1108,10 +1109,11 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root)
Pointer to the last non-comment symbol of the statement.
*/
-char *skip_rear_comments(char *begin, char *end)
+char *skip_rear_comments(CHARSET_INFO *cs, char *begin, char *end)
{
- while (begin < end && (end[-1] <= ' ' || end[-1] == '*' ||
- end[-1] == '/' || end[-1] == ';'))
+ while (begin < end && (end[-1] == '*' ||
+ end[-1] == '/' || end[-1] == ';' ||
+ my_isspace(cs, end[-1])))
end-= 1;
return end;
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 6c9283126c4..f8405ef14ca 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1271,4 +1271,4 @@ extern void lex_free(void);
extern void lex_start(THD *thd);
extern void lex_end(LEX *lex);
extern int MYSQLlex(void *arg, void *yythd);
-extern char *skip_rear_comments(char *begin, char *end);
+extern char *skip_rear_comments(CHARSET_INFO *cs, char *begin, char *end);
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index d14e165a788..c2267ba5dfc 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -414,9 +414,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (error)
{
- if (transactional_table)
- ha_autocommit_or_rollback(thd,error);
-
if (read_file_from_client)
while (!read_info.next_line())
;
@@ -460,6 +457,9 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
}
}
#endif /*!EMBEDDED_LIBRARY*/
+ if (transactional_table)
+ ha_autocommit_or_rollback(thd,error);
+
error= -1; // Error on read
goto err;
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 7e58b36a939..488f05ab41f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -75,6 +75,7 @@ static bool check_db_used(THD *thd,TABLE_LIST *tables);
static void remove_escape(char *name);
static bool append_file_to_dir(THD *thd, const char **filename_ptr,
const char *table_name);
+static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
const char *any_db="*any*"; // Special symbol for check_access
@@ -1008,9 +1009,12 @@ static int check_connection(THD *thd)
Old clients send null-terminated string as password; new clients send
the size (1 byte) + string (not null-terminated). Hence in case of empty
password both send '\0'.
+
+ Cast *passwd to an unsigned char, so that it doesn't extend the sign for
+ *passwd > 127 and become 2**32-127 after casting to uint.
*/
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
- *passwd++ : strlen(passwd);
+ (uchar)(*passwd++) : strlen(passwd);
db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
db + passwd_len + 1 : 0;
uint db_len= db ? strlen(db) : 0;
@@ -1139,8 +1143,8 @@ pthread_handler_t handle_one_connection(void *arg)
net->no_send_error= 0;
/* Use "connect_timeout" value during connection phase */
- net_set_read_timeout(net, connect_timeout);
- net_set_write_timeout(net, connect_timeout);
+ my_net_set_read_timeout(net, connect_timeout);
+ my_net_set_write_timeout(net, connect_timeout);
if ((error=check_connection(thd)))
{ // Wrong permissions
@@ -1183,8 +1187,8 @@ pthread_handler_t handle_one_connection(void *arg)
}
/* Connect completed, set read/write timeouts back to tdefault */
- net_set_read_timeout(net, thd->variables.net_read_timeout);
- net_set_write_timeout(net, thd->variables.net_write_timeout);
+ my_net_set_read_timeout(net, thd->variables.net_read_timeout);
+ my_net_set_write_timeout(net, thd->variables.net_write_timeout);
while (!net->error && net->vio != 0 &&
!(thd->killed == THD::KILL_CONNECTION))
@@ -1536,7 +1540,7 @@ bool do_command(THD *thd)
the client, the connection is closed or "net_wait_timeout"
number of seconds has passed
*/
- net_set_read_timeout(net, thd->variables.net_wait_timeout);
+ my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
thd->clear_error(); // Clear error message
@@ -1568,7 +1572,7 @@ bool do_command(THD *thd)
}
/* Restore read timeout value */
- net_set_read_timeout(net, thd->variables.net_read_timeout);
+ my_net_set_read_timeout(net, thd->variables.net_read_timeout);
/*
packet_length contains length of data, as it was stored in packet
@@ -1696,11 +1700,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
Old clients send null-terminated string ('\0' for empty string) for
password. New clients send the size (1 byte) + string (not null
terminated, so also '\0' for empty string).
+
+ Cast *passwd to an unsigned char, so that it doesn't extend the sign
+ for *passwd > 127 and become 2**32-127 after casting to uint.
*/
char db_buff[NAME_LEN+1]; // buffer to store db in utf8
char *db= passwd;
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
- *passwd++ : strlen(passwd);
+ (uchar)(*passwd++) : strlen(passwd);
db+= passwd_len + 1;
#ifndef EMBEDDED_LIBRARY
/* Small check for incoming packet */
@@ -3080,9 +3087,9 @@ mysql_execute_command(THD *thd)
else
{
/* regular create */
- if (lex->name)
- res= mysql_create_like_table(thd, create_table, &create_info,
- (Table_ident *)lex->name);
+ if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE)
+ res= mysql_create_like_table(thd, create_table, select_tables,
+ &create_info);
else
{
res= mysql_create_table(thd, create_table->db,
@@ -3319,11 +3326,7 @@ end_with_restore_list:
first_table->skip_temporary= 1;
if (check_db_used(thd, all_tables) ||
- check_access(thd, SELECT_ACL | EXTRA_ACL, first_table->db,
- &first_table->grant.privilege, 0, 0,
- test(first_table->schema_table)))
- goto error;
- if (grant_option && check_grant(thd, SELECT_ACL, all_tables, 2, UINT_MAX, 0))
+ check_show_create_table_access(thd, first_table))
goto error;
res= mysqld_show_create(thd, first_table);
break;
@@ -3834,7 +3837,10 @@ end_with_restore_list:
break;
case SQLCOM_LOCK_TABLES:
unlock_locked_tables(thd);
- if (check_db_used(thd, all_tables) || end_active_trans(thd))
+ /* we must end the trasaction first, regardless of anything */
+ if (end_active_trans(thd))
+ goto error;
+ if (check_db_used(thd, all_tables))
goto error;
if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, 0))
goto error;
@@ -3852,7 +3858,15 @@ end_with_restore_list:
send_ok(thd);
}
else
+ {
+ /*
+ Need to end the current transaction, so the storage engine (InnoDB)
+ can free its locks if LOCK TABLES locked some tables before finding
+ that it can't lock a table in its list
+ */
+ end_active_trans(thd);
thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
+ }
thd->in_lock_tables=0;
break;
case SQLCOM_CREATE_DB:
@@ -5255,7 +5269,17 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
Security_context *sctx= thd->security_ctx;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong db_access;
- bool db_is_pattern= test(want_access & GRANT_ACL);
+ /*
+ GRANT command:
+ In case of database level grant the database name may be a pattern,
+ in case of table|column level grant the database name can not be a pattern.
+ We use 'dont_check_global_grants' as a flag to determine
+ if it's database level grant command
+ (see SQLCOM_GRANT case, mysql_execute_command() function) and
+ set db_is_pattern according to 'dont_check_global_grants' value.
+ */
+ bool db_is_pattern= (test(want_access & GRANT_ACL) &&
+ dont_check_global_grants);
#endif
ulong dummy;
DBUG_ENTER("check_access");
@@ -7519,6 +7543,25 @@ bool insert_precheck(THD *thd, TABLE_LIST *tables)
}
+/**
+ @brief Check privileges for SHOW CREATE TABLE statement.
+
+ @param thd Thread context
+ @param table Target table
+
+ @retval TRUE Failure
+ @retval FALSE Success
+*/
+
+static bool check_show_create_table_access(THD *thd, TABLE_LIST *table)
+{
+ return check_access(thd, SELECT_ACL | EXTRA_ACL, table->db,
+ &table->grant.privilege, 0, 0,
+ test(table->schema_table)) ||
+ grant_option && check_grant(thd, SELECT_ACL, table, 2, UINT_MAX, 0);
+}
+
+
/*
CREATE TABLE query pre-check
@@ -7583,6 +7626,11 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
if (tables && check_table_access(thd, SELECT_ACL, tables,0))
goto err;
}
+ else if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE)
+ {
+ if (check_show_create_table_access(thd, tables))
+ goto err;
+ }
error= FALSE;
err:
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 42655608196..f781d1372ad 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -562,6 +562,8 @@ void set_param_date(Item_param *param, uchar **pos, ulong len)
static void set_param_str(Item_param *param, uchar **pos, ulong len)
{
ulong length= get_param_length(pos, len);
+ if (length > len)
+ length= len;
param->set_str((const char *)*pos, length);
*pos+= length;
}
@@ -731,6 +733,8 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array,
if (read_pos >= data_end)
DBUG_RETURN(1);
param->set_param_func(param, &read_pos, data_end - read_pos);
+ if (param->state == Item_param::NO_VALUE)
+ DBUG_RETURN(1);
}
}
res= param->query_val_str(&str);
@@ -767,6 +771,8 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array,
if (read_pos >= data_end)
DBUG_RETURN(1);
param->set_param_func(param, &read_pos, data_end - read_pos);
+ if (param->state == Item_param::NO_VALUE)
+ DBUG_RETURN(1);
}
}
if (param->convert_str_value(stmt->thd))
@@ -849,6 +855,8 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query)
client_param->length ?
*client_param->length :
client_param->buffer_length);
+ if (param->state == Item_param::NO_VALUE)
+ DBUG_RETURN(1);
}
}
if (param->convert_str_value(thd))
@@ -890,6 +898,8 @@ static bool emb_insert_params_withlog(Prepared_statement *stmt, String *query)
client_param->length ?
*client_param->length :
client_param->buffer_length);
+ if (param->state == Item_param::NO_VALUE)
+ DBUG_RETURN(1);
}
}
res= param->query_val_str(&str);
@@ -969,6 +979,7 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
String buf;
const String *val;
uint32 length= 0;
+ THD *thd= stmt->thd;
DBUG_ENTER("insert_params_from_vars");
@@ -979,34 +990,20 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
{
Item_param *param= *it;
varname= var_it++;
- if (get_var_with_binlog(stmt->thd, stmt->lex->sql_command,
- *varname, &entry))
- DBUG_RETURN(1);
- if (param->set_from_user_var(stmt->thd, entry))
+ entry= (user_var_entry *) hash_search(&thd->user_vars, (byte*) varname->str,
+ varname->length);
+ /*
+ We have to call the setup_one_conversion_function() here to set
+ the parameter's members that might be needed further
+ (e.g. value.cs_info.character_set_client is used in the query_val_str()).
+ */
+ setup_one_conversion_function(thd, param, param->param_type);
+ if (param->set_from_user_var(thd, entry))
DBUG_RETURN(1);
- /* Insert @'escaped-varname' instead of parameter in the query */
- if (entry)
- {
- char *start, *ptr;
- buf.length(0);
- if (buf.reserve(entry->name.length*2+3))
- DBUG_RETURN(1);
+ val= param->query_val_str(&buf);
- start= ptr= buf.c_ptr_quick();
- *ptr++= '@';
- *ptr++= '\'';
- ptr+= escape_string_for_mysql(&my_charset_utf8_general_ci,
- ptr, 0, entry->name.str,
- entry->name.length);
- *ptr++= '\'';
- buf.length(ptr - start);
- val= &buf;
- }
- else
- val= &my_null_string;
-
- if (param->convert_str_value(stmt->thd))
+ if (param->convert_str_value(thd))
DBUG_RETURN(1); /* out of memory */
if (query->replace(param->pos_in_query+length, 1, *val))
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index b451c612398..86ededd5587 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -94,7 +94,7 @@ static int send_file(THD *thd)
the job
*/
old_timeout= net->read_timeout;
- net_set_read_timeout(net, thd->variables.net_wait_timeout);
+ my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
/*
We need net_flush here because the client will not know it needs to send
@@ -138,7 +138,7 @@ static int send_file(THD *thd)
error = 0;
err:
- net_set_read_timeout(net, old_timeout);
+ my_net_set_read_timeout(net, old_timeout);
if (fd >= 0)
(void) my_close(fd, MYF(0));
if (errmsg)
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index d284ebbfb0f..c403a50de20 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -49,15 +49,15 @@ static int sort_keyuse(KEYUSE *a,KEYUSE *b);
static void set_position(JOIN *join,uint index,JOIN_TAB *table,KEYUSE *key);
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
table_map used_tables);
-static void choose_plan(JOIN *join,table_map join_tables);
+static bool choose_plan(JOIN *join,table_map join_tables);
static void best_access_path(JOIN *join, JOIN_TAB *s, THD *thd,
table_map remaining_tables, uint idx,
double record_count, double read_time);
static void optimize_straight_join(JOIN *join, table_map join_tables);
-static void greedy_search(JOIN *join, table_map remaining_tables,
+static bool greedy_search(JOIN *join, table_map remaining_tables,
uint depth, uint prune_level);
-static void best_extension_by_limited_search(JOIN *join,
+static bool best_extension_by_limited_search(JOIN *join,
table_map remaining_tables,
uint idx, double record_count,
double read_time, uint depth,
@@ -69,7 +69,7 @@ static int join_tab_cmp_straight(const void* ptr1, const void* ptr2);
TODO: 'find_best' is here only temporarily until 'greedy_search' is
tested and approved.
*/
-static void find_best(JOIN *join,table_map rest_tables,uint index,
+static bool find_best(JOIN *join,table_map rest_tables,uint index,
double record_count,double read_time);
static uint cache_record_length(JOIN *join,uint index);
static double prev_record_reads(JOIN *join,table_map found_ref);
@@ -1344,8 +1344,7 @@ JOIN::optimize()
there are aggregate functions, because in all these cases we need
all result rows.
*/
- ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order ||
- test(select_options & OPTION_BUFFER_RESULT)) &&
+ ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order) &&
!tmp_group &&
!thd->lex->current_select->with_sum_func) ?
select_limit : HA_POS_ERROR;
@@ -2072,6 +2071,17 @@ JOIN::exec()
thd->examined_row_count+= curr_join->examined_rows;
DBUG_PRINT("counts", ("thd->examined_row_count: %lu",
(ulong) thd->examined_row_count));
+
+ /*
+ With EXPLAIN EXTENDED we have to restore original ref_array
+ for a derived table which is always materialized.
+ Otherwise we would not be able to print the query correctly.
+ */
+ if (items0 &&
+ (thd->lex->describe & DESCRIBE_EXTENDED) &&
+ select_lex->linkage == DERIVED_TABLE_TYPE)
+ set_items_ref_array(items0);
+
DBUG_VOID_RETURN;
}
@@ -2714,7 +2724,8 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if (join->const_tables != join->tables)
{
optimize_keyuse(join, keyuse_array);
- choose_plan(join, all_table_map & ~join->const_table_map);
+ if (choose_plan(join, all_table_map & ~join->const_table_map))
+ DBUG_RETURN(TRUE);
}
else
{
@@ -4304,11 +4315,12 @@ best_access_path(JOIN *join,
the array 'join->best_positions', and the cost of the plan in
'join->best_read'.
- RETURN
- None
+ RETURN VALUES
+ FALSE ok
+ TRUE Fatal error
*/
-static void
+static bool
choose_plan(JOIN *join, table_map join_tables)
{
uint search_depth= join->thd->variables.optimizer_search_depth;
@@ -4341,14 +4353,16 @@ choose_plan(JOIN *join, table_map join_tables)
the greedy version. Will be removed when greedy_search is approved.
*/
join->best_read= DBL_MAX;
- find_best(join, join_tables, join->const_tables, 1.0, 0.0);
+ if (find_best(join, join_tables, join->const_tables, 1.0, 0.0))
+ DBUG_RETURN(TRUE);
}
else
{
if (search_depth == 0)
/* Automatically determine a reasonable value for 'search_depth' */
search_depth= determine_search_depth(join);
- greedy_search(join, join_tables, search_depth, prune_level);
+ if (greedy_search(join, join_tables, search_depth, prune_level))
+ DBUG_RETURN(TRUE);
}
}
@@ -4358,7 +4372,7 @@ choose_plan(JOIN *join, table_map join_tables)
*/
if (join->thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS)
join->thd->status_var.last_query_cost= join->best_read;
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -4586,11 +4600,12 @@ optimize_straight_join(JOIN *join, table_map join_tables)
In the future, 'greedy_search' might be extended to support other
implementations of 'best_extension', e.g. some simpler quadratic procedure.
- RETURN
- None
+ RETURN VALUES
+ FALSE ok
+ TRUE Fatal error
*/
-static void
+static bool
greedy_search(JOIN *join,
table_map remaining_tables,
uint search_depth,
@@ -4612,8 +4627,9 @@ greedy_search(JOIN *join,
do {
/* Find the extension of the current QEP with the lowest cost */
join->best_read= DBL_MAX;
- best_extension_by_limited_search(join, remaining_tables, idx, record_count,
- read_time, search_depth, prune_level);
+ if (best_extension_by_limited_search(join, remaining_tables, idx, record_count,
+ read_time, search_depth, prune_level))
+ DBUG_RETURN(TRUE);
if (size_remain <= search_depth)
{
@@ -4624,7 +4640,7 @@ greedy_search(JOIN *join,
DBUG_EXECUTE("opt", print_plan(join, join->tables,
record_count, read_time, read_time,
"optimal"););
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
/* select the first table in the optimal extension as most promising */
@@ -4769,11 +4785,12 @@ greedy_search(JOIN *join,
The parameter 'search_depth' provides control over the recursion
depth, and thus the size of the resulting optimal plan.
- RETURN
- None
+ RETURN VALUES
+ FALSE ok
+ TRUE Fatal error
*/
-static void
+static bool
best_extension_by_limited_search(JOIN *join,
table_map remaining_tables,
uint idx,
@@ -4782,11 +4799,11 @@ best_extension_by_limited_search(JOIN *join,
uint search_depth,
uint prune_level)
{
+ DBUG_ENTER("best_extension_by_limited_search");
+
THD *thd= join->thd;
if (thd->killed) // Abort
- return;
-
- DBUG_ENTER("best_extension_by_limited_search");
+ DBUG_RETURN(TRUE);
/*
'join' is a partial plan with lower cost than the best plan so far,
@@ -4866,15 +4883,14 @@ best_extension_by_limited_search(JOIN *join,
if ( (search_depth > 1) && (remaining_tables & ~real_table_bit) )
{ /* Recursively expand the current partial plan */
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
- best_extension_by_limited_search(join,
- remaining_tables & ~real_table_bit,
- idx + 1,
- current_record_count,
- current_read_time,
- search_depth - 1,
- prune_level);
- if (thd->killed)
- DBUG_VOID_RETURN;
+ if (best_extension_by_limited_search(join,
+ remaining_tables & ~real_table_bit,
+ idx + 1,
+ current_record_count,
+ current_read_time,
+ search_depth - 1,
+ prune_level))
+ DBUG_RETURN(TRUE);
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
}
else
@@ -4903,19 +4919,26 @@ best_extension_by_limited_search(JOIN *join,
restore_prev_nj_state(s);
}
}
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
/*
TODO: this function is here only temporarily until 'greedy_search' is
tested and accepted.
+
+ RETURN VALUES
+ FALSE ok
+ TRUE Fatal error
*/
-static void
+static bool
find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
double read_time)
{
+ DBUG_ENTER("find_best");
THD *thd= join->thd;
+ if (thd->killed)
+ DBUG_RETURN(TRUE);
if (!rest_tables)
{
DBUG_PRINT("best",("read_time: %g record_count: %g",read_time,
@@ -4932,10 +4955,10 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
sizeof(POSITION)*idx);
join->best_read= read_time - 0.001;
}
- return;
+ DBUG_RETURN(FALSE);
}
if (read_time+record_count/(double) TIME_FOR_COMPARE >= join->best_read)
- return; /* Found better before */
+ DBUG_RETURN(FALSE); /* Found better before */
JOIN_TAB *s;
double best_record_count=DBL_MAX,best_read_time=DBL_MAX;
@@ -4968,10 +4991,9 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
best_read_time=current_read_time;
}
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
- find_best(join,rest_tables & ~real_table_bit,idx+1,
- current_record_count,current_read_time);
- if (thd->killed)
- return;
+ if (find_best(join,rest_tables & ~real_table_bit,idx+1,
+ current_record_count,current_read_time))
+ DBUG_RETURN(TRUE);
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
}
restore_prev_nj_state(s);
@@ -4979,6 +5001,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
break; // Don't test all combinations
}
}
+ DBUG_RETURN(FALSE);
}
@@ -5663,28 +5686,6 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
join->const_table_map,
(table_map) 0);
DBUG_EXECUTE("where",print_where(const_cond,"constants"););
- for (JOIN_TAB *tab= join->join_tab+join->const_tables;
- tab < join->join_tab+join->tables ; tab++)
- {
- if (*tab->on_expr_ref)
- {
- JOIN_TAB *cond_tab= tab->first_inner;
- COND *tmp= make_cond_for_table(*tab->on_expr_ref,
- join->const_table_map,
- ( table_map) 0);
- if (!tmp)
- continue;
- tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
- if (!tmp)
- DBUG_RETURN(1);
- tmp->quick_fix_field();
- cond_tab->select_cond= !cond_tab->select_cond ? tmp :
- new Item_cond_and(cond_tab->select_cond,tmp);
- if (!cond_tab->select_cond)
- DBUG_RETURN(1);
- cond_tab->select_cond->quick_fix_field();
- }
- }
if (const_cond && !const_cond->val_int())
{
DBUG_PRINT("info",("Found impossible WHERE condition"));
@@ -5915,13 +5916,39 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
}
/*
- Push down all predicates from on expressions.
- Each of these predicated are guarded by a variable
+ Push down conditions from all on expressions.
+ Each of these conditions are guarded by a variable
that turns if off just before null complemented row for
- outer joins is formed. Thus, the predicates from an
+ outer joins is formed. Thus, the condition from an
'on expression' are guaranteed not to be checked for
the null complemented row.
*/
+
+ /* First push down constant conditions from on expressions */
+ for (JOIN_TAB *join_tab= join->join_tab+join->const_tables;
+ join_tab < join->join_tab+join->tables ; join_tab++)
+ {
+ if (*join_tab->on_expr_ref)
+ {
+ JOIN_TAB *cond_tab= join_tab->first_inner;
+ COND *tmp= make_cond_for_table(*join_tab->on_expr_ref,
+ join->const_table_map,
+ (table_map) 0);
+ if (!tmp)
+ continue;
+ tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
+ if (!tmp)
+ DBUG_RETURN(1);
+ tmp->quick_fix_field();
+ cond_tab->select_cond= !cond_tab->select_cond ? tmp :
+ new Item_cond_and(cond_tab->select_cond,tmp);
+ if (!cond_tab->select_cond)
+ DBUG_RETURN(1);
+ cond_tab->select_cond->quick_fix_field();
+ }
+ }
+
+ /* Push down non-constant conditions from on expressions */
JOIN_TAB *last_tab= tab;
while (first_inner_tab && first_inner_tab->last_inner == last_tab)
{
@@ -6372,7 +6399,6 @@ void JOIN::cleanup(bool full)
for (tab= join_tab, end= tab+tables; tab != end; tab++)
tab->cleanup();
table= 0;
- tables= 0;
}
else
{
@@ -8797,7 +8823,7 @@ Field* create_tmp_field_from_field(THD *thd, Field* org_field,
Make sure that the blob fits into a Field_varstring which has
2-byte lenght.
*/
- if (convert_blob_length && convert_blob_length < UINT_MAX16 &&
+ if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
(org_field->flags & BLOB_FLAG))
new_field= new Field_varstring(convert_blob_length,
org_field->maybe_null(),
@@ -8863,8 +8889,13 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
item->name, table, item->decimals, TRUE);
break;
case INT_RESULT:
- /* Select an integer type with the minimal fit precision */
- if (item->max_length > MY_INT32_NUM_DECIMAL_DIGITS)
+ /*
+ Select an integer type with the minimal fit precision.
+ MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
+ Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into
+ Field_long : make them Field_longlong.
+ */
+ if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
new_field=new Field_longlong(item->max_length, maybe_null,
item->name, table, item->unsigned_flag);
else
@@ -8888,7 +8919,8 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
2-byte lenght.
*/
else if (item->max_length/item->collation.collation->mbmaxlen > 255 &&
- convert_blob_length < UINT_MAX16 && convert_blob_length)
+ convert_blob_length <= Field_varstring::MAX_SIZE &&
+ convert_blob_length)
new_field= new Field_varstring(convert_blob_length, maybe_null,
item->name, table,
item->collation.collation);
@@ -9128,7 +9160,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
bool using_unique_constraint= 0;
bool use_packed_rows= 0;
bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
- char *tmpname,path[FN_REFLEN];
+ char *tmpname, *tmppath, path[FN_REFLEN], table_name[NAME_LEN+1];
byte *pos,*group_buff;
uchar *null_flags;
Field **reg_field, **from_field, **default_field;
@@ -9151,12 +9183,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
temp_pool_slot = bitmap_set_next(&temp_pool);
if (temp_pool_slot != MY_BIT_NONE) // we got a slot
- sprintf(path, "%s_%lx_%i", tmp_file_prefix,
- current_pid, temp_pool_slot);
+ sprintf(table_name, "%s_%lx_%i", tmp_file_prefix,
+ current_pid, temp_pool_slot);
else
{
/* if we run out of slots or we are not using tempool */
- sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
+ sprintf(table_name, "%s%lx_%lx_%x", tmp_file_prefix,current_pid,
thd->thread_id, thd->tmp_table++);
}
@@ -9164,7 +9196,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
No need to change table name to lower case as we are only creating
MyISAM or HEAP tables here
*/
- fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
+ fn_format(path, table_name, mysql_tmpdir, "",
+ MY_REPLACE_EXT|MY_UNPACK_FILENAME);
if (group)
{
@@ -9209,7 +9242,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
sizeof(*key_part_info)*(param->group_parts+1),
&param->start_recinfo,
sizeof(*param->recinfo)*(field_count*2+4),
- &tmpname, (uint) strlen(path)+1,
+ &tmppath, (uint) strlen(path)+1,
+ &tmpname, (uint) strlen(table_name)+1,
&group_buff, group && ! using_unique_constraint ?
param->group_length : 0,
NullS))
@@ -9227,7 +9261,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
DBUG_RETURN(NULL); /* purecov: inspected */
}
param->items_to_copy= copy_func;
- strmov(tmpname,path);
+ strmov(tmppath, path);
+ strmov(tmpname, table_name);
/* make table according to fields */
bzero((char*) table,sizeof(*table));
@@ -9253,7 +9288,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->s= &table->share_not_to_be_used;
table->s->blob_field= blob_field;
- table->s->table_name= table->s->path= tmpname;
+ table->s->table_name= tmpname;
+ table->s->path= tmppath;
table->s->db= "";
table->s->blob_ptr_size= mi_portable_sizeof_char_ptr;
table->s->tmp_table= NON_TRANSACTIONAL_TMP_TABLE;
@@ -10111,7 +10147,9 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
/* copy all old rows */
while (!table->file->rnd_next(new_table.record[1]))
{
- if ((write_err=new_table.file->write_row(new_table.record[1])))
+ write_err=new_table.file->write_row(new_table.record[1]);
+ DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;);
+ if (write_err)
goto err;
}
/* copy row that filled HEAP table */
@@ -10138,7 +10176,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
err:
DBUG_PRINT("error",("Got error: %d",write_err));
- table->file->print_error(error,MYF(0)); // Give table is full error
+ table->file->print_error(write_err, MYF(0));
(void) table->file->ha_rnd_end();
(void) new_table.file->close();
err1:
@@ -10146,6 +10184,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
delete new_table.file;
err2:
thd->proc_info=save_proc_info;
+ table->mem_root= new_table.mem_root;
DBUG_RETURN(1);
}
@@ -12243,10 +12282,11 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
LINT_INIT(ref_key_parts);
/*
- Check which keys can be used to resolve ORDER BY.
- We must not try to use disabled keys.
+ Keys disabled by ALTER TABLE ... DISABLE KEYS should have already
+ been taken into account.
*/
- usable_keys= table->s->keys_in_use;
+ usable_keys= table->keys_in_use_for_query;
+ DBUG_ASSERT(usable_keys.is_subset(table->s->keys_in_use));
for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
{
@@ -12508,10 +12548,14 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
/*
When there is SQL_BIG_RESULT do not sort using index for GROUP BY,
- and thus force sorting on disk.
+ and thus force sorting on disk unless a group min-max optimization
+ is going to be used as it is applied now only for one table queries
+ with covering indexes.
*/
if ((order != join->group_list ||
- !(join->select_options & SELECT_BIG_RESULT)) &&
+ !(join->select_options & SELECT_BIG_RESULT) ||
+ select && select->quick &&
+ select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) &&
test_if_skip_sort_order(tab,order,select_limit,0))
DBUG_RETURN(0);
for (ORDER *ord= join->order; ord; ord= ord->next)
@@ -14201,6 +14245,13 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
if (!item_field)
DBUG_RETURN(TRUE); // Fatal error
item_field->name= item->name;
+ if (item->type() == Item::REF_ITEM)
+ {
+ Item_field *ifield= (Item_field *) item_field;
+ Item_ref *iref= (Item_ref *) item;
+ ifield->table_name= iref->table_name;
+ ifield->db_name= iref->db_name;
+ }
#ifndef DBUG_OFF
if (_db_on_ && !item_field->name)
{
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index be1355699ba..902b298e423 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1463,6 +1463,8 @@ static bool show_status_array(THD *thd, const char *wild,
case SHOW_LONG_CONST:
end= int10_to_str(*(long*) value, buff, 10);
break;
+ case SHOW_LONGLONG_STATUS:
+ value= ((char *) status_var + (ulonglong) value);
case SHOW_LONGLONG:
end= longlong10_to_str(*(longlong*) value, buff, 10);
break;
@@ -2433,7 +2435,7 @@ static int get_schema_tables_record(THD *thd, struct st_table_list *tables,
const char *file_name)
{
const char *tmp_buff;
- TIME time;
+ MYSQL_TIME time;
CHARSET_INFO *cs= system_charset_info;
DBUG_ENTER("get_schema_tables_record");
@@ -2939,7 +2941,7 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
{
String tmp_string;
String sp_db, sp_name, definer;
- TIME time;
+ MYSQL_TIME time;
LEX *lex= thd->lex;
CHARSET_INFO *cs= system_charset_info;
get_field(thd->mem_root, proc_table->field[0], &sp_db);
@@ -3158,6 +3160,7 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables,
DBUG_ENTER("get_schema_views_record");
char definer[USER_HOST_BUFF_SIZE];
uint definer_len;
+ bool updatable_view;
if (tables->view)
{
@@ -3195,7 +3198,34 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables,
else
table->field[4]->store(STRING_WITH_LEN("NONE"), cs);
- if (tables->updatable_view)
+ updatable_view= 0;
+ if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE)
+ {
+ /*
+ We should use tables->view->select_lex.item_list here and
+ can not use Field_iterator_view because the view always uses
+ temporary algorithm during opening for I_S and
+ TABLE_LIST fields 'field_translation' & 'field_translation_end'
+ are uninitialized is this case.
+ */
+ List<Item> *fields= &tables->view->select_lex.item_list;
+ List_iterator<Item> it(*fields);
+ Item *item;
+ Item_field *field;
+ /*
+ chech that at least one coulmn in view is updatable
+ */
+ while ((item= it++))
+ {
+ if ((field= item->filed_for_view_update()) && field->field &&
+ !field->field->table->pos_in_table_list->schema_table)
+ {
+ updatable_view= 1;
+ break;
+ }
+ }
+ }
+ if (updatable_view)
table->field[5]->store(STRING_WITH_LEN("YES"), cs);
else
table->field[5]->store(STRING_WITH_LEN("NO"), cs);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index a8ed2a53601..87f23097a66 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2284,33 +2284,16 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
*/
if (!table->table)
{
- char buf[ERRMSGSIZE+ERRMSGSIZE+2];
- const char *err_msg;
- protocol->prepare_for_resend();
- protocol->store(table_name, system_charset_info);
- protocol->store(operator_name, system_charset_info);
- protocol->store(STRING_WITH_LEN("error"), system_charset_info);
- if (!(err_msg=thd->net.last_error))
- err_msg=ER(ER_CHECK_NO_SUCH_TABLE);
+ if (!thd->warn_list.elements)
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
/* if it was a view will check md5 sum */
if (table->view &&
view_checksum(thd, table) == HA_ADMIN_WRONG_CHECKSUM)
- {
- strxmov(buf, err_msg, "; ", ER(ER_VIEW_CHECKSUM), NullS);
- err_msg= (const char *)buf;
- }
- protocol->store(err_msg, system_charset_info);
- lex->cleanup_after_one_table_open();
- thd->clear_error();
- /*
- View opening can be interrupted in the middle of process so some
- tables can be left opening
- */
- close_thread_tables(thd);
- lex->reset_query_tables_list(FALSE);
- if (protocol->write())
- goto err;
- continue;
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_VIEW_CHECKSUM, ER(ER_VIEW_CHECKSUM));
+ result_code= HA_ADMIN_CORRUPT;
+ goto send_result;
}
if (table->view)
@@ -2392,6 +2375,22 @@ send_result:
lex->cleanup_after_one_table_open();
thd->clear_error(); // these errors shouldn't get client
+ {
+ List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
+ MYSQL_ERROR *err;
+ while ((err= it++))
+ {
+ protocol->prepare_for_resend();
+ protocol->store(table_name, system_charset_info);
+ protocol->store((char*) operator_name, system_charset_info);
+ protocol->store(warning_level_names[err->level],
+ warning_level_length[err->level], system_charset_info);
+ protocol->store(err->msg, system_charset_info);
+ if (protocol->write())
+ goto err;
+ }
+ mysql_reset_errors(thd, true);
+ }
protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info);
protocol->store(operator_name, system_charset_info);
@@ -2719,7 +2718,8 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* tables)
SYNOPSIS
mysql_create_like_table()
thd Thread object
- table Table list (one table only)
+ table Table list element for target table
+ src_table Table list element for source table
create_info Create info
table_ident Src table_ident
@@ -2728,61 +2728,52 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* tables)
TRUE error
*/
-bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
- HA_CREATE_INFO *create_info,
- Table_ident *table_ident)
+bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST *src_table,
+ HA_CREATE_INFO *create_info)
{
TABLE **tmp_table;
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
char *db= table->db;
char *table_name= table->table_name;
- char *src_db;
- char *src_table= table_ident->table.str;
int err;
bool res= TRUE;
db_type not_used;
-
- TABLE_LIST src_tables_list;
DBUG_ENTER("mysql_create_like_table");
- DBUG_ASSERT(table_ident->db.str); /* Must be set in the parser */
- src_db= table_ident->db.str;
/*
- Validate the source table
+ By taking name-lock on the source table and holding LOCK_open mutex we
+ ensure that no concurrent DDL operation will mess with this table. Note
+ that holding only name-lock is not enough for this, because it won't block
+ other DDL statements that only take name-locks on the table and don't
+ open it (simple name-locks are not exclusive between each other).
+
+ Unfortunately, simply opening this table is not enough for our purproses,
+ since in 5.0 ALTER TABLE may change .FRM files on disk even if there are
+ connections that still have old version of table open. This 'optimization'
+ was removed in 5.1 so there we open the source table instead of taking
+ name-lock on it.
+
+ We also have to acquire LOCK_open to make copying of .frm file, call to
+ ha_create_table() and binlogging atomic against concurrent DML and DDL
+ operations on the target table.
*/
- if (table_ident->table.length > NAME_LEN ||
- (table_ident->table.length &&
- check_table_name(src_table,table_ident->table.length)))
- {
- my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table);
- DBUG_RETURN(TRUE);
- }
- if (!src_db || check_db_name(src_db))
- {
- my_error(ER_WRONG_DB_NAME, MYF(0), src_db ? src_db : "NULL");
- DBUG_RETURN(-1);
- }
-
- bzero((gptr)&src_tables_list, sizeof(src_tables_list));
- src_tables_list.db= src_db;
- src_tables_list.table_name= src_table;
-
- if (lock_and_wait_for_table_name(thd, &src_tables_list))
+ if (lock_and_wait_for_table_name(thd, src_table))
goto err;
- if ((tmp_table= find_temporary_table(thd, src_db, src_table)))
+ pthread_mutex_lock(&LOCK_open);
+
+ if ((tmp_table= find_temporary_table(thd, src_table->db,
+ src_table->table_name)))
strxmov(src_path, (*tmp_table)->s->path, reg_ext, NullS);
else
{
- strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table,
- reg_ext, NullS);
+ strxmov(src_path, mysql_data_home, "/", src_table->db, "/",
+ src_table->table_name, reg_ext, NullS);
/* Resolve symlinks (for windows) */
fn_format(src_path, src_path, "", "", MYF(MY_UNPACK_FILENAME));
- if (lower_case_table_names)
- my_casedn_str(files_charset_info, src_path);
if (access(src_path, F_OK))
{
- my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table);
+ my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table->table_name);
goto err;
}
}
@@ -2792,10 +2783,13 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
*/
if (mysql_frm_type(thd, src_path, &not_used) != FRMTYPE_TABLE)
{
- my_error(ER_WRONG_OBJECT, MYF(0), src_db, src_table, "BASE TABLE");
+ my_error(ER_WRONG_OBJECT, MYF(0), src_table->db, src_table->table_name,
+ "BASE TABLE");
goto err;
}
+ DBUG_EXECUTE_IF("sleep_create_like_before_check_if_exists", my_sleep(6000000););
+
/*
Validate the destination table
@@ -2811,27 +2805,22 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
}
else
{
- bool exists;
strxmov(dst_path, mysql_data_home, "/", db, "/", table_name,
reg_ext, NullS);
fn_format(dst_path, dst_path, "", "", MYF(MY_UNPACK_FILENAME));
/*
- Note that this critical section should actually cover most
- of mysql_create_like_table() function. See bugs #18950 and
- #23667 for more information.
- Also note that starting from 5.1 we obtain name-lock on
- target table instead of inspecting table cache for presence
+ Note that starting from 5.1 we obtain name-lock on target
+ table instead of inspecting table cache for presence
of open placeholders (see comment in mysql_create_table()).
*/
- pthread_mutex_lock(&LOCK_open);
- exists= (table_cache_has_open_placeholder(thd, db, table_name) ||
- !access(dst_path, F_OK));
- pthread_mutex_unlock(&LOCK_open);
- if (exists)
+ if (table_cache_has_open_placeholder(thd, db, table_name) ||
+ !access(dst_path, F_OK))
goto table_exists;
}
+ DBUG_EXECUTE_IF("sleep_create_like_before_copy", my_sleep(6000000););
+
/*
Create a new table by copying from source table
*/
@@ -2844,6 +2833,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
goto err;
}
+ DBUG_EXECUTE_IF("sleep_create_like_before_ha_create", my_sleep(6000000););
+
/*
As mysql_truncate don't work on a new table at this stage of
creation, instead create the table directly (for both normal
@@ -2868,6 +2859,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
goto err; /* purecov: inspected */
}
+ DBUG_EXECUTE_IF("sleep_create_like_before_binlogging", my_sleep(6000000););
+
// Must be written before unlock
if (mysql_bin_log.is_open())
{
@@ -2892,8 +2885,7 @@ table_exists:
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
err:
- pthread_mutex_lock(&LOCK_open);
- unlock_table_name(thd, &src_tables_list);
+ unlock_table_name(thd, src_table);
pthread_mutex_unlock(&LOCK_open);
DBUG_RETURN(res);
}
@@ -2925,7 +2917,7 @@ bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
DBUG_ENTER("mysql_check_table");
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
"check", lock_type,
- 0, HA_OPEN_FOR_REPAIR, 0, 0,
+ 0, 0, HA_OPEN_FOR_REPAIR, 0,
&handler::ha_check, &view_checksum));
}
@@ -3108,8 +3100,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
alter_info->tablespace_op));
sprintf(new_name_buff,"%s/%s/%s%s",mysql_data_home, db, table_name, reg_ext);
unpack_filename(new_name_buff, new_name_buff);
- if (lower_case_table_names != 2)
- my_casedn_str(files_charset_info, new_name_buff);
frm_type= mysql_frm_type(thd, new_name_buff, &table_type);
/* Rename a view */
if (frm_type == FRMTYPE_VIEW && !(alter_info->flags & ~ALTER_RENAME))
@@ -3804,6 +3794,9 @@ view_err:
alter_info->keys_onoff);
table->file->external_lock(thd, F_UNLCK);
VOID(pthread_mutex_unlock(&LOCK_open));
+ error= ha_commit_stmt(thd);
+ if (ha_commit(thd))
+ error= 1;
}
thd->last_insert_id=next_insert_id; // Needed for correct log
@@ -3974,16 +3967,6 @@ view_err:
goto err;
}
}
- /* The ALTER TABLE is always in its own transaction */
- error = ha_commit_stmt(thd);
- if (ha_commit(thd))
- error=1;
- if (error)
- {
- VOID(pthread_mutex_unlock(&LOCK_open));
- broadcast_refresh();
- goto err;
- }
thd->proc_info="end";
if (mysql_bin_log.is_open())
{
@@ -4054,7 +4037,8 @@ err:
}
bool save_abort_on_warning= thd->abort_on_warning;
thd->abort_on_warning= TRUE;
- make_truncated_value_warning(thd, f_val, strlength(f_val), t_type,
+ make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ f_val, strlength(f_val), t_type,
new_datetime_field->field_name);
thd->abort_on_warning= save_abort_on_warning;
}
@@ -4231,8 +4215,12 @@ copy_data_between_tables(TABLE *from,TABLE *to,
}
to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
- ha_enable_transaction(thd,TRUE);
-
+ if (ha_enable_transaction(thd, TRUE))
+ {
+ error= 1;
+ goto err;
+ }
+
/*
Ensure that the new table is saved properly to disk so that we
can do a rename
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 222e33345cc..f4239afc4cd 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -521,6 +521,37 @@ int mysql_update(THD *thd,
table->file->unlock_row();
thd->row_count++;
}
+
+ /*
+ todo bug#27571: to avoid asynchronization of `error' and
+ `error_code' of binlog event constructor
+
+ The concept, which is a bit different for insert(!), is to
+ replace `error' assignment with the following lines
+
+ killed_status= thd->killed; // get the status of the volatile
+
+ Notice: thd->killed is type of "state" whereas the lhs has
+ "status" the suffix which translates according to WordNet: a state
+ at a particular time - at the time of the end of per-row loop in
+ our case. Binlogging ops are conducted with the status.
+
+ error= (killed_status == THD::NOT_KILLED)? error : 1;
+
+ which applies to most mysql_$query functions.
+ Event's constructor will accept `killed_status' as an argument:
+
+ Query_log_event qinfo(..., killed_status);
+
+ thd->killed might be changed after killed_status had got cached and this
+ won't affect binlogging event but other effects remain.
+
+ Open issue: In a case the error happened not because of KILLED -
+ and then KILLED was caught later still within the loop - we shall
+ do something to avoid binlogging of incorrect ER_SERVER_SHUTDOWN
+ error_code.
+ */
+
if (thd->killed && !error)
error= 1; // Aborted
end_read_record(&info);
@@ -915,6 +946,7 @@ bool mysql_multi_update(THD *thd,
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex)
{
multi_update *result;
+ bool res;
DBUG_ENTER("mysql_multi_update");
if (!(result= new multi_update(table_list,
@@ -929,7 +961,7 @@ bool mysql_multi_update(THD *thd,
MODE_STRICT_ALL_TABLES));
List<Item> total_list;
- (void) mysql_select(thd, &select_lex->ref_pointer_array,
+ res= mysql_select(thd, &select_lex->ref_pointer_array,
table_list, select_lex->with_wild,
total_list,
conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
@@ -937,6 +969,15 @@ bool mysql_multi_update(THD *thd,
options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
OPTION_SETUP_TABLES_DONE,
result, unit, select_lex);
+ DBUG_PRINT("info",("res: %d report_error: %d", res,
+ thd->net.report_error));
+ res|= thd->net.report_error;
+ if (unlikely(res))
+ {
+ /* If we had a another error reported earlier then this will be ignored */
+ result->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR));
+ result->abort();
+ }
delete result;
thd->abort_on_warning= 0;
DBUG_RETURN(FALSE);
@@ -970,6 +1011,7 @@ int multi_update::prepare(List<Item> &not_used_values,
List_iterator_fast<Item> field_it(*fields);
List_iterator_fast<Item> value_it(*values);
uint i, max_fields;
+ uint leaf_table_count= 0;
DBUG_ENTER("multi_update::prepare");
thd->count_cuted_fields= CHECK_FIELD_WARN;
@@ -1003,6 +1045,7 @@ int multi_update::prepare(List<Item> &not_used_values,
{
/* TODO: add support of view of join support */
TABLE *table=table_ref->table;
+ leaf_table_count++;
if (tables_to_update & table->map)
{
TABLE_LIST *tl= (TABLE_LIST*) thd->memdup((char*) table_ref,
@@ -1067,7 +1110,7 @@ int multi_update::prepare(List<Item> &not_used_values,
/* Allocate copy fields */
max_fields=0;
for (i=0 ; i < table_count ; i++)
- set_if_bigger(max_fields, fields_for_table[i]->elements);
+ set_if_bigger(max_fields, fields_for_table[i]->elements + leaf_table_count);
copy_field= new Copy_field[max_fields];
DBUG_RETURN(thd->is_fatal_error != 0);
}
@@ -1160,13 +1203,22 @@ multi_update::initialize_tables(JOIN *join)
trans_safe= transactional_tables= main_table->file->has_transactions();
table_to_update= 0;
+ /* Any update has at least one pair (field, value) */
+ DBUG_ASSERT(fields->elements);
+ /*
+ Only one table may be modified by UPDATE of an updatable view.
+ For an updatable view first_table_for_update indicates this
+ table.
+ For a regular multi-update it refers to some updated table.
+ */
+ TABLE *first_table_for_update= ((Item_field *) fields->head())->field->table;
+
/* Create a temporary table for keys to all tables, except main table */
for (table_ref= update_tables; table_ref; table_ref= table_ref->next_local)
{
TABLE *table=table_ref->table;
uint cnt= table_ref->shared;
- Item_field *ifield;
- List<Item> temp_fields= *fields_for_table[cnt];
+ List<Item> temp_fields;
ORDER group;
if (ignore)
@@ -1174,34 +1226,63 @@ multi_update::initialize_tables(JOIN *join)
if (table == main_table) // First table in join
{
if (safe_update_on_fly(thd, join->join_tab, table_ref, all_tables,
- &temp_fields))
+ fields_for_table[cnt]))
{
table_to_update= main_table; // Update table on the fly
continue;
}
}
+ if (table == first_table_for_update && table_ref->check_option)
+ {
+ table_map unupdated_tables= table_ref->check_option->used_tables() &
+ ~first_table_for_update->map;
+ for (TABLE_LIST *tbl_ref =leaves;
+ unupdated_tables && tbl_ref;
+ tbl_ref= tbl_ref->next_leaf)
+ {
+ if (unupdated_tables & tbl_ref->table->map)
+ unupdated_tables&= ~tbl_ref->table->map;
+ else
+ continue;
+ if (unupdated_check_opt_tables.push_back(tbl_ref->table))
+ DBUG_RETURN(1);
+ }
+ }
+
TMP_TABLE_PARAM *tmp_param= tmp_table_param+cnt;
/*
Create a temporary table to store all fields that are changed for this
table. The first field in the temporary table is a pointer to the
- original row so that we can find and update it
+ original row so that we can find and update it. For the updatable
+ VIEW a few following fields are rowids of tables used in the CHECK
+ OPTION condition.
*/
- /* ok to be on stack as this is not referenced outside of this func */
- Field_string offset(table->file->ref_length, 0, "offset",
- table, &my_charset_bin);
- /*
- The field will be converted to varstring when creating tmp table if
- table to be updated was created by mysql 4.1. Deny this.
- */
- offset.can_alter_field_type= 0;
- if (!(ifield= new Item_field(((Field *) &offset))))
- DBUG_RETURN(1);
- ifield->maybe_null= 0;
- if (temp_fields.push_front(ifield))
- DBUG_RETURN(1);
+ List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
+ TABLE *tbl= table;
+ do
+ {
+ Field_string *field= new Field_string(tbl->file->ref_length, 0,
+ tbl->alias,
+ tbl, &my_charset_bin);
+ if (!field)
+ DBUG_RETURN(1);
+ /*
+ The field will be converted to varstring when creating tmp table if
+ table to be updated was created by mysql 4.1. Deny this.
+ */
+ field->can_alter_field_type= 0;
+ Item_field *ifield= new Item_field((Field *) field);
+ if (!ifield)
+ DBUG_RETURN(1);
+ ifield->maybe_null= 0;
+ if (temp_fields.push_back(ifield))
+ DBUG_RETURN(1);
+ } while ((tbl= tbl_it++));
+
+ temp_fields.concat(fields_for_table[cnt]);
/* Make an unique key over the first field to avoid duplicated updates */
bzero((char*) &group, sizeof(group));
@@ -1250,8 +1331,9 @@ multi_update::~multi_update()
if (copy_field)
delete [] copy_field;
thd->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
- if (!trans_safe)
+ if (!trans_safe) // todo: remove since redundant
thd->no_trans_update.all= TRUE;
+ DBUG_ASSERT(trans_safe || thd->no_trans_update.all);
}
@@ -1337,8 +1419,15 @@ bool multi_update::send_data(List<Item> &not_used_values)
}
else
{
- if (!table->file->has_transactions())
+ /* non-transactional or transactional table got modified */
+ /* either multi_update class' flag is raised in its branch */
+ if (table->file->has_transactions())
+ transactional_tables= 1;
+ else
+ {
+ trans_safe= 0;
thd->no_trans_update.stmt= TRUE;
+ }
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
TRG_ACTION_AFTER, TRUE))
@@ -1350,10 +1439,26 @@ bool multi_update::send_data(List<Item> &not_used_values)
{
int error;
TABLE *tmp_table= tmp_tables[offset];
- fill_record(thd, tmp_table->field+1, *values_for_table[offset], 1);
- /* Store pointer to row */
- memcpy((char*) tmp_table->field[0]->ptr,
- (char*) table->file->ref, table->file->ref_length);
+ /* Store regular updated fields in the row. */
+ fill_record(thd,
+ tmp_table->field + 1 + unupdated_check_opt_tables.elements,
+ *values_for_table[offset], 1);
+ /*
+ For updatable VIEW store rowid of the updated table and
+ rowids of tables used in the CHECK OPTION condition.
+ */
+ uint field_num= 0;
+ List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
+ TABLE *tbl= table;
+ do
+ {
+ if (tbl != table)
+ tbl->file->position(tbl->record[0]);
+ memcpy((char*) tmp_table->field[field_num]->ptr,
+ (char*) tbl->file->ref, tbl->file->ref_length);
+ field_num++;
+ } while ((tbl= tbl_it++));
+
/* Write row, ignoring duplicated updates to a row */
error= tmp_table->file->write_row(tmp_table->record[0]);
if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
@@ -1379,8 +1484,8 @@ void multi_update::send_error(uint errcode,const char *err)
my_error(errcode, MYF(0), err);
/* If nothing updated return */
- if (!updated)
- return;
+ if (updated == 0) /* the counter might be reset in send_eof */
+ return; /* and then the query has been binlogged */
/* Something already updated so we have to invalidate cache */
query_cache_invalidate3(thd, update_tables, 1);
@@ -1391,11 +1496,43 @@ void multi_update::send_error(uint errcode,const char *err)
*/
if (trans_safe)
- ha_rollback_stmt(thd);
- else if (do_update && table_count > 1)
{
- /* Add warning here */
- VOID(do_updates(0));
+ DBUG_ASSERT(transactional_tables);
+ (void) ha_autocommit_or_rollback(thd, 1);
+ }
+ else
+ {
+ DBUG_ASSERT(thd->no_trans_update.stmt);
+ if (do_update && table_count > 1)
+ {
+ /* Add warning here */
+ /*
+ todo/fixme: do_update() is never called with the arg 1.
+ should it change the signature to become argless?
+ */
+ VOID(do_updates(0));
+ }
+ }
+ if (thd->no_trans_update.stmt)
+ {
+ /*
+ The query has to binlog because there's a modified non-transactional table
+ either from the query's list or via a stored routine: bug#13270,23333
+ */
+ if (mysql_bin_log.is_open())
+ {
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ transactional_tables, FALSE);
+ mysql_bin_log.write(&qinfo);
+ }
+ if (!trans_safe)
+ thd->no_trans_update.all= TRUE;
+ }
+ DBUG_ASSERT(trans_safe || !updated || thd->no_trans_update.stmt);
+
+ if (transactional_tables)
+ {
+ (void) ha_autocommit_or_rollback(thd, 1);
}
}
@@ -1403,9 +1540,10 @@ void multi_update::send_error(uint errcode,const char *err)
int multi_update::do_updates(bool from_send_error)
{
TABLE_LIST *cur_table;
- int local_error;
+ int local_error= 0;
ha_rows org_updated;
TABLE *table, *tmp_table;
+ List_iterator_fast<TABLE> check_opt_it(unupdated_check_opt_tables);
DBUG_ENTER("do_updates");
do_update= 0; // Don't retry this function
@@ -1413,8 +1551,8 @@ int multi_update::do_updates(bool from_send_error)
DBUG_RETURN(0);
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
{
- byte *ref_pos;
bool can_compare_record;
+ uint offset= cur_table->shared;
table = cur_table->table;
if (table == table_to_update)
@@ -1425,11 +1563,20 @@ int multi_update::do_updates(bool from_send_error)
(void) table->file->ha_rnd_init(0);
table->file->extra(HA_EXTRA_NO_CACHE);
+ check_opt_it.rewind();
+ while(TABLE *tbl= check_opt_it++)
+ {
+ if (tbl->file->ha_rnd_init(1))
+ goto err;
+ tbl->file->extra(HA_EXTRA_CACHE);
+ }
+
/*
Setup copy functions to copy fields from temporary table
*/
- List_iterator_fast<Item> field_it(*fields_for_table[cur_table->shared]);
- Field **field= tmp_table->field+1; // Skip row pointer
+ List_iterator_fast<Item> field_it(*fields_for_table[offset]);
+ Field **field= tmp_table->field +
+ 1 + unupdated_check_opt_tables.elements; // Skip row pointers
Copy_field *copy_field_ptr= copy_field, *copy_field_end;
for ( ; *field ; field++)
{
@@ -1444,7 +1591,6 @@ int multi_update::do_updates(bool from_send_error)
can_compare_record= !(table->file->table_flags() &
HA_PARTIAL_COLUMN_READ);
- ref_pos= (byte*) tmp_table->field[0]->ptr;
for (;;)
{
if (thd->killed && trans_safe)
@@ -1457,8 +1603,20 @@ int multi_update::do_updates(bool from_send_error)
continue; // May happen on dup key
goto err;
}
- if ((local_error= table->file->rnd_pos(table->record[0], ref_pos)))
- goto err;
+
+ /* call rnd_pos() using rowids from temporary table */
+ check_opt_it.rewind();
+ TABLE *tbl= table;
+ uint field_num= 0;
+ do
+ {
+ if((local_error=
+ tbl->file->rnd_pos(tbl->record[0],
+ (byte *) tmp_table->field[field_num]->ptr)))
+ goto err;
+ field_num++;
+ } while((tbl= check_opt_it++));
+
table->status|= STATUS_UPDATED;
store_record(table,record[1]);
@@ -1502,12 +1660,19 @@ int multi_update::do_updates(bool from_send_error)
if (updated != org_updated)
{
if (table->file->has_transactions())
- transactional_tables= 1;
+ transactional_tables= 1;
else
- trans_safe= 0; // Can't do safe rollback
+ {
+ trans_safe= 0; // Can't do safe rollback
+ thd->no_trans_update.stmt= TRUE;
+ }
}
(void) table->file->ha_rnd_end();
(void) tmp_table->file->ha_rnd_end();
+ check_opt_it.rewind();
+ while (TABLE *tbl= check_opt_it++)
+ tbl->file->ha_rnd_end();
+
}
DBUG_RETURN(0);
@@ -1521,13 +1686,19 @@ err:
err2:
(void) table->file->ha_rnd_end();
(void) tmp_table->file->ha_rnd_end();
+ check_opt_it.rewind();
+ while (TABLE *tbl= check_opt_it++)
+ tbl->file->ha_rnd_end();
if (updated != org_updated)
{
if (table->file->has_transactions())
transactional_tables= 1;
else
+ {
trans_safe= 0;
+ thd->no_trans_update.stmt= TRUE;
+ }
}
DBUG_RETURN(1);
}
@@ -1556,20 +1727,26 @@ bool multi_update::send_eof()
Write the SQL statement to the binlog if we updated
rows and we succeeded or if we updated some non
transactional tables.
+
+ The query has to binlog because there's a modified non-transactional table
+ either from the query's list or via a stored routine: bug#13270,23333
*/
- if ((local_error == 0) || (updated && !trans_safe))
+ DBUG_ASSERT(trans_safe || !updated || thd->no_trans_update.stmt);
+ if (local_error == 0 || thd->no_trans_update.stmt)
{
if (mysql_bin_log.is_open())
{
if (local_error == 0)
thd->clear_error();
+ else
+ updated= 0; /* if there's an error binlog it here not in ::send_error */
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_tables, FALSE);
if (mysql_bin_log.write(&qinfo) && trans_safe)
local_error= 1; // Rollback update
}
- if (!transactional_tables)
+ if (!trans_safe)
thd->no_trans_update.all= TRUE;
}
@@ -1581,7 +1758,7 @@ bool multi_update::send_eof()
if (local_error > 0) // if the above log write did not fail ...
{
- /* Safety: If we haven't got an error before (should not happen) */
+ /* Safety: If we haven't got an error before (can happen in do_updates) */
my_message(ER_UNKNOWN_ERROR, "An error occured in multi-table update",
MYF(0));
return TRUE;
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index ba367040b36..40f54799295 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -692,6 +692,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
bool can_be_merged;
char dir_buff[FN_REFLEN], file_buff[FN_REFLEN];
LEX_STRING dir, file;
+ int error= 0;
DBUG_ENTER("mysql_register_view");
/* print query */
@@ -702,9 +703,58 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
lex->unit.print(&str);
thd->variables.sql_mode|= sql_mode;
}
- str.append('\0');
DBUG_PRINT("info", ("View: %s", str.ptr()));
+ /* fill structure */
+ view->query.str= str.c_ptr_safe();
+ view->query.length= str.length();
+ view->source.str= thd->query + thd->lex->create_view_select_start;
+ view->source.length= (char *)skip_rear_comments(thd->charset(),
+ (char *)view->source.str,
+ (char *)thd->query +
+ thd->query_length) -
+ view->source.str;
+ view->file_version= 1;
+ view->calc_md5(md5);
+ view->md5.str= md5;
+ view->md5.length= 32;
+ can_be_merged= lex->can_be_merged();
+ if (lex->create_view_algorithm == VIEW_ALGORITHM_MERGE &&
+ !lex->can_be_merged())
+ {
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_VIEW_MERGE,
+ ER(ER_WARN_VIEW_MERGE));
+ lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
+ }
+ view->algorithm= lex->create_view_algorithm;
+ view->definer.user= lex->definer->user;
+ view->definer.host= lex->definer->host;
+ view->view_suid= lex->create_view_suid;
+ view->with_check= lex->create_view_check;
+ if ((view->updatable_view= (can_be_merged &&
+ view->algorithm != VIEW_ALGORITHM_TMPTABLE)))
+ {
+ /* TODO: change here when we will support UNIONs */
+ for (TABLE_LIST *tbl= (TABLE_LIST *)lex->select_lex.table_list.first;
+ tbl;
+ tbl= tbl->next_local)
+ {
+ if ((tbl->view && !tbl->updatable_view) || tbl->schema_table)
+ {
+ view->updatable_view= 0;
+ break;
+ }
+ for (TABLE_LIST *up= tbl; up; up= up->embedding)
+ {
+ if (up->outer_join)
+ {
+ view->updatable_view= 0;
+ goto loop_out;
+ }
+ }
+ }
+ }
+loop_out:
/* print file name */
(void) my_snprintf(dir_buff, FN_REFLEN, "%s/%s/",
mysql_data_home, view->db);
@@ -734,16 +784,21 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
if (mode == VIEW_CREATE_NEW)
{
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), view->alias);
- DBUG_RETURN(-1);
+ error= -1;
+ goto err;
}
if (!(parser= sql_parse_prepare(&path, thd->mem_root, 0)))
- DBUG_RETURN(1);
+ {
+ error= 1;
+ goto err;
+ }
if (!parser->ok() || !is_equal(&view_type, parser->type()))
{
my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->table_name, "VIEW");
- DBUG_RETURN(-1);
+ error= -1;
+ goto err;
}
/*
@@ -756,67 +811,21 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
view_parameters + revision_number_position, 1,
&file_parser_dummy_hook))
{
- DBUG_RETURN(thd->net.report_error? -1 : 0);
+ error= thd->net.report_error? -1 : 0;
+ goto err;
}
}
else
- {
+ {
if (mode == VIEW_ALTER)
{
my_error(ER_NO_SUCH_TABLE, MYF(0), view->db, view->alias);
- DBUG_RETURN(-1);
- }
- }
- }
- /* fill structure */
- view->query.str= (char*)str.ptr();
- view->query.length= str.length()-1; // we do not need last \0
- view->source.str= thd->query + thd->lex->create_view_select_start;
- view->source.length= (char *)skip_rear_comments((char *)view->source.str,
- (char *)thd->query +
- thd->query_length) -
- view->source.str;
- view->file_version= 1;
- view->calc_md5(md5);
- view->md5.str= md5;
- view->md5.length= 32;
- can_be_merged= lex->can_be_merged();
- if (lex->create_view_algorithm == VIEW_ALGORITHM_MERGE &&
- !lex->can_be_merged())
- {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_VIEW_MERGE,
- ER(ER_WARN_VIEW_MERGE));
- lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
- }
- view->algorithm= lex->create_view_algorithm;
- view->definer.user= lex->definer->user;
- view->definer.host= lex->definer->host;
- view->view_suid= lex->create_view_suid;
- view->with_check= lex->create_view_check;
- if ((view->updatable_view= (can_be_merged &&
- view->algorithm != VIEW_ALGORITHM_TMPTABLE)))
- {
- /* TODO: change here when we will support UNIONs */
- for (TABLE_LIST *tbl= (TABLE_LIST *)lex->select_lex.table_list.first;
- tbl;
- tbl= tbl->next_local)
- {
- if ((tbl->view && !tbl->updatable_view) || tbl->schema_table)
- {
- view->updatable_view= 0;
- break;
- }
- for (TABLE_LIST *up= tbl; up; up= up->embedding)
- {
- if (up->outer_join)
- {
- view->updatable_view= 0;
- goto loop_out;
- }
+ error= -1;
+ goto err;
}
}
}
-loop_out:
+
/*
Check that table of main select do not used in subqueries.
@@ -841,15 +850,23 @@ loop_out:
!view->updatable_view)
{
my_error(ER_VIEW_NONUPD_CHECK, MYF(0), view->db, view->table_name);
- DBUG_RETURN(-1);
+ error= -1;
+ goto err;
}
if (sql_create_definition_file(&dir, &file, view_file_type,
(gptr)view, view_parameters, num_view_backups))
{
- DBUG_RETURN(thd->net.report_error? -1 : 1);
+ error= thd->net.report_error? -1 : 1;
+ goto err;
}
DBUG_RETURN(0);
+err:
+ view->query.str= NULL;
+ view->query.length= 0;
+ view->md5.str= NULL;
+ view->md5.length= 0;
+ DBUG_RETURN(error);
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index c1da870960b..f09ba5b8b3a 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1483,7 +1483,6 @@ create:
lex->create_info.options=$2 | $4;
lex->create_info.db_type= (enum db_type) lex->thd->variables.table_type;
lex->create_info.default_table_charset= NULL;
- lex->name=0;
}
create2
{ Lex->current_select= &Lex->select_lex; }
@@ -2763,27 +2762,15 @@ create2:
| opt_create_table_options create3 {}
| LIKE table_ident
{
- LEX *lex=Lex;
- THD *thd= lex->thd;
- if (!(lex->name= (char *)$2))
- MYSQL_YYABORT;
- if ($2->db.str == NULL &&
- thd->copy_db_to(&($2->db.str), &($2->db.length)))
- {
+ Lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE;
+ if (!Lex->select_lex.add_table_to_list(YYTHD, $2, NULL, 0, TL_READ))
MYSQL_YYABORT;
- }
}
| '(' LIKE table_ident ')'
{
- LEX *lex=Lex;
- THD *thd= lex->thd;
- if (!(lex->name= (char *)$3))
+ Lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE;
+ if (!Lex->select_lex.add_table_to_list(YYTHD, $3, NULL, 0, TL_READ))
MYSQL_YYABORT;
- if ($3->db.str == NULL &&
- thd->copy_db_to(&($3->db.str), &($3->db.length)))
- {
- MYSQL_YYABORT;
- }
}
;
@@ -4376,8 +4363,12 @@ select_option:
}
| SQL_CACHE_SYM
{
- /* Honor this flag only if SQL_NO_CACHE wasn't specified. */
- if (Lex->select_lex.sql_cache != SELECT_LEX::SQL_NO_CACHE)
+ /*
+ Honor this flag only if SQL_NO_CACHE wasn't specified AND
+ we are parsing the outermost SELECT in the query.
+ */
+ if (Lex->select_lex.sql_cache != SELECT_LEX::SQL_NO_CACHE &&
+ Lex->current_select == &Lex->select_lex)
{
Lex->safe_to_cache_query=1;
Lex->select_lex.options|= OPTION_TO_QUERY_CACHE;
@@ -5163,8 +5154,8 @@ simple_expr:
$$= new Item_func_sp(Lex->current_context(), name, *$4);
else
$$= new Item_func_sp(Lex->current_context(), name);
- lex->safe_to_cache_query=0;
- }
+ }
+ lex->safe_to_cache_query=0;
}
| UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' expr_list ')'
{
@@ -5833,7 +5824,8 @@ select_derived2:
LEX *lex= Lex;
lex->derived_tables|= DERIVED_SUBQUERY;
if (lex->sql_command == (int)SQLCOM_HA_READ ||
- lex->sql_command == (int)SQLCOM_KILL)
+ lex->sql_command == (int)SQLCOM_KILL ||
+ lex->sql_command == (int)SQLCOM_PURGE)
{
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
@@ -6214,6 +6206,9 @@ limit_options:
;
limit_option:
param_marker
+ {
+ ((Item_param *) $1)->set_strict_type(INT_RESULT);
+ }
| ULONGLONG_NUM { $$= new Item_uint($1.str, $1.length); }
| LONG_NUM { $$= new Item_uint($1.str, $1.length); }
| NUM { $$= new Item_uint($1.str, $1.length); }
@@ -6561,7 +6556,7 @@ insert_lock_option:
insert visible only after the table unlocking but everyone can
read table.
*/
- $$= (Lex->sphead ? TL_WRITE :TL_WRITE_CONCURRENT_INSERT);
+ $$= (Lex->sphead ? TL_WRITE_DEFAULT : TL_WRITE_CONCURRENT_INSERT);
#else
$$= TL_WRITE_CONCURRENT_INSERT;
#endif
@@ -6739,7 +6734,7 @@ insert_update_elem:
};
opt_low_priority:
- /* empty */ { $$= YYTHD->update_lock_default; }
+ /* empty */ { $$= TL_WRITE_DEFAULT; }
| LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; };
/* Delete rows from a table */
@@ -6750,7 +6745,7 @@ delete:
LEX *lex= Lex;
lex->sql_command= SQLCOM_DELETE;
mysql_init_select(lex);
- lex->lock_option= lex->thd->update_lock_default;
+ lex->lock_option= TL_WRITE_DEFAULT;
lex->ignore= 0;
lex->select_lex.init_order();
}
@@ -7285,6 +7280,7 @@ purge:
{
LEX *lex=Lex;
lex->type=0;
+ lex->sql_command = SQLCOM_PURGE;
} purge_options
{}
;
@@ -7296,7 +7292,6 @@ purge_options:
purge_option:
TO_SYM TEXT_STRING_sys
{
- Lex->sql_command = SQLCOM_PURGE;
Lex->to_log = $2.str;
}
| BEFORE_SYM expr
@@ -7415,7 +7410,7 @@ opt_local:
| LOCAL_SYM { $$=1;};
load_data_lock:
- /* empty */ { $$= YYTHD->update_lock_default; }
+ /* empty */ { $$= TL_WRITE_DEFAULT; }
| CONCURRENT
{
#ifdef HAVE_QUERY_CACHE
@@ -7423,7 +7418,7 @@ load_data_lock:
Ignore this option in SP to avoid problem with query cache
*/
if (Lex->sphead != 0)
- $$= YYTHD->update_lock_default;
+ $$= TL_WRITE_DEFAULT;
else
#endif
$$= TL_WRITE_CONCURRENT_INSERT;
@@ -8736,7 +8731,7 @@ table_lock:
lock_option:
READ_SYM { $$=TL_READ_NO_INSERT; }
- | WRITE_SYM { $$=YYTHD->update_lock_default; }
+ | WRITE_SYM { $$=TL_WRITE_DEFAULT; }
| LOW_PRIORITY WRITE_SYM { $$=TL_WRITE_LOW_PRIORITY; }
| READ_SYM LOCAL_SYM { $$= TL_READ; }
;
@@ -9415,7 +9410,8 @@ subselect_start:
{
LEX *lex=Lex;
if (lex->sql_command == (int)SQLCOM_HA_READ ||
- lex->sql_command == (int)SQLCOM_KILL)
+ lex->sql_command == (int)SQLCOM_KILL ||
+ lex->sql_command == (int)SQLCOM_PURGE)
{
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
diff --git a/sql/structs.h b/sql/structs.h
index 2dcafdef615..28bdd8c1519 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -142,12 +142,11 @@ typedef struct st_read_record { /* Parameter to read_record */
/*
- Originally MySQL used TIME structure inside server only, but since
+ Originally MySQL used MYSQL_TIME structure inside server only, but since
4.1 it's exported to user in the new client API. Define aliases for
new names to keep existing code simple.
*/
-typedef struct st_mysql_time TIME;
typedef enum enum_mysql_timestamp_type timestamp_type;
@@ -191,7 +190,8 @@ enum SHOW_TYPE
SHOW_NET_COMPRESSION,
SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING, SHOW_SLAVE_RETRIED_TRANS,
SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_CONST_LONG, SHOW_KEY_CACHE_LONGLONG,
- SHOW_LONG_STATUS, SHOW_LONG_CONST_STATUS, SHOW_SLAVE_SKIP_ERRORS
+ SHOW_LONG_STATUS, SHOW_LONG_CONST_STATUS, SHOW_SLAVE_SKIP_ERRORS,
+ SHOW_LONGLONG_STATUS
};
enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED};
diff --git a/sql/table.cc b/sql/table.cc
index fb2012a79d1..9868aa9b9c1 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1986,6 +1986,47 @@ bool st_table_list::prep_where(THD *thd, Item **conds,
/*
+ Merge ON expressions for a view
+
+ SYNOPSIS
+ merge_on_conds()
+ thd thread handle
+ table table for the VIEW
+ is_cascaded TRUE <=> merge ON expressions from underlying views
+
+ DESCRIPTION
+ This function returns the result of ANDing the ON expressions
+ of the given view and all underlying views. The ON expressions
+ of the underlying views are added only if is_cascaded is TRUE.
+
+ RETURN
+ Pointer to the built expression if there is any.
+ Otherwise and in the case of a failure NULL is returned.
+*/
+
+static Item *
+merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
+{
+ DBUG_ENTER("merge_on_conds");
+
+ Item *cond= NULL;
+ DBUG_PRINT("info", ("alias: %s", table->alias));
+ if (table->on_expr)
+ cond= table->on_expr->copy_andor_structure(thd);
+ if (!table->nested_join)
+ DBUG_RETURN(cond);
+ List_iterator<TABLE_LIST> li(table->nested_join->join_list);
+ while (TABLE_LIST *tbl= li++)
+ {
+ if (tbl->view && !is_cascaded)
+ continue;
+ cond= and_conds(cond, merge_on_conds(thd, tbl, is_cascaded));
+ }
+ DBUG_RETURN(cond);
+}
+
+
+/*
Prepare check option expression of table
SYNOPSIS
@@ -2001,8 +2042,8 @@ bool st_table_list::prep_where(THD *thd, Item **conds,
VIEW_CHECK_LOCAL option.
NOTE
- This method build check options for every call
- (usual execution or every SP/PS call)
+ This method builds check option condition to use it later on
+ every call (usual execution or every SP/PS call).
This method have to be called after WHERE preparation
(st_table_list::prep_where)
@@ -2014,38 +2055,42 @@ bool st_table_list::prep_where(THD *thd, Item **conds,
bool st_table_list::prep_check_option(THD *thd, uint8 check_opt_type)
{
DBUG_ENTER("st_table_list::prep_check_option");
+ bool is_cascaded= check_opt_type == VIEW_CHECK_CASCADED;
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
{
/* see comment of check_opt_type parameter */
- if (tbl->view &&
- tbl->prep_check_option(thd,
- ((check_opt_type == VIEW_CHECK_CASCADED) ?
- VIEW_CHECK_CASCADED :
- VIEW_CHECK_NONE)))
- {
+ if (tbl->view && tbl->prep_check_option(thd, (is_cascaded ?
+ VIEW_CHECK_CASCADED :
+ VIEW_CHECK_NONE)))
DBUG_RETURN(TRUE);
- }
}
- if (check_opt_type)
+ if (check_opt_type && !check_option_processed)
{
- Item *item= 0;
+ Query_arena *arena= thd->stmt_arena, backup;
+ arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test
+
if (where)
{
DBUG_ASSERT(where->fixed);
- item= where->copy_andor_structure(thd);
+ check_option= where->copy_andor_structure(thd);
}
- if (check_opt_type == VIEW_CHECK_CASCADED)
+ if (is_cascaded)
{
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
{
if (tbl->check_option)
- item= and_conds(item, tbl->check_option);
+ check_option= and_conds(check_option, tbl->check_option);
}
}
- if (item)
- thd->change_item_tree(&check_option, item);
+ check_option= and_conds(check_option,
+ merge_on_conds(thd, this, is_cascaded));
+
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ check_option_processed= TRUE;
+
}
if (check_option)
@@ -2150,7 +2195,7 @@ void st_table_list::cleanup_items()
check CHECK OPTION condition
SYNOPSIS
- check_option()
+ st_table_list::view_check_option()
ignore_failure ignore check option fail
RETURN
diff --git a/sql/table.h b/sql/table.h
index da2c90ab212..d4dc3e8c0b8 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -137,7 +137,12 @@ typedef struct st_table_share
const char *table_name; /* Table name (for open) */
const char *path; /* Path to .frm file (from datadir) */
LEX_STRING connect_string;
- key_map keys_in_use; /* Keys in use for table */
+
+ /*
+ Set of keys in use, implemented as a Bitmap.
+ Excludes keys disabled by ALTER TABLE ... DISABLE KEYS.
+ */
+ key_map keys_in_use;
key_map keys_for_keyread;
ulong avg_row_length; /* create information */
ulong raid_chunksize;
@@ -208,7 +213,21 @@ struct st_table {
byte *record[2]; /* Pointer to records */
byte *insert_values; /* used by INSERT ... UPDATE */
- key_map quick_keys, used_keys, keys_in_use_for_query;
+ key_map quick_keys, used_keys;
+
+ /*
+ A set of keys that can be used in the query that references this
+ table
+
+ All indexes disabled on the table's TABLE_SHARE (see TABLE::s) will be
+ subtracted from this set upon instantiation. Thus for any TABLE t it holds
+ that t.keys_in_use_for_query is a subset of t.s.keys_in_use. Generally we
+ must not introduce any new keys here (see setup_tables).
+
+ The set is implemented as a bitmap.
+ */
+ key_map keys_in_use_for_query;
+ key_map merge_keys;
KEY *key_info; /* data of keys in database */
Field *next_number_field, /* Set if next_number is activated */
@@ -666,6 +685,8 @@ typedef struct st_table_list
bool compact_view_format; /* Use compact format for SHOW CREATE VIEW */
/* view where processed */
bool where_processed;
+ /* TRUE <=> VIEW CHECK OPTION expression has been processed */
+ bool check_option_processed;
/* FRMTYPE_ERROR if any type is acceptable */
enum frm_type_enum required_type;
char timestamp_buffer[20]; /* buffer for timestamp (19+1) */
diff --git a/sql/time.cc b/sql/time.cc
index a46f2fc237d..b4a8b047998 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -61,7 +61,7 @@ int calc_weekday(long daynr,bool sunday_first_day_of_week)
next week is week 1.
*/
-uint calc_week(TIME *l_time, uint week_behaviour, uint *year)
+uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year)
{
uint days;
ulong daynr=calc_daynr(l_time->year,l_time->month,l_time->day);
@@ -179,7 +179,7 @@ ulong convert_month_to_period(ulong month)
/*
- Convert a timestamp string to a TIME value and produce a warning
+ Convert a timestamp string to a MYSQL_TIME value and produce a warning
if string was truncated during conversion.
NOTE
@@ -187,7 +187,7 @@ ulong convert_month_to_period(ulong month)
*/
timestamp_type
-str_to_datetime_with_warn(const char *str, uint length, TIME *l_time,
+str_to_datetime_with_warn(const char *str, uint length, MYSQL_TIME *l_time,
uint flags)
{
int was_cut;
@@ -200,13 +200,14 @@ str_to_datetime_with_warn(const char *str, uint length, TIME *l_time,
MODE_NO_ZERO_DATE))),
&was_cut);
if (was_cut || ts_type <= MYSQL_TIMESTAMP_ERROR)
- make_truncated_value_warning(current_thd, str, length, ts_type, NullS);
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ str, length, ts_type, NullS);
return ts_type;
}
/*
- Convert a datetime from broken-down TIME representation to corresponding
+ Convert a datetime from broken-down MYSQL_TIME representation to corresponding
TIMESTAMP value.
SYNOPSIS
@@ -222,7 +223,7 @@ str_to_datetime_with_warn(const char *str, uint length, TIME *l_time,
0 - t contains datetime value which is out of TIMESTAMP range.
*/
-my_time_t TIME_to_timestamp(THD *thd, const TIME *t, my_bool *in_dst_time_gap)
+my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, my_bool *in_dst_time_gap)
{
my_time_t timestamp;
@@ -241,20 +242,20 @@ my_time_t TIME_to_timestamp(THD *thd, const TIME *t, my_bool *in_dst_time_gap)
/*
- Convert a time string to a TIME struct and produce a warning
+ Convert a time string to a MYSQL_TIME struct and produce a warning
if string was cut during conversion.
NOTE
See str_to_time() for more info.
*/
bool
-str_to_time_with_warn(const char *str, uint length, TIME *l_time)
+str_to_time_with_warn(const char *str, uint length, MYSQL_TIME *l_time)
{
int warning;
bool ret_val= str_to_time(str, length, l_time, &warning);
if (ret_val || warning)
- make_truncated_value_warning(current_thd, str, length,
- MYSQL_TIMESTAMP_TIME, NullS);
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ str, length, MYSQL_TIMESTAMP_TIME, NullS);
return ret_val;
}
@@ -263,7 +264,7 @@ str_to_time_with_warn(const char *str, uint length, TIME *l_time)
Convert a system time structure to TIME
*/
-void localtime_to_TIME(TIME *to, struct tm *from)
+void localtime_to_TIME(MYSQL_TIME *to, struct tm *from)
{
to->neg=0;
to->second_part=0;
@@ -275,7 +276,7 @@ void localtime_to_TIME(TIME *to, struct tm *from)
to->second= (int) from->tm_sec;
}
-void calc_time_from_sec(TIME *to, long seconds, long microseconds)
+void calc_time_from_sec(MYSQL_TIME *to, long seconds, long microseconds)
{
long t_seconds;
to->hour= seconds/3600L;
@@ -644,7 +645,7 @@ const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format,
MySQL doesn't support comparing of date/time/datetime strings that
are not in arbutary order as dates are compared as strings in some
context)
- This functions don't check that given TIME structure members are
+ This functions don't check that given MYSQL_TIME structure members are
in valid range. If they are not, return value won't reflect any
valid date either. Additionally, make_time doesn't take into
account time->day member: it's assumed that days have been converted
@@ -652,7 +653,7 @@ const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format,
****************************************************************************/
void make_time(const DATE_TIME_FORMAT *format __attribute__((unused)),
- const TIME *l_time, String *str)
+ const MYSQL_TIME *l_time, String *str)
{
uint length= (uint) my_time_to_str(l_time, (char*) str->ptr());
str->length(length);
@@ -661,7 +662,7 @@ void make_time(const DATE_TIME_FORMAT *format __attribute__((unused)),
void make_date(const DATE_TIME_FORMAT *format __attribute__((unused)),
- const TIME *l_time, String *str)
+ const MYSQL_TIME *l_time, String *str)
{
uint length= (uint) my_date_to_str(l_time, (char*) str->ptr());
str->length(length);
@@ -670,7 +671,7 @@ void make_date(const DATE_TIME_FORMAT *format __attribute__((unused)),
void make_datetime(const DATE_TIME_FORMAT *format __attribute__((unused)),
- const TIME *l_time, String *str)
+ const MYSQL_TIME *l_time, String *str)
{
uint length= (uint) my_datetime_to_str(l_time, (char*) str->ptr());
str->length(length);
@@ -678,7 +679,8 @@ void make_datetime(const DATE_TIME_FORMAT *format __attribute__((unused)),
}
-void make_truncated_value_warning(THD *thd, const char *str_val,
+void make_truncated_value_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
+ const char *str_val,
uint str_length, timestamp_type time_type,
const char *field_name)
{
@@ -710,7 +712,7 @@ void make_truncated_value_warning(THD *thd, const char *str_val,
cs->cset->snprintf(cs, warn_buff, sizeof(warn_buff),
ER(ER_TRUNCATED_WRONG_VALUE),
type_str, str.c_ptr());
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ push_warning(thd, level,
ER_TRUNCATED_WRONG_VALUE, warn_buff);
}
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 70f7cc5ea86..bedbf921cae 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -77,7 +77,7 @@ typedef struct lsinfo
/*
Structure with information describing ranges of my_time_t shifted to local
- time (my_time_t + offset). Used for local TIME -> my_time_t conversion.
+ time (my_time_t + offset). Used for local MYSQL_TIME -> my_time_t conversion.
See comments for TIME_to_gmt_sec() for more info.
*/
typedef struct revtinfo
@@ -292,9 +292,9 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage)
be used if there are no transitions or we have moment in time before
any transitions.
Second task is to build "shifted my_time_t" -> my_time_t map used in
- TIME -> my_time_t conversion.
+ MYSQL_TIME -> my_time_t conversion.
Note: See description of TIME_to_gmt_sec() function first.
- In order to perform TIME -> my_time_t conversion we need to build table
+ In order to perform MYSQL_TIME -> my_time_t conversion we need to build table
which defines "shifted by tz offset and leap seconds my_time_t" ->
my_time_t function wich is almost the same (except ranges of ambiguity)
as reverse function to piecewise linear function used for my_time_t ->
@@ -531,14 +531,14 @@ static const uint year_lengths[2]=
offset - local time zone offset
DESCRIPTION
- Convert my_time_t with offset to TIME struct. Differs from timesub
+ Convert my_time_t with offset to MYSQL_TIME struct. Differs from timesub
(from elsie code) because doesn't contain any leap correction and
TM_GMTOFF and is_dst setting and contains some MySQL specific
initialization. Funny but with removing of these we almost have
glibc's offtime function.
*/
static void
-sec_to_TIME(TIME * tmp, my_time_t t, long offset)
+sec_to_TIME(MYSQL_TIME * tmp, my_time_t t, long offset)
{
long days;
long rem;
@@ -594,7 +594,7 @@ sec_to_TIME(TIME * tmp, my_time_t t, long offset)
tmp->month++;
tmp->day= (uint)(days + 1);
- /* filling MySQL specific TIME members */
+ /* filling MySQL specific MYSQL_TIME members */
tmp->neg= 0; tmp->second_part= 0;
tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
}
@@ -686,7 +686,7 @@ find_transition_type(my_time_t t, const TIME_ZONE_INFO *sp)
/*
Converts time in my_time_t representation (seconds in UTC since Epoch) to
- broken down TIME representation in local time zone.
+ broken down MYSQL_TIME representation in local time zone.
SYNOPSIS
gmt_sec_to_TIME()
@@ -701,12 +701,12 @@ find_transition_type(my_time_t t, const TIME_ZONE_INFO *sp)
(60th and 61st second, look how we calculate them as "hit" in this
function).
Under realistic assumptions about frequency of transitions the same array
- can be used fot TIME -> my_time_t conversion. For this we need to
+ can be used fot MYSQL_TIME -> my_time_t conversion. For this we need to
implement tweaked binary search which will take into account that some
- TIME has two matching my_time_t ranges and some of them have none.
+ MYSQL_TIME has two matching my_time_t ranges and some of them have none.
*/
static void
-gmt_sec_to_TIME(TIME *tmp, my_time_t sec_in_utc, const TIME_ZONE_INFO *sp)
+gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t sec_in_utc, const TIME_ZONE_INFO *sp)
{
const TRAN_TYPE_INFO *ttisp;
const LS_INFO *lp;
@@ -809,7 +809,7 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
/*
- Converts local time in broken down TIME representation to my_time_t
+ Converts local time in broken down MYSQL_TIME representation to my_time_t
representation.
SYNOPSIS
@@ -851,7 +851,7 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
We use completely different approach. It is better since it is both
faster than iterative implementations and fully determenistic. If you
- look at my_time_t to TIME conversion then you'll find that it consist
+ look at my_time_t to MYSQL_TIME conversion then you'll find that it consist
of two steps:
The first is calculating shifted my_time_t value and the second - TIME
calculation from shifted my_time_t value (well it is a bit simplified
@@ -881,7 +881,7 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
0 in case of error.
*/
static my_time_t
-TIME_to_gmt_sec(const TIME *t, const TIME_ZONE_INFO *sp,
+TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp,
my_bool *in_dst_time_gap)
{
my_time_t local_t;
@@ -1008,20 +1008,20 @@ class Time_zone_system : public Time_zone
{
public:
Time_zone_system() {} /* Remove gcc warning */
- virtual my_time_t TIME_to_gmt_sec(const TIME *t,
+ virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
my_bool *in_dst_time_gap) const;
- virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const;
+ virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
virtual const String * get_name() const;
};
/*
- Converts local time in system time zone in TIME representation
+ Converts local time in system time zone in MYSQL_TIME representation
to its my_time_t representation.
SYNOPSIS
TIME_to_gmt_sec()
- t - pointer to TIME structure with local time in
+ t - pointer to MYSQL_TIME structure with local time in
broken-down representation.
in_dst_time_gap - pointer to bool which is set to true if datetime
value passed doesn't really exist (i.e. falls into
@@ -1029,7 +1029,7 @@ public:
DESCRIPTION
This method uses system function (localtime_r()) for conversion
- local time in system time zone in TIME structure to its my_time_t
+ local time in system time zone in MYSQL_TIME structure to its my_time_t
representation. Unlike the same function for Time_zone_db class
it it won't handle unnormalized input properly. Still it will
return lowest possible my_time_t in case of ambiguity or if we
@@ -1041,7 +1041,7 @@ public:
Corresponding my_time_t value or 0 in case of error
*/
my_time_t
-Time_zone_system::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
+Time_zone_system::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const
{
long not_used;
return my_system_gmt_sec(t, &not_used, in_dst_time_gap);
@@ -1054,7 +1054,7 @@ Time_zone_system::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
SYNOPSIS
gmt_sec_to_TIME()
- tmp - pointer to TIME structure to fill-in
+ tmp - pointer to MYSQL_TIME structure to fill-in
t - my_time_t value to be converted
NOTE
@@ -1065,7 +1065,7 @@ Time_zone_system::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
the 1902 easily.
*/
void
-Time_zone_system::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const
+Time_zone_system::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
{
struct tm tmp_tm;
time_t tmp_t= (time_t)t;
@@ -1095,26 +1095,26 @@ Time_zone_system::get_name() const
/*
Instance of this class represents UTC time zone. It uses system gmtime_r
function for conversions and is always available. It is used only for
- my_time_t -> TIME conversions in various UTC_... functions, it is not
- intended for TIME -> my_time_t conversions and shouldn't be exposed to user.
+ my_time_t -> MYSQL_TIME conversions in various UTC_... functions, it is not
+ intended for MYSQL_TIME -> my_time_t conversions and shouldn't be exposed to user.
*/
class Time_zone_utc : public Time_zone
{
public:
Time_zone_utc() {} /* Remove gcc warning */
- virtual my_time_t TIME_to_gmt_sec(const TIME *t,
+ virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
my_bool *in_dst_time_gap) const;
- virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const;
+ virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
virtual const String * get_name() const;
};
/*
- Convert UTC time from TIME representation to its my_time_t representation.
+ Convert UTC time from MYSQL_TIME representation to its my_time_t representation.
SYNOPSIS
TIME_to_gmt_sec()
- t - pointer to TIME structure with local time
+ t - pointer to MYSQL_TIME structure with local time
in broken-down representation.
in_dst_time_gap - pointer to bool which is set to true if datetime
value passed doesn't really exist (i.e. falls into
@@ -1129,7 +1129,7 @@ public:
0
*/
my_time_t
-Time_zone_utc::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
+Time_zone_utc::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const
{
/* Should be never called */
DBUG_ASSERT(0);
@@ -1143,14 +1143,14 @@ Time_zone_utc::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
SYNOPSIS
gmt_sec_to_TIME()
- tmp - pointer to TIME structure to fill-in
+ tmp - pointer to MYSQL_TIME structure to fill-in
t - my_time_t value to be converted
NOTE
See note for apropriate Time_zone_system method.
*/
void
-Time_zone_utc::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const
+Time_zone_utc::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
{
struct tm tmp_tm;
time_t tmp_t= (time_t)t;
@@ -1191,9 +1191,9 @@ class Time_zone_db : public Time_zone
{
public:
Time_zone_db(TIME_ZONE_INFO *tz_info_arg, const String * tz_name_arg);
- virtual my_time_t TIME_to_gmt_sec(const TIME *t,
+ virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
my_bool *in_dst_time_gap) const;
- virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const;
+ virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
virtual const String * get_name() const;
private:
TIME_ZONE_INFO *tz_info;
@@ -1227,7 +1227,7 @@ Time_zone_db::Time_zone_db(TIME_ZONE_INFO *tz_info_arg,
SYNOPSIS
TIME_to_gmt_sec()
- t - pointer to TIME structure with local time
+ t - pointer to MYSQL_TIME structure with local time
in broken-down representation.
in_dst_time_gap - pointer to bool which is set to true if datetime
value passed doesn't really exist (i.e. falls into
@@ -1241,7 +1241,7 @@ Time_zone_db::Time_zone_db(TIME_ZONE_INFO *tz_info_arg,
Corresponding my_time_t value or 0 in case of error
*/
my_time_t
-Time_zone_db::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
+Time_zone_db::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const
{
return ::TIME_to_gmt_sec(t, tz_info, in_dst_time_gap);
}
@@ -1253,11 +1253,11 @@ Time_zone_db::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
SYNOPSIS
gmt_sec_to_TIME()
- tmp - pointer to TIME structure to fill-in
+ tmp - pointer to MYSQL_TIME structure to fill-in
t - my_time_t value to be converted
*/
void
-Time_zone_db::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const
+Time_zone_db::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
{
::gmt_sec_to_TIME(tmp, t, tz_info);
}
@@ -1287,9 +1287,9 @@ class Time_zone_offset : public Time_zone
{
public:
Time_zone_offset(long tz_offset_arg);
- virtual my_time_t TIME_to_gmt_sec(const TIME *t,
+ virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
my_bool *in_dst_time_gap) const;
- virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const;
+ virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
virtual const String * get_name() const;
/*
This have to be public because we want to be able to access it from
@@ -1324,11 +1324,11 @@ Time_zone_offset::Time_zone_offset(long tz_offset_arg):
/*
Converts local time in time zone described as offset from UTC
- from TIME representation to its my_time_t representation.
+ from MYSQL_TIME representation to its my_time_t representation.
SYNOPSIS
TIME_to_gmt_sec()
- t - pointer to TIME structure with local time
+ t - pointer to MYSQL_TIME structure with local time
in broken-down representation.
in_dst_time_gap - pointer to bool which should be set to true if
datetime value passed doesn't really exist
@@ -1340,7 +1340,7 @@ Time_zone_offset::Time_zone_offset(long tz_offset_arg):
Corresponding my_time_t value or 0 in case of error
*/
my_time_t
-Time_zone_offset::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
+Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const
{
my_time_t local_t;
int shift= 0;
@@ -1385,11 +1385,11 @@ Time_zone_offset::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
SYNOPSIS
gmt_sec_to_TIME()
- tmp - pointer to TIME structure to fill-in
+ tmp - pointer to MYSQL_TIME structure to fill-in
t - my_time_t value to be converted
*/
void
-Time_zone_offset::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const
+Time_zone_offset::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
{
sec_to_TIME(tmp, t, offset);
}
@@ -2651,7 +2651,7 @@ main(int argc, char **argv)
my_bool localtime_negative;
TIME_ZONE_INFO tz_info;
struct tm tmp;
- TIME time_tmp;
+ MYSQL_TIME time_tmp;
time_t t, t1, t2;
char fullname[FN_REFLEN+1];
char *str_end;
diff --git a/sql/tztime.h b/sql/tztime.h
index d1f33843810..32a942a26e1 100644
--- a/sql/tztime.h
+++ b/sql/tztime.h
@@ -22,7 +22,7 @@
/*
This class represents abstract time zone and provides
- basic interface for TIME <-> my_time_t conversion.
+ basic interface for MYSQL_TIME <-> my_time_t conversion.
Actual time zones which are specified by DB, or via offset
or use system functions are its descendants.
*/
@@ -31,18 +31,18 @@ class Time_zone: public Sql_alloc
public:
Time_zone() {} /* Remove gcc warning */
/*
- Converts local time in broken down TIME representation to
+ Converts local time in broken down MYSQL_TIME representation to
my_time_t (UTC seconds since Epoch) represenation.
Returns 0 in case of error. Sets in_dst_time_gap to true if date provided
falls into spring time-gap (or lefts it untouched otherwise).
*/
- virtual my_time_t TIME_to_gmt_sec(const TIME *t,
+ virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
my_bool *in_dst_time_gap) const = 0;
/*
Converts time in my_time_t representation to local time in
- broken down TIME representation.
+ broken down MYSQL_TIME representation.
*/
- virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const = 0;
+ virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const = 0;
/*
Because of constness of String returned by get_name() time zone name
have to be already zeroended to be able to use String::ptr() instead
diff --git a/sql/udf_example.c b/sql/udf_example.c
index 2bb4fe92d2f..0f28c2a14b0 100644
--- a/sql/udf_example.c
+++ b/sql/udf_example.c
@@ -130,7 +130,8 @@ typedef long long longlong;
#include <m_string.h> /* To get strmov() */
#else
/* when compiled as standalone */
-#define strmov(a,b) strcpy(a,b)
+#include <string.h>
+#define strmov(a,b) stpcpy(a,b)
#define bzero(a,b) memset(a,0,b)
#define memcpy_fixed(a,b,c) memcpy(a,b,c)
#endif
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 06b2e0c10a2..c01e6a0f00c 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -859,7 +859,9 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
(regfield->real_type() != FIELD_TYPE_YEAR ||
field->def->val_int() != 0))
{
- if (field->def->save_in_field(regfield, 1))
+ int res= field->def->save_in_field(regfield, 1);
+ /* If not ok or warning of level 'note' */
+ if (res != 0 && res != 3)
{
my_error(ER_INVALID_DEFAULT, MYF(0), regfield->field_name);
error= 1;
diff --git a/sql/unireg.h b/sql/unireg.h
index 886b3d99212..0f7c1709c6c 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -71,6 +71,7 @@
#define MAX_TIME_WIDTH 23 /* -DDDDDD HH:MM:SS.###### */
#define MAX_DATETIME_FULL_WIDTH 29 /* YYYY-MM-DD HH:MM:SS.###### AM */
#define MAX_DATETIME_WIDTH 19 /* YYYY-MM-DD HH:MM:SS */
+#define MAX_DATETIME_COMPRESSED_WIDTH 14 /* YYYYMMDDHHMMSS */
#define MAX_TABLES (sizeof(table_map)*8-3) /* Max tables in join */
#define PARAM_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-3))
diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c
index be04d19a756..8bbbcac63e4 100644
--- a/strings/ctype-big5.c
+++ b/strings/ctype-big5.c
@@ -6400,7 +6400,7 @@ CHARSET_INFO my_charset_big5_chinese_ci=
0, /* min_sort_char */
255, /* max_sort_char */
' ', /* pad char */
- 0, /* escape_with_backslash_is_dangerous */
+ 1, /* escape_with_backslash_is_dangerous */
&my_charset_big5_handler,
&my_collation_big5_chinese_ci_handler
};
@@ -6433,7 +6433,7 @@ CHARSET_INFO my_charset_big5_bin=
0, /* min_sort_char */
255, /* max_sort_char */
' ', /* pad char */
- 0, /* escape_with_backslash_is_dangerous */
+ 1, /* escape_with_backslash_is_dangerous */
&my_charset_big5_handler,
&my_collation_mb_bin_handler
};
diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c
index e9de0ade557..f9d29ca1739 100644
--- a/strings/ctype-bin.c
+++ b/strings/ctype-bin.c
@@ -271,6 +271,29 @@ static int my_wc_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
}
+void my_hash_sort_8bit_bin(CHARSET_INFO *cs __attribute__((unused)),
+ const uchar *key, uint len,ulong *nr1, ulong *nr2)
+{
+ const uchar *pos = key;
+
+ key+= len;
+
+ /*
+ Remove trailing spaces. We have to do this to be able to compare
+ 'A ' and 'A' as identical
+ */
+ while (key > pos && key[-1] == ' ')
+ key--;
+
+ for (; pos < (uchar*) key ; pos++)
+ {
+ nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
+ ((uint)*pos)) + (nr1[0] << 8);
+ nr2[0]+=3;
+ }
+}
+
+
void my_hash_sort_bin(CHARSET_INFO *cs __attribute__((unused)),
const uchar *key, uint len,ulong *nr1, ulong *nr2)
{
@@ -471,7 +494,7 @@ MY_COLLATION_HANDLER my_collation_8bit_bin_handler =
my_wildcmp_bin,
my_strcasecmp_bin,
my_instr_bin,
- my_hash_sort_bin,
+ my_hash_sort_8bit_bin,
my_propagate_simple
};
diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c
index c7160e923a9..8ac7d62c9da 100644
--- a/strings/ctype-gbk.c
+++ b/strings/ctype-gbk.c
@@ -10046,7 +10046,7 @@ CHARSET_INFO my_charset_gbk_chinese_ci=
0, /* min_sort_char */
255, /* max_sort_char */
' ', /* pad char */
- 0, /* escape_with_backslash_is_dangerous */
+ 1, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
&my_collation_ci_handler
};
@@ -10078,7 +10078,7 @@ CHARSET_INFO my_charset_gbk_bin=
0, /* min_sort_char */
255, /* max_sort_char */
' ', /* pad char */
- 0, /* escape_with_backslash_is_dangerous */
+ 1, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
&my_collation_mb_bin_handler
};
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index 40cec669766..c12426b555f 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -467,6 +467,13 @@ static void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
key+= len;
+ /*
+ Remove trailing spaces. We have to do this to be able to compare
+ 'A ' and 'A' as identical
+ */
+ while (key > pos && key[-1] == ' ')
+ key--;
+
for (; pos < (uchar*) key ; pos++)
{
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c
index a66a7a000a6..6a7c7d7c0a0 100644
--- a/strings/ctype-sjis.c
+++ b/strings/ctype-sjis.c
@@ -4694,7 +4694,7 @@ CHARSET_INFO my_charset_sjis_japanese_ci=
0, /* min_sort_char */
255, /* max_sort_char */
' ', /* pad char */
- 0, /* escape_with_backslash_is_dangerous */
+ 1, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
&my_collation_ci_handler
};
@@ -4726,7 +4726,7 @@ CHARSET_INFO my_charset_sjis_bin=
0, /* min_sort_char */
255, /* max_sort_char */
' ', /* pad char */
- 0, /* escape_with_backslash_is_dangerous */
+ 1, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
&my_collation_mb_bin_handler
};
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index 1263882846d..4dbda0b9239 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -8073,7 +8073,7 @@ MY_COLLATION_HANDLER my_collation_ucs2_uca_handler =
my_propagate_complex
};
-CHARSET_INFO my_charset_ucs2_general_uca=
+CHARSET_INFO my_charset_ucs2_unicode_ci=
{
128,0,0, /* number */
MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
@@ -8734,7 +8734,7 @@ static uchar ctype_utf8[] = {
extern MY_CHARSET_HANDLER my_charset_utf8_handler;
-CHARSET_INFO my_charset_utf8_general_uca_ci=
+CHARSET_INFO my_charset_utf8_unicode_ci=
{
192,0,0, /* number */
MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c
index 6b1ba3c1ef6..f3abbaa6e7e 100644
--- a/strings/ctype-ucs2.c
+++ b/strings/ctype-ucs2.c
@@ -1484,7 +1484,10 @@ void my_hash_sort_ucs2_bin(CHARSET_INFO *cs __attribute__((unused)),
const uchar *pos = key;
key+= len;
-
+
+ while (key > pos+1 && key[-1] == ' ' && key[-2] == '\0')
+ key-= 2;
+
for (; pos < (uchar*) key ; pos++)
{
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
diff --git a/strings/ctype.c b/strings/ctype.c
index f02b5542e78..e7399c5438b 100644
--- a/strings/ctype.c
+++ b/strings/ctype.c
@@ -123,7 +123,7 @@ static struct my_cs_file_section_st * cs_file_sec(const char *attr, uint len)
}
#define MY_CS_CSDESCR_SIZE 64
-#define MY_CS_TAILORING_SIZE 128
+#define MY_CS_TAILORING_SIZE 1024
typedef struct my_cs_file_info
{
diff --git a/strings/strtod.c b/strings/strtod.c
index 15707a9b944..5fe59d10bd2 100644
--- a/strings/strtod.c
+++ b/strings/strtod.c
@@ -31,13 +31,40 @@
#define MAX_DBL_EXP 308
#define MAX_RESULT_FOR_MAX_EXP 1.7976931348623157
-static double scaler10[] = {
- 1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90
-};
-static double scaler1[] = {
- 1.0, 10.0, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9
-};
+const double log_10[] = {
+ 1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009,
+ 1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019,
+ 1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029,
+ 1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039,
+ 1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049,
+ 1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059,
+ 1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069,
+ 1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079,
+ 1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089,
+ 1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099,
+ 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
+ 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
+ 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
+ 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
+ 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
+ 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
+ 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
+ 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
+ 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
+ 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
+ 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
+ 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
+ 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
+ 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
+ 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
+ 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
+ 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
+ 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
+ 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
+ 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
+ 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308
+};
/*
Convert string to double (string doesn't have to be null terminated)
@@ -57,7 +84,7 @@ double my_strtod(const char *str, char **end_ptr, int *error)
{
double result= 0.0;
uint negative= 0, ndigits, dec_digits= 0, neg_exp= 0;
- int exponent= 0, digits_after_dec_point= 0, tmp_exp;
+ int exponent= 0, digits_after_dec_point= 0, tmp_exp, step;
const char *old_str, *end= *end_ptr, *start_of_number;
char next_char;
my_bool overflow=0;
@@ -179,22 +206,16 @@ double my_strtod(const char *str, char **end_ptr, int *error)
exponent= -exponent;
neg_exp= 1; /* neg_exp was 0 before */
}
- while (exponent >= 100)
- {
- result= neg_exp ? result/1.0e100 : result*1.0e100;
- exponent-= 100;
- }
- scaler= scaler10[exponent/10]*scaler1[exponent%10];
- if (neg_exp)
- result/= scaler;
- else
- result*= scaler;
+ step= array_elements(log_10) - 1;
+ for (; exponent > step; exponent-= step)
+ result= neg_exp ? result / log_10[step] : result * log_10[step];
+ result= neg_exp ? result / log_10[exponent] : result * log_10[exponent];
}
done:
*end_ptr= (char*) str; /* end of number */
- if (overflow || isinf(result))
+ if (overflow || my_isinf(result))
{
result= DBL_MAX;
*error= EOVERFLOW;
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 38346ad0dbc..9bf062f7df8 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -15561,6 +15561,179 @@ static void test_bug24179()
/*
+ Bug#27876 (SF with cyrillic variable name fails during execution (regression))
+*/
+static void test_bug27876()
+{
+ int rc;
+ MYSQL_RES *result;
+
+ char utf8_func[] =
+ {
+ 0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba,
+ 0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba,
+ 0xd0, 0xb0,
+ 0x00
+ };
+
+ char utf8_param[] =
+ {
+ 0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0,
+ 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a,
+ 0xd1, 0x80, 0x5f, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1,
+ 0x80, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f,
+ 0x00
+ };
+
+ char query[500];
+
+ DBUG_ENTER("test_bug27876");
+ myheader("test_bug27876");
+
+ rc= mysql_query(mysql, "set names utf8");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "select version()");
+ myquery(rc);
+ result= mysql_store_result(mysql);
+ mytest(result);
+
+ sprintf(query, "DROP FUNCTION IF EXISTS %s", utf8_func);
+ rc= mysql_query(mysql, query);
+ myquery(rc);
+
+ sprintf(query,
+ "CREATE FUNCTION %s( %s VARCHAR(25))"
+ " RETURNS VARCHAR(25) DETERMINISTIC RETURN %s",
+ utf8_func, utf8_param, utf8_param);
+ rc= mysql_query(mysql, query);
+ myquery(rc);
+ sprintf(query, "SELECT %s(VERSION())", utf8_func);
+ rc= mysql_query(mysql, query);
+ myquery(rc);
+ result= mysql_store_result(mysql);
+ mytest(result);
+
+ sprintf(query, "DROP FUNCTION %s", utf8_func);
+ rc= mysql_query(mysql, query);
+ myquery(rc);
+
+ rc= mysql_query(mysql, "set names default");
+ myquery(rc);
+}
+
+
+/*
+ Bug#28505: mysql_affected_rows() returns wrong value if CLIENT_FOUND_ROWS
+ flag is set.
+*/
+
+static void test_bug28505()
+{
+ my_ulonglong res;
+
+ myquery(mysql_query(mysql, "drop table if exists t1"));
+ myquery(mysql_query(mysql, "create table t1(f1 int primary key)"));
+ myquery(mysql_query(mysql, "insert into t1 values(1)"));
+ myquery(mysql_query(mysql,
+ "insert into t1 values(1) on duplicate key update f1=1"));
+ res= mysql_affected_rows(mysql);
+ DIE_UNLESS(!res);
+ myquery(mysql_query(mysql, "drop table t1"));
+}
+
+
+/*
+ Bug#28934: server crash when receiving malformed com_execute packets
+*/
+
+static void test_bug28934()
+{
+ my_bool error= 0;
+ MYSQL_BIND bind[5];
+ MYSQL_STMT *stmt;
+ int cnt;
+
+ myquery(mysql_query(mysql, "drop table if exists t1"));
+ myquery(mysql_query(mysql, "create table t1(id int)"));
+
+ myquery(mysql_query(mysql, "insert into t1 values(1),(2),(3),(4),(5)"));
+ stmt= mysql_simple_prepare(mysql,"select * from t1 where id in(?,?,?,?,?)");
+ check_stmt(stmt);
+
+ memset (&bind, 0, sizeof (bind));
+ for (cnt= 0; cnt < 5; cnt++)
+ {
+ bind[cnt].buffer_type= MYSQL_TYPE_LONG;
+ bind[cnt].buffer= (char*)&cnt;
+ bind[cnt].buffer_length= 0;
+ }
+ myquery(mysql_stmt_bind_param(stmt, bind));
+
+ stmt->param_count=2;
+ error= mysql_stmt_execute(stmt);
+ DIE_UNLESS(error != 0);
+ myerror(NULL);
+ mysql_stmt_close(stmt);
+
+ myquery(mysql_query(mysql, "drop table t1"));
+}
+
+
+/*
+ Bug#27592 (stack overrun when storing datetime value using prepared statements)
+*/
+
+static void test_bug27592()
+{
+ const int NUM_ITERATIONS= 40;
+ int i;
+ int rc;
+ MYSQL_STMT *stmt= NULL;
+ MYSQL_BIND bind[1];
+ MYSQL_TIME time_val;
+
+ DBUG_ENTER("test_bug27592");
+ myheader("test_bug27592");
+
+ mysql_query(mysql, "DROP TABLE IF EXISTS t1");
+ mysql_query(mysql, "CREATE TABLE t1(c2 DATETIME)");
+
+ stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?)");
+ DIE_UNLESS(stmt);
+
+ memset(bind, 0, sizeof(bind));
+
+ bind[0].buffer_type= MYSQL_TYPE_DATETIME;
+ bind[0].buffer= (char *) &time_val;
+ bind[0].length= NULL;
+
+ for (i= 0; i < NUM_ITERATIONS; i++)
+ {
+ time_val.year= 2007;
+ time_val.month= 6;
+ time_val.day= 7;
+ time_val.hour= 18;
+ time_val.minute= 41;
+ time_val.second= 3;
+
+ time_val.second_part=0;
+ time_val.neg=0;
+
+ rc= mysql_stmt_bind_param(stmt, bind);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+ }
+
+ mysql_stmt_close(stmt);
+
+ DBUG_VOID_RETURN;
+}
+
+
+/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -15840,6 +16013,10 @@ static struct my_tests_st my_tests[]= {
{ "test_bug23383", test_bug23383 },
{ "test_bug21635", test_bug21635 },
{ "test_bug24179", test_bug24179 },
+ { "test_bug27876", test_bug27876 },
+ { "test_bug28505", test_bug28505 },
+ { "test_bug28934", test_bug28934 },
+ { "test_bug27592", test_bug27592 },
{ 0, 0 }
};
diff --git a/vio/vio_priv.h b/vio/vio_priv.h
index 4a272e519a3..9036952d575 100644
--- a/vio/vio_priv.h
+++ b/vio/vio_priv.h
@@ -23,6 +23,7 @@
#include <violite.h>
void vio_ignore_timeout(Vio *vio, uint which, uint timeout);
+void vio_timeout(Vio *vio,uint which, uint timeout);
#ifdef HAVE_OPENSSL
#include "my_net.h" /* needed because of struct in_addr */
diff --git a/vio/viosocket.c b/vio/viosocket.c
index 01abde6e0f7..84fdd6f57e4 100644
--- a/vio/viosocket.c
+++ b/vio/viosocket.c
@@ -204,13 +204,14 @@ int vio_fastsend(Vio * vio __attribute__((unused)))
{
#ifdef __WIN__
BOOL nodelay= 1;
- r= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (const char*) &nodelay,
- sizeof(nodelay));
#else
int nodelay = 1;
- r= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void*) &nodelay,
+#endif
+
+ r= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY,
+ IF_WIN(const char*, void*) &nodelay,
sizeof(nodelay));
-#endif /* __WIN__ */
+
}
if (r)
{
@@ -380,28 +381,39 @@ my_bool vio_poll_read(Vio *vio,uint timeout)
void vio_timeout(Vio *vio, uint which, uint timeout)
{
-/* TODO: some action should be taken if socket timeouts are not supported. */
#if defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO)
+ int r;
+ DBUG_ENTER("vio_timeout");
+ {
#ifdef __WIN__
-
- /* Windows expects time in milliseconds as int. */
+ /* Windows expects time in milliseconds as int */
int wait_timeout= (int) timeout * 1000;
-
-#else /* ! __WIN__ */
-
+#else
/* POSIX specifies time as struct timeval. */
struct timeval wait_timeout;
wait_timeout.tv_sec= timeout;
wait_timeout.tv_usec= 0;
+#endif
+
+ r= setsockopt(vio->sd, SOL_SOCKET, which ? SO_SNDTIMEO : SO_RCVTIMEO,
+ IF_WIN(const char*, const void*)&wait_timeout,
+ sizeof(wait_timeout));
-#endif /* ! __WIN__ */
+ }
- /* TODO: return value should be checked. */
- (void) setsockopt(vio->sd, SOL_SOCKET, which ? SO_SNDTIMEO : SO_RCVTIMEO,
- (char*) &wait_timeout, sizeof(wait_timeout));
+#ifndef DBUG_OFF
+ if (r != 0)
+ DBUG_PRINT("error", ("setsockopt failed: %d, errno: %d", r, socket_errno));
+#endif
-#endif /* defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO) */
+ DBUG_VOID_RETURN;
+#else
+/*
+ Platforms not suporting setting of socket timeout should either use
+ thr_alarm or just run without read/write timeout(s)
+*/
+#endif
}
diff --git a/win/create_manifest.js b/win/create_manifest.js
index 5605f57ef74..520ecec21b8 100755
--- a/win/create_manifest.js
+++ b/win/create_manifest.js
@@ -27,7 +27,12 @@ try
var app_name= parts[1];
break;
case "version":
- var app_version= parts[1];
+ var supp_version= parts[1];
+ // Clean up the supplied version string.
+ var end= supp_version.indexOf("-");
+ if (end == -1) end= supp_version.length;
+ var app_version= supp_version.substring(0, end);
+ app_version+= ".0";
break;
case "arch":
var app_arch= parts[1];