summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore7
-rw-r--r--Docs/INSTALL-BINARY2
-rw-r--r--Docs/Makefile.am2
-rw-r--r--INSTALL-SOURCE2
-rw-r--r--INSTALL-WIN-SOURCE2
-rw-r--r--Makefile.am13
-rw-r--r--client/mysql.cc21
-rw-r--r--client/mysqltest.c3
-rw-r--r--configure.in7
-rw-r--r--include/m_string.h1
-rw-r--r--include/my_getopt.h4
-rw-r--r--include/my_global.h55
-rw-r--r--include/myisammrg.h1
-rw-r--r--include/mysql_com.h34
-rw-r--r--include/mysql_embed.h1
-rw-r--r--include/mysql_h.ic10
-rw-r--r--include/queues.h6
-rwxr-xr-xlibmysql/CMakeLists.txt3
-rw-r--r--libmysql/Makefile.am2
-rw-r--r--libmysql/libmysql.c40
-rw-r--r--libmysql/manager.c2
-rw-r--r--libmysql/mytest.c175
-rw-r--r--libmysql_r/Makefile.am1
-rw-r--r--libmysqld/CMakeLists.txt2
-rw-r--r--libmysqld/emb_qcache.cc105
-rw-r--r--libmysqld/emb_qcache.h5
-rw-r--r--libmysqld/lib_sql.cc100
-rw-r--r--libmysqld/libmysqld.c5
-rw-r--r--mysql-test/Makefile.am4
-rw-r--r--mysql-test/extra/binlog_tests/ctype_cp932.test4
-rw-r--r--mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test9
-rw-r--r--mysql-test/include/ctype_common.inc2
-rw-r--r--mysql-test/include/have_multi_ndb.inc32
-rw-r--r--mysql-test/include/mix1.inc13
-rw-r--r--mysql-test/include/ps_query.inc4
-rw-r--r--mysql-test/lib/mtr_report.pl19
-rwxr-xr-xmysql-test/mysql-test-run.pl26
-rw-r--r--mysql-test/r/archive.result9
-rw-r--r--mysql-test/r/change_user.result4
-rw-r--r--mysql-test/r/create.result38
-rw-r--r--mysql-test/r/csv.result10
-rw-r--r--mysql-test/r/ctype_big5.result4
-rw-r--r--mysql-test/r/ctype_euckr.result4
-rw-r--r--mysql-test/r/ctype_gb2312.result4
-rw-r--r--mysql-test/r/ctype_gbk.result4
-rw-r--r--mysql-test/r/ctype_uca.result4
-rw-r--r--mysql-test/r/delayed.result6
-rw-r--r--mysql-test/r/drop.result7
-rw-r--r--mysql-test/r/events.result3
-rw-r--r--mysql-test/r/events_scheduling.result4
-rw-r--r--mysql-test/r/explain.result20
-rw-r--r--mysql-test/r/federated.result111
-rw-r--r--mysql-test/r/func_misc.result14
-rw-r--r--mysql-test/r/func_time.result12
-rw-r--r--mysql-test/r/gis.result40
-rw-r--r--mysql-test/r/grant.result4
-rw-r--r--mysql-test/r/group_min_max.result46
-rw-r--r--mysql-test/r/index_merge_myisam.result2
-rw-r--r--mysql-test/r/information_schema.result8
-rw-r--r--mysql-test/r/innodb.result4
-rw-r--r--mysql-test/r/innodb_mysql.result16
-rw-r--r--mysql-test/r/key_cache.result2
-rw-r--r--mysql-test/r/lock_multi.result30
-rw-r--r--mysql-test/r/merge.result37
-rw-r--r--mysql-test/r/merge_innodb.result37
-rw-r--r--mysql-test/r/myisam.result22
-rw-r--r--mysql-test/r/no-threads.result4
-rw-r--r--mysql-test/r/outfile_loaddata.result18
-rw-r--r--mysql-test/r/packet.result8
-rw-r--r--mysql-test/r/partition.result110
-rw-r--r--mysql-test/r/partition_archive.result78
-rw-r--r--mysql-test/r/partition_hash.result12
-rw-r--r--mysql-test/r/partition_innodb.result12
-rw-r--r--mysql-test/r/partition_range.result2
-rw-r--r--mysql-test/r/ps.result2
-rw-r--r--mysql-test/r/ps_2myisam.result12
-rw-r--r--mysql-test/r/ps_3innodb.result12
-rw-r--r--mysql-test/r/ps_4heap.result12
-rw-r--r--mysql-test/r/ps_5merge.result24
-rw-r--r--mysql-test/r/ps_ddl.result2329
-rw-r--r--mysql-test/r/range.result18
-rw-r--r--mysql-test/r/read_only.result28
-rw-r--r--mysql-test/r/select.result6
-rw-r--r--mysql-test/r/status.result21
-rw-r--r--mysql-test/r/subselect.result133
-rw-r--r--mysql-test/r/subselect3.result2
-rw-r--r--mysql-test/r/subselect_notembedded.result101
-rw-r--r--mysql-test/r/trigger_notembedded.result14
-rw-r--r--mysql-test/r/type_bit.result12
-rw-r--r--mysql-test/r/type_bit_innodb.result2
-rw-r--r--mysql-test/r/type_blob.result14
-rw-r--r--mysql-test/r/type_date.result39
-rw-r--r--mysql-test/r/type_datetime.result55
-rw-r--r--mysql-test/r/udf.result27
-rw-r--r--mysql-test/r/user_var.result7
-rw-r--r--mysql-test/r/variables.result36
-rw-r--r--mysql-test/r/windows.result1
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_ctype_cp932.result74
-rwxr-xr-xmysql-test/suite/binlog/r/binlog_stm_ctype_cp932.result74
-rw-r--r--mysql-test/suite/funcs_1/r/innodb_views.result15
-rw-r--r--mysql-test/suite/funcs_1/r/memory_views.result15
-rw-r--r--mysql-test/suite/funcs_1/r/myisam_views.result15
-rw-r--r--mysql-test/suite/funcs_1/r/ndb_views.result15
-rw-r--r--mysql-test/suite/funcs_1/views/views_master.inc9
-rw-r--r--mysql-test/suite/ndb/r/ndb_auto_increment.result445
-rw-r--r--mysql-test/suite/ndb/r/ndb_basic.result24
-rw-r--r--mysql-test/suite/ndb/r/ndb_blob.result21
-rw-r--r--mysql-test/suite/ndb/r/ndb_charset.result8
-rw-r--r--mysql-test/suite/ndb/r/ndb_index_unique.result14
-rw-r--r--mysql-test/suite/ndb/r/ndb_insert.result169
-rw-r--r--mysql-test/suite/ndb/r/ndb_multi.result1
-rw-r--r--mysql-test/suite/ndb/r/ndb_multi_row.result1
-rw-r--r--mysql-test/suite/ndb/r/ndb_update.result6
-rw-r--r--mysql-test/suite/ndb/r/ps_7ndb.result12
-rw-r--r--mysql-test/suite/ndb/t/disabled.def3
-rw-r--r--mysql-test/suite/ndb/t/ndb_auto_increment.test293
-rw-r--r--mysql-test/suite/ndb/t/ndb_basic.test22
-rw-r--r--mysql-test/suite/ndb/t/ndb_blob.test20
-rw-r--r--mysql-test/suite/ndb/t/ndb_insert.test138
-rw-r--r--mysql-test/suite/ndb/t/ndb_multi.test4
-rw-r--r--mysql-test/suite/ndb/t/ndb_multi_row.test3
-rw-r--r--mysql-test/suite/ndb_team/r/ndb_backup_print.result (renamed from mysql-test/suite/ndb/r/ndb_backup_print.result)0
-rw-r--r--mysql-test/suite/ndb_team/r/ndb_dd_backuprestore.result (renamed from mysql-test/suite/ndb/r/ndb_dd_backuprestore.result)0
-rw-r--r--mysql-test/suite/ndb_team/t/ndb_backup_print.test (renamed from mysql-test/suite/ndb/t/ndb_backup_print.test)0
-rw-r--r--mysql-test/suite/ndb_team/t/ndb_dd_backuprestore.test (renamed from mysql-test/suite/ndb/t/ndb_dd_backuprestore.test)0
-rw-r--r--mysql-test/suite/parts/r/rpl_partition.result2
-rw-r--r--mysql-test/suite/parts/t/partition_basic_myisam.test3
-rw-r--r--mysql-test/suite/rpl/include/rpl_mixed_dml.inc2
-rw-r--r--mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result15
-rw-r--r--mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result15
-rw-r--r--mysql-test/suite/rpl/r/rpl_innodb_bug28430.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result4
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result4
-rw-r--r--mysql-test/suite/rpl_ndb/r/rpl_ndb_ddl.result40
-rw-r--r--mysql-test/suite/rpl_ndb/r/rpl_ndb_extraColMaster.result10
-rw-r--r--mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result4
-rw-r--r--mysql-test/suite/rpl_ndb/t/disabled.def1
-rw-r--r--mysql-test/t/archive.test9
-rw-r--r--mysql-test/t/create.test13
-rw-r--r--mysql-test/t/csv.test11
-rw-r--r--mysql-test/t/delayed.test11
-rw-r--r--mysql-test/t/disabled.def3
-rw-r--r--mysql-test/t/drop.test13
-rw-r--r--mysql-test/t/events_scheduling.test2
-rw-r--r--mysql-test/t/explain.test28
-rw-r--r--mysql-test/t/federated.test31
-rw-r--r--mysql-test/t/func_misc.test27
-rw-r--r--mysql-test/t/func_time.test10
-rw-r--r--mysql-test/t/gis.test51
-rw-r--r--mysql-test/t/grant.test1
-rw-r--r--mysql-test/t/group_min_max.test24
-rw-r--r--mysql-test/t/information_schema.test9
-rw-r--r--mysql-test/t/innodb_mysql.test3
-rw-r--r--mysql-test/t/lock_multi.test98
-rw-r--r--mysql-test/t/merge.test24
-rw-r--r--mysql-test/t/merge_innodb.test41
-rw-r--r--mysql-test/t/myisam.test17
-rw-r--r--mysql-test/t/no-threads.test10
-rw-r--r--mysql-test/t/order_fill_sortbuf-master.opt2
-rw-r--r--mysql-test/t/outfile_loaddata.test24
-rw-r--r--mysql-test/t/partition.test103
-rw-r--r--mysql-test/t/partition_archive.test75
-rw-r--r--mysql-test/t/partition_hash.test16
-rw-r--r--mysql-test/t/partition_innodb.test15
-rw-r--r--mysql-test/t/partition_range.test28
-rw-r--r--mysql-test/t/ps_ddl.test1851
-rw-r--r--mysql-test/t/range.test20
-rw-r--r--mysql-test/t/read_only.test35
-rw-r--r--mysql-test/t/select.test11
-rw-r--r--mysql-test/t/status.test19
-rw-r--r--mysql-test/t/subselect.test107
-rw-r--r--mysql-test/t/subselect_notembedded.test96
-rw-r--r--mysql-test/t/trigger_notembedded.test6
-rw-r--r--mysql-test/t/type_bit.test15
-rw-r--r--mysql-test/t/type_blob.test11
-rw-r--r--mysql-test/t/type_date.test20
-rw-r--r--mysql-test/t/type_datetime.test37
-rw-r--r--mysql-test/t/udf.test21
-rw-r--r--mysql-test/t/user_var.test6
-rw-r--r--mysql-test/t/variables.test6
-rw-r--r--mysql-test/t/windows.test3
-rw-r--r--mysys/my_getopt.c159
-rw-r--r--mysys/queues.c36
-rwxr-xr-xscripts/make_win_bin_dist1
-rw-r--r--scripts/mysql_install_db.sh62
-rw-r--r--scripts/mysql_system_tables_data.sql12
-rw-r--r--server-tools/instance-manager/mysql_connection.cc2
-rw-r--r--sql-common/client.c74
-rw-r--r--sql-common/my_time.c9
-rw-r--r--sql/Makefile.am1
-rw-r--r--sql/event_data_objects.cc2
-rw-r--r--sql/events.cc4
-rw-r--r--sql/field.cc3
-rw-r--r--sql/field.h1
-rw-r--r--sql/ha_ndbcluster.cc127
-rw-r--r--sql/ha_ndbcluster.h3
-rw-r--r--sql/ha_ndbcluster_binlog.cc122
-rw-r--r--sql/ha_partition.cc36
-rw-r--r--sql/handler.h432
-rw-r--r--sql/item.cc28
-rw-r--r--sql/item.h25
-rw-r--r--sql/item_cmpfunc.cc124
-rw-r--r--sql/item_func.cc17
-rw-r--r--sql/item_func.h50
-rw-r--r--sql/item_geofunc.cc2
-rw-r--r--sql/item_subselect.cc4
-rw-r--r--sql/key.cc13
-rw-r--r--sql/lock.cc20
-rw-r--r--sql/log.cc69
-rw-r--r--sql/log_event.cc52
-rw-r--r--sql/log_event_old.cc16
-rw-r--r--sql/mysql_priv.h41
-rw-r--r--sql/mysqld.cc443
-rw-r--r--sql/net_serv.cc58
-rw-r--r--sql/opt_range.cc40
-rw-r--r--sql/opt_sum.cc2
-rw-r--r--sql/partition_info.cc7
-rw-r--r--sql/protocol.cc244
-rw-r--r--sql/protocol.h5
-rw-r--r--sql/repl_failsafe.cc4
-rw-r--r--sql/rpl_record.cc5
-rw-r--r--sql/rpl_rli.cc4
-rw-r--r--sql/set_var.cc131
-rw-r--r--sql/set_var.h19
-rw-r--r--sql/slave.cc81
-rw-r--r--sql/sp_head.cc16
-rw-r--r--sql/sp_rcontext.cc22
-rw-r--r--sql/sql_acl.cc9
-rw-r--r--sql/sql_base.cc104
-rw-r--r--sql/sql_binlog.cc16
-rw-r--r--sql/sql_cache.cc1
-rw-r--r--sql/sql_class.cc172
-rw-r--r--sql/sql_class.h167
-rw-r--r--sql/sql_connect.cc33
-rw-r--r--sql/sql_db.cc6
-rw-r--r--sql/sql_delete.cc8
-rw-r--r--sql/sql_derived.cc5
-rw-r--r--sql/sql_insert.cc38
-rw-r--r--sql/sql_parse.cc308
-rw-r--r--sql/sql_partition.cc29
-rw-r--r--sql/sql_partition.h1
-rw-r--r--sql/sql_plugin.cc66
-rw-r--r--sql/sql_prepare.cc27
-rw-r--r--sql/sql_select.cc41
-rw-r--r--sql/sql_select.h11
-rw-r--r--sql/sql_servers.cc2
-rw-r--r--sql/sql_show.cc55
-rw-r--r--sql/sql_string.cc5
-rw-r--r--sql/sql_table.cc166
-rw-r--r--sql/sql_update.cc11
-rw-r--r--sql/sql_yacc.yy47
-rw-r--r--sql/table.cc39
-rw-r--r--sql/table.h1
-rw-r--r--sql/tztime.cc2
-rw-r--r--sql/udf_example.c10
-rw-r--r--storage/archive/azio.c2
-rw-r--r--storage/archive/ha_archive.cc37
-rw-r--r--storage/csv/ha_tina.cc13
-rw-r--r--storage/federated/ha_federated.cc18
-rw-r--r--storage/federated/ha_federated.h1
-rw-r--r--storage/myisam/ha_myisam.cc8
-rw-r--r--storage/myisam/mi_check.c2
-rw-r--r--storage/myisam/mi_open.c2
-rw-r--r--storage/myisammrg/ha_myisammrg.cc37
-rw-r--r--storage/myisammrg/myrg_close.c1
-rw-r--r--storage/myisammrg/myrg_open.c17
-rw-r--r--storage/ndb/include/kernel/signaldata/TcKeyRef.hpp3
-rw-r--r--storage/ndb/include/kernel/signaldata/TcRollbackRep.hpp3
-rw-r--r--storage/ndb/include/ndbapi/NdbDictionary.hpp2
-rw-r--r--storage/ndb/src/common/transporter/Transporter.cpp4
-rw-r--r--storage/ndb/src/common/transporter/TransporterRegistry.cpp3
-rw-r--r--storage/ndb/src/kernel/blocks/ERROR_codes.txt7
-rw-r--r--storage/ndb/src/kernel/blocks/backup/Backup.cpp5
-rw-r--r--storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp57
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp5
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp10
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp117
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp19
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp4
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp219
-rw-r--r--storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp2
-rw-r--r--storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp42
-rw-r--r--storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp3
-rw-r--r--storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp26
-rw-r--r--storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp362
-rw-r--r--storage/ndb/src/kernel/blocks/suma/Suma.cpp54
-rw-r--r--storage/ndb/src/kernel/vm/SimulatedBlock.cpp2
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvr.cpp81
-rw-r--r--storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp12
-rw-r--r--storage/ndb/src/ndbapi/NdbOperationExec.cpp7
-rw-r--r--storage/ndb/src/ndbapi/NdbTransaction.cpp12
-rw-r--r--storage/ndb/src/ndbapi/TransporterFacade.cpp2
-rw-r--r--storage/ndb/src/ndbapi/ndberror.c4
-rw-r--r--storage/ndb/test/ndbapi/testDict.cpp10
-rw-r--r--storage/ndb/test/ndbapi/testNodeRestart.cpp50
-rw-r--r--storage/ndb/test/ndbapi/testSystemRestart.cpp41
-rw-r--r--storage/ndb/test/run-test/daily-basic-tests.txt7
-rw-r--r--storage/ndb/test/tools/Makefile.am3
-rw-r--r--storage/ndb/test/tools/connect.cpp152
-rw-r--r--storage/ndb/tools/restore/Restore.cpp156
-rw-r--r--storage/ndb/tools/restore/Restore.hpp4
-rw-r--r--strings/ctype-cp932.c4
-rw-r--r--strings/llstr.c6
-rw-r--r--support-files/MacOSX/ReadMe.txt2
-rw-r--r--tests/bug25714.c6
-rw-r--r--tests/mysql_client_test.c44
306 files changed, 11693 insertions, 2852 deletions
diff --git a/.bzrignore b/.bzrignore
index 7a8066fdba1..6e09cdd7b5d 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -902,6 +902,7 @@ libmysql_r/.libs/libmysqlclient_r.so.15.0.0
libmysql_r/acconfig.h
libmysql_r/client_settings.h
libmysql_r/conf_to_src
+libmysql_r/link_sources
libmysql_r/my_static.h
libmysql_r/mysys_priv.h
libmysql_r/vio_priv.h
@@ -1137,6 +1138,7 @@ libmysqld/rpl_filter.cc
libmysqld/rpl_injector.cc
libmysqld/rpl_record.cc
libmysqld/rpl_record_old.cc
+libmysqld/scheduler.cc
libmysqld/set_var.cc
libmysqld/simple-test
libmysqld/slave.cc
@@ -1153,6 +1155,7 @@ libmysqld/sql_builtin.cc
libmysqld/sql_cache.cc
libmysqld/sql_class.cc
libmysqld/sql_command
+libmysqld/sql_connect.cc
libmysqld/sql_crypt.cc
libmysqld/sql_cursor.cc
libmysqld/sql_cursor.h
@@ -1183,6 +1186,7 @@ libmysqld/sql_show.cc
libmysqld/sql_state.c
libmysqld/sql_string.cc
libmysqld/sql_table.cc
+libmysqld/sql_tablespace.cc
libmysqld/sql_test.cc
libmysqld/sql_trigger.cc
libmysqld/sql_udf.cc
@@ -1841,6 +1845,7 @@ scripts/make_binary_distribution
scripts/make_sharedlib_distribution
scripts/make_win_binary_distribution
scripts/make_win_src_distribution
+scripts/make_win_src_distribution_old
scripts/msql2mysql
scripts/mysql_config
scripts/mysql_convert_table_format
@@ -2082,6 +2087,7 @@ sql/gen_lex_hash
sql/gmon.out
sql/handlerton.cc
sql/lex_hash.h
+sql/link_sources
sql/max/*
sql/message.h
sql/message.mc
@@ -3003,5 +3009,6 @@ vio/viotest.cpp
win/configure.data
win/vs71cache.txt
win/vs8cache.txt
+ylwrap
zlib/*.ds?
zlib/*.vcproj
diff --git a/Docs/INSTALL-BINARY b/Docs/INSTALL-BINARY
index ba7e72af94d..d1c409acd67 100644
--- a/Docs/INSTALL-BINARY
+++ b/Docs/INSTALL-BINARY
@@ -1,7 +1,7 @@
You can find information about how to install binary distributions at
- http://dev.mysql.com/doc/refman/5.0/en/quick-standard-installation.html
+ http://dev.mysql.com/doc/refman/5.1/en/quick-standard-installation.html
The MySQL Reference Manual is also available in various formats on
http://dev.mysql.com/doc; if you're interested in the DocBook XML
diff --git a/Docs/Makefile.am b/Docs/Makefile.am
index dac256f8fd6..629618609a3 100644
--- a/Docs/Makefile.am
+++ b/Docs/Makefile.am
@@ -13,7 +13,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-EXTRA_DIST = mysql.info INSTALL-BINARY
+EXTRA_DIST = mysql.info INSTALL-BINARY @extra_docs@
# make sure that "make install" installs the info page, too
# automake only seems to take care of this automatically,
diff --git a/INSTALL-SOURCE b/INSTALL-SOURCE
index 3d9d7d41114..3a5dd22fa38 100644
--- a/INSTALL-SOURCE
+++ b/INSTALL-SOURCE
@@ -1,7 +1,7 @@
You can find information about how to install from a source distributions at
- http://dev.mysql.com/doc/refman/5.0/en/installing-source.html
+ http://dev.mysql.com/doc/refman/5.1/en/installing-source.html
The MySQL Reference Manual is also available in various formats on
http://dev.mysql.com/doc; if you're interested in the DocBook XML
diff --git a/INSTALL-WIN-SOURCE b/INSTALL-WIN-SOURCE
index 2478e2cf609..9484513c431 100644
--- a/INSTALL-WIN-SOURCE
+++ b/INSTALL-WIN-SOURCE
@@ -2,7 +2,7 @@
You can find information about how to install from a Windows source
distributions at
- http://dev.mysql.com/doc/refman/5.0/en/windows-source-build.html
+ http://dev.mysql.com/doc/refman/5.1/en/windows-source-build.html
The MySQL Reference Manual is also available in various formats on
http://dev.mysql.com/doc; if you're interested in the DocBook XML
diff --git a/Makefile.am b/Makefile.am
index 0125f37d44c..b3f069f0e78 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -53,8 +53,8 @@ bin-dist: all
dist-hook:
rm -rf `find $(distdir) -type d -name SCCS -print`
mkdir -p $(distdir)/win
- scripts/mysql_install_db --no-defaults --windows \
- --basedir=$(top_builddir) \
+ scripts/mysql_install_db --no-defaults --cross-bootstrap \
+ --builddir=$(top_builddir) \
--datadir=$(distdir)/win/data \
--srcdir=$(top_srcdir)
@@ -101,6 +101,7 @@ test-binlog-statement:
cd mysql-test ; \
@PERL@ ./mysql-test-run.pl $(force) --mysqld=--binlog-format=statement
+# This code is duplicated in "test-bt", see the Changeset comment of 2007-Dec-07
test-embedded:
if [ -e bin/mysqltest_embedded -o -e libmysqld/examples/mysqltest_embedded ] ; then \
cd mysql-test ; MTR_BUILD_THREAD=auto \
@@ -140,7 +141,13 @@ test-bt:
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --comment=NDB --force --timer \
--with-ndbcluster-only
- -$(MAKE) test-embedded
+ -if [ -e bin/mysqltest_embedded -o -e libmysqld/examples/mysqltest_embedded ] ; then \
+ cd mysql-test ; MTR_BUILD_THREAD=auto \
+ @PERL@ ./mysql-test-run.pl --comment=embedded --force --timer \
+ --embedded-server --skip-rpl --skip-ndbcluster ; \
+ else \
+ echo "no program found for 'embedded' tests - skipped testing" ; \
+ fi
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --force --comment=funcs1_ps --ps-protocol --suite=funcs_1
-cd mysql-test ; MTR_BUILD_THREAD=auto \
diff --git a/client/mysql.cc b/client/mysql.cc
index b102c80655a..d30b60732bc 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -605,6 +605,10 @@ static struct my_option my_long_options[] =
{"column-type-info", OPT_COLUMN_TYPES, "Display column type information.",
(uchar**) &column_types_flag, (uchar**) &column_types_flag,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"comments", 'c', "Preserve comments. Send comments to the server."
+ " The default is --skip-comments (discard comments), enable with --comments",
+ (uchar**) &preserve_comments, (uchar**) &preserve_comments,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"compress", 'C', "Use compression in server/client protocol.",
(uchar**) &opt_compress, (uchar**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
@@ -755,9 +759,9 @@ static struct my_option my_long_options[] =
0, 0},
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
"Max packet length to send to, or receive from server",
- (uchar**) &opt_max_allowed_packet, (uchar**) &opt_max_allowed_packet, 0, GET_ULONG,
- REQUIRED_ARG, 16 *1024L*1024L, 4096, (longlong) 2*1024L*1024L*1024L,
- MALLOC_OVERHEAD, 1024, 0},
+ (uchar**) &opt_max_allowed_packet, (uchar**) &opt_max_allowed_packet, 0,
+ GET_ULONG, REQUIRED_ARG, 16 *1024L*1024L, 4096,
+ (longlong) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
{"net_buffer_length", OPT_NET_BUFFER_LENGTH,
"Buffer for TCP/IP and socket communication",
(uchar**) &opt_net_buffer_length, (uchar**) &opt_net_buffer_length, 0, GET_ULONG,
@@ -765,12 +769,13 @@ static struct my_option my_long_options[] =
{"select_limit", OPT_SELECT_LIMIT,
"Automatic limit for SELECT when using --safe-updates",
(uchar**) &select_limit,
- (uchar**) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ~0L, 0, 1, 0},
+ (uchar**) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ULONG_MAX,
+ 0, 1, 0},
{"max_join_size", OPT_MAX_JOIN_SIZE,
"Automatic limit for rows in a join when using --safe-updates",
(uchar**) &max_join_size,
- (uchar**) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ~0L, 0, 1,
- 0},
+ (uchar**) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ULONG_MAX,
+ 0, 1, 0},
{"secure-auth", OPT_SECURE_AUTH, "Refuse client connecting to server if it"
" uses old (pre-4.1.1) protocol", (uchar**) &opt_secure_auth,
(uchar**) &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -779,10 +784,6 @@ static struct my_option my_long_options[] =
{"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.",
(uchar**) &show_warnings, (uchar**) &show_warnings, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
- {"comments", 'c', "Preserve comments. Send comments to the server."
- " Comments are discarded by default, enable with --enable-comments",
- (uchar**) &preserve_comments, (uchar**) &preserve_comments,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
diff --git a/client/mysqltest.c b/client/mysqltest.c
index cca2420d498..e0662fc2251 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -5050,7 +5050,7 @@ static struct my_option my_long_options[] =
"Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG,
0, 0, 0, 0, 0, 0},
{"sleep", 'T', "Sleep always this many seconds on sleep commands.",
- (uchar**) &opt_sleep, (uchar**) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, 0, 0,
+ (uchar**) &opt_sleep, (uchar**) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, -1, 0,
0, 0, 0},
{"socket", 'S', "Socket file to use for connection.",
(uchar**) &unix_sock, (uchar**) &unix_sock, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
@@ -8018,7 +8018,6 @@ REPLACE *init_replace(char * *from, char * *to,uint count,
if (!len)
{
errno=EINVAL;
- my_message(0,"No to-string for last from-string",MYF(ME_BELL));
DBUG_RETURN(0);
}
states+=len+1;
diff --git a/configure.in b/configure.in
index cd77cb24f72..a63f8d6b44c 100644
--- a/configure.in
+++ b/configure.in
@@ -20,6 +20,7 @@ SHARED_LIB_MAJOR_VERSION=16
SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0
NDB_SHARED_LIB_MAJOR_VERSION=3
NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0
+
# Set all version vars based on $VERSION. How do we do this more elegant ?
# Remember that regexps needs to quote [ and ] since this is run through m4
MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|[[a-z]]*-.*$||"`
@@ -827,7 +828,6 @@ AC_CHECK_LIB(m, floor, [], AC_CHECK_LIB(m, __infinity))
AC_CHECK_LIB(nsl_r, gethostbyname_r, [],
AC_CHECK_LIB(nsl, gethostbyname_r))
AC_CHECK_FUNC(gethostbyname_r)
-AC_CHECK_LIB(mtmalloc, malloc)
AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt))
AC_CHECK_FUNC(yp_get_default_domain, ,
@@ -2417,10 +2417,15 @@ AC_ARG_WITH(docs,
if test "$with_docs" = "yes"
then
docs_dirs="Docs"
+ if test -f "$srcdir/Docs/manual.chm" ; then
+ extra_docs="manual.chm"
+ fi
else
docs_dirs=""
+ extra_docs=""
fi
AC_SUBST(docs_dirs)
+AC_SUBST(extra_docs)
# Shall we build the man pages?
AC_ARG_WITH(man,
diff --git a/include/m_string.h b/include/m_string.h
index 00fb4cb0656..9d2a30917bd 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -200,6 +200,7 @@ double my_strtod(const char *str, char **end, int *error);
double my_atof(const char *nptr);
extern char *llstr(longlong value,char *buff);
+extern char *ullstr(longlong value,char *buff);
#ifndef HAVE_STRTOUL
extern long strtol(const char *str, char **ptr, int base);
extern ulong strtoul(const char *str, char **ptr, int base);
diff --git a/include/my_getopt.h b/include/my_getopt.h
index 30c2eb9531a..14f8e6df95b 100644
--- a/include/my_getopt.h
+++ b/include/my_getopt.h
@@ -74,7 +74,9 @@ extern void my_print_variables(const struct my_option *options);
extern void my_getopt_register_get_addr(uchar ** (*func_addr)(const char *, uint,
const struct my_option *));
-ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp);
+ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp,
+ bool *fix);
+longlong getopt_ll_limit_value(longlong, const struct my_option *,bool *fix);
my_bool getopt_compare_strings(const char *s, const char *t, uint length);
C_MODE_END
diff --git a/include/my_global.h b/include/my_global.h
index ce76aeaec20..4b0786aa826 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -116,36 +116,31 @@
The macros below are used to allow build of Universal/fat binaries of
MySQL and MySQL applications under darwin.
*/
-#ifdef TARGET_FAT_BINARY
-# undef SIZEOF_CHARP
-# undef SIZEOF_INT
-# undef SIZEOF_LONG
-# undef SIZEOF_LONG_LONG
-# undef SIZEOF_OFF_T
-# undef SIZEOF_SHORT
-
-#if defined(__i386__)
-# undef WORDS_BIGENDIAN
-# define SIZEOF_CHARP 4
-# define SIZEOF_INT 4
-# define SIZEOF_LONG 4
-# define SIZEOF_LONG_LONG 8
-# define SIZEOF_OFF_T 8
-# define SIZEOF_SHORT 2
-
-#elif defined(__ppc__)
-# define WORDS_BIGENDIAN
-# define SIZEOF_CHARP 4
-# define SIZEOF_INT 4
-# define SIZEOF_LONG 4
-# define SIZEOF_LONG_LONG 8
-# define SIZEOF_OFF_T 8
-# define SIZEOF_SHORT 2
-
-#else
-# error Building FAT binary for an unknown architecture.
-#endif
-#endif /* TARGET_FAT_BINARY */
+#if defined(__APPLE__) && defined(__MACH__)
+# undef SIZEOF_CHARP
+# undef SIZEOF_SHORT
+# undef SIZEOF_INT
+# undef SIZEOF_LONG
+# undef SIZEOF_LONG_LONG
+# undef SIZEOF_OFF_T
+# undef WORDS_BIGENDIAN
+# define SIZEOF_SHORT 2
+# define SIZEOF_INT 4
+# define SIZEOF_LONG_LONG 8
+# define SIZEOF_OFF_T 8
+# if defined(__i386__) || defined(__ppc__)
+# define SIZEOF_CHARP 4
+# define SIZEOF_LONG 4
+# elif defined(__x86_64__) || defined(__ppc64__)
+# define SIZEOF_CHARP 8
+# define SIZEOF_LONG 8
+# else
+# error Building FAT binary for an unknown architecture.
+# endif
+# if defined(__ppc__) || defined(__ppc64__)
+# define WORDS_BIGENDIAN
+# endif
+#endif /* defined(__APPLE__) && defined(__MACH__) */
/*
diff --git a/include/myisammrg.h b/include/myisammrg.h
index 0cf3aa222b3..cc6e6aac6cd 100644
--- a/include/myisammrg.h
+++ b/include/myisammrg.h
@@ -74,6 +74,7 @@ typedef struct st_myrg_info
LIST open_list;
QUEUE by_key;
ulong *rec_per_key_part; /* for sql optimizing */
+ pthread_mutex_t mutex;
} MYRG_INFO;
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 4ae7f66060f..7eefad44716 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -203,14 +203,10 @@ typedef struct st_net {
unsigned int *return_status;
unsigned char reading_or_writing;
char save_char;
- my_bool no_send_ok; /* For SPs and other things that do multiple stmts */
+ my_bool unused0; /* Please remove with the next incompatible ABI change. */
my_bool unused; /* Please remove with the next incompatible ABI change */
my_bool compress;
- /*
- Set if OK packet is already sent, and we do not need to send error
- messages
- */
- my_bool no_send_error;
+ my_bool unused1; /* Please remove with the next incompatible ABI change. */
/*
Pointer to query object in query cache, do not equal NULL (0) for
queries in cache that have not stored its results yet
@@ -221,11 +217,14 @@ typedef struct st_net {
functions and methods to maintain proper locking.
*/
unsigned char *query_cache_query;
- unsigned int last_errno;
- unsigned char error;
- my_bool report_error; /* We should report error (we have unreported error) */
+ unsigned int client_last_errno;
+ unsigned char error;
+ my_bool unused2; /* Please remove with the next incompatible ABI change. */
my_bool return_errno;
- char last_error[MYSQL_ERRMSG_SIZE], sqlstate[SQLSTATE_LENGTH+1];
+ /** Client library error message buffer. Actually belongs to struct MYSQL. */
+ char client_last_error[MYSQL_ERRMSG_SIZE];
+ /** Client library sqlstate buffer. Set along with the error message. */
+ char sqlstate[SQLSTATE_LENGTH+1];
void *extension;
} NET;
@@ -397,14 +396,17 @@ typedef struct st_udf_args
typedef struct st_udf_init
{
- my_bool maybe_null; /* 1 if function can return NULL */
- unsigned int decimals; /* for real functions */
- unsigned long max_length; /* For string functions */
- char *ptr; /* free pointer for function data */
- /* 0 if result is independent of arguments */
- my_bool const_item;
+ my_bool maybe_null; /* 1 if function can return NULL */
+ unsigned int decimals; /* for real functions */
+ unsigned long max_length; /* For string functions */
+ char *ptr; /* free pointer for function data */
+ my_bool const_item; /* 1 if function always returns the same value */
void *extension;
} UDF_INIT;
+/*
+ TODO: add a notion for determinism of the UDF.
+ See Item_udf_func::update_used_tables ()
+*/
/* Constants when using compression */
#define NET_HEADER_SIZE 4 /* standard header size */
diff --git a/include/mysql_embed.h b/include/mysql_embed.h
index 7416283d83d..4a7fd3ef63c 100644
--- a/include/mysql_embed.h
+++ b/include/mysql_embed.h
@@ -21,7 +21,6 @@
/* TODO HF add #undef HAVE_VIO if we don't want client in embedded library */
#undef HAVE_PSTACK /* No stacktrace */
-#undef HAVE_DLOPEN /* No udf functions */
#undef HAVE_OPENSSL
#undef HAVE_SMEM /* No shared memory */
#undef HAVE_NDBCLUSTER_DB /* No NDB cluster */
diff --git a/include/mysql_h.ic b/include/mysql_h.ic
index 4bedb9e8050..4f138d9a229 100644
--- a/include/mysql_h.ic
+++ b/include/mysql_h.ic
@@ -537,16 +537,16 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned
unsigned int * return_status;
unsigned char reading_or_writing;
char save_char;
- my_bool no_send_ok;
+ my_bool unused0;
my_bool unused;
my_bool compress;
- my_bool no_send_error;
+ my_bool unused1;
unsigned char * query_cache_query;
- unsigned int last_errno;
+ unsigned int client_last_errno;
unsigned char error;
- my_bool report_error;
+ my_bool unused2;
my_bool return_errno;
- char last_error[512];
+ char client_last_error[512];
char sqlstate[(5 + 1)];
void * extension;
};
diff --git a/include/queues.h b/include/queues.h
index 4fd0f72484e..d01b73ba999 100644
--- a/include/queues.h
+++ b/include/queues.h
@@ -31,8 +31,8 @@ typedef struct st_queue {
void *first_cmp_arg;
uint elements;
uint max_elements;
- uint offset_to_key; /* compare is done on element+offset */
- int max_at_top; /* Set if queue_top gives max */
+ uint offset_to_key; /* compare is done on element+offset */
+ int max_at_top; /* Normally 1, set to -1 if queue_top gives max */
int (*compare)(void *, uchar *,uchar *);
uint auto_extent;
} QUEUE;
@@ -43,7 +43,7 @@ typedef struct st_queue {
#define queue_replaced(queue) _downheap(queue,1)
#define queue_set_cmp_arg(queue, set_arg) (queue)->first_cmp_arg= set_arg
#define queue_set_max_at_top(queue, set_arg) \
- (queue)->max_at_top= set_arg ? (-1 ^ 1) : 0
+ (queue)->max_at_top= set_arg ? -1 : 1
typedef int (*queue_compare)(void *,uchar *, uchar *);
int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
index 249e6294c22..b761907ec9d 100755
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
@@ -126,9 +126,6 @@ ENDIF(WIN32)
ADD_DEPENDENCIES(libmysql GenError)
TARGET_LINK_LIBRARIES(libmysql wsock32)
-ADD_EXECUTABLE(myTest mytest.c)
-TARGET_LINK_LIBRARIES(myTest libmysql)
-
IF(EMBED_MANIFESTS)
MYSQL_EMBED_MANIFEST("myTest" "asInvoker")
ENDIF(EMBED_MANIFESTS)
diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am
index e5005553467..21f8f372d0f 100644
--- a/libmysql/Makefile.am
+++ b/libmysql/Makefile.am
@@ -31,7 +31,7 @@ include $(srcdir)/Makefile.shared
libmysqlclient_la_SOURCES = $(target_sources)
libmysqlclient_la_LIBADD = $(target_libadd) $(yassl_las)
libmysqlclient_la_LDFLAGS = $(target_ldflags)
-EXTRA_DIST = Makefile.shared libmysql.def dll.c mytest.c CMakeLists.txt
+EXTRA_DIST = Makefile.shared libmysql.def dll.c CMakeLists.txt
noinst_HEADERS = client_settings.h
link_sources:
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index bf5dd7d63eb..f5ac1c09248 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -440,11 +440,11 @@ static void expand_error(MYSQL* mysql, int error)
char tmp[MYSQL_ERRMSG_SIZE];
char *p;
uint err_length;
- strmake(tmp, mysql->net.last_error, MYSQL_ERRMSG_SIZE-1);
- p = strmake(mysql->net.last_error, ER(error), MYSQL_ERRMSG_SIZE-1);
- err_length= (uint) (p - mysql->net.last_error);
+ strmake(tmp, mysql->net.client_last_error, MYSQL_ERRMSG_SIZE-1);
+ p = strmake(mysql->net.client_last_error, ER(error), MYSQL_ERRMSG_SIZE-1);
+ err_length= (uint) (p - mysql->net.client_last_error);
strmake(p, tmp, MYSQL_ERRMSG_SIZE-1 - err_length);
- mysql->net.last_errno = error;
+ mysql->net.client_last_errno = error;
}
/*
@@ -870,9 +870,10 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename)
VOID(my_net_write(net,(const uchar*) "",0)); /* Server needs one packet */
net_flush(net);
strmov(net->sqlstate, unknown_sqlstate);
- net->last_errno= (*options->local_infile_error)(li_ptr,
- net->last_error,
- sizeof(net->last_error)-1);
+ net->client_last_errno=
+ (*options->local_infile_error)(li_ptr,
+ net->client_last_error,
+ sizeof(net->client_last_error)-1);
goto err;
}
@@ -899,9 +900,10 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename)
if (readcount < 0)
{
- net->last_errno= (*options->local_infile_error)(li_ptr,
- net->last_error,
- sizeof(net->last_error)-1);
+ net->client_last_errno=
+ (*options->local_infile_error)(li_ptr,
+ net->client_last_error,
+ sizeof(net->client_last_error)-1);
goto err;
}
@@ -1395,7 +1397,7 @@ const char *cli_read_statistics(MYSQL *mysql)
if (!mysql->net.read_pos[0])
{
set_mysql_error(mysql, CR_WRONG_HOST_INFO, unknown_sqlstate);
- return mysql->net.last_error;
+ return mysql->net.client_last_error;
}
return (char*) mysql->net.read_pos;
}
@@ -1406,7 +1408,7 @@ mysql_stat(MYSQL *mysql)
{
DBUG_ENTER("mysql_stat");
if (simple_command(mysql,COM_STATISTICS,0,0,0))
- DBUG_RETURN(mysql->net.last_error);
+ DBUG_RETURN(mysql->net.client_last_error);
DBUG_RETURN((*mysql->methods->read_statistics)(mysql));
}
@@ -1771,7 +1773,7 @@ static my_bool my_realloc_str(NET *net, ulong length)
if (res)
{
strmov(net->sqlstate, unknown_sqlstate);
- strmov(net->last_error, ER(net->last_errno));
+ strmov(net->client_last_error, ER(net->client_last_errno));
}
net->write_pos= net->buff+ buf_length;
}
@@ -1822,13 +1824,15 @@ void set_stmt_error(MYSQL_STMT * stmt, int errcode,
void set_stmt_errmsg(MYSQL_STMT *stmt, NET *net)
{
DBUG_ENTER("set_stmt_errmsg");
- DBUG_PRINT("enter", ("error: %d/%s '%s'", net->last_errno, net->sqlstate,
- net->last_error));
+ DBUG_PRINT("enter", ("error: %d/%s '%s'",
+ net->client_last_errno,
+ net->sqlstate,
+ net->client_last_error));
DBUG_ASSERT(stmt != 0);
- stmt->last_errno= net->last_errno;
- if (net->last_error && net->last_error[0])
- strmov(stmt->last_error, net->last_error);
+ stmt->last_errno= net->client_last_errno;
+ if (net->client_last_error && net->client_last_error[0])
+ strmov(stmt->last_error, net->client_last_error);
strmov(stmt->sqlstate, net->sqlstate);
DBUG_VOID_RETURN;
diff --git a/libmysql/manager.c b/libmysql/manager.c
index 53ffffa55c0..27d35758f3e 100644
--- a/libmysql/manager.c
+++ b/libmysql/manager.c
@@ -160,7 +160,7 @@ MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
msg_len=strlen(msg_buf);
if (my_net_write(&con->net,(uchar*) msg_buf,msg_len) || net_flush(&con->net))
{
- con->last_errno=con->net.last_errno;
+ con->last_errno=con->net.client_last_errno;
strmov(con->last_error,"Write error on socket");
goto err;
}
diff --git a/libmysql/mytest.c b/libmysql/mytest.c
deleted file mode 100644
index 2d5c576b72a..00000000000
--- a/libmysql/mytest.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*C4*/
-/****************************************************************/
-/* Author: Jethro Wright, III TS : 3/ 4/1998 9:15 */
-/* Date: 02/18/1998 */
-/* mytest.c : do some testing of the libmySQL.DLL.... */
-/* */
-/* History: */
-/* 02/18/1998 jw3 also sprach zarathustra.... */
-/****************************************************************/
-
-
-#include <windows.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <mysql.h>
-
-#define DEFALT_SQL_STMT "SELECT * FROM db"
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-
-
-/********************************************************
-**
-** main :-
-**
-********************************************************/
-
-int
-main( int argc, char * argv[] )
-{
-
- char szSQL[ 200 ], aszFlds[ 25 ][ 25 ], szDB[ 50 ] ;
- const char *pszT;
- int i, j, k, l, x ;
- MYSQL * myData ;
- MYSQL_RES * res ;
- MYSQL_FIELD * fd ;
- MYSQL_ROW row ;
-
- //....just curious....
- printf( "sizeof( MYSQL ) == %d\n", (int) sizeof( MYSQL ) ) ;
- if ( argc == 2 )
- {
- strcpy( szDB, argv[ 1 ] ) ;
- strcpy( szSQL, DEFALT_SQL_STMT ) ;
- if (!strcmp(szDB,"--debug"))
- {
- strcpy( szDB, "mysql" ) ;
- printf("Some mysql struct information (size and offset):\n");
- printf("net:\t%3d %3d\n",(int) sizeof(myData->net),
- (int) offsetof(MYSQL,net));
- printf("host:\t%3d %3d\n",(int) sizeof(myData->host),
- (int) offsetof(MYSQL,host));
- printf("port:\t%3d %3d\n", (int) sizeof(myData->port),
- (int) offsetof(MYSQL,port));
- printf("protocol_version:\t%3d %3d\n",
- (int) sizeof(myData->protocol_version),
- (int) offsetof(MYSQL,protocol_version));
- printf("thread_id:\t%3d %3d\n",(int) sizeof(myData->thread_id),
- (int) offsetof(MYSQL,thread_id));
- printf("affected_rows:\t%3d %3d\n",(int) sizeof(myData->affected_rows),
- (int) offsetof(MYSQL,affected_rows));
- printf("packet_length:\t%3d %3d\n",(int) sizeof(myData->packet_length),
- (int) offsetof(MYSQL,packet_length));
- printf("status:\t%3d %3d\n",(int) sizeof(myData->status),
- (int) offsetof(MYSQL,status));
- printf("fields:\t%3d %3d\n",(int) sizeof(myData->fields),
- (int) offsetof(MYSQL,fields));
- printf("field_alloc:\t%3d %3d\n",(int) sizeof(myData->field_alloc),
- (int) offsetof(MYSQL,field_alloc));
- printf("free_me:\t%3d %3d\n",(int) sizeof(myData->free_me),
- (int) offsetof(MYSQL,free_me));
- printf("options:\t%3d %3d\n",(int) sizeof(myData->options),
- (int) offsetof(MYSQL,options));
- puts("");
- }
- }
- else if ( argc > 2 ) {
- strcpy( szDB, argv[ 1 ] ) ;
- strcpy( szSQL, argv[ 2 ] ) ;
- }
- else {
- strcpy( szDB, "mysql" ) ;
- strcpy( szSQL, DEFALT_SQL_STMT ) ;
- }
- //....
-
- if ( (myData = mysql_init((MYSQL*) 0)) &&
- mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT,
- NULL, 0 ) )
- {
- myData->reconnect= 1;
- if ( mysql_select_db( myData, szDB ) < 0 ) {
- printf( "Can't select the %s database !\n", szDB ) ;
- mysql_close( myData ) ;
- return 2 ;
- }
- }
- else {
- printf( "Can't connect to the mysql server on port %d !\n",
- MYSQL_PORT ) ;
- mysql_close( myData ) ;
- return 1 ;
- }
- //....
- if ( ! mysql_query( myData, szSQL ) ) {
- res = mysql_store_result( myData ) ;
- i = (int) mysql_num_rows( res ) ; l = 1 ;
- printf( "Query: %s\nNumber of records found: %ld\n", szSQL, i ) ;
- //....we can get the field-specific characteristics here....
- for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
- strcpy( aszFlds[ x ], fd->name ) ;
- //....
- while ( row = mysql_fetch_row( res ) ) {
- j = mysql_num_fields( res ) ;
- printf( "Record #%ld:-\n", l++ ) ;
- for ( k = 0 ; k < j ; k++ )
- printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
- (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
- puts( "==============================\n" ) ;
- }
- mysql_free_result( res ) ;
- }
- else printf( "Couldn't execute %s on the server !\n", szSQL ) ;
- //....
- puts( "==== Diagnostic info ====" ) ;
- pszT = mysql_get_client_info() ;
- printf( "Client info: %s\n", pszT ) ;
- //....
- pszT = mysql_get_host_info( myData ) ;
- printf( "Host info: %s\n", pszT ) ;
- //....
- pszT = mysql_get_server_info( myData ) ;
- printf( "Server info: %s\n", pszT ) ;
- //....
- res = mysql_list_processes( myData ) ; l = 1 ;
- if (res)
- {
- for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
- strcpy( aszFlds[ x ], fd->name ) ;
- while ( row = mysql_fetch_row( res ) ) {
- j = mysql_num_fields( res ) ;
- printf( "Process #%ld:-\n", l++ ) ;
- for ( k = 0 ; k < j ; k++ )
- printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
- (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
- puts( "==============================\n" ) ;
- }
- }
- else
- {
- printf("Got error %s when retreiving processlist\n",mysql_error(myData));
- }
- //....
- res = mysql_list_tables( myData, "%" ) ; l = 1 ;
- for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
- strcpy( aszFlds[ x ], fd->name ) ;
- while ( row = mysql_fetch_row( res ) ) {
- j = mysql_num_fields( res ) ;
- printf( "Table #%ld:-\n", l++ ) ;
- for ( k = 0 ; k < j ; k++ )
- printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
- (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
- puts( "==============================\n" ) ;
- }
- //....
- pszT = mysql_stat( myData ) ;
- puts( pszT ) ;
- //....
- mysql_close( myData ) ;
- return 0 ;
-
-}
diff --git a/libmysql_r/Makefile.am b/libmysql_r/Makefile.am
index 2ff4082b014..4a37dcfdec9 100644
--- a/libmysql_r/Makefile.am
+++ b/libmysql_r/Makefile.am
@@ -41,6 +41,7 @@ link_sources:
@LN_CP_F@ $$d/$$f $$f; \
done; \
done
+ echo timestamp > link_sources
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index fb3316c303c..9fa7d46d466 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -22,7 +22,7 @@ IF(WIN32)
ADD_DEFINITIONS(-DUSE_TLS)
ENDIF(WIN32)
-ADD_DEFINITIONS(-DMYSQL_SERVER -DEMBEDDED_LIBRARY)
+ADD_DEFINITIONS(-DMYSQL_SERVER -DEMBEDDED_LIBRARY -DHAVE_DLOPEN)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/libmysqld
diff --git a/libmysqld/emb_qcache.cc b/libmysqld/emb_qcache.cc
index 17549bfa96b..fdd7f8ed776 100644
--- a/libmysqld/emb_qcache.cc
+++ b/libmysqld/emb_qcache.cc
@@ -19,7 +19,7 @@
#include "emb_qcache.h"
#include "embedded_priv.h"
-void Querycache_stream::store_char(char c)
+void Querycache_stream::store_uchar(uchar c)
{
if (data_end == cur_data)
use_next_block(TRUE);
@@ -142,7 +142,7 @@ void Querycache_stream::store_safe_str(const char *str, uint str_len)
store_int(0);
}
-char Querycache_stream::load_char()
+uchar Querycache_stream::load_uchar()
{
if (cur_data == data_end)
use_next_block(FALSE);
@@ -301,8 +301,8 @@ uint emb_count_querycache_size(THD *thd)
*data->embedded_info->prev_ptr= NULL; // this marks the last record
cur_row= data->data;
n_rows= data->rows;
- /* n_fields + n_rows + (field_info + strlen * n_rows) * n_fields */
- result+= (uint) (4+8 + (42 + 4*n_rows)*data->fields);
+ /* n_fields + n_rows + field_info * n_fields */
+ result+= (uint) (4+8 + 42*data->fields);
for(; field < field_end; field++)
{
@@ -313,13 +313,23 @@ uint emb_count_querycache_size(THD *thd)
result+= field->def_length;
}
- for (; cur_row; cur_row=cur_row->next)
+ if (thd->protocol == &thd->protocol_binary)
{
- MYSQL_ROW col= cur_row->data;
- MYSQL_ROW col_end= col + data->fields;
- for (; col < col_end; col++)
- if (*col)
- result+= *(uint *)((*col) - sizeof(uint));
+ result+= (uint) (4*n_rows);
+ for (; cur_row; cur_row=cur_row->next)
+ result+= cur_row->length;
+ }
+ else
+ {
+ result+= (uint) (4*n_rows*data->fields);
+ for (; cur_row; cur_row=cur_row->next)
+ {
+ MYSQL_ROW col= cur_row->data;
+ MYSQL_ROW col_end= col + data->fields;
+ for (; col < col_end; col++)
+ if (*col)
+ result+= *(uint *)((*col) - sizeof(uint));
+ }
}
return result;
}
@@ -353,10 +363,10 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
{
dst->store_int((uint)field->length);
dst->store_int((uint)field->max_length);
- dst->store_char((char)field->type);
+ dst->store_uchar((uchar)field->type);
dst->store_short((ushort)field->flags);
dst->store_short((ushort)field->charsetnr);
- dst->store_char((char)field->decimals);
+ dst->store_uchar((uchar)field->decimals);
dst->store_str(field->name, field->name_length);
dst->store_str(field->table, field->table_length);
dst->store_str(field->org_name, field->org_name_length);
@@ -366,14 +376,22 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
dst->store_safe_str(field->def, field->def_length);
}
- for (; cur_row; cur_row=cur_row->next)
+ if (thd->protocol == &thd->protocol_binary)
{
- MYSQL_ROW col= cur_row->data;
- MYSQL_ROW col_end= col + data->fields;
- for (; col < col_end; col++)
+ for (; cur_row; cur_row=cur_row->next)
+ dst->store_str((char *) cur_row->data, cur_row->length);
+ }
+ else
+ {
+ for (; cur_row; cur_row=cur_row->next)
{
- uint len= *col ? *(uint *)((*col) - sizeof(uint)) : 0;
- dst->store_safe_str(*col, len);
+ MYSQL_ROW col= cur_row->data;
+ MYSQL_ROW col_end= col + data->fields;
+ for (; col < col_end; col++)
+ {
+ uint len= *col ? *(uint *)((*col) - sizeof(uint)) : 0;
+ dst->store_safe_str(*col, len);
+ }
}
}
DBUG_ASSERT(emb_count_querycache_size(thd) == dst->stored_size);
@@ -408,10 +426,10 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
{
field->length= src->load_int();
field->max_length= (unsigned int)src->load_int();
- field->type= (enum enum_field_types)src->load_char();
+ field->type= (enum enum_field_types)src->load_uchar();
field->flags= (unsigned int)src->load_short();
field->charsetnr= (unsigned int)src->load_short();
- field->decimals= (unsigned int)src->load_char();
+ field->decimals= src->load_uchar();
if (!(field->name= src->load_str(f_alloc, &field->name_length)) ||
!(field->table= src->load_str(f_alloc,&field->table_length)) ||
@@ -423,31 +441,48 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
goto err;
}
- row= (MYSQL_ROWS *)alloc_root(&data->alloc,
- (uint) (rows * sizeof(MYSQL_ROWS) +
- rows*(data->fields+1)*sizeof(char*)));
- end_row= row + rows;
- columns= (MYSQL_ROW)end_row;
-
data->rows= rows;
- data->data= row;
if (!rows)
goto return_ok;
+ if (thd->protocol == &thd->protocol_binary)
+ {
+ uint length;
+ row= (MYSQL_ROWS *)alloc_root(&data->alloc, rows * sizeof(MYSQL_ROWS));
+ end_row= row + rows;
+ data->data= row;
- for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++)
+ for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++)
+ {
+ *prev_row= row;
+ row->data= (MYSQL_ROW) src->load_str(&data->alloc, &length);
+ row->length= length;
+ }
+ }
+ else
{
- *prev_row= row;
- row->data= columns;
- MYSQL_ROW col_end= columns + data->fields;
- for (; columns < col_end; columns++)
- src->load_column(&data->alloc, columns);
+ row= (MYSQL_ROWS *)alloc_root(&data->alloc,
+ (uint) (rows * sizeof(MYSQL_ROWS) +
+ rows*(data->fields+1)*sizeof(char*)));
+ end_row= row + rows;
+ columns= (MYSQL_ROW)end_row;
- *(columns++)= NULL;
+ data->data= row;
+
+ for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++)
+ {
+ *prev_row= row;
+ row->data= columns;
+ MYSQL_ROW col_end= columns + data->fields;
+ for (; columns < col_end; columns++)
+ src->load_column(&data->alloc, columns);
+
+ *(columns++)= NULL;
+ }
}
*prev_row= NULL;
data->embedded_info->prev_ptr= prev_row;
return_ok:
- send_eof(thd);
+ net_send_eof(thd, thd->server_status, thd->total_warn_count);
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
diff --git a/libmysqld/emb_qcache.h b/libmysqld/emb_qcache.h
index 6e320fbd967..67413739f2c 100644
--- a/libmysqld/emb_qcache.h
+++ b/libmysqld/emb_qcache.h
@@ -58,7 +58,7 @@ public:
data_end= cur_data + (block->used-headers_len);
}
- void store_char(char c);
+ void store_uchar(uchar c);
void store_short(ushort s);
void store_int(uint i);
void store_ll(ulonglong ll);
@@ -66,7 +66,7 @@ public:
void store_str(const char *str, uint str_len);
void store_safe_str(const char *str, uint str_len);
- char load_char();
+ uchar load_uchar();
ushort load_short();
uint load_int();
ulonglong load_ll();
@@ -79,3 +79,4 @@ public:
uint emb_count_querycache_size(THD *thd);
int emb_load_querycache_result(THD *thd, Querycache_stream *src);
void emb_store_querycache_result(Querycache_stream *dst, THD* thd);
+void net_send_eof(THD *thd, uint server_status, uint total_warn_count);
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index cf6013f2ffb..cb3b6a7115d 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -61,9 +61,10 @@ void embedded_get_error(MYSQL *mysql, MYSQL_DATA *data)
{
NET *net= &mysql->net;
struct embedded_query_result *ei= data->embedded_info;
- net->last_errno= ei->last_errno;
- strmake(net->last_error, ei->info, sizeof(net->last_error));
+ net->client_last_errno= ei->last_errno;
+ strmake(net->client_last_error, ei->info, sizeof(net->client_last_error)-1);
memcpy(net->sqlstate, ei->sqlstate, sizeof(net->sqlstate));
+ mysql->server_status= ei->server_status;
my_free(data, MYF(0));
}
@@ -91,6 +92,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
/* Clear result variables */
thd->clear_error();
+ thd->main_da.reset_diagnostics_area();
mysql->affected_rows= ~(my_ulonglong) 0;
mysql->field_count= 0;
net_clear_error(net);
@@ -114,12 +116,11 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
arg_length= header_length;
}
- thd->net.no_send_error= 0;
result= dispatch_command(command, thd, (char *) arg, arg_length);
thd->cur_data= 0;
if (!skip_check)
- result= thd->net.last_errno ? -1 : 0;
+ result= thd->is_error() ? -1 : 0;
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
thd->profiling.finish_current_query();
@@ -249,9 +250,11 @@ static my_bool emb_read_query_result(MYSQL *mysql)
mysql->warning_count= res->embedded_info->warning_count;
mysql->server_status= res->embedded_info->server_status;
mysql->field_count= res->fields;
- mysql->fields= res->embedded_info->fields_list;
- mysql->affected_rows= res->embedded_info->affected_rows;
- mysql->insert_id= res->embedded_info->insert_id;
+ if (!(mysql->fields= res->embedded_info->fields_list))
+ {
+ mysql->affected_rows= res->embedded_info->affected_rows;
+ mysql->insert_id= res->embedded_info->insert_id;
+ }
net_clear_error(&mysql->net);
mysql->info= 0;
@@ -377,7 +380,7 @@ static void emb_free_embedded_thd(MYSQL *mysql)
static const char * emb_read_statistics(MYSQL *mysql)
{
THD *thd= (THD*)mysql->thd;
- return thd->net.last_error;
+ return thd->is_error() ? thd->main_da.message() : "";
}
@@ -553,7 +556,6 @@ void end_embedded_server()
{
my_free((char*) copy_arguments_ptr, MYF(MY_ALLOW_ZERO_PTR));
copy_arguments_ptr=0;
- release_ddl_log();
clean_up(0);
}
@@ -633,6 +635,7 @@ int check_embedded_connection(MYSQL *mysql, const char *db)
strmake(sctx->priv_host, (char*) my_localhost, MAX_HOSTNAME-1);
sctx->priv_user= sctx->user= my_strdup(mysql->user, MYF(0));
result= check_user(thd, COM_CONNECT, NULL, 0, db, true);
+ net_end_statement(thd);
emb_read_query_result(mysql);
return result;
}
@@ -682,8 +685,10 @@ int check_embedded_connection(MYSQL *mysql, const char *db)
err:
{
NET *net= &mysql->net;
- memcpy(net->last_error, thd->net.last_error, sizeof(net->last_error));
- memcpy(net->sqlstate, thd->net.sqlstate, sizeof(net->sqlstate));
+ strmake(net->client_last_error, thd->main_da.message(), sizeof(net->client_last_error)-1);
+ memcpy(net->sqlstate,
+ mysql_errno_to_sqlstate(thd->main_da.sql_errno()),
+ sizeof(net->sqlstate)-1);
}
return result;
}
@@ -706,9 +711,8 @@ void THD::clear_data_list()
void THD::clear_error()
{
- net.last_error[0]= 0;
- net.last_errno= 0;
- net.report_error= 0;
+ if (main_da.is_error())
+ main_da.reset_diagnostics_area();
}
static char *dup_str_aux(MEM_ROOT *root, const char *from, uint length,
@@ -771,20 +775,18 @@ MYSQL_DATA *THD::alloc_new_dataset()
}
-/*
- stores server_status and warning_count in the current
- query result structures
-
- SYNOPSIS
- write_eof_packet()
- thd current thread
+/**
+ Stores server_status and warning_count in the current
+ query result structures.
- NOTES
- should be called to after we get the recordset-result
+ @param thd current thread
+ @note Should be called after we get the recordset-result.
*/
-static void write_eof_packet(THD *thd)
+static
+void
+write_eof_packet(THD *thd, uint server_status, uint total_warn_count)
{
if (!thd->mysql) // bootstrap file handling
return;
@@ -795,13 +797,13 @@ static void write_eof_packet(THD *thd)
*/
if (thd->is_fatal_error)
thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
- thd->cur_data->embedded_info->server_status= thd->server_status;
+ thd->cur_data->embedded_info->server_status= server_status;
/*
Don't send warn count during SP execution, as the warn_list
is cleared between substatements, and mysqltest gets confused
*/
thd->cur_data->embedded_info->warning_count=
- (thd->spcont ? 0 : min(thd->total_warn_count, 65535));
+ (thd->spcont ? 0 : min(total_warn_count, 65535));
}
@@ -957,7 +959,7 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
}
if (flags & SEND_EOF)
- write_eof_packet(thd);
+ write_eof_packet(thd, thd->server_status, thd->total_warn_count);
DBUG_RETURN(prepare_for_send(list));
err:
@@ -997,17 +999,35 @@ bool Protocol_binary::write()
return false;
}
+
+/**
+ Embedded library implementation of OK response.
+
+ This function is used by the server to write 'OK' packet to
+ the "network" when the server is compiled as an embedded library.
+ Since there is no network in the embedded configuration,
+ a different implementation is necessary.
+ Instead of marshalling response parameters to a network representation
+ and then writing it to the socket, here we simply copy the data to the
+ corresponding client-side connection structures.
+
+ @sa Server implementation of net_send_ok in protocol.cc for
+ description of the arguments.
+
+ @return The function does not return errors.
+*/
+
void
-send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message)
+net_send_ok(THD *thd,
+ uint server_status, uint total_warn_count,
+ ha_rows affected_rows, ulonglong id, const char *message)
{
- DBUG_ENTER("send_ok");
+ DBUG_ENTER("emb_net_send_ok");
MYSQL_DATA *data;
MYSQL *mysql= thd->mysql;
-
+
if (!mysql) // bootstrap file handling
DBUG_VOID_RETURN;
- if (thd->net.no_send_ok) // hack for re-parsing queries
- DBUG_VOID_RETURN;
if (!(data= thd->alloc_new_dataset()))
return;
data->embedded_info->affected_rows= affected_rows;
@@ -1016,15 +1036,24 @@ send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message)
strmake(data->embedded_info->info, message,
sizeof(data->embedded_info->info)-1);
- write_eof_packet(thd);
+ write_eof_packet(thd, server_status, total_warn_count);
thd->cur_data= 0;
DBUG_VOID_RETURN;
}
+
+/**
+ Embedded library implementation of EOF response.
+
+ @sa net_send_ok
+
+ @return This function does not return errors.
+*/
+
void
-send_eof(THD *thd)
+net_send_eof(THD *thd, uint server_status, uint total_warn_count)
{
- write_eof_packet(thd);
+ write_eof_packet(thd, server_status, total_warn_count);
thd->cur_data= 0;
}
@@ -1037,6 +1066,7 @@ void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
ei->last_errno= sql_errno;
strmake(ei->info, err, sizeof(ei->info)-1);
strmov(ei->sqlstate, mysql_errno_to_sqlstate(sql_errno));
+ ei->server_status= thd->server_status;
thd->cur_data= 0;
}
diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c
index eb47a045669..a8542f6fca9 100644
--- a/libmysqld/libmysqld.c
+++ b/libmysqld/libmysqld.c
@@ -209,8 +209,9 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
DBUG_RETURN(mysql);
error:
- DBUG_PRINT("error",("message: %u (%s)", mysql->net.last_errno,
- mysql->net.last_error));
+ DBUG_PRINT("error",("message: %u (%s)",
+ mysql->net.client_last_errno,
+ mysql->net.client_last_error));
{
/* Free alloced memory */
my_bool free_me=mysql->free_me;
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index 900ee14bd4e..79d11c857ab 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -44,6 +44,7 @@ dist-hook:
$(distdir)/std_data/ndb_backup51 \
$(distdir)/std_data/ndb_backup51_data_be \
$(distdir)/std_data/ndb_backup51_data_le \
+ $(distdir)/std_data/parts \
$(distdir)/lib
-$(INSTALL_DATA) $(srcdir)/t/*.def $(distdir)/t
$(INSTALL_DATA) $(srcdir)/t/*.test $(distdir)/t
@@ -71,6 +72,7 @@ dist-hook:
$(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51/BACKUP* $(distdir)/std_data/ndb_backup51
$(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_be/BACKUP* $(distdir)/std_data/ndb_backup51_data_be
$(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_le/BACKUP* $(distdir)/std_data/ndb_backup51_data_le
+ $(INSTALL_DATA) $(srcdir)/std_data/parts/part_* $(distdir)/std_data/parts
$(INSTALL_DATA) $(srcdir)/lib/*.pl $(distdir)/lib
-rm -rf `find $(distdir)/suite -type d -name SCCS` $(distdir)/suite/row_lock
@@ -86,6 +88,7 @@ install-data-local:
$(DESTDIR)$(testdir)/std_data/ndb_backup51 \
$(DESTDIR)$(testdir)/std_data/ndb_backup51_data_be \
$(DESTDIR)$(testdir)/std_data/ndb_backup51_data_le \
+ $(DESTDIR)$(testdir)/std_data/parts \
$(DESTDIR)$(testdir)/lib
$(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(testdir)
-$(INSTALL_DATA) $(srcdir)/t/*.def $(DESTDIR)$(testdir)/t
@@ -118,6 +121,7 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup51
$(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_be/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup51_data_be
$(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_le/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup51_data_le
+ $(INSTALL_DATA) $(srcdir)/std_data/parts/part_* $(DESTDIR)$(testdir)/std_data/parts
$(INSTALL_DATA) $(srcdir)/lib/*.pl $(DESTDIR)$(testdir)/lib
for f in `(cd $(srcdir); find suite -type f | egrep -v 'SCCS|row_lock')`; \
do \
diff --git a/mysql-test/extra/binlog_tests/ctype_cp932.test b/mysql-test/extra/binlog_tests/ctype_cp932.test
index 0839f5d43aa..3deeea13997 100644
--- a/mysql-test/extra/binlog_tests/ctype_cp932.test
+++ b/mysql-test/extra/binlog_tests/ctype_cp932.test
@@ -8,6 +8,10 @@ drop table if exists t3;
drop table if exists t4;
--enable_warnings
+SET @test_character_set= 'cp932';
+SET @test_collation= 'cp932_japanese_ci';
+-- source include/ctype_common.inc
+
set names cp932;
set character_set_database = cp932;
diff --git a/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test b/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test
index cdd828305dc..efca53d5698 100644
--- a/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test
+++ b/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test
@@ -973,14 +973,7 @@ SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1;
--echo
--echo ** update from master **
connection master;
-#######################################
-# This test should be uncommented
-# once bug30674 is patched
-#######################################
-
-#***************************
-#UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3;
-#***************************
+UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3;
--replace_column 5 CURRENT_TIMESTAMP
SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1;
diff --git a/mysql-test/include/ctype_common.inc b/mysql-test/include/ctype_common.inc
index 9ee0a40c8ce..89b7ceb0c72 100644
--- a/mysql-test/include/ctype_common.inc
+++ b/mysql-test/include/ctype_common.inc
@@ -53,11 +53,13 @@ DROP TABLE t1;
#
# Bug #31070: crash during conversion of charsets
+# Bug #32726: crash with cast in order by clause and cp932 charset
#
create table t1 (a set('a') not null);
insert into t1 values (),();
select cast(a as char(1)) from t1;
select a sounds like a from t1;
+select 1 from t1 order by cast(a as char(1));
drop table t1;
DROP DATABASE d1;
diff --git a/mysql-test/include/have_multi_ndb.inc b/mysql-test/include/have_multi_ndb.inc
index deda22b64c0..9779f181191 100644
--- a/mysql-test/include/have_multi_ndb.inc
+++ b/mysql-test/include/have_multi_ndb.inc
@@ -5,10 +5,6 @@ connect (server2,127.0.0.1,root,,test,$MASTER_MYPORT1,);
# Check that server1 has NDB support
connection server1;
disable_query_log;
---disable_warnings
-drop table if exists t1, t2;
---enable_warnings
-flush tables;
--require r/true.require
select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'ndbcluster';
--source include/ndb_not_readonly.inc
@@ -17,14 +13,32 @@ enable_query_log;
# Check that server2 has NDB support
connection server2;
disable_query_log;
---disable_warnings
-drop table if exists t1, t2;
---enable_warnings
-flush tables;
--require r/true.require
select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'ndbcluster';
--source include/ndb_not_readonly.inc
enable_query_log;
-# Set the default connection to 'server1'
+# cleanup
+
+connection server1;
+disable_query_log;
+disable_warnings;
+--error 0,1051
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
+flush tables;
+flush status;
+enable_warnings;
+enable_query_log;
+
+connection server2;
+disable_query_log;
+disable_warnings;
+--error 0,1051
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
+flush tables;
+flush status;
+enable_warnings;
+enable_query_log;
+
+# Set the default connection
connection server1;
diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc
index e695e7d5570..3005e67935b 100644
--- a/mysql-test/include/mix1.inc
+++ b/mysql-test/include/mix1.inc
@@ -724,6 +724,19 @@ set @@sort_buffer_size=default;
DROP TABLE t1,t2;
#
+# Bug #32815: query with ORDER BY and a possible ref_or_null access
+#
+
+CREATE TABLE t1 (id int, type char(6), d int, INDEX idx(id,d)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+ (191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2);
+
+EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
+SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
+
+DROP TABLE t1;
+
+
# Test of behaviour with CREATE ... SELECT
#
diff --git a/mysql-test/include/ps_query.inc b/mysql-test/include/ps_query.inc
index e96d666eaec..ae6027a0e07 100644
--- a/mysql-test/include/ps_query.inc
+++ b/mysql-test/include/ps_query.inc
@@ -434,8 +434,8 @@ execute stmt1 ;
let $1= 3 ;
while ($1)
{
- prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+ prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
deallocate prepare stmt1 ;
dec $1 ;
diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl
index 8b004a0c6c8..73598fc1bac 100644
--- a/mysql-test/lib/mtr_report.pl
+++ b/mysql-test/lib/mtr_report.pl
@@ -234,6 +234,7 @@ sub mtr_report_stats ($) {
"\\[ERROR\\]",
"^Error:", "^==.* at 0x",
"InnoDB: Warning",
+ "InnoDB: Error",
"^safe_mutex:",
"missing DBUG_RETURN",
"mysqld: Warning",
@@ -303,6 +304,7 @@ sub mtr_report_stats ($) {
/Slave: Error .*Unknown table/ or
/Slave: Error in Write_rows event: / or
/Slave: Field .* of table .* has no default value/ or
+ /Slave: Field .* doesn't have a default value/ or
/Slave: Query caused different errors on master and slave/ or
/Slave: Table .* doesn't exist/ or
/Slave: Table width mismatch/ or
@@ -335,18 +337,26 @@ sub mtr_report_stats ($) {
/\QError in Log_event::read_log_event(): 'Sanity check failed', data_len: 258, event_type: 49\E/ or
/Statement is not safe to log in statement format/ or
+ # test case for Bug#bug29807 copies a stray frm into database
+ /InnoDB: Error: table `test`.`bug29807` does not exist in the InnoDB internal/ or
+ /Cannot find or open table test\/bug29807 from/ or
+
+ # innodb foreign key tests that fail in ALTER or RENAME produce this
+ /InnoDB: Error: in ALTER TABLE `test`.`t[12]`/ or
+ /InnoDB: Error: in RENAME TABLE table `test`.`t1`/ or
+ /InnoDB: Error: table `test`.`t[12]` does not exist in the InnoDB internal/ or
+
# Test case for Bug#14233 produces the following warnings:
/Stored routine 'test'.'bug14233_1': invalid value in column mysql.proc/ or
/Stored routine 'test'.'bug14233_2': invalid value in column mysql.proc/ or
/Stored routine 'test'.'bug14233_3': invalid value in column mysql.proc/ or
- # BUG#29807 - innodb_mysql.test: Cannot find table test/t2
- # from the internal data dictionary
- /Cannot find or open table test\/bug29807 from/ or
-
# BUG#29839 - lowercase_table3.test: Cannot find table test/T1
# from the internal data dictiona
/Cannot find table test\/BUG29839 from the internal data dictionary/ or
+ # BUG#32080 - Excessive warnings on Solaris: setrlimit could not
+ # change the size of core files
+ /setrlimit could not change the size of core files to 'infinity'/ or
# rpl_extrColmaster_*.test, the slave thread produces warnings
# when it get updates to a table that has more columns on the
@@ -354,7 +364,6 @@ sub mtr_report_stats ($) {
/Slave: Unknown column 'c7' in 't15' Error_code: 1054/ or
/Slave: Can't DROP 'c7'.* 1091/ or
/Slave: Key column 'c6'.* 1072/
-
)
{
next; # Skip these lines
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 1a8c18f7d27..18633d095b0 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -129,7 +129,15 @@ our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
our $default_vardir;
our $opt_usage;
-our $opt_suites= "main,binlog,rpl,rpl_ndb,ndb"; # Default suites to run
+our $opt_suites;
+our $opt_suites_default= "main,binlog,rpl,rpl_ndb,ndb"; # Default suites to run
+our @extra_suites=
+(
+ ["mysql-5.1-new-ndb", "ndb_team"],
+ ["mysql-5.1-telco-6.2", "ndb_team"],
+ ["mysql-5.1-telco-6.3", "ndb_team"],
+);
+
our $opt_script_debug= 0; # Script debugging, enable with --script-debug
our $opt_verbose= 0; # Verbose output, enable with --verbose
@@ -397,6 +405,20 @@ sub main () {
else
{
# Figure out which tests we are going to run
+ if (!$opt_suites)
+ {
+ # use default and add any extra_suites as defined
+ $opt_suites= $opt_suites_default;
+ my $ddd= basename(dirname($glob_mysql_test_dir));
+ foreach my $extra_suite (@extra_suites)
+ {
+ if ($extra_suite->[0] eq "$ddd")
+ {
+ $opt_suites= "$extra_suite->[1],$opt_suites";
+ }
+ }
+ }
+
my $tests= collect_test_cases($opt_suites);
# Turn off NDB and other similar options if no tests use it
@@ -5195,7 +5217,7 @@ Options to control what test suites or cases to run
start-from=PREFIX Run test cases starting from test prefixed with PREFIX
suite[s]=NAME1,..,NAMEN Collect tests in suites from the comma separated
list of suite names.
- The default is: "$opt_suites"
+ The default is: "$opt_suites_default"
skip-rpl Skip the replication test cases.
skip-im Don't start IM, and skip the IM test cases
big-test Set the environment variable BIG_TEST, which can be
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result
index edd49988a5f..e9eb50fc805 100644
--- a/mysql-test/r/archive.result
+++ b/mysql-test/r/archive.result
@@ -12665,7 +12665,7 @@ t6 CREATE TABLE `t6` (
`b` tinyblob,
`c` int(11) DEFAULT NULL,
KEY `a` (`a`)
-) ENGINE=ARCHIVE DEFAULT CHARSET=latin1
+) ENGINE=ARCHIVE AUTO_INCREMENT=36 DEFAULT CHARSET=latin1
DROP TABLE t1, t2, t4, t5, t6;
create table t1 (i int) engine=archive;
insert into t1 values (1);
@@ -12687,3 +12687,10 @@ CREATE TABLE t1(a VARCHAR(510)) ENGINE = ARCHIVE;
INSERT INTO t1(a) VALUES ('');
SELECT * FROM t1 ORDER BY a;
DROP TABLE t1;
+CREATE TABLE t1(a INT NOT NULL AUTO_INCREMENT, b BLOB, KEY(a)) ENGINE=archive;
+INSERT INTO t1 VALUES (NULL, NULL),(NULL, NULL);
+FLUSH TABLE t1;
+SELECT * FROM t1 ORDER BY a;
+a b
+1 NULL
+2 NULL
diff --git a/mysql-test/r/change_user.result b/mysql-test/r/change_user.result
index cb409621d56..28b55dfd5e5 100644
--- a/mysql-test/r/change_user.result
+++ b/mysql-test/r/change_user.result
@@ -4,14 +4,14 @@ SELECT @@session.sql_big_selects;
1
SELECT @@global.max_join_size;
@@global.max_join_size
--1
+18446744073709551615
change_user
SELECT @@session.sql_big_selects;
@@session.sql_big_selects
1
SELECT @@global.max_join_size;
@@global.max_join_size
--1
+18446744073709551615
SET @@global.max_join_size = 10000;
SET @@session.max_join_size = default;
change_user
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index 73a9dba4e69..0613c9ba488 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -1705,4 +1705,42 @@ create table t1 as select 1;
create table t2 as select f1() from t1;
drop table t1,t2;
drop function f1;
+create table t1 like information_schema.processlist;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `ID` bigint(4) NOT NULL DEFAULT '0',
+ `USER` varchar(16) NOT NULL DEFAULT '',
+ `HOST` varchar(64) NOT NULL DEFAULT '',
+ `DB` varchar(64) DEFAULT NULL,
+ `COMMAND` varchar(16) NOT NULL DEFAULT '',
+ `TIME` bigint(7) NOT NULL DEFAULT '0',
+ `STATE` varchar(64) DEFAULT NULL,
+ `INFO` longtext
+) ENGINE=MyISAM DEFAULT CHARSET=utf8
+drop table t1;
+create temporary table t1 like information_schema.processlist;
+show create table t1;
+Table Create Table
+t1 CREATE TEMPORARY TABLE `t1` (
+ `ID` bigint(4) NOT NULL DEFAULT '0',
+ `USER` varchar(16) NOT NULL DEFAULT '',
+ `HOST` varchar(64) NOT NULL DEFAULT '',
+ `DB` varchar(64) DEFAULT NULL,
+ `COMMAND` varchar(16) NOT NULL DEFAULT '',
+ `TIME` bigint(7) NOT NULL DEFAULT '0',
+ `STATE` varchar(64) DEFAULT NULL,
+ `INFO` longtext
+) ENGINE=MyISAM DEFAULT CHARSET=utf8
+drop table t1;
+create table t1 like information_schema.character_sets;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `CHARACTER_SET_NAME` varchar(64) NOT NULL DEFAULT '',
+ `DEFAULT_COLLATE_NAME` varchar(64) NOT NULL DEFAULT '',
+ `DESCRIPTION` varchar(60) NOT NULL DEFAULT '',
+ `MAXLEN` bigint(3) NOT NULL DEFAULT '0'
+) ENGINE=MEMORY DEFAULT CHARSET=utf8
+drop table t1;
End of 5.1 tests
diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result
index 69f77dc3cd8..b0033383f00 100644
--- a/mysql-test/r/csv.result
+++ b/mysql-test/r/csv.result
@@ -5364,13 +5364,19 @@ BIN(a)
0
drop table t1;
create table t1(a enum('foo','bar') default null) engine=csv;
-ERROR HY000: Can't create table 'test.t1' (errno: -1)
+ERROR 42000: The storage engine for the table doesn't support nullable columns
create table t1(a enum('foo','bar') default 'foo') engine=csv;
-ERROR HY000: Can't create table 'test.t1' (errno: -1)
+ERROR 42000: The storage engine for the table doesn't support nullable columns
create table t1(a enum('foo','bar') default 'foo' not null) engine=csv;
insert into t1 values();
select * from t1;
a
foo
drop table t1;
+CREATE TABLE t1(a INT) ENGINE=CSV;
+ERROR 42000: The storage engine for the table doesn't support nullable columns
+SHOW WARNINGS;
+Level Code Message
+Error 1178 The storage engine for the table doesn't support nullable columns
+Error 1005 Can't create table 'test.t1' (errno: 138)
End of 5.1 tests
diff --git a/mysql-test/r/ctype_big5.result b/mysql-test/r/ctype_big5.result
index b190273cc64..8103e9b856f 100644
--- a/mysql-test/r/ctype_big5.result
+++ b/mysql-test/r/ctype_big5.result
@@ -64,6 +64,10 @@ select a sounds like a from t1;
a sounds like a
1
1
+select 1 from t1 order by cast(a as char(1));
+1
+1
+1
drop table t1;
DROP DATABASE d1;
USE test;
diff --git a/mysql-test/r/ctype_euckr.result b/mysql-test/r/ctype_euckr.result
index ee786202c01..bb1b3f5995b 100644
--- a/mysql-test/r/ctype_euckr.result
+++ b/mysql-test/r/ctype_euckr.result
@@ -64,6 +64,10 @@ select a sounds like a from t1;
a sounds like a
1
1
+select 1 from t1 order by cast(a as char(1));
+1
+1
+1
drop table t1;
DROP DATABASE d1;
USE test;
diff --git a/mysql-test/r/ctype_gb2312.result b/mysql-test/r/ctype_gb2312.result
index 90c94c3b299..95246525368 100644
--- a/mysql-test/r/ctype_gb2312.result
+++ b/mysql-test/r/ctype_gb2312.result
@@ -64,6 +64,10 @@ select a sounds like a from t1;
a sounds like a
1
1
+select 1 from t1 order by cast(a as char(1));
+1
+1
+1
drop table t1;
DROP DATABASE d1;
USE test;
diff --git a/mysql-test/r/ctype_gbk.result b/mysql-test/r/ctype_gbk.result
index fe90c7bff29..8437e34be1e 100644
--- a/mysql-test/r/ctype_gbk.result
+++ b/mysql-test/r/ctype_gbk.result
@@ -64,6 +64,10 @@ select a sounds like a from t1;
a sounds like a
1
1
+select 1 from t1 order by cast(a as char(1));
+1
+1
+1
drop table t1;
DROP DATABASE d1;
USE test;
diff --git a/mysql-test/r/ctype_uca.result b/mysql-test/r/ctype_uca.result
index 3fff9b9cda8..92b76802d0b 100644
--- a/mysql-test/r/ctype_uca.result
+++ b/mysql-test/r/ctype_uca.result
@@ -2599,6 +2599,10 @@ select a sounds like a from t1;
a sounds like a
1
1
+select 1 from t1 order by cast(a as char(1));
+1
+1
+1
drop table t1;
DROP DATABASE d1;
USE test;
diff --git a/mysql-test/r/delayed.result b/mysql-test/r/delayed.result
index 95f7fe5aa61..bcda6ddb6ab 100644
--- a/mysql-test/r/delayed.result
+++ b/mysql-test/r/delayed.result
@@ -250,6 +250,11 @@ SELECT HEX(a) FROM t1;
HEX(a)
1
DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+INSERT DELAYED INTO t1 SET b= b();
+ERROR 42S22: Unknown column 'b' in 'field list'
+DROP TABLE t1;
+End of 5.0 tests
DROP TABLE IF EXISTS t1,t2;
SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
CREATE TABLE `t1` (
@@ -279,3 +284,4 @@ ERROR 22007: Incorrect date value: '0000-00-00' for column 'f1' at row 1
INSERT DELAYED INTO t2 VALUES (0,'2007-00-00');
ERROR 22007: Incorrect date value: '2007-00-00' for column 'f1' at row 1
DROP TABLE t1,t2;
+End of 5.1 tests
diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result
index ff11905aa34..71d6fcc7cd0 100644
--- a/mysql-test/r/drop.result
+++ b/mysql-test/r/drop.result
@@ -85,3 +85,10 @@ select 1;
1
unlock tables;
End of 5.0 tests
+create database mysql_test;
+create table mysql_test.t1(f1 int);
+create table mysql_test.`#sql-347f_7` (f1 int);
+create table mysql_test.`#sql-347f_8` (f1 int);
+drop table mysql_test.`#sql-347f_8`;
+drop database mysql_test;
+End of 5.1 tests
diff --git a/mysql-test/r/events.result b/mysql-test/r/events.result
index d1ee6d1c5a1..7b68914e219 100644
--- a/mysql-test/r/events.result
+++ b/mysql-test/r/events.result
@@ -403,9 +403,10 @@ ERROR 42S02: Table 'mysql.event' doesn't exist
DROP DATABASE IF EXISTS mysqltest_no_such_database;
Warnings:
Note 1008 Can't drop database 'mysqltest_no_such_database'; database doesn't exist
-Error 1146 Table 'mysql.event' doesn't exist
CREATE DATABASE mysqltest_db2;
DROP DATABASE mysqltest_db2;
+Warnings:
+Error 1146 Table 'mysql.event' doesn't exist
OK, there is an unnecessary warning about the non-existent table
but it's not easy to fix and no one complained about it.
A similar warning is printed if mysql.proc is missing.
diff --git a/mysql-test/r/events_scheduling.result b/mysql-test/r/events_scheduling.result
index d45bffcd7ff..033136ba354 100644
--- a/mysql-test/r/events_scheduling.result
+++ b/mysql-test/r/events_scheduling.result
@@ -78,10 +78,10 @@ FROM INFORMATION_SCHEMA.EVENTS
WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='event_2';
IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR')
OK
-SELECT IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR')
+SELECT IF(LAST_EXECUTED-ENDS <= 0, 'OK', 'ERROR')
FROM INFORMATION_SCHEMA.EVENTS
WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='event_2';
-IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR')
+IF(LAST_EXECUTED-ENDS <= 0, 'OK', 'ERROR')
OK
"Already dropped because ended. Therefore an error."
DROP EVENT event_3;
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index 6f348447fbb..2ce8b8c384f 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -87,3 +87,23 @@ Warnings:
Note 1003 select '1' AS `f1`,'1' AS `f2` from `test`.`t1` having 1
drop view v1;
drop table t1;
+CREATE TABLE t1(c INT);
+INSERT INTO t1 VALUES (),();
+CREATE TABLE t2 (b INT,
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b));
+INSERT INTO t2 VALUES (),(),();
+EXPLAIN SELECT 1 FROM
+(SELECT 1 FROM t2,t1 WHERE b < c GROUP BY 1 LIMIT 1) AS d2;
+id select_type table type possible_keys key key_len ref rows Extra
+X X X X X X X X X const row not found
+X X X X X X X X X
+X X X X X X X X X Range checked for each record (index map: 0xFFFFFFFFFF)
+DROP TABLE t2;
+DROP TABLE t1;
diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result
index 8f1fe20ea3b..00287338459 100644
--- a/mysql-test/r/federated.result
+++ b/mysql-test/r/federated.result
@@ -1955,6 +1955,117 @@ a
2
DROP TABLE federated.t1;
DROP TABLE federated.t1;
+create table t1 (a varchar(256));
+drop view if exists v1;
+create view v1 as select a from t1;
+create table t1
+(a varchar(256)) engine=federated
+connection='mysql://root@127.0.0.1:SLAVE_PORT/test/v1';
+select 1 from t1 order by a;
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+drop table t1;
+drop table t1;
+drop view v1;
End of 5.1 tests
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
index a7119090ec0..745a340ec94 100644
--- a/mysql-test/r/func_misc.result
+++ b/mysql-test/r/func_misc.result
@@ -1,4 +1,4 @@
-DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t1, t2;
select format(1.5555,0),format(123.5555,1),format(1234.5555,2),format(12345.55555,3),format(123456.5555,4),format(1234567.5555,5),format("12345.2399",2);
format(1.5555,0) format(123.5555,1) format(1234.5555,2) format(12345.55555,3) format(123456.5555,4) format(1234567.5555,5) format("12345.2399",2)
2 123.6 1,234.56 12,345.556 123,456.5555 1,234,567.55550 12,345.24
@@ -212,6 +212,18 @@ test
SELECT NAME_CONST('test', 'test');
test
test
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (5), (2);
+SELECT NAME_CONST(x,2) FROM (SELECT a x FROM t1) t;
+ERROR HY000: Incorrect arguments to NAME_CONST
+DROP TABLE t1;
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (), (), ();
+SELECT NAME_CONST(a, '1') FROM t1;
+ERROR HY000: Incorrect arguments to NAME_CONST
+SET INSERT_ID= NAME_CONST(a, a);
+ERROR HY000: Incorrect arguments to NAME_CONST
+DROP TABLE t1;
create table t1 (a int not null);
insert into t1 values (-1), (-2);
select min(a) from t1 group by inet_ntoa(a);
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index a355d7929b5..5e3726a06d6 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -1246,6 +1246,18 @@ select concat(a,ifnull(min(date_format(now(), '%Y-%m-%d')),' ull')) from t1;
ERROR HY000: Illegal mix of collations (ascii_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation 'concat'
set lc_time_names=en_US;
drop table t1;
+select DATE_ADD('20071108181000', INTERVAL 1 DAY);
+DATE_ADD('20071108181000', INTERVAL 1 DAY)
+2007-11-09 18:10:00
+select DATE_ADD(20071108181000, INTERVAL 1 DAY);
+DATE_ADD(20071108181000, INTERVAL 1 DAY)
+2007-11-09 18:10:00
+select DATE_ADD('20071108', INTERVAL 1 DAY);
+DATE_ADD('20071108', INTERVAL 1 DAY)
+2007-11-09
+select DATE_ADD(20071108, INTERVAL 1 DAY);
+DATE_ADD(20071108, INTERVAL 1 DAY)
+2007-11-09
End of 5.0 tests
select date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND);
date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND)
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index 61394409947..73fb9cc69e0 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -680,7 +680,7 @@ def test t1 t1 g g 255 4294967295 0 Y 144 0 63
g
select asbinary(g) from t1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
-def asbinary(g) 252 16777216 0 Y 128 0 63
+def asbinary(g) 252 4294967295 0 Y 128 0 63
asbinary(g)
drop table t1;
create table t1 (a TEXT, b GEOMETRY NOT NULL, SPATIAL KEY(b));
@@ -742,6 +742,38 @@ select geomfromtext(col9,col89) as a from t1;
a
NULL
DROP TABLE t1;
+CREATE TABLE t1 (
+geomdata polygon NOT NULL,
+SPATIAL KEY index_geom (geomdata)
+) ENGINE=MyISAM DEFAULT CHARSET=latin2 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED;
+CREATE TABLE t2 (
+geomdata polygon NOT NULL,
+SPATIAL KEY index_geom (geomdata)
+) ENGINE=MyISAM DEFAULT CHARSET=latin2 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED;
+CREATE TABLE t3
+select
+aswkb(ws.geomdata) AS geomdatawkb
+from
+t1 ws
+union
+select
+aswkb(ws.geomdata) AS geomdatawkb
+from
+t2 ws;
+describe t3;
+Field Type Null Key Default Extra
+geomdatawkb longblob YES NULL
+drop table t1;
+drop table t2;
+drop table t3;
+create table t1(col1 geometry default null,col15 geometrycollection not
+null,spatial index(col15),index(col1(15)))engine=myisam;
+insert into t1 set col15 = GeomFromText('POINT(6 5)');
+insert into t1 set col15 = GeomFromText('POINT(6 5)');
+check table t1 extended;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
End of 4.1 tests
create table t1 (s1 geometry not null,s2 char(100));
create trigger t1_bu before update on t1 for each row set new.s1 = null;
@@ -934,6 +966,12 @@ COUNT(*)
2
DROP TABLE t1, t2;
End of 5.0 tests
+create table `t1` (`col002` point)engine=myisam;
+insert into t1 values (),(),();
+select min(`col002`) from t1 union select `col002` from t1;
+min(`col002`)
+NULL
+drop table t1;
End of 5.0 tests
create table t1 (f1 tinyint(1), f2 char(1), f3 varchar(1), f4 geometry, f5 datetime);
create view v1 as select * from t1;
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index c46f29b787f..0df3ac6de8a 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -1269,9 +1269,7 @@ use test;
FLUSH PRIVILEGES without procs_priv table.
RENAME TABLE mysql.procs_priv TO mysql.procs_gone;
FLUSH PRIVILEGES;
-Warnings:
-Error 1146 Table 'mysql.procs_priv' doesn't exist
-Error 1548 Cannot load from mysql.mysql.procs_priv. The table is probably corrupted
+ERROR 42S02: Table 'mysql.procs_priv' doesn't exist
Assigning privileges without procs_priv table.
CREATE DATABASE mysqltest1;
CREATE PROCEDURE mysqltest1.test() SQL SECURITY DEFINER
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index a3744b36e87..103a7f5515a 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -2326,3 +2326,49 @@ a
2
4
DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3);
+INSERT INTO t1 SELECT a + 1, b FROM t1;
+INSERT INTO t1 SELECT a + 2, b FROM t1;
+EXPLAIN
+SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 12 Using temporary; Using filesort
+SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC;
+a MIN(b) MAX(b)
+4 1 3
+3 1 3
+2 1 3
+1 1 3
+CREATE INDEX break_it ON t1 (a, b);
+EXPLAIN
+SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range NULL break_it 10 NULL 7 Using index for group-by
+SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a;
+a MIN(b) MAX(b)
+1 1 3
+2 1 3
+3 1 3
+4 1 3
+EXPLAIN
+SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range NULL break_it 10 NULL 7 Using index for group-by; Using temporary; Using filesort
+SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC;
+a MIN(b) MAX(b)
+4 1 3
+3 1 3
+2 1 3
+1 1 3
+EXPLAIN
+SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL break_it 10 NULL 12 Using index
+SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC;
+a MIN(b) MAX(b) AVG(b)
+4 1 3 2.0000
+3 1 3 2.0000
+2 1 3 2.0000
+1 1 3 2.0000
+DROP TABLE t1;
diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result
index 9d7d06f7f1b..1827871861e 100644
--- a/mysql-test/r/index_merge_myisam.result
+++ b/mysql-test/r/index_merge_myisam.result
@@ -342,6 +342,8 @@ create table t4 (a int);
insert into t4 values (1),(4),(3);
set @save_join_buffer_size=@@join_buffer_size;
set join_buffer_size= 4000;
+Warnings:
+Warning 1292 Truncated incorrect join_buffer_size value: '4000'
explain select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
from t0 as A force index(i1,i2), t0 as B force index (i1,i2)
where (A.key1 < 500000 or A.key2 < 3)
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index ba6c2cd7854..ddc0e189cd2 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -1615,4 +1615,12 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE tables ALL NULL NULL NULL NULL NULL NULL Skip_open_table; Scanned all databases
Warnings:
Note 1003 select 1 AS `1` from `information_schema`.`tables`
+use information_schema;
+show events;
+Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
+show events from information_schema;
+Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
+show events where Db= 'information_schema';
+Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
+use test;
End of 5.1 tests.
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index c04ec77846a..d0c586de8d4 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1768,6 +1768,8 @@ show variables like "innodb_thread_concurrency";
Variable_name Value
innodb_thread_concurrency 8
set global innodb_thread_concurrency=1001;
+Warnings:
+Warning 1292 Truncated incorrect thread_concurrency value: '1001'
show variables like "innodb_thread_concurrency";
Variable_name Value
innodb_thread_concurrency 1000
@@ -1787,6 +1789,8 @@ show variables like "innodb_concurrency_tickets";
Variable_name Value
innodb_concurrency_tickets 1000
set global innodb_concurrency_tickets=0;
+Warnings:
+Warning 1292 Truncated incorrect concurrency_tickets value: '0'
show variables like "innodb_concurrency_tickets";
Variable_name Value
innodb_concurrency_tickets 1
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index c3896e97165..87cf1acc10c 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -1,3 +1,5 @@
+set global innodb_support_xa=default;
+set session innodb_support_xa=default;
SET SESSION STORAGE_ENGINE = InnoDB;
drop table if exists t1,t2,t3,t1m,t1i,t2m,t2i,t4;
drop procedure if exists p1;
@@ -675,6 +677,8 @@ INSERT INTO t1(b,c) SELECT b,c FROM t2;
UPDATE t2 SET c='2007-01-03';
INSERT INTO t1(b,c) SELECT b,c FROM t2;
set @@sort_buffer_size=8192;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '8192'
SELECT COUNT(*) FROM t1;
COUNT(*)
3072
@@ -1340,6 +1344,18 @@ t1 CREATE TABLE `t1` (
UNIQUE KEY `aa` (`a`(1))
) ENGINE=InnoDB DEFAULT CHARSET=latin1
drop table t1;
+CREATE TABLE t1 (id int, type char(6), d int, INDEX idx(id,d)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2);
+EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL idx NULL NULL NULL 3 Using where; Using filesort
+SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
+id type d
+191 member 1
+NULL member 3
+NULL member 4
+DROP TABLE t1;
End of 5.0 tests
CREATE TABLE `t2` (
`k` int(11) NOT NULL auto_increment,
diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result
index 08d8059f61b..9ada5dc0784 100644
--- a/mysql-test/r/key_cache.result
+++ b/mysql-test/r/key_cache.result
@@ -276,6 +276,8 @@ Variable_name Value
Key_blocks_unused KEY_BLOCKS_UNUSED
set global keycache2.key_buffer_size=0;
set global keycache3.key_buffer_size=100;
+Warnings:
+Warning 1292 Truncated incorrect key_buffer_size value: '100'
set global keycache3.key_buffer_size=0;
create table t1 (mytext text, FULLTEXT (mytext));
insert t1 values ('aaabbb');
diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result
index 4a0f70a7b88..9c4f1b17dcc 100644
--- a/mysql-test/r/lock_multi.result
+++ b/mysql-test/r/lock_multi.result
@@ -113,4 +113,34 @@ handler t1 open;
ERROR HY000: Table storage engine for 't1' doesn't have this option
--> client 1
drop table t1;
+drop table if exists t1;
+create table t1 (i int);
+connection: default
+lock tables t1 write;
+connection: flush
+flush tables with read lock;;
+connection: default
+alter table t1 add column j int;
+connection: insert
+insert into t1 values (1,2);;
+connection: default
+unlock tables;
+connection: flush
+select * from t1;
+i j
+unlock tables;
+select * from t1;
+i j
+1 2
+drop table t1;
+drop table if exists t1;
+create table t1 (i int);
+connection: default
+lock tables t1 write;
+connection: flush
+flush tables with read lock;;
+connection: default
+flush tables;
+unlock tables;
+drop table t1;
End of 5.1 tests
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index ba1680f2cac..a709817b7ef 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -927,6 +927,43 @@ CREATE TABLE t2 (c1 INT) ENGINE=MERGE UNION=(t1) INSERT_METHOD=FIRST;
CREATE TABLE IF NOT EXISTS t1 SELECT * FROM t2;
ERROR HY000: You can't specify target table 't1' for update in FROM clause
DROP TABLE t1, t2;
+CREATE TABLE t1 (id INT NOT NULL, ref INT NOT NULL, INDEX (id)) ENGINE=MyISAM;
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4);
+INSERT INTO t1 SELECT * FROM t2;
+INSERT INTO t1 SELECT * FROM t2;
+CREATE TABLE t3 (id INT NOT NULL, ref INT NOT NULL, INDEX (id)) ENGINE=MERGE
+UNION(t1);
+SELECT * FROM t3 AS a INNER JOIN t3 AS b USING (id) WHERE a.ref < b.ref;
+id ref ref
+4 4 5
+4 4 5
+4 4 5
+4 4 5
+SELECT * FROM t3;
+id ref
+1 3
+2 1
+3 2
+4 5
+4 4
+1 3
+2 1
+3 2
+4 5
+4 4
+DELETE FROM a USING t3 AS a INNER JOIN t3 AS b USING (id) WHERE a.ref < b.ref;
+SELECT * FROM t3;
+id ref
+1 3
+2 1
+3 2
+4 5
+1 3
+2 1
+3 2
+4 5
+DROP TABLE t1, t2, t3;
End of 5.0 tests
create table t1 (c1 int, index(c1));
create table t2 (c1 int, index(c1)) engine=merge union=(t1);
diff --git a/mysql-test/r/merge_innodb.result b/mysql-test/r/merge_innodb.result
new file mode 100644
index 00000000000..f6057d279b1
--- /dev/null
+++ b/mysql-test/r/merge_innodb.result
@@ -0,0 +1,37 @@
+DROP TABLE IF EXISTS t1, t2, t3, t4, t5;
+CREATE TABLE t1 (c1 varchar(100)) ENGINE=MyISAM;
+CREATE TABLE t2 (c1 varchar(100)) ENGINE=MyISAM;
+CREATE TABLE t3 (c1 varchar(100)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('Ann'), ('Alice');
+INSERT INTO t2 VALUES ('Bob'), ('Brian');
+INSERT INTO t3 VALUES ('Chris'), ('Charlie');
+CREATE TABLE t4 (c1 varchar(100)) ENGINE=MRG_MYISAM UNION=(t1,t2)
+INSERT_METHOD=LAST;
+CREATE TABLE t5 (c1 varchar(100)) ENGINE=MRG_MYISAM UNION=(t1,t3)
+INSERT_METHOD=LAST;
+SELECT * FROM t5;
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+SELECT * FROM t4;
+c1
+Ann
+Alice
+Bob
+Brian
+ALTER TABLE t2 ENGINE=InnoDB;
+SELECT * FROM t4;
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+DELETE FROM t2 LIMIT 1;
+SELECT * FROM t4;
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+INSERT INTO t4 VALUES ('Beware');
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+SELECT * FROM t4;
+ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
+SELECT * FROM t2;
+c1
+Brian
+SELECT * FROM t1;
+c1
+Ann
+Alice
+DROP TABLE t1, t2, t3, t4, t5;
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 353d66b1ad5..1c8b5e9d7d9 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -1809,6 +1809,28 @@ CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
+CREATE TABLE t1 (id int NOT NULL, ref int NOT NULL, INDEX (id)) ENGINE=MyISAM;
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4);
+INSERT INTO t1 SELECT * FROM t2;
+SELECT * FROM t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref;
+id ref ref
+4 4 5
+SELECT * FROM t1;
+id ref
+1 3
+2 1
+3 2
+4 5
+4 4
+DELETE FROM a USING t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref;
+SELECT * FROM t1;
+id ref
+1 3
+2 1
+3 2
+4 5
+DROP TABLE t1, t2;
End of 5.0 tests
create table t1 (a int not null, key `a` (a) key_block_size=1024);
show create table t1;
diff --git a/mysql-test/r/no-threads.result b/mysql-test/r/no-threads.result
index aefecd0f7bc..9bc2dad6e2a 100644
--- a/mysql-test/r/no-threads.result
+++ b/mysql-test/r/no-threads.result
@@ -7,3 +7,7 @@ select 1+2;
SHOW GLOBAL VARIABLES LIKE 'thread_handling';
Variable_name Value
thread_handling no-threads
+select @@session.thread_handling;
+ERROR HY000: Variable 'thread_handling' is a GLOBAL variable
+set GLOBAL thread_handling='one-thread';
+ERROR HY000: Variable 'thread_handling' is a read only variable
diff --git a/mysql-test/r/outfile_loaddata.result b/mysql-test/r/outfile_loaddata.result
index 1bcaf308b7c..4a9bdcf412d 100644
--- a/mysql-test/r/outfile_loaddata.result
+++ b/mysql-test/r/outfile_loaddata.result
@@ -82,4 +82,22 @@ c1 c2
-r- =raker=
DROP TABLE t2;
DROP TABLE t1;
+#
+# Bug#32533: SELECT INTO OUTFILE never escapes multibyte character
+#
+CREATE TABLE t1 (c1 VARCHAR(256));
+INSERT INTO t1 VALUES (0xC3);
+SELECT HEX(c1) FROM t1;
+HEX(c1)
+C3
+SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug32533.txt' FIELDS ENCLOSED BY 0xC3 FROM t1;
+TRUNCATE t1;
+SELECT HEX(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug32533.txt'));
+HEX(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug32533.txt'))
+C35CC3C30A
+LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug32533.txt' INTO TABLE t1 FIELDS ENCLOSED BY 0xC3;
+SELECT HEX(c1) FROM t1;
+HEX(c1)
+C3
+DROP TABLE t1;
# End of 5.0 tests.
diff --git a/mysql-test/r/packet.result b/mysql-test/r/packet.result
index dfb5595e02d..df0d9ff9adc 100644
--- a/mysql-test/r/packet.result
+++ b/mysql-test/r/packet.result
@@ -1,7 +1,15 @@
set global max_allowed_packet=100;
+Warnings:
+Warning 1292 Truncated incorrect max_allowed_packet value: '100'
set max_allowed_packet=100;
+Warnings:
+Warning 1292 Truncated incorrect max_allowed_packet value: '100'
set global net_buffer_length=100;
+Warnings:
+Warning 1292 Truncated incorrect net_buffer_length value: '100'
set net_buffer_length=100;
+Warnings:
+Warning 1292 Truncated incorrect net_buffer_length value: '100'
SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len;
len
1024
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index 7c25e948d6c..a361a8f6bcc 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -1297,6 +1297,19 @@ create table t1
partition by key(s1) partitions 3;
insert into t1 values (null,null);
drop table t1;
+create table t1 (
+c0 int,
+c1 bigint,
+c2 set('sweet'),
+key (c2,c1,c0),
+key(c0)
+) engine=myisam partition by hash (month(c0)) partitions 5;
+insert ignore into t1 set c0 = -6502262, c1 = 3992917, c2 = 35019;
+insert ignore into t1 set c0 = 241221, c1 = -6862346, c2 = 56644;
+select c1 from t1 group by (select c0 from t1 limit 1);
+c1
+-6862346
+drop table t1;
CREATE TABLE t1(a int)
PARTITION BY RANGE (a) (
PARTITION p1 VALUES LESS THAN (10),
@@ -1307,4 +1320,101 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
ALTER TABLE t1 ANALYZE PARTITION p1 EXTENDED;
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 'EXTENDED' at line 1
DROP TABLE t1;
+CREATE TABLE t1 (s1 BIGINT UNSIGNED)
+PARTITION BY RANGE (s1) (
+PARTITION p0 VALUES LESS THAN (0),
+PARTITION p1 VALUES LESS THAN (1),
+PARTITION p2 VALUES LESS THAN (18446744073709551615)
+);
+INSERT INTO t1 VALUES (0), (18446744073709551614);
+INSERT INTO t1 VALUES (18446744073709551615);
+ERROR HY000: Table has no partition for value 18446744073709551615
+DROP TABLE t1;
+CREATE TABLE t1 (s1 BIGINT UNSIGNED)
+PARTITION BY RANGE (s1) (
+PARTITION p0 VALUES LESS THAN (0),
+PARTITION p1 VALUES LESS THAN (1),
+PARTITION p2 VALUES LESS THAN (18446744073709551614),
+PARTITION p3 VALUES LESS THAN MAXVALUE
+);
+INSERT INTO t1 VALUES (-1), (0), (18446744073709551613),
+(18446744073709551614), (18446744073709551615);
+Warnings:
+Warning 1264 Out of range value for column 's1' at row 1
+SELECT * FROM t1;
+s1
+0
+0
+18446744073709551613
+18446744073709551614
+18446744073709551615
+SELECT * FROM t1 WHERE s1 = 0;
+s1
+0
+0
+SELECT * FROM t1 WHERE s1 = 18446744073709551614;
+s1
+18446744073709551614
+SELECT * FROM t1 WHERE s1 = 18446744073709551615;
+s1
+18446744073709551615
+DROP TABLE t1;
+CREATE TABLE t1 (s1 BIGINT UNSIGNED)
+PARTITION BY RANGE (s1) (
+PARTITION p0 VALUES LESS THAN (0),
+PARTITION p1 VALUES LESS THAN (1),
+PARTITION p2 VALUES LESS THAN (18446744073709551615),
+PARTITION p3 VALUES LESS THAN MAXVALUE
+);
+DROP TABLE t1;
+CREATE TABLE t1
+(int_column INT, char_column CHAR(5),
+PRIMARY KEY(char_column,int_column))
+PARTITION BY KEY(char_column,int_column)
+PARTITIONS 101;
+INSERT INTO t1 (int_column, char_column) VALUES
+( 39868 ,'zZZRW'),
+( 545592 ,'zZzSD'),
+( 4936 ,'zzzsT'),
+( 9274 ,'ZzZSX'),
+( 970185 ,'ZZzTN'),
+( 786036 ,'zZzTO'),
+( 37240 ,'zZzTv'),
+( 313801 ,'zzzUM'),
+( 782427 ,'ZZZva'),
+( 907955 ,'zZZvP'),
+( 453491 ,'zzZWV'),
+( 756594 ,'ZZZXU'),
+( 718061 ,'ZZzZH');
+SELECT * FROM t1 ORDER BY char_column DESC;
+int_column char_column
+718061 ZZzZH
+756594 ZZZXU
+453491 zzZWV
+907955 zZZvP
+782427 ZZZva
+313801 zzzUM
+37240 zZzTv
+786036 zZzTO
+970185 ZZzTN
+9274 ZzZSX
+4936 zzzsT
+545592 zZzSD
+39868 zZZRW
+DROP TABLE t1;
+CREATE TABLE t1(id MEDIUMINT NOT NULL AUTO_INCREMENT,
+user CHAR(25), PRIMARY KEY(id))
+PARTITION BY RANGE(id)
+SUBPARTITION BY hash(id) subpartitions 2
+(PARTITION pa1 values less than (10),
+PARTITION pa2 values less than (20),
+PARTITION pa11 values less than MAXVALUE);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` mediumint(9) NOT NULL AUTO_INCREMENT,
+ `user` char(25) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM AUTO_INCREMENT=16 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (id) SUBPARTITION BY HASH (id) SUBPARTITIONS 2 (PARTITION pa1 VALUES LESS THAN (10) ENGINE = MyISAM, PARTITION pa2 VALUES LESS THAN (20) ENGINE = MyISAM, PARTITION pa11 VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
+drop table t1;
End of 5.1 tests
diff --git a/mysql-test/r/partition_archive.result b/mysql-test/r/partition_archive.result
index dd063f6224c..5c84b41e81b 100644
--- a/mysql-test/r/partition_archive.result
+++ b/mysql-test/r/partition_archive.result
@@ -1,4 +1,5 @@
drop database if exists db99;
+drop table if exists t1;
create database db99;
use db99;
create table t1 (a int not null)
@@ -11,3 +12,80 @@ alter table t1 add partition (partition p2 values in (3));
alter table t1 drop partition p2;
use test;
drop database db99;
+create table t1 (f1 integer) engine= ARCHIVE partition by list(f1)
+(
+partition p1 values in (1),
+partition p2 values in (NULL),
+partition p3 values in (2),
+partition p4 values in (3),
+partition p5 values in (4)
+);
+insert into t1 values (1),(2),(3),(4),(null);
+select * from t1;
+f1
+1
+NULL
+2
+3
+4
+select * from t1 where f1 < 3;
+f1
+1
+2
+drop table t1;
+CREATE TABLE t1 (
+a int not null,
+b int not null,
+c int not null) engine=ARCHIVE
+partition by hash (a + 2)
+partitions 3
+(partition x1 tablespace ts1,
+partition x2 tablespace ts2,
+partition x3 tablespace ts3);
+insert into t1 values (1,1,1);
+insert into t1 values (2,1,1);
+insert into t1 values (3,1,1);
+insert into t1 values (4,1,1);
+insert into t1 values (5,1,1);
+select * from t1;
+a b c
+1 1 1
+4 1 1
+2 1 1
+5 1 1
+3 1 1
+drop table t1;
+create table t1 (a int) engine=archive partition by hash(a);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (a) */
+drop table t1;
+CREATE TABLE t1(id MEDIUMINT NOT NULL AUTO_INCREMENT,
+f1 VARCHAR(25),
+PRIMARY KEY(id)) ENGINE=ARCHIVE
+PARTITION BY RANGE(id)
+SUBPARTITION BY hash(id) subpartitions 2
+(PARTITION pa1 values less than (10),
+PARTITION pa2 values less than (20),
+PARTITION pa3 values less than (30),
+PARTITION pa4 values less than (40),
+PARTITION pa5 values less than (50),
+PARTITION pa6 values less than (60),
+PARTITION pa7 values less than (70),
+PARTITION pa8 values less than (80),
+PARTITION pa9 values less than (90),
+PARTITION pa10 values less than (100),
+PARTITION pa11 values less than MAXVALUE);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` mediumint(9) NOT NULL AUTO_INCREMENT,
+ `f1` varchar(25) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=ARCHIVE AUTO_INCREMENT=101 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (id) SUBPARTITION BY HASH (id) SUBPARTITIONS 2 (PARTITION pa1 VALUES LESS THAN (10) ENGINE = ARCHIVE, PARTITION pa2 VALUES LESS THAN (20) ENGINE = ARCHIVE, PARTITION pa3 VALUES LESS THAN (30) ENGINE = ARCHIVE, PARTITION pa4 VALUES LESS THAN (40) ENGINE = ARCHIVE, PARTITION pa5 VALUES LESS THAN (50) ENGINE = ARCHIVE, PARTITION pa6 VALUES LESS THAN (60) ENGINE = ARCHIVE, PARTITION pa7 VALUES LESS THAN (70) ENGINE = ARCHIVE, PARTITION pa8 VALUES LESS THAN (80) ENGINE = ARCHIVE, PARTITION pa9 VALUES LESS THAN (90) ENGINE = ARCHIVE, PARTITION pa10 VALUES LESS THAN (100) ENGINE = ARCHIVE, PARTITION pa11 VALUES LESS THAN MAXVALUE ENGINE = ARCHIVE) */
+select count(*) from t1;
+count(*)
+100
+drop table t1;
diff --git a/mysql-test/r/partition_hash.result b/mysql-test/r/partition_hash.result
index 72f036be099..94fefe77a77 100644
--- a/mysql-test/r/partition_hash.result
+++ b/mysql-test/r/partition_hash.result
@@ -1,4 +1,16 @@
drop table if exists t1;
+CREATE TABLE t1 (c1 INT)
+PARTITION BY HASH (c1)
+PARTITIONS 15;
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
+ALTER TABLE t1 COALESCE PARTITION 13;
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT)
+PARTITION BY LINEAR HASH (c1)
+PARTITIONS 5;
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
+ALTER TABLE t1 COALESCE PARTITION 3;
+DROP TABLE t1;
create table t1 (a int unsigned)
partition by hash(a div 2)
partitions 4;
diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result
index f80e0001ea8..5cbe34c94ca 100644
--- a/mysql-test/r/partition_innodb.result
+++ b/mysql-test/r/partition_innodb.result
@@ -1,3 +1,15 @@
+# Bug#32948
+CREATE TABLE t1 (c1 INT, PRIMARY KEY (c1)) ENGINE=INNODB;
+CREATE TABLE t2 (c1 INT, PRIMARY KEY (c1),
+FOREIGN KEY (c1) REFERENCES t1 (c1)
+ON DELETE CASCADE)
+ENGINE=INNODB;
+ALTER TABLE t1 PARTITION BY HASH(c1) PARTITIONS 5;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+ALTER TABLE t1 ENGINE=MyISAM;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+DROP TABLE t2;
+DROP TABLE t1;
create table t1 (a int) engine=innodb partition by hash(a) ;
show table status like 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
diff --git a/mysql-test/r/partition_range.result b/mysql-test/r/partition_range.result
index a61006e87a4..4da79704ec3 100644
--- a/mysql-test/r/partition_range.result
+++ b/mysql-test/r/partition_range.result
@@ -1,4 +1,4 @@
-drop table if exists t1;
+drop table if exists t1, t2;
create table t1 (a int unsigned)
partition by range (a)
(partition pnull values less than (0),
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index ae68f8a4c5e..a6b07bfc127 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -807,6 +807,8 @@ select @@max_prepared_stmt_count;
@@max_prepared_stmt_count
0
set global max_prepared_stmt_count=10000000000000000;
+Warnings:
+Warning 1292 Truncated incorrect max_prepared_stmt_count value: '10000000000000000'
select @@max_prepared_stmt_count;
@@max_prepared_stmt_count
1048576
diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result
index eb8ef7a85c3..fbc6781e5e7 100644
--- a/mysql-test/r/ps_2myisam.result
+++ b/mysql-test/r/ps_2myisam.result
@@ -783,20 +783,20 @@ a b
2 two
3 three
4 four
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result
index 15650efa41d..fcd0b5de9a0 100644
--- a/mysql-test/r/ps_3innodb.result
+++ b/mysql-test/r/ps_3innodb.result
@@ -783,20 +783,20 @@ a b
2 two
3 three
4 four
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result
index 486f770220e..862c0ff75c1 100644
--- a/mysql-test/r/ps_4heap.result
+++ b/mysql-test/r/ps_4heap.result
@@ -784,20 +784,20 @@ a b
2 two
3 three
4 four
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result
index 0229b0ece08..51393cc8bc3 100644
--- a/mysql-test/r/ps_5merge.result
+++ b/mysql-test/r/ps_5merge.result
@@ -826,20 +826,20 @@ a b
2 two
3 three
4 four
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
@@ -3848,20 +3848,20 @@ a b
2 two
3 three
4 four
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
diff --git a/mysql-test/r/ps_ddl.result b/mysql-test/r/ps_ddl.result
new file mode 100644
index 00000000000..0987e765265
--- /dev/null
+++ b/mysql-test/r/ps_ddl.result
@@ -0,0 +1,2329 @@
+=====================================================================
+Testing 1: NOTHING -> TABLE transitions
+=====================================================================
+drop table if exists t1;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+prepare stmt from 'select * from t1';
+ERROR 42S02: Table 'test.t1' doesn't exist
+=====================================================================
+Testing 2: NOTHING -> TEMPORARY TABLE transitions
+=====================================================================
+=====================================================================
+Testing 3: NOTHING -> VIEW transitions
+=====================================================================
+=====================================================================
+Testing 4: TABLE -> NOTHING transitions
+=====================================================================
+drop table if exists t4;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t4(a int);
+prepare stmt from 'select * from t4';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t4;
+execute stmt;
+ERROR 42S02: Table 'test.t4' doesn't exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+ERROR 42S02: Table 'test.t4' doesn't exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+=====================================================================
+Testing 5: TABLE -> TABLE (DDL) transitions
+=====================================================================
+drop table if exists t5;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t5(a int);
+prepare stmt from 'select * from t5';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+alter table t5 add column (b int);
+execute stmt;
+a b
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt;
+a b
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+drop table t5;
+=====================================================================
+Testing 6: TABLE -> TABLE (TRIGGER) transitions
+=====================================================================
+drop table if exists t6;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t6(a int);
+prepare stmt from 'insert into t6(a) value (?)';
+set @val=1;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+set @val=2;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+create trigger t6_bi before insert on t6 for each row
+begin
+set @message= "t6_bi";
+end
+$$
+set @message="none";
+set @val=3;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+select @message;
+@message
+t6_bi
+set @val=4;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+select @message;
+@message
+t6_bi
+prepare stmt from 'insert into t6(a) value (?)';
+set @message="none";
+set @val=5;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+select @message;
+@message
+t6_bi
+set @message="none";
+set @val=6;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+select @message;
+@message
+t6_bi
+create trigger t6_bd before delete on t6 for each row
+begin
+set @message= "t6_bd";
+end
+$$
+set @message="none";
+set @val=7;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+select @message;
+@message
+t6_bi
+set @message="none";
+set @val=8;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+select @message;
+@message
+t6_bi
+prepare stmt from 'insert into t6(a) value (?)';
+set @message="none";
+set @val=9;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+select @message;
+@message
+t6_bi
+set @message="none";
+set @val=10;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+select @message;
+@message
+t6_bi
+drop trigger t6_bi;
+create trigger t6_bi before insert on t6 for each row
+begin
+set @message= "t6_bi (2)";
+end
+$$
+set @message="none";
+set @val=11;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+select @message;
+@message
+t6_bi (2)
+set @val=12;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+select @message;
+@message
+t6_bi (2)
+prepare stmt from 'insert into t6(a) value (?)';
+set @message="none";
+set @val=13;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+select @message;
+@message
+t6_bi (2)
+set @message="none";
+set @val=14;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+select @message;
+@message
+t6_bi (2)
+drop trigger t6_bd;
+create trigger t6_bd before delete on t6 for each row
+begin
+set @message= "t6_bd (2)";
+end
+$$
+set @message="none";
+set @val=15;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+select @message;
+@message
+t6_bi (2)
+set @message="none";
+set @val=16;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+select @message;
+@message
+t6_bi (2)
+prepare stmt from 'insert into t6(a) value (?)';
+set @message="none";
+set @val=17;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+select @message;
+@message
+t6_bi (2)
+set @message="none";
+set @val=18;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+select @message;
+@message
+t6_bi (2)
+drop trigger t6_bi;
+set @message="none";
+set @val=19;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+select @message;
+@message
+none
+set @val=20;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+select @message;
+@message
+none
+prepare stmt from 'insert into t6(a) value (?)';
+set @message="none";
+set @val=21;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+select @message;
+@message
+none
+set @val=22;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+select @message;
+@message
+none
+drop trigger t6_bd;
+set @val=23;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+select @message;
+@message
+none
+set @val=24;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+select @message;
+@message
+none
+select * from t6 order by a;
+a
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+drop table t6;
+=====================================================================
+Testing 7: TABLE -> TABLE (TRIGGER dependencies) transitions
+=====================================================================
+drop table if exists t7_proc;
+drop table if exists t7_func;
+drop table if exists t7_view;
+drop table if exists t7_table;
+drop table if exists t7_dependent_table;
+drop table if exists t7_table_trigger;
+drop table if exists t7_audit;
+drop procedure if exists audit_proc;
+drop function if exists audit_func;
+drop view if exists audit_view;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t7_proc(a int);
+create table t7_func(a int);
+create table t7_view(a int);
+create table t7_table(a int);
+create table t7_table_trigger(a int);
+create table t7_audit(old_a int, new_a int, reason varchar(50));
+create table t7_dependent_table(old_a int, new_a int, reason varchar(50));
+create procedure audit_proc(a int)
+insert into t7_audit values (NULL, a, "proc v1");
+create function audit_func() returns varchar(50)
+return "func v1";
+create view audit_view as select "view v1" as reason from dual;
+create trigger t7_proc_bi before insert on t7_proc for each row
+call audit_proc(NEW.a);
+create trigger t7_func_bi before insert on t7_func for each row
+insert into t7_audit values (NULL, NEW.a, audit_func());
+create trigger t7_view_bi before insert on t7_view for each row
+insert into t7_audit values (NULL, NEW.a, (select reason from audit_view));
+create trigger t7_table_bi before insert on t7_table for each row
+insert into t7_dependent_table values (NULL, NEW.a, "dependent table");
+create trigger t7_table_trigger_bi before insert on t7_dependent_table
+for each row set NEW.reason="trigger v1";
+prepare stmt_proc from 'insert into t7_proc(a) value (?)';
+set @val=101;
+execute stmt_proc using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+set @val=102;
+execute stmt_proc using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop procedure audit_proc;
+create procedure audit_proc(a int)
+insert into t7_audit values (NULL, a, "proc v2");
+set @val=103;
+execute stmt_proc using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+set @val=104;
+execute stmt_proc using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+prepare stmt_func from 'insert into t7_func(a) value (?)';
+set @val=201;
+execute stmt_func using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+set @val=202;
+execute stmt_func using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop function audit_func;
+create function audit_func() returns varchar(50)
+return "func v2";
+set @val=203;
+execute stmt_func using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+set @val=204;
+execute stmt_func using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+prepare stmt_view from 'insert into t7_view(a) value (?)';
+set @val=301;
+execute stmt_view using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+set @val=302;
+execute stmt_view using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop view audit_view;
+create view audit_view as select "view v2" as reason from dual;
+set @val=303;
+execute stmt_view using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+set @val=304;
+execute stmt_view using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+prepare stmt_table from 'insert into t7_table(a) value (?)';
+set @val=401;
+execute stmt_table using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+set @val=402;
+execute stmt_table using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+alter table t7_dependent_table add column comments varchar(100) default NULL;
+set @val=403;
+execute stmt_table using @val;
+ERROR 21S01: Column count doesn't match value count at row 1
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+set @val=404;
+execute stmt_table using @val;
+ERROR 21S01: Column count doesn't match value count at row 1
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+alter table t7_dependent_table drop column comments;
+set @val=405;
+execute stmt_table using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+3
+set @val=406;
+execute stmt_table using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+3
+prepare stmt_table_trigger from 'insert into t7_table(a) value (?)';
+set @val=501;
+execute stmt_table_trigger using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+3
+set @val=502;
+execute stmt_table_trigger using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+3
+drop trigger t7_table_trigger_bi;
+create trigger t7_table_trigger_bi before insert on t7_dependent_table
+for each row set NEW.reason="trigger v2";
+set @val=503;
+execute stmt_table_trigger using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+4
+set @val=504;
+execute stmt_table_trigger using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+4
+select * from t7_audit order by new_a;
+old_a new_a reason
+NULL 101 proc v1
+NULL 102 proc v1
+NULL 103 proc v2
+NULL 104 proc v2
+NULL 201 func v1
+NULL 202 func v1
+NULL 203 func v2
+NULL 204 func v2
+NULL 301 view v1
+NULL 302 view v1
+NULL 303 view v1
+NULL 304 view v1
+select * from t7_dependent_table order by new_a;
+old_a new_a reason
+NULL 401 trigger v1
+NULL 402 trigger v1
+NULL 405 trigger v1
+NULL 406 trigger v1
+NULL 501 trigger v1
+NULL 502 trigger v1
+NULL 503 trigger v2
+NULL 504 trigger v2
+drop table t7_proc;
+drop table t7_func;
+drop table t7_view;
+drop table t7_table;
+drop table t7_dependent_table;
+drop table t7_table_trigger;
+drop table t7_audit;
+drop procedure audit_proc;
+drop function audit_func;
+drop view audit_view;
+=====================================================================
+Testing 8: TABLE -> TEMPORARY TABLE transitions
+=====================================================================
+drop table if exists t8;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t8(a int);
+prepare stmt from 'select * from t8';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t8;
+create temporary table t8(a int);
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+drop table t8;
+=====================================================================
+Testing 9: TABLE -> VIEW transitions
+=====================================================================
+drop table if exists t9;
+drop table if exists t9_b;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t9(a int);
+create table t9_b(a int);
+prepare stmt from 'select * from t9';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t9;
+create view t9 as select * from t9_b;
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+drop view t9;
+drop table t9_b;
+=====================================================================
+Testing 10: TEMPORARY TABLE -> NOTHING transitions
+=====================================================================
+drop temporary table if exists t10;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create temporary table t10(a int);
+prepare stmt from 'select * from t10';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop temporary table t10;
+execute stmt;
+ERROR 42S02: Table 'test.t10' doesn't exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+ERROR 42S02: Table 'test.t10' doesn't exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+=====================================================================
+Testing 11: TEMPORARY TABLE -> TABLE transitions
+=====================================================================
+drop table if exists t11;
+drop temporary table if exists t11;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t11(a int);
+insert into t11(a) value (1);
+create temporary table t11(a int);
+prepare stmt from 'select * from t11';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop temporary table t11;
+execute stmt;
+a
+1
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt;
+a
+1
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+select * from t11;
+a
+1
+drop table t11;
+=====================================================================
+Testing 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL) transitions
+=====================================================================
+drop temporary table if exists t12;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create temporary table t12(a int);
+prepare stmt from 'select * from t12';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop temporary table t12;
+create temporary table t12(a int, b int);
+execute stmt;
+a b
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt;
+a b
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+select * from t12;
+a b
+drop table t12;
+=====================================================================
+Testing 13: TEMPORARY TABLE -> VIEW transitions
+=====================================================================
+drop temporary table if exists t13;
+drop table if exists t13_b;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create temporary table t13(a int);
+create table t13_b(a int);
+prepare stmt from 'select * from t13';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop temporary table t13;
+create view t13 as select * from t13_b;
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+drop view t13;
+drop table t13_b;
+=====================================================================
+Testing 14: VIEW -> NOTHING transitions
+=====================================================================
+drop view if exists t14;
+drop table if exists t14_b;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t14_b(a int);
+create view t14 as select * from t14_b;
+prepare stmt from 'select * from t14';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop view t14;
+execute stmt;
+ERROR 42S02: Table 'test.t14' doesn't exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt;
+ERROR 42S02: Table 'test.t14' doesn't exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+drop table t14_b;
+=====================================================================
+Testing 15: VIEW -> TABLE transitions
+=====================================================================
+drop view if exists t15;
+drop table if exists t15_b;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t15_b(a int);
+create view t15 as select * from t15_b;
+prepare stmt from 'select * from t15';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop view t15;
+create table t15(a int);
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+drop table t15_b;
+drop table t15;
+=====================================================================
+Testing 16: VIEW -> TEMPORARY TABLE transitions
+=====================================================================
+drop view if exists t16;
+drop table if exists t16_b;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t16_b(a int);
+create view t16 as select * from t16_b;
+prepare stmt from 'select * from t16';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop view t16;
+create temporary table t16(a int);
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+drop table t16_b;
+drop temporary table t16;
+=====================================================================
+Testing 17: VIEW -> VIEW (DDL) transitions
+=====================================================================
+drop view if exists t17;
+drop table if exists t17_b;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t17_b(a int);
+insert into t17_b values (10), (20), (30);
+create view t17 as select a, 2*a as b, 3*a as c from t17_b;
+select * from t17;
+a b c
+10 20 30
+20 40 60
+30 60 90
+prepare stmt from 'select * from t17';
+execute stmt;
+a b c
+10 20 30
+20 40 60
+30 60 90
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a b c
+10 20 30
+20 40 60
+30 60 90
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop view t17;
+create view t17 as select a, 2*a as b, 10*a as c from t17_b;
+select * from t17;
+a b c
+10 20 100
+20 40 200
+30 60 300
+execute stmt;
+a b c
+10 20 100
+20 40 200
+30 60 300
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt;
+a b c
+10 20 100
+20 40 200
+30 60 300
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+drop table t17_b;
+drop view t17;
+=====================================================================
+Testing 18: VIEW -> VIEW (VIEW dependencies) transitions
+=====================================================================
+drop table if exists t18;
+drop table if exists t18_dependent_table;
+drop view if exists t18_func;
+drop view if exists t18_view;
+drop view if exists t18_table;
+drop function if exists view_func;
+drop view if exists view_view;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t18(a int);
+insert into t18 values (1), (2), (3);
+create function view_func(x int) returns int
+return x+1;
+create view view_view as select "view v1" as reason from dual;
+create table t18_dependent_table(a int);
+create view t18_func as select a, view_func(a) as b from t18;
+create view t18_view as select a, reason as b from t18, view_view;
+create view t18_table as select * from t18;
+prepare stmt_func from 'select * from t18_func';
+execute stmt_func;
+a b
+1 2
+2 3
+3 4
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt_func;
+a b
+1 2
+2 3
+3 4
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop function view_func;
+create function view_func(x int) returns int
+return x*x;
+execute stmt_func;
+a b
+1 1
+2 4
+3 9
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt_func;
+a b
+1 1
+2 4
+3 9
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+prepare stmt_view from 'select * from t18_view';
+execute stmt_view;
+a b
+1 view v1
+2 view v1
+3 view v1
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt_view;
+a b
+1 view v1
+2 view v1
+3 view v1
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop view view_view;
+create view view_view as select "view v2" as reason from dual;
+execute stmt_view;
+a b
+1 view v2
+2 view v2
+3 view v2
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt_view;
+a b
+1 view v2
+2 view v2
+3 view v2
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+prepare stmt_table from 'select * from t18_table';
+execute stmt_table;
+a
+1
+2
+3
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt_table;
+a
+1
+2
+3
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+alter table t18 add column comments varchar(50) default NULL;
+execute stmt_table;
+a
+1
+2
+3
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+execute stmt_table;
+a
+1
+2
+3
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+drop table t18;
+drop table t18_dependent_table;
+drop view t18_func;
+drop view t18_view;
+drop view t18_table;
+drop function view_func;
+drop view view_view;
+=====================================================================
+Testing 19: Special tables (INFORMATION_SCHEMA)
+=====================================================================
+drop procedure if exists proc_19;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+prepare stmt from
+'select ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE
+ from INFORMATION_SCHEMA.ROUTINES where
+ routine_name=\'proc_19\'';
+create procedure proc_19() select "hi there";
+execute stmt;
+ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE
+test proc_19 PROCEDURE
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE
+test proc_19 PROCEDURE
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop procedure proc_19;
+create procedure proc_19() select "hi there, again";
+execute stmt;
+ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE
+test proc_19 PROCEDURE
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE
+test proc_19 PROCEDURE
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop procedure proc_19;
+=====================================================================
+Testing 20: Special tables (log tables)
+=====================================================================
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+prepare stmt from
+'select * from mysql.general_log where argument=\'IMPOSSIBLE QUERY STRING\'';
+execute stmt;
+event_time user_host thread_id server_id command_type argument
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+event_time user_host thread_id server_id command_type argument
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+event_time user_host thread_id server_id command_type argument
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+event_time user_host thread_id server_id command_type argument
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+=====================================================================
+Testing 21: Special tables (system tables)
+=====================================================================
+drop procedure if exists proc_21;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+prepare stmt from
+'select type, db, name from mysql.proc where name=\'proc_21\'';
+create procedure proc_21() select "hi there";
+execute stmt;
+type db name
+PROCEDURE test proc_21
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+type db name
+PROCEDURE test proc_21
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop procedure proc_21;
+create procedure proc_21() select "hi there, again";
+execute stmt;
+type db name
+PROCEDURE test proc_21
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+type db name
+PROCEDURE test proc_21
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop procedure proc_21;
+=====================================================================
+Testing 22: Special tables (views temp tables)
+=====================================================================
+drop table if exists t22_b;
+drop view if exists t22;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t22_b(a int);
+create algorithm=temptable view t22 as select a*a as a2 from t22_b;
+show create view t22;
+View Create View character_set_client collation_connection
+t22 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `t22` AS select (`t22_b`.`a` * `t22_b`.`a`) AS `a2` from `t22_b` latin1 latin1_swedish_ci
+prepare stmt from 'select * from t22';
+insert into t22_b values (1), (2), (3);
+execute stmt;
+a2
+1
+4
+9
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a2
+1
+4
+9
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+insert into t22_b values (4), (5), (6);
+execute stmt;
+a2
+1
+4
+9
+16
+25
+36
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a2
+1
+4
+9
+16
+25
+36
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t22_b;
+drop view t22;
+=====================================================================
+Testing 23: Special tables (internal join tables)
+=====================================================================
+drop table if exists t23_a;
+drop table if exists t23_b;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t23_a(a int);
+create table t23_b(b int);
+prepare stmt from 'select * from t23_a join t23_b';
+insert into t23_a values (1), (2), (3);
+insert into t23_b values (10), (20), (30);
+execute stmt;
+a b
+1 10
+2 10
+3 10
+1 20
+2 20
+3 20
+1 30
+2 30
+3 30
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a b
+1 10
+2 10
+3 10
+1 20
+2 20
+3 20
+1 30
+2 30
+3 30
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+insert into t23_a values (4);
+insert into t23_b values (40);
+execute stmt;
+a b
+1 10
+2 10
+3 10
+4 10
+1 20
+2 20
+3 20
+4 20
+1 30
+2 30
+3 30
+4 30
+1 40
+2 40
+3 40
+4 40
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a b
+1 10
+2 10
+3 10
+4 10
+1 20
+2 20
+3 20
+4 20
+1 30
+2 30
+3 30
+4 30
+1 40
+2 40
+3 40
+4 40
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t23_a;
+drop table t23_b;
+=====================================================================
+Testing 24: Special statements
+=====================================================================
+drop table if exists t24_alter;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t24_alter(a int);
+prepare stmt from 'alter table t24_alter add column b int';
+execute stmt;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t24_alter;
+create table t24_alter(a1 int, a2 int);
+execute stmt;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+alter table t24_alter drop column b;
+execute stmt;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+alter table t24_alter drop column b;
+execute stmt;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t24_alter;
+drop table if exists t24_repair;
+create table t24_repair(a int);
+insert into t24_repair values (1), (2), (3);
+prepare stmt from 'repair table t24_repair';
+execute stmt;
+Table Op Msg_type Msg_text
+test.t24_repair repair status OK
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t24_repair;
+create table t24_repair(a1 int, a2 int);
+insert into t24_repair values (1, 10), (2, 20), (3, 30);
+execute stmt;
+Table Op Msg_type Msg_text
+test.t24_repair repair status OK
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+alter table t24_repair add column b varchar(50) default NULL;
+execute stmt;
+Table Op Msg_type Msg_text
+test.t24_repair repair status OK
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+alter table t24_repair drop column b;
+execute stmt;
+Table Op Msg_type Msg_text
+test.t24_repair repair status OK
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t24_repair;
+drop table if exists t24_analyze;
+create table t24_analyze(a int);
+insert into t24_analyze values (1), (2), (3);
+prepare stmt from 'analyze table t24_analyze';
+execute stmt;
+Table Op Msg_type Msg_text
+test.t24_analyze analyze status OK
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t24_analyze;
+create table t24_analyze(a1 int, a2 int);
+insert into t24_analyze values (1, 10), (2, 20), (3, 30);
+execute stmt;
+Table Op Msg_type Msg_text
+test.t24_analyze analyze status OK
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+alter table t24_analyze add column b varchar(50) default NULL;
+execute stmt;
+Table Op Msg_type Msg_text
+test.t24_analyze analyze status OK
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+alter table t24_analyze drop column b;
+execute stmt;
+Table Op Msg_type Msg_text
+test.t24_analyze analyze status OK
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t24_analyze;
+drop table if exists t24_optimize;
+create table t24_optimize(a int);
+insert into t24_optimize values (1), (2), (3);
+prepare stmt from 'optimize table t24_optimize';
+execute stmt;
+Table Op Msg_type Msg_text
+test.t24_optimize optimize status OK
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t24_optimize;
+create table t24_optimize(a1 int, a2 int);
+insert into t24_optimize values (1, 10), (2, 20), (3, 30);
+execute stmt;
+Table Op Msg_type Msg_text
+test.t24_optimize optimize status OK
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+alter table t24_optimize add column b varchar(50) default NULL;
+execute stmt;
+Table Op Msg_type Msg_text
+test.t24_optimize optimize status OK
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+alter table t24_optimize drop column b;
+execute stmt;
+Table Op Msg_type Msg_text
+test.t24_optimize optimize status OK
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t24_optimize;
+drop procedure if exists changing_proc;
+prepare stmt from 'show create procedure changing_proc';
+execute stmt;
+ERROR 42000: PROCEDURE changing_proc does not exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+ERROR 42000: PROCEDURE changing_proc does not exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+create procedure changing_proc() begin end;
+execute stmt;
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+changing_proc CREATE DEFINER=`root`@`localhost` PROCEDURE `changing_proc`()
+begin end latin1 latin1_swedish_ci latin1_swedish_ci
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+changing_proc CREATE DEFINER=`root`@`localhost` PROCEDURE `changing_proc`()
+begin end latin1 latin1_swedish_ci latin1_swedish_ci
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop procedure changing_proc;
+create procedure changing_proc(x int, y int) begin end;
+execute stmt;
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+changing_proc CREATE DEFINER=`root`@`localhost` PROCEDURE `changing_proc`(x int, y int)
+begin end latin1 latin1_swedish_ci latin1_swedish_ci
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+changing_proc CREATE DEFINER=`root`@`localhost` PROCEDURE `changing_proc`(x int, y int)
+begin end latin1 latin1_swedish_ci latin1_swedish_ci
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop procedure changing_proc;
+execute stmt;
+ERROR 42000: PROCEDURE changing_proc does not exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+ERROR 42000: PROCEDURE changing_proc does not exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop function if exists changing_func;
+prepare stmt from 'show create function changing_func';
+execute stmt;
+ERROR 42000: FUNCTION changing_func does not exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+ERROR 42000: FUNCTION changing_func does not exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+create function changing_func() returns int return 0;
+execute stmt;
+Function sql_mode Create Function character_set_client collation_connection Database Collation
+changing_func CREATE DEFINER=`root`@`localhost` FUNCTION `changing_func`() RETURNS int(11)
+return 0 latin1 latin1_swedish_ci latin1_swedish_ci
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+Function sql_mode Create Function character_set_client collation_connection Database Collation
+changing_func CREATE DEFINER=`root`@`localhost` FUNCTION `changing_func`() RETURNS int(11)
+return 0 latin1 latin1_swedish_ci latin1_swedish_ci
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop function changing_func;
+create function changing_func(x int, y int) returns int return x+y;
+execute stmt;
+Function sql_mode Create Function character_set_client collation_connection Database Collation
+changing_func CREATE DEFINER=`root`@`localhost` FUNCTION `changing_func`(x int, y int) RETURNS int(11)
+return x+y latin1 latin1_swedish_ci latin1_swedish_ci
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+Function sql_mode Create Function character_set_client collation_connection Database Collation
+changing_func CREATE DEFINER=`root`@`localhost` FUNCTION `changing_func`(x int, y int) RETURNS int(11)
+return x+y latin1 latin1_swedish_ci latin1_swedish_ci
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop function changing_func;
+execute stmt;
+ERROR 42000: FUNCTION changing_func does not exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+ERROR 42000: FUNCTION changing_func does not exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table if exists t24_trigger;
+create table t24_trigger(a int);
+prepare stmt from 'show create trigger t24_bi;';
+execute stmt;
+ERROR HY000: Trigger does not exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+ERROR HY000: Trigger does not exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+create trigger t24_bi before insert on t24_trigger for each row
+begin
+set @message= "t24_bi";
+end
+$$
+execute stmt;
+Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation
+t24_bi CREATE DEFINER=`root`@`localhost` trigger t24_bi before insert on t24_trigger for each row
+begin
+set @message= "t24_bi";
+end latin1 latin1_swedish_ci latin1_swedish_ci
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation
+t24_bi CREATE DEFINER=`root`@`localhost` trigger t24_bi before insert on t24_trigger for each row
+begin
+set @message= "t24_bi";
+end latin1 latin1_swedish_ci latin1_swedish_ci
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop trigger t24_bi;
+create trigger t24_bi before insert on t24_trigger for each row
+begin
+set @message= "t24_bi (2)";
+end
+$$
+execute stmt;
+Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation
+t24_bi CREATE DEFINER=`root`@`localhost` trigger t24_bi before insert on t24_trigger for each row
+begin
+set @message= "t24_bi (2)";
+end latin1 latin1_swedish_ci latin1_swedish_ci
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation
+t24_bi CREATE DEFINER=`root`@`localhost` trigger t24_bi before insert on t24_trigger for each row
+begin
+set @message= "t24_bi (2)";
+end latin1 latin1_swedish_ci latin1_swedish_ci
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop trigger t24_bi;
+execute stmt;
+ERROR HY000: Trigger does not exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+ERROR HY000: Trigger does not exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t24_trigger;
+=====================================================================
+Testing 25: Testing the strength of TABLE_SHARE version
+=====================================================================
+drop table if exists t25_num_col;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t25_num_col(a int);
+prepare stmt from 'select * from t25_num_col';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+alter table t25_num_col add column b varchar(50) default NULL;
+execute stmt;
+a b
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt;
+a b
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+drop table t25_num_col;
+drop table if exists t25_col_name;
+create table t25_col_name(a int);
+prepare stmt from 'select * from t25_col_name';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+alter table t25_col_name change a b int;
+execute stmt;
+b
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+execute stmt;
+b
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+drop table t25_col_name;
+drop table if exists t25_col_type;
+create table t25_col_type(a int);
+prepare stmt from 'select * from t25_col_type';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+alter table t25_col_type change a a varchar(10);
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+3
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+3
+drop table t25_col_type;
+drop table if exists t25_col_type_length;
+create table t25_col_type_length(a varchar(10));
+prepare stmt from 'select * from t25_col_type_length';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+3
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+3
+alter table t25_col_type_length change a a varchar(20);
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+4
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+4
+drop table t25_col_type_length;
+drop table if exists t25_col_null;
+create table t25_col_null(a varchar(10));
+prepare stmt from 'select * from t25_col_null';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+4
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+4
+alter table t25_col_null change a a varchar(10) NOT NULL;
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+5
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+5
+drop table t25_col_null;
+drop table if exists t25_col_default;
+create table t25_col_default(a int, b int DEFAULT 10);
+prepare stmt from 'insert into t25_col_default(a) values (?)';
+set @val=1;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+5
+set @val=2;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+5
+alter table t25_col_default change b b int DEFAULT 20;
+set @val=3;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+5
+set @val=4;
+execute stmt using @val;
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+5
+select * from t25_col_default;
+a b
+1 10
+2 10
+3 20
+4 20
+drop table t25_col_default;
+drop table if exists t25_index;
+create table t25_index(a varchar(10));
+prepare stmt from 'select * from t25_index';
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+5
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+5
+create index i1 on t25_index(a);
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+6
+execute stmt;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+6
+drop table t25_index;
+drop table if exists t25_index_unique;
+create table t25_index_unique(a varchar(10), b varchar(10));
+create index i1 on t25_index_unique(a, b);
+show create table t25_index_unique;
+Table Create Table
+t25_index_unique CREATE TABLE `t25_index_unique` (
+ `a` varchar(10) DEFAULT NULL,
+ `b` varchar(10) DEFAULT NULL,
+ KEY `i1` (`a`,`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+prepare stmt from 'select * from t25_index_unique';
+execute stmt;
+a b
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+6
+execute stmt;
+a b
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+6
+alter table t25_index_unique drop index i1;
+create unique index i1 on t25_index_unique(a, b);
+show create table t25_index_unique;
+Table Create Table
+t25_index_unique CREATE TABLE `t25_index_unique` (
+ `a` varchar(10) DEFAULT NULL,
+ `b` varchar(10) DEFAULT NULL,
+ UNIQUE KEY `i1` (`a`,`b`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+execute stmt;
+a b
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+7
+execute stmt;
+a b
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+7
+drop table t25_index_unique;
+=====================================================================
+Testing reported bugs
+=====================================================================
+drop table if exists table_12093;
+drop function if exists func_12093;
+drop function if exists func_12093_unrelated;
+drop procedure if exists proc_12093;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table table_12093(a int);
+create function func_12093()
+returns int
+begin
+return (select count(*) from table_12093);
+end//
+create procedure proc_12093(a int)
+begin
+select * from table_12093;
+end//
+create function func_12093_unrelated() returns int return 2;
+create procedure proc_12093_unrelated() begin end;
+prepare stmt_sf from 'select func_12093();';
+prepare stmt_sp from 'call proc_12093(func_12093())';
+execute stmt_sf;
+func_12093()
+0
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt_sp;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop function func_12093_unrelated;
+drop procedure proc_12093_unrelated;
+execute stmt_sf;
+func_12093()
+0
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt_sp;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt_sf;
+func_12093()
+0
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt_sp;
+a
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+deallocate prepare stmt_sf;
+deallocate prepare stmt_sp;
+drop table table_12093;
+drop function func_12093;
+drop procedure proc_12093;
+drop function if exists func_21294;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create function func_21294() returns int return 10;
+prepare stmt from "select func_21294()";
+execute stmt;
+func_21294()
+10
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop function func_21294;
+create function func_21294() returns int return 10;
+execute stmt;
+func_21294()
+10
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop function func_21294;
+create function func_21294() returns int return 20;
+execute stmt;
+func_21294()
+20
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+deallocate prepare stmt;
+drop function func_21294;
+drop table if exists t_27420_100;
+drop table if exists t_27420_101;
+drop view if exists v_27420;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t_27420_100(a int);
+insert into t_27420_100 values (1), (2);
+create table t_27420_101(a int);
+insert into t_27420_101 values (1), (2);
+create view v_27420 as select t_27420_100.a X, t_27420_101.a Y
+from t_27420_100, t_27420_101
+where t_27420_100.a=t_27420_101.a;
+prepare stmt from 'select * from v_27420';
+execute stmt;
+X Y
+1 1
+2 2
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop view v_27420;
+create table v_27420(X int, Y int);
+execute stmt;
+X Y
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+drop table v_27420;
+create table v_27420 (a int, b int, filler char(200));
+execute stmt;
+a b filler
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+2
+deallocate prepare stmt;
+drop table t_27420_100;
+drop table t_27420_101;
+drop table v_27420;
+drop table if exists t_27430_1;
+drop table if exists t_27430_2;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t_27430_1 (a int not null, oref int not null, key(a));
+insert into t_27430_1 values
+(1, 1),
+(1, 1234),
+(2, 3),
+(2, 1234),
+(3, 1234);
+create table t_27430_2 (a int not null, oref int not null);
+insert into t_27430_2 values
+(1, 1),
+(2, 2),
+(1234, 3),
+(1234, 4);
+prepare stmt from
+'select oref, a, a in (select a from t_27430_1 where oref=t_27430_2.oref) Z from t_27430_2';
+execute stmt;
+oref a Z
+1 1 1
+2 2 0
+3 1234 0
+4 1234 0
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+oref a Z
+1 1 1
+2 2 0
+3 1234 0
+4 1234 0
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table t_27430_1, t_27430_2;
+create table t_27430_1 (a int, oref int, key(a));
+insert into t_27430_1 values
+(1, 1),
+(1, NULL),
+(2, 3),
+(2, NULL),
+(3, NULL);
+create table t_27430_2 (a int, oref int);
+insert into t_27430_2 values
+(1, 1),
+(2,2),
+(NULL, 3),
+(NULL, 4);
+execute stmt;
+oref a Z
+1 1 1
+2 2 0
+3 NULL NULL
+4 NULL 0
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt;
+oref a Z
+1 1 1
+2 2 0
+3 NULL NULL
+4 NULL 0
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+deallocate prepare stmt;
+drop table t_27430_1;
+drop table t_27430_2;
+drop table if exists t_27690_1;
+drop view if exists v_27690_1;
+drop table if exists v_27690_2;
+SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+create table t_27690_1 (a int, b int);
+insert into t_27690_1 values (1,1),(2,2);
+create table v_27690_1 as select * from t_27690_1;
+create table v_27690_2 as select * from t_27690_1;
+prepare stmt from 'select * from v_27690_1, v_27690_2';
+execute stmt;
+a b a b
+1 1 1 1
+2 2 1 1
+1 1 2 2
+2 2 2 2
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+a b a b
+1 1 1 1
+2 2 1 1
+1 1 2 2
+2 2 2 2
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+drop table v_27690_1;
+execute stmt;
+ERROR 42S02: Table 'test.v_27690_1' doesn't exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+execute stmt;
+ERROR 42S02: Table 'test.v_27690_1' doesn't exist
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+0
+create view v_27690_1 as select A.a, A.b from t_27690_1 A, t_27690_1 B;
+execute stmt;
+a b a b
+1 1 1 1
+2 2 1 1
+1 1 1 1
+2 2 1 1
+1 1 2 2
+2 2 2 2
+1 1 2 2
+2 2 2 2
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+execute stmt;
+a b a b
+1 1 1 1
+2 2 1 1
+1 1 1 1
+2 2 1 1
+1 1 2 2
+2 2 2 2
+1 1 2 2
+2 2 2 2
+SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+REPREPARED
+1
+deallocate prepare stmt;
+drop table t_27690_1;
+drop view v_27690_1;
+drop table v_27690_2;
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 108264b3bf2..92db6d8429f 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1135,6 +1135,24 @@ item started price
A1 2005-11-01 08:00:00 1000.000
A1 2005-11-15 00:00:00 2000.000
DROP TABLE t1;
+
+BUG#32198 "Comparison of DATE with DATETIME still not using indexes correctly"
+
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+dateval date default NULL,
+PRIMARY KEY (id),
+KEY dateval (dateval)
+) AUTO_INCREMENT=173;
+INSERT INTO t1 VALUES
+(1,'2007-01-01'),(2,'2007-01-02'),(3,'2007-01-03'),(4,'2007-01-04'),
+(5,'2007-01-05'),(6,'2007-01-06'),(7,'2007-01-07'),(8,'2007-01-08'),
+(9,'2007-01-09'),(10,'2007-01-10'),(11,'2007-01-11');
+This must use range access:
+explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '2007-01-02 23:59:59';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range dateval dateval 4 NULL 2 Using where
+drop table t1;
create table t1 (a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2 (a int, b int, filler char(100));
diff --git a/mysql-test/r/read_only.result b/mysql-test/r/read_only.result
index f270f1ed5ad..cf81566f4e5 100644
--- a/mysql-test/r/read_only.result
+++ b/mysql-test/r/read_only.result
@@ -97,3 +97,31 @@ Note 1051 Unknown table 'ttt'
set global read_only=0;
drop table t1,t2;
drop user test@localhost;
+#
+# Bug #27440 read_only allows create and drop database
+#
+set global read_only= 1;
+drop database if exists mysqltest_db1;
+drop database if exists mysqltest_db2;
+delete from mysql.user where User like 'mysqltest_%';
+delete from mysql.db where User like 'mysqltest_%';
+delete from mysql.tables_priv where User like 'mysqltest_%';
+delete from mysql.columns_priv where User like 'mysqltest_%';
+flush privileges;
+grant all on mysqltest_db2.* to `mysqltest_u1`@`%`;
+create database mysqltest_db1;
+grant all on mysqltest_db1.* to `mysqltest_u1`@`%`;
+flush privileges;
+create database mysqltest_db2;
+ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
+show databases like '%mysqltest_db2%';
+Database (%mysqltest_db2%)
+drop database mysqltest_db1;
+ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
+delete from mysql.user where User like 'mysqltest_%';
+delete from mysql.db where User like 'mysqltest_%';
+delete from mysql.tables_priv where User like 'mysqltest_%';
+delete from mysql.columns_priv where User like 'mysqltest_%';
+flush privileges;
+drop database mysqltest_db1;
+set global read_only=0;
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 719d0926022..2f305f6ec5d 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -4307,6 +4307,12 @@ c3
DROP TABLE t1;
DROP TABLE t2;
+CREATE TABLE t1 (c1 BIGINT NOT NULL);
+INSERT INTO t1 (c1) VALUES (1);
+SELECT * FROM t1 WHERE c1 > NULL + 1;
+c1
+DROP TABLE t1;
+
End of 5.0 tests
create table t1(a INT, KEY (a));
INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result
index c95b09597fc..fc78f4ad40f 100644
--- a/mysql-test/r/status.result
+++ b/mysql-test/r/status.result
@@ -162,3 +162,24 @@ Variable_name Value
Com_show_status 8
rnd_diff tmp_table_diff
20 8
+show global status like 'Com%function%';
+Variable_name Value
+Com_alter_function 0
+Com_create_function 0
+Com_drop_function 0
+Com_show_function_code 0
+Com_show_function_status 0
+create function f1 (x INTEGER) returns integer
+begin
+declare ret integer;
+set ret = x * 10;
+return ret;
+end //
+drop function f1;
+show global status like 'Com%function%';
+Variable_name Value
+Com_alter_function 0
+Com_create_function 1
+Com_drop_function 1
+Com_show_function_code 0
+Com_show_function_status 0
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 25df7a56aa3..d1173fed7f4 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -77,10 +77,9 @@ ERROR HY000: Incorrect usage of PROCEDURE and subquery
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
ERROR HY000: Incorrect parameters to procedure 'ANALYSE'
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
-a
+ERROR 42S22: Unknown column 'a' in 'field list'
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
-a
-1
+ERROR 42S22: Unknown column 'a' in 'field list'
SELECT (SELECT 1,2,3) = ROW(1,2,3);
(SELECT 1,2,3) = ROW(1,2,3)
1
@@ -1307,7 +1306,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using where
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY where (`test`.`t1`.`b` <> 30))))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`)))))
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
a
2
@@ -1315,8 +1314,8 @@ a
explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
-2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where
-2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 func 1 100.00
+2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 Using index
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select 1 AS `Not_used` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))
drop table t1, t2, t3;
@@ -1334,9 +1333,9 @@ a
explain extended select * from t2 where t2.a in (select a from t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
-2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index
+2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index; Using where
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a)))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a where (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
2
@@ -1346,7 +1345,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index; Using where
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a where (`test`.`t1`.`b` <> 30))))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`)))))
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
a
2
@@ -1373,7 +1372,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index; Using where
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a where (`test`.`t1`.`b` <> 30))))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`)))))
drop table t1, t2, t3;
create table t1 (a int, b int);
create table t2 (a int, b int);
@@ -1737,7 +1736,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 12 100.00 Using where
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where
Warnings:
-Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not(<in_optimizer>(`test`.`t1`.`id`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`id`) in t1 on PRIMARY where (`test`.`t1`.`id` < 8))))))
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not(<in_optimizer>(`test`.`t1`.`id`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`id`) in t1 on PRIMARY where ((`test`.`t1`.`id` < 8) and (<cache>(`test`.`t1`.`id`) = `test`.`t1`.`id`)))))))
explain extended select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY tt ALL NULL NULL NULL NULL 12 100.00 Using where
@@ -2304,24 +2303,27 @@ drop table t1,t2;
CREATE TABLE t1 ( a int, b int );
CREATE TABLE t2 ( c int, d int );
INSERT INTO t1 VALUES (1,2), (2,3), (3,4);
-SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);
+SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
abc b
1 2
2 3
3 4
-INSERT INTO t2 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);
+INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
select * from t2;
c d
1 2
2 3
3 4
-CREATE TABLE t3 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);
+CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
select * from t3;
abc b
1 2
2 3
3 4
-prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);";
+prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
execute stmt1;
deallocate prepare stmt1;
select * from t2;
@@ -2333,7 +2335,7 @@ c d
2 3
3 4
drop table t3;
-prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);";
+prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
execute stmt1;
select * from t3;
abc b
@@ -2515,7 +2517,9 @@ INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,680
INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
/*!40000 ALTER TABLE t1 ENABLE KEYS */;
-SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
+SELECT DISTINCT Continent AS c FROM t1 outr WHERE
+Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND
+Population < 200);
c
Oceania
drop table t1;
@@ -3558,22 +3562,19 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
(SELECT i FROM t1) UNION
(SELECT i FROM t1)
);
-i
+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 'UNION
+(SELECT i FROM t1)
+)' at line 3
SELECT * FROM t1
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
-i
+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 'UNION (SELECT i FROM t1)))' at line 2
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
from t1;
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 'union (select t12.i from t1 t12))
from t1' at line 1
explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
-3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
-4 UNION t12 system NULL NULL NULL NULL 0 const row not found
-NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL
+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 'union (select t12.i from t1 t12))' at line 2
DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b));
insert into t1 (a) values (FLOOR(rand() * 100));
@@ -3666,6 +3667,8 @@ CREATE TABLE t1 (a int, b int auto_increment, PRIMARY KEY (b));
CREATE TABLE t2 (x int auto_increment, y int, z int,
PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
SET SESSION sort_buffer_size = 32 * 1024;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '32768'
SELECT SQL_NO_CACHE COUNT(*)
FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
FROM t1) t;
@@ -4101,6 +4104,8 @@ 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;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '8192'
SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2;
d1
1
@@ -4199,6 +4204,84 @@ LEFT(t1.a1,1)
SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
a2
DROP TABLE t1, t2, t3;
+CREATE TABLE t1 (a CHAR(1), b VARCHAR(10));
+INSERT INTO t1 VALUES ('a', 'aa');
+INSERT INTO t1 VALUES ('a', 'aaa');
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+a b
+CREATE INDEX I1 ON t1 (a);
+CREATE INDEX I2 ON t1 (b);
+EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 2 Using index; Using where
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+a b
+CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10));
+INSERT INTO t2 SELECT * FROM t1;
+CREATE INDEX I1 ON t2 (a);
+CREATE INDEX I2 ON t2 (b);
+EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 index_subquery I1 I1 4 func 2 Using index; Using where
+SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
+a b
+EXPLAIN
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 2 Using index; Using where
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
+a b
+DROP TABLE t1,t2;
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4);
+EXPLAIN
+SELECT a AS out_a, MIN(b) FROM t1
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
+GROUP BY a;
+ERROR 42S22: Unknown column 'out_a' in 'where clause'
+SELECT a AS out_a, MIN(b) FROM t1
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
+GROUP BY a;
+ERROR 42S22: Unknown column 'out_a' in 'where clause'
+EXPLAIN
+SELECT a AS out_a, MIN(b) FROM t1 t1_outer
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
+GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1_outer ALL NULL NULL NULL NULL 4 Using where; Using temporary; Using filesort
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 4 Using where
+SELECT a AS out_a, MIN(b) FROM t1 t1_outer
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
+GROUP BY a;
+out_a MIN(b)
+1 2
+2 4
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+INSERT INTO t2 VALUES (1),(2);
+SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
+2
+2
+2
+EXPLAIN EXTENDED
+SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select 2 AS `2` from `test`.`t1` where exists(select 1 AS `1` from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`))
+EXPLAIN EXTENDED
+SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
+(SELECT 1 FROM t2 WHERE t1.a = t2.a));
+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 'UNION
+(SELECT 1 FROM t2 WHERE t1.a = t2.a))' at line 2
+DROP TABLE t1,t2;
End of 5.0 tests.
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result
index 2f3ea31a2a4..ac492caf89a 100644
--- a/mysql-test/r/subselect3.result
+++ b/mysql-test/r/subselect3.result
@@ -757,6 +757,6 @@ a
EXPLAIN SELECT a FROM t1 WHERE a NOT IN (SELECT a FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
-2 DEPENDENT SUBQUERY t2 unique_subquery PRIMARY PRIMARY 4 func 1 Using index
+2 DEPENDENT SUBQUERY t2 unique_subquery PRIMARY PRIMARY 4 func 1 Using index; Using where
DROP TABLE t1;
End of 5.0 tests
diff --git a/mysql-test/r/subselect_notembedded.result b/mysql-test/r/subselect_notembedded.result
index 44ae055425e..90aadcae398 100644
--- a/mysql-test/r/subselect_notembedded.result
+++ b/mysql-test/r/subselect_notembedded.result
@@ -1,3 +1,104 @@
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);
+create table t1(a int,b int,key(a),key(b));
+insert into t1(a,b) values (1,2),(2,1),(2,3),(3,4),(5,4),(5,5),
+(6,7),(7,4),(5,3);
+select sum(a),a from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1
+)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1)
+group by a;
+sum(a) a
+select sum(a),a from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1)
+group by a;
+ERROR HY000: Thread stack overrun detected
+explain select sum(a),a from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1
+)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1)
+group by a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index a a 5 NULL 9 Using where; Using index
+2 SUBQUERY t1 index a b 5 NULL 9 Using where; Using filesort
+3 SUBQUERY t1 index a b 5 NULL 9 Using where; Using filesort
+4 SUBQUERY t1 index a b 5 NULL 9 Using where; Using filesort
+5 SUBQUERY t1 index a b 5 NULL 9 Using where; Using filesort
+6 SUBQUERY t1 index a b 5 NULL 9 Using where; Using filesort
+7 SUBQUERY t1 index a b 5 NULL 9 Using where; Using filesort
+8 SUBQUERY t1 index a b 5 NULL 9 Using where; Using filesort
+9 SUBQUERY t1 index a b 5 NULL 9 Using where; Using filesort
+10 SUBQUERY t1 index a b 5 NULL 9 Using where; Using filesort
+11 SUBQUERY t1 index a b 5 NULL 9 Using where; Using filesort
+12 SUBQUERY t1 range a a 5 NULL 1 Using where; Using temporary; Using filesort
+13 SUBQUERY t1 index NULL a 5 NULL 9 Using index
+explain select sum(a),a from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+select sum(a) from t1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1
+)group by b limit 1)group by b limit 1)group by b limit 1)
+group by a;
+ERROR HY000: Thread stack overrun detected
+drop table t1;
diff --git a/mysql-test/r/trigger_notembedded.result b/mysql-test/r/trigger_notembedded.result
index d56f83993a6..87e8f68da38 100644
--- a/mysql-test/r/trigger_notembedded.result
+++ b/mysql-test/r/trigger_notembedded.result
@@ -448,4 +448,18 @@ DROP TABLE t1;
DROP DATABASE mysqltest_db1;
USE test;
End of 5.0 tests.
+drop table if exists t1;
+create table t1 (i int);
+connection: default
+lock tables t1 write;
+connection: flush
+flush tables with read lock;;
+connection: default
+create trigger t1_bi before insert on t1 for each row begin end;
+unlock tables;
+connection: flush
+unlock tables;
+select * from t1;
+i
+drop table t1;
End of 5.1 tests.
diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result
index dc8ab079ad8..fee0df9ab02 100644
--- a/mysql-test/r/type_bit.result
+++ b/mysql-test/r/type_bit.result
@@ -269,6 +269,8 @@ a+0 b+0
56 379
68 454
set @@max_length_for_sort_data=0;
+Warnings:
+Warning 1292 Truncated incorrect max_length_for_sort_data value: '0'
select a+0, b+0 from t1 where a > 40 and a < 70 order by 2;
a+0 b+0
57 135
@@ -672,6 +674,16 @@ COUNT(DISTINCT b,c)
2
2
DROP TABLE t2;
+CREATE TABLE t1(a BIT(13), KEY(a));
+INSERT INTO t1(a) VALUES
+(65535),(65525),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535);
+EXPLAIN SELECT 1 FROM t1 GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range NULL a 3 NULL 6 Using index for group-by
+SELECT 1 FROM t1 GROUP BY a;
+1
+1
+DROP TABLE t1;
End of 5.0 tests
create table t1(a bit(7));
insert into t1 values(0x40);
diff --git a/mysql-test/r/type_bit_innodb.result b/mysql-test/r/type_bit_innodb.result
index 97331408b40..a9c3cae1770 100644
--- a/mysql-test/r/type_bit_innodb.result
+++ b/mysql-test/r/type_bit_innodb.result
@@ -269,6 +269,8 @@ a+0 b+0
56 379
68 454
set @@max_length_for_sort_data=0;
+Warnings:
+Warning 1292 Truncated incorrect max_length_for_sort_data value: '0'
select a+0, b+0 from t1 where a > 40 and a < 70 order by 2;
a+0 b+0
57 135
diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result
index 869efb535e6..c98c8c5b68c 100644
--- a/mysql-test/r/type_blob.result
+++ b/mysql-test/r/type_blob.result
@@ -807,4 +807,18 @@ set @@sql_mode='TRADITIONAL';
create table t1 (a text default '');
ERROR 42000: BLOB/TEXT column 'a' can't have a default value
set @@sql_mode='';
+CREATE TABLE t (c TEXT CHARSET ASCII);
+INSERT INTO t (c) VALUES (REPEAT('1',65537));
+Warnings:
+Warning 1265 Data truncated for column 'c' at row 1
+INSERT INTO t (c) VALUES (REPEAT('2',65536));
+Warnings:
+Warning 1265 Data truncated for column 'c' at row 1
+INSERT INTO t (c) VALUES (REPEAT('3',65535));
+SELECT LENGTH(c), CHAR_LENGTH(c) FROM t;
+LENGTH(c) CHAR_LENGTH(c)
+65535 65535
+65535 65535
+65535 65535
+DROP TABLE t;
End of 5.0 tests
diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result
index 392260edb55..5921991bf50 100644
--- a/mysql-test/r/type_date.result
+++ b/mysql-test/r/type_date.result
@@ -211,7 +211,6 @@ a
Warnings:
Warning 1292 Incorrect date value: '0000-00-00' for column 'a' at row 1
Warning 1292 Incorrect date value: '0000-00-00' for column 'a' at row 1
-Warning 1292 Incorrect date value: '0000-00-00' for column 'a' at row 1
SELECT * FROM t2 WHERE a = '0000-00-00';
a
0000-00-00
@@ -223,6 +222,44 @@ INSERT INTO t1 VALUES ('0000-00-00');
ERROR 22007: Incorrect date value: '0000-00-00' for column 'a' at row 1
SET SQL_MODE=DEFAULT;
DROP TABLE t1,t2;
+CREATE TABLE t1 (a DATE);
+CREATE TABLE t2 (a DATE);
+CREATE INDEX i ON t1 (a);
+INSERT INTO t1 VALUES ('1000-00-00'),('1000-00-00');
+INSERT INTO t2 VALUES ('1000-00-00'),('1000-00-00');
+SELECT * FROM t1 WHERE a = '1000-00-00';
+a
+1000-00-00
+1000-00-00
+SELECT * FROM t2 WHERE a = '1000-00-00';
+a
+1000-00-00
+1000-00-00
+SET SQL_MODE=TRADITIONAL;
+EXPLAIN SELECT * FROM t1 WHERE a = '1000-00-00';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref i i 4 const 1 Using where; Using index
+Warnings:
+Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1
+Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1
+SELECT * FROM t1 WHERE a = '1000-00-00';
+a
+1000-00-00
+1000-00-00
+Warnings:
+Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1
+Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1
+SELECT * FROM t2 WHERE a = '1000-00-00';
+a
+1000-00-00
+1000-00-00
+Warnings:
+Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1
+Warning 1292 Incorrect date value: '1000-00-00' for column 'a' at row 1
+INSERT INTO t1 VALUES ('1000-00-00');
+ERROR 22007: Incorrect date value: '1000-00-00' for column 'a' at row 1
+SET SQL_MODE=DEFAULT;
+DROP TABLE t1,t2;
End of 5.0 tests
create table t1 (a date, primary key (a))engine=memory;
insert into t1 values ('0000-01-01'), ('0000-00-01'), ('0001-01-01');
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index c15deb8b1e5..d485c468a39 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -505,6 +505,61 @@ select sum(a) from t1 group by convert(a, datetime);
sum(a)
NULL
drop table t1;
+create table t1 (id int(10) not null, cur_date datetime not null);
+create table t2 (id int(10) not null, cur_date date not null);
+insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22');
+insert into t2 (id, cur_date) values (1, '2007-04-25');
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+Warnings:
+Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select '1' AS `id`,'2007-04-25 18:30:22' AS `cur_date` from `test`.`t1` where <in_optimizer>('1',<exists>(select 1 AS `Not_used` from `test`.`t1` `x1` where 0))
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id cur_date
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+Warnings:
+Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select '1' AS `id`,'2007-04-25' AS `cur_date` from `test`.`t2` where <in_optimizer>('1',<exists>(select 1 AS `Not_used` from `test`.`t2` `x1` where 0))
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id cur_date
+insert into t1 (id, cur_date) values (2, '2007-04-26 18:30:22');
+insert into t2 (id, cur_date) values (2, '2007-04-26');
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY x1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`cur_date` AS `cur_date` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`id`,<exists>(select 1 AS `Not_used` from `test`.`t1` `x1` where ((`test`.`t1`.`cur_date` = 0) and (<cache>(`test`.`t1`.`id`) = `test`.`x1`.`id`))))
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id cur_date
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY x1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t2`.`id` AS `id`,`test`.`t2`.`cur_date` AS `cur_date` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`id`,<exists>(select 1 AS `Not_used` from `test`.`t2` `x1` where ((`test`.`t2`.`cur_date` = 0) and (<cache>(`test`.`t2`.`id`) = `test`.`x1`.`id`))))
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id cur_date
+drop table t1,t2;
End of 5.0 tests
set @org_mode=@@sql_mode;
create table t1 (da date default '1962-03-03 23:33:34', dt datetime default '1962-03-03');
diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result
index cb5afcf5f17..15410ac2039 100644
--- a/mysql-test/r/udf.result
+++ b/mysql-test/r/udf.result
@@ -365,4 +365,31 @@ DROP FUNCTION check_const_len;
DROP PROCEDURE check_const_len_sp;
DROP TRIGGER check_const_len_trigger;
DROP TABLE const_len_bug;
+CREATE FUNCTION sequence RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT PRIMARY KEY);
+INSERT INTO t1 VALUES (4),(3),(2),(1);
+INSERT INTO t2 SELECT * FROM t1;
+SELECT sequence() AS seq, a FROM t1 ORDER BY seq ASC;
+seq a
+1 4
+2 3
+3 2
+4 1
+SELECT sequence() AS seq, a FROM t1 ORDER BY seq DESC;
+seq a
+4 1
+3 2
+2 3
+1 4
+SELECT * FROM t1 WHERE a = sequence();
+a
+SELECT * FROM t2 WHERE a = sequence();
+a
+1
+2
+3
+4
+DROP FUNCTION sequence;
+DROP TABLE t1,t2;
End of 5.0 tests.
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index 431134b03c7..2cd132ce03c 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -353,6 +353,13 @@ select @a:=f4, count(f4) from t1 group by 1 desc;
2.6 1
1.6 4
drop table t1;
+create table t1 (f1 int);
+insert into t1 values (2), (1);
+select @i := f1 as j from t1 order by 1;
+j
+1
+2
+drop table t1;
create table t1(a int);
insert into t1 values(5),(4),(4),(3),(2),(2),(2),(1);
set @rownum := 0;
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index bdaec70021b..658a3ffa7a1 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -220,7 +220,7 @@ select * from information_schema.global_variables where variable_name like 'myis
VARIABLE_NAME VARIABLE_VALUE
MYISAM_MAX_SORT_FILE_SIZE 1048576
set GLOBAL myisam_max_sort_file_size=default;
-show variables like 'myisam_max_sort_file_size';
+show global variables like 'myisam_max_sort_file_size';
Variable_name Value
myisam_max_sort_file_size FILE_SIZE
select * from information_schema.session_variables where variable_name like 'myisam_max_sort_file_size';
@@ -279,6 +279,8 @@ NET_READ_TIMEOUT 600
NET_RETRY_COUNT 10
NET_WRITE_TIMEOUT 500
set net_buffer_length=1;
+Warnings:
+Warning 1292 Truncated incorrect net_buffer_length value: '1'
show variables like 'net_buffer_length';
Variable_name Value
net_buffer_length 1024
@@ -312,14 +314,14 @@ show variables like '%alloc%';
Variable_name Value
query_alloc_block_size 8192
query_prealloc_size 8192
-range_alloc_block_size 2048
+range_alloc_block_size 4096
transaction_alloc_block_size 8192
transaction_prealloc_size 4096
select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
QUERY_ALLOC_BLOCK_SIZE 8192
QUERY_PREALLOC_SIZE 8192
-RANGE_ALLOC_BLOCK_SIZE 2048
+RANGE_ALLOC_BLOCK_SIZE 4096
TRANSACTION_ALLOC_BLOCK_SIZE 8192
TRANSACTION_PREALLOC_SIZE 4096
set @@range_alloc_block_size=1024*16;
@@ -351,14 +353,14 @@ show variables like '%alloc%';
Variable_name Value
query_alloc_block_size 8192
query_prealloc_size 8192
-range_alloc_block_size 2048
+range_alloc_block_size 4096
transaction_alloc_block_size 8192
transaction_prealloc_size 4096
select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
QUERY_ALLOC_BLOCK_SIZE 8192
QUERY_PREALLOC_SIZE 8192
-RANGE_ALLOC_BLOCK_SIZE 2048
+RANGE_ALLOC_BLOCK_SIZE 4096
TRANSACTION_ALLOC_BLOCK_SIZE 8192
TRANSACTION_PREALLOC_SIZE 4096
SELECT @@version LIKE 'non-existent';
@@ -416,6 +418,8 @@ select @@autocommit, @@big_tables;
@@autocommit @@big_tables
1 1
set global binlog_cache_size=100;
+Warnings:
+Warning 1292 Truncated incorrect binlog_cache_size value: '100'
set bulk_insert_buffer_size=100;
set character set cp1251_koi8;
set character set default;
@@ -444,6 +448,8 @@ set global flush_time=100;
set insert_id=1;
set interactive_timeout=100;
set join_buffer_size=100;
+Warnings:
+Warning 1292 Truncated incorrect join_buffer_size value: '100'
set last_insert_id=1;
set global local_infile=1;
set long_query_time=0.000001;
@@ -456,12 +462,20 @@ select @@long_query_time;
100.000001
set low_priority_updates=1;
set max_allowed_packet=100;
+Warnings:
+Warning 1292 Truncated incorrect max_allowed_packet value: '100'
set global max_binlog_cache_size=100;
+Warnings:
+Warning 1292 Truncated incorrect max_binlog_cache_size value: '100'
set global max_binlog_size=100;
+Warnings:
+Warning 1292 Truncated incorrect max_binlog_size value: '100'
set global max_connect_errors=100;
set global max_connections=100;
set global max_delayed_threads=100;
set max_heap_table_size=100;
+Warnings:
+Warning 1292 Truncated incorrect max_heap_table_size value: '100'
set max_join_size=100;
set max_sort_length=100;
set max_tmp_tables=100;
@@ -472,17 +486,25 @@ select @@max_user_connections;
set global max_write_lock_count=100;
set myisam_sort_buffer_size=100;
set net_buffer_length=100;
+Warnings:
+Warning 1292 Truncated incorrect net_buffer_length value: '100'
set net_read_timeout=100;
set net_write_timeout=100;
set global query_cache_limit=100;
set global query_cache_size=100;
set global query_cache_type=demand;
set read_buffer_size=100;
+Warnings:
+Warning 1292 Truncated incorrect read_buffer_size value: '100'
set read_rnd_buffer_size=100;
+Warnings:
+Warning 1292 Truncated incorrect read_rnd_buffer_size value: '100'
set global rpl_recovery_rank=100;
set global server_id=100;
set global slow_launch_time=100;
set sort_buffer_size=100;
+Warnings:
+Warning 1292 Truncated incorrect sort_buffer_size value: '100'
set @@max_sp_recursion_depth=10;
select @@max_sp_recursion_depth;
@@max_sp_recursion_depth
@@ -522,6 +544,8 @@ set storage_engine=myisam;
set global thread_cache_size=100;
set timestamp=1, timestamp=default;
set tmp_table_size=100;
+Warnings:
+Warning 1292 Truncated incorrect tmp_table_size value: '100'
set tx_isolation="READ-COMMITTED";
set wait_timeout=100;
set log_warnings=1;
@@ -691,6 +715,8 @@ SELECT * FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME LIKE 'MYI
VARIABLE_NAME VARIABLE_VALUE
MYISAM_DATA_POINTER_SIZE 7
SET GLOBAL table_open_cache=-1;
+Warnings:
+Warning 1292 Truncated incorrect table_open_cache value: '0'
SHOW VARIABLES LIKE 'table_open_cache';
Variable_name Value
table_open_cache 1
diff --git a/mysql-test/r/windows.result b/mysql-test/r/windows.result
index c97d3dd8867..e58a891838a 100644
--- a/mysql-test/r/windows.result
+++ b/mysql-test/r/windows.result
@@ -19,6 +19,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
End of 5.0 tests.
+drop procedure if exists proc_1;
create procedure proc_1() install plugin my_plug soname '\\root\\some_plugin.dll';
call proc_1();
ERROR HY000: No paths allowed for shared library
diff --git a/mysql-test/suite/binlog/r/binlog_row_ctype_cp932.result b/mysql-test/suite/binlog/r/binlog_row_ctype_cp932.result
index ef9f76b7d9c..655100203b5 100644
--- a/mysql-test/suite/binlog/r/binlog_row_ctype_cp932.result
+++ b/mysql-test/suite/binlog/r/binlog_row_ctype_cp932.result
@@ -2,6 +2,80 @@ drop table if exists t1;
drop table if exists t2;
drop table if exists t3;
drop table if exists t4;
+SET @test_character_set= 'cp932';
+SET @test_collation= 'cp932_japanese_ci';
+SET @safe_character_set_server= @@character_set_server;
+SET @safe_collation_server= @@collation_server;
+SET character_set_server= @test_character_set;
+SET collation_server= @test_collation;
+CREATE DATABASE d1;
+USE d1;
+CREATE TABLE t1 (c CHAR(10), KEY(c));
+SHOW FULL COLUMNS FROM t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+c char(10) cp932_japanese_ci YES MUL NULL
+INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa');
+SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%';
+want3results
+aaa
+aaaa
+aaaaa
+DROP TABLE t1;
+CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2)));
+SHOW FULL COLUMNS FROM t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+c1 varchar(15) cp932_japanese_ci YES MUL NULL
+INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab');
+SELECT c1 as want3results from t1 where c1 like 'l%';
+want3results
+location
+loberge
+lotre
+SELECT c1 as want3results from t1 where c1 like 'lo%';
+want3results
+location
+loberge
+lotre
+SELECT c1 as want1result from t1 where c1 like 'loc%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'loca%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locat%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locati%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locatio%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'location%';
+want1result
+location
+DROP TABLE t1;
+create table t1 (a set('a') not null);
+insert into t1 values (),();
+Warnings:
+Warning 1364 Field 'a' doesn't have a default value
+select cast(a as char(1)) from t1;
+cast(a as char(1))
+
+
+select a sounds like a from t1;
+a sounds like a
+1
+1
+select 1 from t1 order by cast(a as char(1));
+1
+1
+1
+drop table t1;
+DROP DATABASE d1;
+USE test;
+SET character_set_server= @safe_character_set_server;
+SET collation_server= @safe_collation_server;
set names cp932;
set character_set_database = cp932;
CREATE TABLE t1(c1 CHAR(1)) DEFAULT CHARACTER SET = cp932;
diff --git a/mysql-test/suite/binlog/r/binlog_stm_ctype_cp932.result b/mysql-test/suite/binlog/r/binlog_stm_ctype_cp932.result
index ef9f76b7d9c..655100203b5 100755
--- a/mysql-test/suite/binlog/r/binlog_stm_ctype_cp932.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_ctype_cp932.result
@@ -2,6 +2,80 @@ drop table if exists t1;
drop table if exists t2;
drop table if exists t3;
drop table if exists t4;
+SET @test_character_set= 'cp932';
+SET @test_collation= 'cp932_japanese_ci';
+SET @safe_character_set_server= @@character_set_server;
+SET @safe_collation_server= @@collation_server;
+SET character_set_server= @test_character_set;
+SET collation_server= @test_collation;
+CREATE DATABASE d1;
+USE d1;
+CREATE TABLE t1 (c CHAR(10), KEY(c));
+SHOW FULL COLUMNS FROM t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+c char(10) cp932_japanese_ci YES MUL NULL
+INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa');
+SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%';
+want3results
+aaa
+aaaa
+aaaaa
+DROP TABLE t1;
+CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2)));
+SHOW FULL COLUMNS FROM t1;
+Field Type Collation Null Key Default Extra Privileges Comment
+c1 varchar(15) cp932_japanese_ci YES MUL NULL
+INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab');
+SELECT c1 as want3results from t1 where c1 like 'l%';
+want3results
+location
+loberge
+lotre
+SELECT c1 as want3results from t1 where c1 like 'lo%';
+want3results
+location
+loberge
+lotre
+SELECT c1 as want1result from t1 where c1 like 'loc%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'loca%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locat%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locati%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'locatio%';
+want1result
+location
+SELECT c1 as want1result from t1 where c1 like 'location%';
+want1result
+location
+DROP TABLE t1;
+create table t1 (a set('a') not null);
+insert into t1 values (),();
+Warnings:
+Warning 1364 Field 'a' doesn't have a default value
+select cast(a as char(1)) from t1;
+cast(a as char(1))
+
+
+select a sounds like a from t1;
+a sounds like a
+1
+1
+select 1 from t1 order by cast(a as char(1));
+1
+1
+1
+drop table t1;
+DROP DATABASE d1;
+USE test;
+SET character_set_server= @safe_character_set_server;
+SET collation_server= @safe_collation_server;
set names cp932;
set character_set_database = cp932;
CREATE TABLE t1(c1 CHAR(1)) DEFAULT CHARACTER SET = cp932;
diff --git a/mysql-test/suite/funcs_1/r/innodb_views.result b/mysql-test/suite/funcs_1/r/innodb_views.result
index 275192365e8..b826f2a8449 100644
--- a/mysql-test/suite/funcs_1/r/innodb_views.result
+++ b/mysql-test/suite/funcs_1/r/innodb_views.result
@@ -9886,16 +9886,23 @@ f2
two
SET sql_mode = 'traditional,ansi';
CREATE OR REPLACE VIEW v1 AS
+SELECT f3 AS "pure column f3:", f1 + f3 AS "sum of columns f1 + f3 =",
+3 * (- 0.11111E+1) AS "product of constants 3 * (- 0.11111E+1):",
+'->' || CAST(f3 AS CHAR) || '<-'
+ AS "expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR):"
+FROM t1 WHERE f1 = 2;
+CREATE OR REPLACE VIEW v1 AS
SELECT f3 AS "pure column f3: ", f1 + f3 AS "sum of columns f1 + f3 = ",
3 * (- 0.11111E+1) AS "product of constants 3 * (- 0.11111E+1): ",
'->' || CAST(f3 AS CHAR) || '<-'
AS "expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR): "
FROM t1 WHERE f1 = 2;
+ERROR 42000: Incorrect column name 'pure column f3: '
SELECT * FROM v1;
-pure column f3: 2.20000
-sum of columns f1 + f3 = 4.20000
-product of constants 3 * (- 0.11111E+1): -3.3333
-expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR): ->2.20000<-
+pure column f3: 2.20000
+sum of columns f1 + f3 = 4.20000
+product of constants 3 * (- 0.11111E+1): -3.3333
+expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR): ->2.20000<-
SET sql_mode = '';
Testcases 3.3.1.55 - 3.3.1.62
diff --git a/mysql-test/suite/funcs_1/r/memory_views.result b/mysql-test/suite/funcs_1/r/memory_views.result
index 2ec3c714e46..7d045e3412a 100644
--- a/mysql-test/suite/funcs_1/r/memory_views.result
+++ b/mysql-test/suite/funcs_1/r/memory_views.result
@@ -9891,16 +9891,23 @@ f2
two
SET sql_mode = 'traditional,ansi';
CREATE OR REPLACE VIEW v1 AS
+SELECT f3 AS "pure column f3:", f1 + f3 AS "sum of columns f1 + f3 =",
+3 * (- 0.11111E+1) AS "product of constants 3 * (- 0.11111E+1):",
+'->' || CAST(f3 AS CHAR) || '<-'
+ AS "expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR):"
+FROM t1 WHERE f1 = 2;
+CREATE OR REPLACE VIEW v1 AS
SELECT f3 AS "pure column f3: ", f1 + f3 AS "sum of columns f1 + f3 = ",
3 * (- 0.11111E+1) AS "product of constants 3 * (- 0.11111E+1): ",
'->' || CAST(f3 AS CHAR) || '<-'
AS "expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR): "
FROM t1 WHERE f1 = 2;
+ERROR 42000: Incorrect column name 'pure column f3: '
SELECT * FROM v1;
-pure column f3: 2.20000
-sum of columns f1 + f3 = 4.20000
-product of constants 3 * (- 0.11111E+1): -3.3333
-expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR): ->2.20000<-
+pure column f3: 2.20000
+sum of columns f1 + f3 = 4.20000
+product of constants 3 * (- 0.11111E+1): -3.3333
+expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR): ->2.20000<-
SET sql_mode = '';
Testcases 3.3.1.55 - 3.3.1.62
diff --git a/mysql-test/suite/funcs_1/r/myisam_views.result b/mysql-test/suite/funcs_1/r/myisam_views.result
index bba9238e685..3e494f53a2d 100644
--- a/mysql-test/suite/funcs_1/r/myisam_views.result
+++ b/mysql-test/suite/funcs_1/r/myisam_views.result
@@ -9908,16 +9908,23 @@ f2
two
SET sql_mode = 'traditional,ansi';
CREATE OR REPLACE VIEW v1 AS
+SELECT f3 AS "pure column f3:", f1 + f3 AS "sum of columns f1 + f3 =",
+3 * (- 0.11111E+1) AS "product of constants 3 * (- 0.11111E+1):",
+'->' || CAST(f3 AS CHAR) || '<-'
+ AS "expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR):"
+FROM t1 WHERE f1 = 2;
+CREATE OR REPLACE VIEW v1 AS
SELECT f3 AS "pure column f3: ", f1 + f3 AS "sum of columns f1 + f3 = ",
3 * (- 0.11111E+1) AS "product of constants 3 * (- 0.11111E+1): ",
'->' || CAST(f3 AS CHAR) || '<-'
AS "expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR): "
FROM t1 WHERE f1 = 2;
+ERROR 42000: Incorrect column name 'pure column f3: '
SELECT * FROM v1;
-pure column f3: 2.20000
-sum of columns f1 + f3 = 4.20000
-product of constants 3 * (- 0.11111E+1): -3.3333
-expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR): ->2.20000<-
+pure column f3: 2.20000
+sum of columns f1 + f3 = 4.20000
+product of constants 3 * (- 0.11111E+1): -3.3333
+expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR): ->2.20000<-
SET sql_mode = '';
Testcases 3.3.1.55 - 3.3.1.62
diff --git a/mysql-test/suite/funcs_1/r/ndb_views.result b/mysql-test/suite/funcs_1/r/ndb_views.result
index 35193fa7a76..1f8b00a695b 100644
--- a/mysql-test/suite/funcs_1/r/ndb_views.result
+++ b/mysql-test/suite/funcs_1/r/ndb_views.result
@@ -9886,16 +9886,23 @@ f2
two
SET sql_mode = 'traditional,ansi';
CREATE OR REPLACE VIEW v1 AS
+SELECT f3 AS "pure column f3:", f1 + f3 AS "sum of columns f1 + f3 =",
+3 * (- 0.11111E+1) AS "product of constants 3 * (- 0.11111E+1):",
+'->' || CAST(f3 AS CHAR) || '<-'
+ AS "expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR):"
+FROM t1 WHERE f1 = 2;
+CREATE OR REPLACE VIEW v1 AS
SELECT f3 AS "pure column f3: ", f1 + f3 AS "sum of columns f1 + f3 = ",
3 * (- 0.11111E+1) AS "product of constants 3 * (- 0.11111E+1): ",
'->' || CAST(f3 AS CHAR) || '<-'
AS "expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR): "
FROM t1 WHERE f1 = 2;
+ERROR 42000: Incorrect column name 'pure column f3: '
SELECT * FROM v1;
-pure column f3: 2.20000
-sum of columns f1 + f3 = 4.20000
-product of constants 3 * (- 0.11111E+1): -3.3333
-expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR): ->2.20000<-
+pure column f3: 2.20000
+sum of columns f1 + f3 = 4.20000
+product of constants 3 * (- 0.11111E+1): -3.3333
+expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR): ->2.20000<-
SET sql_mode = '';
Testcases 3.3.1.55 - 3.3.1.62
diff --git a/mysql-test/suite/funcs_1/views/views_master.inc b/mysql-test/suite/funcs_1/views/views_master.inc
index e3917170812..6f07d4f38b3 100644
--- a/mysql-test/suite/funcs_1/views/views_master.inc
+++ b/mysql-test/suite/funcs_1/views/views_master.inc
@@ -2415,6 +2415,15 @@ SELECT * FROM v1;
# 3.3.1.54
--vertical_results
SET sql_mode = 'traditional,ansi';
+# due to bug#32496 "no trailing blanks in identifier".
+CREATE OR REPLACE VIEW v1 AS
+SELECT f3 AS "pure column f3:", f1 + f3 AS "sum of columns f1 + f3 =",
+ 3 * (- 0.11111E+1) AS "product of constants 3 * (- 0.11111E+1):",
+ '->' || CAST(f3 AS CHAR) || '<-'
+ AS "expression with '||'=CONCAT and CAST(DECIMAL column AS CHAR):"
+FROM t1 WHERE f1 = 2;
+# This error is not conformant with ansi (see bug#32496). hhunger
+--error ER_WRONG_COLUMN_NAME
CREATE OR REPLACE VIEW v1 AS
SELECT f3 AS "pure column f3: ", f1 + f3 AS "sum of columns f1 + f3 = ",
3 * (- 0.11111E+1) AS "product of constants 3 * (- 0.11111E+1): ",
diff --git a/mysql-test/suite/ndb/r/ndb_auto_increment.result b/mysql-test/suite/ndb/r/ndb_auto_increment.result
new file mode 100644
index 00000000000..5740ed38242
--- /dev/null
+++ b/mysql-test/suite/ndb/r/ndb_auto_increment.result
@@ -0,0 +1,445 @@
+DROP TABLE IF EXISTS t1,t2;
+DROP TABLE IF EXISTS t1;
+set @old_auto_increment_offset = @@session.auto_increment_offset;
+set @old_auto_increment_increment = @@session.auto_increment_increment;
+set @old_ndb_autoincrement_prefetch_sz = @@session.ndb_autoincrement_prefetch_sz;
+flush status;
+create table t1 (a int not null auto_increment primary key) engine ndb;
+insert into t1 values (NULL);
+select * from t1 order by a;
+a
+1
+update t1 set a = 5 where a = 1;
+insert into t1 values (NULL);
+select * from t1 order by a;
+a
+5
+6
+insert into t1 values (7);
+insert into t1 values (NULL);
+select * from t1 order by a;
+a
+5
+6
+7
+8
+insert into t1 values (2);
+insert into t1 values (NULL);
+select * from t1 order by a;
+a
+2
+5
+6
+7
+8
+9
+update t1 set a = 4 where a = 2;
+insert into t1 values (NULL);
+select * from t1 order by a;
+a
+4
+5
+6
+7
+8
+9
+10
+delete from t1 where a = 10;
+insert into t1 values (NULL);
+select * from t1 order by a;
+a
+4
+5
+6
+7
+8
+9
+11
+replace t1 values (NULL);
+select * from t1 order by a;
+a
+4
+5
+6
+7
+8
+9
+11
+12
+replace t1 values (15);
+select * from t1 order by a;
+a
+4
+5
+6
+7
+8
+9
+11
+12
+15
+replace into t1 values (NULL);
+select * from t1 order by a;
+a
+4
+5
+6
+7
+8
+9
+11
+12
+15
+16
+replace t1 values (15);
+select * from t1 order by a;
+a
+4
+5
+6
+7
+8
+9
+11
+12
+15
+16
+insert ignore into t1 values (NULL);
+select * from t1 order by a;
+a
+4
+5
+6
+7
+8
+9
+11
+12
+15
+16
+17
+insert ignore into t1 values (15), (NULL);
+select * from t1 order by a;
+a
+4
+5
+6
+7
+8
+9
+11
+12
+15
+16
+17
+18
+insert into t1 values (15)
+on duplicate key update a = 20;
+insert into t1 values (NULL);
+select * from t1 order by a;
+a
+4
+5
+6
+7
+8
+9
+11
+12
+16
+17
+18
+20
+21
+insert into t1 values (NULL) on duplicate key update a = 30;
+select * from t1 order by a;
+a
+4
+5
+6
+7
+8
+9
+11
+12
+16
+17
+18
+20
+21
+22
+insert into t1 values (30) on duplicate key update a = 40;
+select * from t1 order by a;
+a
+4
+5
+6
+7
+8
+9
+11
+12
+16
+17
+18
+20
+21
+22
+30
+insert ignore into t1 values(600),(NULL),(NULL),(610),(NULL);
+select * from t1 order by a;
+a
+4
+5
+6
+7
+8
+9
+11
+12
+16
+17
+18
+20
+21
+22
+30
+600
+601
+602
+610
+611
+drop table t1;
+create table t1 (a int not null primary key,
+b int not null unique auto_increment) engine ndb;
+insert into t1 values (1, NULL);
+insert into t1 values (3, NULL);
+update t1 set b = 3 where a = 3;
+insert into t1 values (4, NULL);
+select * from t1 order by a;
+a b
+1 1
+3 3
+4 4
+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;
+SET @@session.auto_increment_offset=1;
+SET @@session.auto_increment_increment=1;
+set ndb_autoincrement_prefetch_sz = 32;
+drop table if exists t1;
+SET @@session.auto_increment_offset=1;
+SET @@session.auto_increment_increment=1;
+set ndb_autoincrement_prefetch_sz = 32;
+create table t1 (a int not null auto_increment primary key) engine ndb;
+insert into t1 values (NULL);
+insert into t1 values (NULL);
+select * from t1 order by a;
+a
+1
+33
+insert into t1 values (20);
+insert into t1 values (NULL);
+select * from t1 order by a;
+a
+1
+20
+33
+34
+insert into t1 values (35);
+insert into t1 values (NULL);
+insert into t1 values (NULL);
+ERROR 23000: Duplicate entry '35' for key 'PRIMARY'
+select * from t1 order by a;
+a
+1
+20
+21
+33
+34
+35
+insert into t1 values (100);
+insert into t1 values (NULL);
+insert into t1 values (NULL);
+select * from t1 order by a;
+a
+1
+20
+21
+22
+33
+34
+35
+100
+101
+set auto_increment_offset = @old_auto_increment_offset;
+set auto_increment_increment = @old_auto_increment_increment;
+set ndb_autoincrement_prefetch_sz = @old_ndb_autoincrement_prefetch_sz;
+drop table t1;
diff --git a/mysql-test/suite/ndb/r/ndb_basic.result b/mysql-test/suite/ndb/r/ndb_basic.result
index 4eddaeb1227..9f4f8c0755c 100644
--- a/mysql-test/suite/ndb/r/ndb_basic.result
+++ b/mysql-test/suite/ndb/r/ndb_basic.result
@@ -869,6 +869,30 @@ a b
3 30
4 1
drop table t1,t2;
+create table t1 (a varchar(100) primary key, b varchar(100)) engine = NDB;
+insert into t1 values
+('a', 'a'),('b','b'),('c', 'c'),('aa', 'aa'),('bb', 'bb'),('cc', 'cc');
+replace into t1 values ('a', '-a');
+replace into t1 values ('b', '-b');
+replace into t1 values ('c', '-c');
+replace into t1 values ('aa', '-aa');
+replace into t1 values ('bb', '-bb');
+replace into t1 values ('cc', '-cc');
+replace into t1 values ('aaa', '-aaa');
+replace into t1 values ('bbb', '-bbb');
+replace into t1 values ('ccc', '-ccc');
+select * from t1 order by 1,2;
+a b
+a -a
+aa -aa
+aaa -aaa
+b -b
+bb -bb
+bbb -bbb
+c -c
+cc -cc
+ccc -ccc
+drop table t1;
End of 5.0 tests
CREATE TABLE t1 (a VARCHAR(255) NOT NULL,
CONSTRAINT pk_a PRIMARY KEY (a))engine=ndb;
diff --git a/mysql-test/suite/ndb/r/ndb_blob.result b/mysql-test/suite/ndb/r/ndb_blob.result
index 34f2c5fdd66..31ce36864af 100644
--- a/mysql-test/suite/ndb/r/ndb_blob.result
+++ b/mysql-test/suite/ndb/r/ndb_blob.result
@@ -568,3 +568,24 @@ select count(*) from t1;
count(*)
0
drop table t1;
+create table t1(
+a int,
+blob_nn blob not null,
+text_nn text not null,
+blob_nl blob,
+text_nl text,
+primary key(a)
+) engine=ndb;
+insert into t1(a) values (1);
+Warnings:
+Warning 1364 Field 'blob_nn' doesn't have a default value
+Warning 1364 Field 'text_nn' doesn't have a default value
+insert into t1(a, text_nl) values (2, 'MySQL Cluster NDB');
+Warnings:
+Warning 1364 Field 'blob_nn' doesn't have a default value
+Warning 1364 Field 'text_nn' doesn't have a default value
+select a, length(blob_nn), length(text_nn), blob_nl, text_nl from t1 order by a;
+a length(blob_nn) length(text_nn) blob_nl text_nl
+1 0 0 NULL NULL
+2 0 0 NULL MySQL Cluster NDB
+drop table t1;
diff --git a/mysql-test/suite/ndb/r/ndb_charset.result b/mysql-test/suite/ndb/r/ndb_charset.result
index 1c65a380039..e84c906dd7e 100644
--- a/mysql-test/suite/ndb/r/ndb_charset.result
+++ b/mysql-test/suite/ndb/r/ndb_charset.result
@@ -112,9 +112,9 @@ unique key(a)
) engine=ndb;
insert into t1 values(1, 'aAa');
insert into t1 values(2, 'aaa');
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry 'aaa' for key 'a'
insert into t1 values(3, 'AAA');
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry 'AAA' for key 'a'
select * from t1 order by p;
p a
1 aAa
@@ -138,9 +138,9 @@ unique key(a)
) engine=ndb;
insert into t1 values (1,'A'),(2,'b '),(3,'C '),(4,'d '),(5,'E'),(6,'f');
insert into t1 values(99,'b');
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry 'b' for key 'a'
insert into t1 values(99,'a ');
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry 'a ' for key 'a'
select a,length(a) from t1 order by a;
a length(a)
A 1
diff --git a/mysql-test/suite/ndb/r/ndb_index_unique.result b/mysql-test/suite/ndb/r/ndb_index_unique.result
index cc63ce69760..bfc0c5a2e56 100644
--- a/mysql-test/suite/ndb/r/ndb_index_unique.result
+++ b/mysql-test/suite/ndb/r/ndb_index_unique.result
@@ -22,7 +22,7 @@ select * from t1 where b = 4 order by a;
a b c
3 4 6
insert into t1 values(8, 2, 3);
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry '2' for key 'ib'
select * from t1 order by a;
a b c
1 2 3
@@ -93,7 +93,7 @@ a b c
1 1 1
4 4 NULL
insert into t1 values(5,1,1);
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry '1-1' for key 'bc'
drop table t1;
CREATE TABLE t2 (
a int unsigned NOT NULL PRIMARY KEY,
@@ -116,7 +116,7 @@ select * from t2 where b = 4 order by a;
a b c
3 4 6
insert into t2 values(8, 2, 3);
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry '2-3' for key 'b'
select * from t2 order by a;
a b c
1 2 3
@@ -139,7 +139,7 @@ a b c
8 2 3
create unique index bi using hash on t2(b);
insert into t2 values(9, 3, 1);
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry '3' for key 'bi'
alter table t2 drop index bi;
insert into t2 values(9, 3, 1);
select * from t2 order by a;
@@ -229,7 +229,7 @@ pk a
3 NULL
4 4
insert into t1 values (5,0);
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry '0' for key 'a'
select * from t1 order by pk;
pk a
-1 NULL
@@ -262,7 +262,7 @@ pk a b c
0 NULL 18 NULL
1 3 19 abc
insert into t2 values(2,3,19,'abc');
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry '3-abc' for key 'si'
select * from t2 order by pk;
pk a b c
-1 1 17 NULL
@@ -682,7 +682,7 @@ create table t1 (a int primary key, b varchar(1000) not null, unique key (b))
engine=ndb charset=utf8;
insert into t1 values (1, repeat(_utf8 0xe288ab6474, 200));
insert into t1 values (2, repeat(_utf8 0xe288ab6474, 200));
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry '∫dt∫dt∫dt∫dt∫dt∫dt∫dt∫dt∫dt∫dt∫dt∫dt∫d' for key 'b'
select a, sha1(b) from t1;
a sha1(b)
1 08f5d02c8b8bc244f275bdfc22c42c5cab0d9d7d
diff --git a/mysql-test/suite/ndb/r/ndb_insert.result b/mysql-test/suite/ndb/r/ndb_insert.result
index 51b346bbf7b..7551dc71823 100644
--- a/mysql-test/suite/ndb/r/ndb_insert.result
+++ b/mysql-test/suite/ndb/r/ndb_insert.result
@@ -657,172 +657,3 @@ 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/suite/ndb/r/ndb_multi.result b/mysql-test/suite/ndb/r/ndb_multi.result
index 17380b10fd7..40483887919 100644
--- a/mysql-test/suite/ndb/r/ndb_multi.result
+++ b/mysql-test/suite/ndb/r/ndb_multi.result
@@ -1,4 +1,5 @@
drop table if exists t1, t2, t3, t4;
+flush status;
drop table if exists t1, t2, t3, t4;
flush status;
create table t1 (a int) engine=ndbcluster;
diff --git a/mysql-test/suite/ndb/r/ndb_multi_row.result b/mysql-test/suite/ndb/r/ndb_multi_row.result
index cf5a76d6f01..3d34b16a1a8 100644
--- a/mysql-test/suite/ndb/r/ndb_multi_row.result
+++ b/mysql-test/suite/ndb/r/ndb_multi_row.result
@@ -1,4 +1,5 @@
drop table if exists t1, t2, t3, t4;
+flush status;
drop table if exists t1, t2, t3, t4;
flush status;
create table t1 (a int) engine=ndbcluster;
diff --git a/mysql-test/suite/ndb/r/ndb_update.result b/mysql-test/suite/ndb/r/ndb_update.result
index ed51daee5cb..fa083587956 100644
--- a/mysql-test/suite/ndb/r/ndb_update.result
+++ b/mysql-test/suite/ndb/r/ndb_update.result
@@ -28,7 +28,7 @@ pk1 b c
2 2 2
4 1 1
UPDATE t1 set pk1 = 1, c = 2 where pk1 = 4;
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry '2' for key 'c'
UPDATE IGNORE t1 set pk1 = 1, c = 2 where pk1 = 4;
select * from t1 order by pk1;
pk1 b c
@@ -62,9 +62,9 @@ INSERT INTO t3 VALUES (2, 2);
UPDATE t1 SET a = 1;
UPDATE t1 SET a = 1 ORDER BY a;
UPDATE t2 SET a = 1;
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry '1-2' for key 'a'
UPDATE t2 SET a = 1 ORDER BY a;
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry '1-2' for key 'a'
UPDATE t3 SET a = 1;
ERROR 23000: Duplicate entry '1-2' for key 'PRIMARY'
UPDATE t3 SET a = 1 ORDER BY a;
diff --git a/mysql-test/suite/ndb/r/ps_7ndb.result b/mysql-test/suite/ndb/r/ps_7ndb.result
index fe694520f7e..6e2e61bbc5e 100644
--- a/mysql-test/suite/ndb/r/ps_7ndb.result
+++ b/mysql-test/suite/ndb/r/ps_7ndb.result
@@ -783,20 +783,20 @@ a b
2 two
3 three
4 four
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
deallocate prepare stmt1 ;
-prepare stmt1 from ' SELECT a as ccc from t1 where a+1=
- (SELECT 1+ccc from t1 where ccc+1=a+1 and a=1) ';
+prepare stmt1 from ' SELECT a as ccc from t1 outr where a+1=
+ (SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1) ';
execute stmt1 ;
ccc
1
diff --git a/mysql-test/suite/ndb/t/disabled.def b/mysql-test/suite/ndb/t/disabled.def
index 1752314ea47..f876039a042 100644
--- a/mysql-test/suite/ndb/t/disabled.def
+++ b/mysql-test/suite/ndb/t/disabled.def
@@ -12,10 +12,7 @@
partition_03ndb : BUG#16385 2006-03-24 mikael Partitions: crash when updating a range partitioned NDB table
ndb_partition_error2 : HF is not sure if the test can work as internded on all the platforms
-ndb_binlog_basic : Bug #32759 2007-11-27 mats ndb_binlog_basic assert failure 'thd->transaction.stmt.modified_non_trans_table'
# the below testcase have been reworked to avoid the bug, test contains comment, keep bug open
#ndb_binlog_ddl_multi : BUG#18976 2006-04-10 kent CRBR: multiple binlog, second binlog may miss schema log events
#ndb_binlog_discover : bug#21806 2006-08-24
-ndb_backup_print : Bug#32357: ndb_backup_print test fails sometimes in pushbuild
-ndb_dd_backuprestore : Bug#32659 ndb_dd_backuprestore.test fails randomly
diff --git a/mysql-test/suite/ndb/t/ndb_auto_increment.test b/mysql-test/suite/ndb/t/ndb_auto_increment.test
new file mode 100644
index 00000000000..14e7ae7ca7b
--- /dev/null
+++ b/mysql-test/suite/ndb/t/ndb_auto_increment.test
@@ -0,0 +1,293 @@
+-- source include/have_multi_ndb.inc
+-- source include/not_embedded.inc
+
+--disable_warnings
+connection server1;
+DROP TABLE IF EXISTS t1,t2;
+connection server2;
+DROP TABLE IF EXISTS t1;
+connection server1;
+--enable_warnings
+
+set @old_auto_increment_offset = @@session.auto_increment_offset;
+set @old_auto_increment_increment = @@session.auto_increment_increment;
+set @old_ndb_autoincrement_prefetch_sz = @@session.ndb_autoincrement_prefetch_sz;
+
+flush status;
+
+create table t1 (a int not null auto_increment primary key) engine ndb;
+
+# Step 1: Verify simple insert
+insert into t1 values (NULL);
+select * from t1 order by a;
+
+# Step 2: Verify simple update with higher than highest value causes
+# next insert to use updated_value + 1
+update t1 set a = 5 where a = 1;
+insert into t1 values (NULL);
+select * from t1 order by a;
+
+# Step 3: Verify insert that inserts higher than highest value causes
+# next insert to use inserted_value + 1
+insert into t1 values (7);
+insert into t1 values (NULL);
+select * from t1 order by a;
+
+# Step 4: Verify that insert into hole, lower than highest value doesn't
+# affect next insert
+insert into t1 values (2);
+insert into t1 values (NULL);
+select * from t1 order by a;
+
+# Step 5: Verify that update into hole, lower than highest value doesn't
+# affect next insert
+update t1 set a = 4 where a = 2;
+insert into t1 values (NULL);
+select * from t1 order by a;
+
+# Step 6: Verify that delete of highest value doesn't cause the next
+# insert to reuse this value
+delete from t1 where a = 10;
+insert into t1 values (NULL);
+select * from t1 order by a;
+
+# Step 7: Verify that REPLACE has the same effect as INSERT
+replace t1 values (NULL);
+select * from t1 order by a;
+replace t1 values (15);
+select * from t1 order by a;
+replace into t1 values (NULL);
+select * from t1 order by a;
+
+# Step 8: Verify that REPLACE has the same effect as UPDATE
+replace t1 values (15);
+select * from t1 order by a;
+
+# Step 9: Verify that IGNORE doesn't affect auto_increment
+insert ignore into t1 values (NULL);
+select * from t1 order by a;
+insert ignore into t1 values (15), (NULL);
+select * from t1 order by a;
+
+# Step 10: Verify that on duplicate key as UPDATE behaves as an
+# UPDATE
+insert into t1 values (15)
+on duplicate key update a = 20;
+insert into t1 values (NULL);
+select * from t1 order by a;
+
+# Step 11: Verify that on duplicate key as INSERT behaves as INSERT
+insert into t1 values (NULL) on duplicate key update a = 30;
+select * from t1 order by a;
+insert into t1 values (30) on duplicate key update a = 40;
+select * from t1 order by a;
+
+#Step 12: Vefify INSERT IGNORE (bug#32055)
+insert ignore into t1 values(600),(NULL),(NULL),(610),(NULL);
+select * from t1 order by a;
+drop table t1;
+
+#Step 13: Verify auto_increment of unique key
+create table t1 (a int not null primary key,
+ b int not null unique auto_increment) engine ndb;
+insert into t1 values (1, NULL);
+insert into t1 values (3, NULL);
+update t1 set b = 3 where a = 3;
+insert into t1 values (4, NULL);
+select * from t1 order by a;
+drop table t1;
+
+#Step 14: Verify that auto_increment_increment and auto_increment_offset
+# work as expected
+
+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;
+
+#Step 15: Now verify that behaviour on multiple MySQL Servers behave
+# properly. Start by dropping table and recreating it to start
+# counters and id caches from zero again.
+--disable_warnings
+connection server2;
+SET @@session.auto_increment_offset=1;
+SET @@session.auto_increment_increment=1;
+set ndb_autoincrement_prefetch_sz = 32;
+drop table if exists t1;
+connection server1;
+SET @@session.auto_increment_offset=1;
+SET @@session.auto_increment_increment=1;
+set ndb_autoincrement_prefetch_sz = 32;
+--enable_warnings
+
+
+create table t1 (a int not null auto_increment primary key) engine ndb;
+# Basic test, ensure that the second server gets a new range.
+#Generate record with key = 1
+insert into t1 values (NULL);
+connection server2;
+#Generate record with key = 33
+insert into t1 values (NULL);
+connection server1;
+select * from t1 order by a;
+
+#This insert should not affect the range of the second server
+insert into t1 values (20);
+connection server2;
+insert into t1 values (NULL);
+select * from t1 order by a;
+
+connection server1;
+#This insert should remove cached values but also skip values already
+#taken by server2, given that there is no method of communicating with
+#the other server it should also cause a conflict
+connection server1;
+
+insert into t1 values (35);
+insert into t1 values (NULL);
+connection server2;
+--error ER_DUP_ENTRY
+insert into t1 values (NULL);
+select * from t1 order by a;
+
+insert into t1 values (100);
+insert into t1 values (NULL);
+connection server1;
+insert into t1 values (NULL);
+select * from t1 order by a;
+
+set auto_increment_offset = @old_auto_increment_offset;
+set auto_increment_increment = @old_auto_increment_increment;
+set ndb_autoincrement_prefetch_sz = @old_ndb_autoincrement_prefetch_sz;
+
+drop table t1;
diff --git a/mysql-test/suite/ndb/t/ndb_basic.test b/mysql-test/suite/ndb/t/ndb_basic.test
index b9ccdf9fd0d..2fc140288ca 100644
--- a/mysql-test/suite/ndb/t/ndb_basic.test
+++ b/mysql-test/suite/ndb/t/ndb_basic.test
@@ -800,9 +800,27 @@ 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
+#
+# Bug#31635
+#
+create table t1 (a varchar(100) primary key, b varchar(100)) engine = NDB;
+insert into t1 values
+ ('a', 'a'),('b','b'),('c', 'c'),('aa', 'aa'),('bb', 'bb'),('cc', 'cc');
+replace into t1 values ('a', '-a');
+replace into t1 values ('b', '-b');
+replace into t1 values ('c', '-c');
+
+replace into t1 values ('aa', '-aa');
+replace into t1 values ('bb', '-bb');
+replace into t1 values ('cc', '-cc');
+
+replace into t1 values ('aaa', '-aaa');
+replace into t1 values ('bbb', '-bbb');
+replace into t1 values ('ccc', '-ccc');
+select * from t1 order by 1,2;
+drop table t1;
+--echo End of 5.0 tests
#
# Bug #18483 Cannot create table with FK constraint
diff --git a/mysql-test/suite/ndb/t/ndb_blob.test b/mysql-test/suite/ndb/t/ndb_blob.test
index b9a8c7e20ee..0388913df8b 100644
--- a/mysql-test/suite/ndb/t/ndb_blob.test
+++ b/mysql-test/suite/ndb/t/ndb_blob.test
@@ -497,3 +497,23 @@ select count(*) from t1;
drop table t1;
# End of 4.1 tests
+
+
+# bug # 30674 :
+# NOT NULL Blobs should default to zero-length. Not NULL TEXT
+# should default to zero-chars
+create table t1(
+ a int,
+ blob_nn blob not null,
+ text_nn text not null,
+ blob_nl blob,
+ text_nl text,
+ primary key(a)
+) engine=ndb;
+
+insert into t1(a) values (1);
+insert into t1(a, text_nl) values (2, 'MySQL Cluster NDB');
+
+select a, length(blob_nn), length(text_nn), blob_nl, text_nl from t1 order by a;
+
+drop table t1;
diff --git a/mysql-test/suite/ndb/t/ndb_insert.test b/mysql-test/suite/ndb/t/ndb_insert.test
index 5b74cc9202c..d659f8357f2 100644
--- a/mysql-test/suite/ndb/t/ndb_insert.test
+++ b/mysql-test/suite/ndb/t/ndb_insert.test
@@ -638,142 +638,4 @@ create table t1(a int primary key, b int, unique key(b)) engine=ndb;
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/suite/ndb/t/ndb_multi.test b/mysql-test/suite/ndb/t/ndb_multi.test
index c2217b51d08..e033ad1e479 100644
--- a/mysql-test/suite/ndb/t/ndb_multi.test
+++ b/mysql-test/suite/ndb/t/ndb_multi.test
@@ -4,11 +4,11 @@
--disable_warnings
connection server2;
drop table if exists t1, t2, t3, t4;
+flush status;
connection server1;
drop table if exists t1, t2, t3, t4;
---enable_warnings
-
flush status;
+--enable_warnings
# Create test tables on server1
create table t1 (a int) engine=ndbcluster;
diff --git a/mysql-test/suite/ndb/t/ndb_multi_row.test b/mysql-test/suite/ndb/t/ndb_multi_row.test
index c82307839f4..26953093ed0 100644
--- a/mysql-test/suite/ndb/t/ndb_multi_row.test
+++ b/mysql-test/suite/ndb/t/ndb_multi_row.test
@@ -6,11 +6,12 @@
--disable_warnings
connection server2;
drop table if exists t1, t2, t3, t4;
+flush status;
connection server1;
drop table if exists t1, t2, t3, t4;
+flush status;
--enable_warnings
-flush status;
# Create test tables on server1
create table t1 (a int) engine=ndbcluster;
diff --git a/mysql-test/suite/ndb/r/ndb_backup_print.result b/mysql-test/suite/ndb_team/r/ndb_backup_print.result
index 7fa073bafb5..7fa073bafb5 100644
--- a/mysql-test/suite/ndb/r/ndb_backup_print.result
+++ b/mysql-test/suite/ndb_team/r/ndb_backup_print.result
diff --git a/mysql-test/suite/ndb/r/ndb_dd_backuprestore.result b/mysql-test/suite/ndb_team/r/ndb_dd_backuprestore.result
index c82fe560121..c82fe560121 100644
--- a/mysql-test/suite/ndb/r/ndb_dd_backuprestore.result
+++ b/mysql-test/suite/ndb_team/r/ndb_dd_backuprestore.result
diff --git a/mysql-test/suite/ndb/t/ndb_backup_print.test b/mysql-test/suite/ndb_team/t/ndb_backup_print.test
index cf869fd56f5..cf869fd56f5 100644
--- a/mysql-test/suite/ndb/t/ndb_backup_print.test
+++ b/mysql-test/suite/ndb_team/t/ndb_backup_print.test
diff --git a/mysql-test/suite/ndb/t/ndb_dd_backuprestore.test b/mysql-test/suite/ndb_team/t/ndb_dd_backuprestore.test
index 48db8ec3e0b..48db8ec3e0b 100644
--- a/mysql-test/suite/ndb/t/ndb_dd_backuprestore.test
+++ b/mysql-test/suite/ndb_team/t/ndb_dd_backuprestore.test
diff --git a/mysql-test/suite/parts/r/rpl_partition.result b/mysql-test/suite/parts/r/rpl_partition.result
index 79a95fd613b..bd77d4317bd 100644
--- a/mysql-test/suite/parts/r/rpl_partition.result
+++ b/mysql-test/suite/parts/r/rpl_partition.result
@@ -121,7 +121,7 @@ Create Table CREATE TABLE `t3` (
`fkid` mediumint(9) DEFAULT NULL,
`filler` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
-) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (id) SUBPARTITION BY HASH (id) SUBPARTITIONS 2 (PARTITION pa1 VALUES LESS THAN (10) ENGINE = MyISAM, PARTITION pa2 VALUES LESS THAN (20) ENGINE = MyISAM, PARTITION pa3 VALUES LESS THAN (30) ENGINE = MyISAM, PARTITION pa4 VALUES LESS THAN (40) ENGINE = MyISAM, PARTITION pa5 VALUES LESS THAN (50) ENGINE = MyISAM, PARTITION pa6 VALUES LESS THAN (60) ENGINE = MyISAM, PARTITION pa7 VALUES LESS THAN (70) ENGINE = MyISAM, PARTITION pa8 VALUES LESS THAN (80) ENGINE = MyISAM, PARTITION pa9 VALUES LESS THAN (90) ENGINE = MyISAM, PARTITION pa10 VALUES LESS THAN (100) ENGINE = MyISAM, PARTITION pa11 VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
+) ENGINE=MyISAM AUTO_INCREMENT=1001 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (id) SUBPARTITION BY HASH (id) SUBPARTITIONS 2 (PARTITION pa1 VALUES LESS THAN (10) ENGINE = MyISAM, PARTITION pa2 VALUES LESS THAN (20) ENGINE = MyISAM, PARTITION pa3 VALUES LESS THAN (30) ENGINE = MyISAM, PARTITION pa4 VALUES LESS THAN (40) ENGINE = MyISAM, PARTITION pa5 VALUES LESS THAN (50) ENGINE = MyISAM, PARTITION pa6 VALUES LESS THAN (60) ENGINE = MyISAM, PARTITION pa7 VALUES LESS THAN (70) ENGINE = MyISAM, PARTITION pa8 VALUES LESS THAN (80) ENGINE = MyISAM, PARTITION pa9 VALUES LESS THAN (90) ENGINE = MyISAM, PARTITION pa10 VALUES LESS THAN (100) ENGINE = MyISAM, PARTITION pa11 VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
show slave status;
Slave_IO_State #
Master_Host 127.0.0.1
diff --git a/mysql-test/suite/parts/t/partition_basic_myisam.test b/mysql-test/suite/parts/t/partition_basic_myisam.test
index 8d84982335c..c363d06b00a 100644
--- a/mysql-test/suite/parts/t/partition_basic_myisam.test
+++ b/mysql-test/suite/parts/t/partition_basic_myisam.test
@@ -48,6 +48,9 @@ let $more_pk_ui_tests= 0;
##### Storage engine to be tested
let $engine= 'MyISAM';
+# The server uses in case of MyISAM symlinking (if available) and the expected
+# results fit to symlinking support.
+--source include/have_symlink.inc
##### Execute the test of "table" files
# MyISAM has files per PK, UI, ...
diff --git a/mysql-test/suite/rpl/include/rpl_mixed_dml.inc b/mysql-test/suite/rpl/include/rpl_mixed_dml.inc
index 70db5b6cf83..d7041d82a2a 100644
--- a/mysql-test/suite/rpl/include/rpl_mixed_dml.inc
+++ b/mysql-test/suite/rpl/include/rpl_mixed_dml.inc
@@ -51,7 +51,7 @@ DELETE FROM t2 WHERE a = 2;
--echo
--echo ******************** LOAD DATA INFILE ********************
---exec cp ./suite/rpl/data/rpl_mixed.dat $MYSQLTEST_VARDIR/tmp/
+--copy_file ./suite/rpl/data/rpl_mixed.dat $MYSQLTEST_VARDIR/tmp/rpl_mixed.dat
LOAD DATA INFILE '../tmp/rpl_mixed.dat' INTO TABLE t1 FIELDS TERMINATED BY '|' ;
--remove_file $MYSQLTEST_VARDIR/tmp/rpl_mixed.dat
SELECT * FROM t1 ORDER BY a;
diff --git a/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result b/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result
index af460ded1e7..ad67f96db71 100644
--- a/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result
+++ b/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result
@@ -1089,18 +1089,19 @@ c1 hex(c4) c5
3 62316231623162316231623162316231 QA
** update from master **
+UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3;
SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1;
c1 hex(c4) c5 c6 c7
1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP
2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP
-3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP
+3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP
** Check slave **
SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1;
c1 hex(c4) c5
1 62316231623162316231623162316231 Kyle
2 62316231623162316231623162316231 JOE
-3 62316231623162316231623162316231 QA
+3 62316231623162316231623162316231 TEST
DROP TABLE t18;
@@ -2229,18 +2230,19 @@ c1 hex(c4) c5
3 62316231623162316231623162316231 QA
** update from master **
+UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3;
SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1;
c1 hex(c4) c5 c6 c7
1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP
2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP
-3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP
+3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP
** Check slave **
SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1;
c1 hex(c4) c5
1 62316231623162316231623162316231 Kyle
2 62316231623162316231623162316231 JOE
-3 62316231623162316231623162316231 QA
+3 62316231623162316231623162316231 TEST
DROP TABLE t18;
@@ -3369,18 +3371,19 @@ c1 hex(c4) c5
3 62316231623162316231623162316231 QA
** update from master **
+UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3;
SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1;
c1 hex(c4) c5 c6 c7
1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP
2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP
-3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP
+3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP
** Check slave **
SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1;
c1 hex(c4) c5
1 62316231623162316231623162316231 Kyle
2 62316231623162316231623162316231 JOE
-3 62316231623162316231623162316231 QA
+3 62316231623162316231623162316231 TEST
DROP TABLE t18;
diff --git a/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result b/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result
index f0613c16825..8859a8e24e3 100644
--- a/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result
+++ b/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result
@@ -1089,18 +1089,19 @@ c1 hex(c4) c5
3 62316231623162316231623162316231 QA
** update from master **
+UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3;
SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1;
c1 hex(c4) c5 c6 c7
1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP
2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP
-3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP
+3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP
** Check slave **
SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1;
c1 hex(c4) c5
1 62316231623162316231623162316231 Kyle
2 62316231623162316231623162316231 JOE
-3 62316231623162316231623162316231 QA
+3 62316231623162316231623162316231 TEST
DROP TABLE t18;
@@ -2229,18 +2230,19 @@ c1 hex(c4) c5
3 62316231623162316231623162316231 QA
** update from master **
+UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3;
SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1;
c1 hex(c4) c5 c6 c7
1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP
2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP
-3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP
+3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP
** Check slave **
SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1;
c1 hex(c4) c5
1 62316231623162316231623162316231 Kyle
2 62316231623162316231623162316231 JOE
-3 62316231623162316231623162316231 QA
+3 62316231623162316231623162316231 TEST
DROP TABLE t18;
@@ -3369,18 +3371,19 @@ c1 hex(c4) c5
3 62316231623162316231623162316231 QA
** update from master **
+UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3;
SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1;
c1 hex(c4) c5 c6 c7
1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP
2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP
-3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP
+3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP
** Check slave **
SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1;
c1 hex(c4) c5
1 62316231623162316231623162316231 Kyle
2 62316231623162316231623162316231 JOE
-3 62316231623162316231623162316231 QA
+3 62316231623162316231623162316231 TEST
DROP TABLE t18;
diff --git a/mysql-test/suite/rpl/r/rpl_innodb_bug28430.result b/mysql-test/suite/rpl/r/rpl_innodb_bug28430.result
index c46b4016715..e92f74e27eb 100644
--- a/mysql-test/suite/rpl/r/rpl_innodb_bug28430.result
+++ b/mysql-test/suite/rpl/r/rpl_innodb_bug28430.result
@@ -113,7 +113,7 @@ Create Table CREATE TABLE `byrange_tbl` (
`fkid` mediumint(9) DEFAULT NULL,
`filler` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (id) SUBPARTITION BY HASH (id) SUBPARTITIONS 2 (PARTITION pa1 VALUES LESS THAN (10) ENGINE = InnoDB, PARTITION pa2 VALUES LESS THAN (20) ENGINE = InnoDB, PARTITION pa3 VALUES LESS THAN (30) ENGINE = InnoDB, PARTITION pa4 VALUES LESS THAN (40) ENGINE = InnoDB, PARTITION pa5 VALUES LESS THAN (50) ENGINE = InnoDB, PARTITION pa6 VALUES LESS THAN (60) ENGINE = InnoDB, PARTITION pa7 VALUES LESS THAN (70) ENGINE = InnoDB, PARTITION pa8 VALUES LESS THAN (80) ENGINE = InnoDB, PARTITION pa9 VALUES LESS THAN (90) ENGINE = InnoDB, PARTITION pa10 VALUES LESS THAN (100) ENGINE = InnoDB, PARTITION pa11 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
+) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (id) SUBPARTITION BY HASH (id) SUBPARTITIONS 2 (PARTITION pa1 VALUES LESS THAN (10) ENGINE = InnoDB, PARTITION pa2 VALUES LESS THAN (20) ENGINE = InnoDB, PARTITION pa3 VALUES LESS THAN (30) ENGINE = InnoDB, PARTITION pa4 VALUES LESS THAN (40) ENGINE = InnoDB, PARTITION pa5 VALUES LESS THAN (50) ENGINE = InnoDB, PARTITION pa6 VALUES LESS THAN (60) ENGINE = InnoDB, PARTITION pa7 VALUES LESS THAN (70) ENGINE = InnoDB, PARTITION pa8 VALUES LESS THAN (80) ENGINE = InnoDB, PARTITION pa9 VALUES LESS THAN (90) ENGINE = InnoDB, PARTITION pa10 VALUES LESS THAN (100) ENGINE = InnoDB, PARTITION pa11 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
SHOW SLAVE STATUS;
Slave_IO_State #
Master_Host 127.0.0.1
diff --git a/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result
index 06dc90f18aa..a8e1c8602e0 100644
--- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result
+++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result
@@ -123,7 +123,7 @@ Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1364
-Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef.
+Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef. Field 'x' doesn't have a default value
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@@ -141,7 +141,7 @@ Master_SSL_Verify_Server_Cert No
Last_IO_Errno 0
Last_IO_Error
Last_SQL_Errno 1364
-Last_SQL_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef.
+Last_SQL_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef. Field 'x' doesn't have a default value
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
INSERT INTO t9 VALUES (2);
diff --git a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result
index 3911fe89b7f..12203379269 100644
--- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result
+++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result
@@ -123,7 +123,7 @@ Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 1364
-Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef.
+Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef. Field 'x' doesn't have a default value
Skip_Counter 0
Exec_Master_Log_Pos #
Relay_Log_Space #
@@ -141,7 +141,7 @@ Master_SSL_Verify_Server_Cert No
Last_IO_Errno 0
Last_IO_Error
Last_SQL_Errno 1364
-Last_SQL_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef.
+Last_SQL_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef. Field 'x' doesn't have a default value
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
INSERT INTO t9 VALUES (2);
diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_ddl.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_ddl.result
index aeaca1e7de0..e668b57293e 100644
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_ddl.result
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_ddl.result
@@ -1086,6 +1086,9 @@ Modified #
Created #
Security_type DEFINER
Comment
+character_set_client latin1
+collation_connection latin1_swedish_ci
+Database Collation latin1_swedish_ci
-------- switch to slave --------
SHOW PROCEDURE STATUS LIKE 'p1';
@@ -1097,6 +1100,9 @@ Modified #
Created #
Security_type DEFINER
Comment
+character_set_client latin1
+collation_connection latin1_swedish_ci
+Database Collation latin1_swedish_ci
-------- switch to master -------
@@ -1149,6 +1155,9 @@ Modified #
Created #
Security_type DEFINER
Comment I have been altered
+character_set_client latin1
+collation_connection latin1_swedish_ci
+Database Collation latin1_swedish_ci
-------- switch to slave --------
SHOW PROCEDURE STATUS LIKE 'p1';
@@ -1160,6 +1169,9 @@ Modified #
Created #
Security_type DEFINER
Comment I have been altered
+character_set_client latin1
+collation_connection latin1_swedish_ci
+Database Collation latin1_swedish_ci
-------- switch to master -------
@@ -1251,13 +1263,13 @@ TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
-------- switch to master -------
SHOW CREATE VIEW v1;
-View Create View
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` latin1 latin1_swedish_ci
-------- switch to slave --------
SHOW CREATE VIEW v1;
-View Create View
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` latin1 latin1_swedish_ci
-------- switch to master -------
@@ -1302,13 +1314,13 @@ TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
-------- switch to master -------
SHOW CREATE VIEW v1;
-View Create View
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` latin1 latin1_swedish_ci
-------- switch to slave --------
SHOW CREATE VIEW v1;
-View Create View
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` latin1 latin1_swedish_ci
-------- switch to master -------
@@ -1402,13 +1414,13 @@ TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
-------- switch to master -------
SHOW TRIGGERS;
-Trigger Event Table Statement Timing Created sql_mode Definer
-trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
-------- switch to slave --------
SHOW TRIGGERS;
-Trigger Event Table Statement Timing Created sql_mode Definer
-trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
-------- switch to master -------
@@ -1453,11 +1465,11 @@ TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
-------- switch to master -------
SHOW TRIGGERS;
-Trigger Event Table Statement Timing Created sql_mode Definer
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
-------- switch to slave --------
SHOW TRIGGERS;
-Trigger Event Table Statement Timing Created sql_mode Definer
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
-------- switch to master -------
diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraColMaster.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraColMaster.result
index d5d4658c01f..194e6a375f3 100644
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraColMaster.result
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraColMaster.result
@@ -1089,18 +1089,19 @@ c1 hex(c4) c5
3 62316231623162316231623162316231 QA
** update from master **
+UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3;
SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1;
c1 hex(c4) c5 c6 c7
1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP
2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP
-3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP
+3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP
** Check slave **
SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1;
c1 hex(c4) c5
1 62316231623162316231623162316231 Kyle
2 62316231623162316231623162316231 JOE
-3 62316231623162316231623162316231 QA
+3 62316231623162316231623162316231 TEST
DROP TABLE t18;
@@ -2229,18 +2230,19 @@ c1 hex(c4) c5
3 62316231623162316231623162316231 QA
** update from master **
+UPDATE t18 SET c5 = 'TEST' WHERE c6 = 3;
SELECT c1,hex(c4),c5,c6,c7 FROM t18 ORDER BY c1;
c1 hex(c4) c5 c6 c7
1 62316231623162316231623162316231 Kyle 1 CURRENT_TIMESTAMP
2 62316231623162316231623162316231 JOE 2 CURRENT_TIMESTAMP
-3 62316231623162316231623162316231 QA 3 CURRENT_TIMESTAMP
+3 62316231623162316231623162316231 TEST 3 CURRENT_TIMESTAMP
** Check slave **
SELECT c1,hex(c4),c5 FROM t18 ORDER BY c1;
c1 hex(c4) c5
1 62316231623162316231623162316231 Kyle
2 62316231623162316231623162316231 JOE
-3 62316231623162316231623162316231 QA
+3 62316231623162316231623162316231 TEST
DROP TABLE t18;
diff --git a/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result b/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result
index abd5bad8e49..f176d4eb52a 100644
--- a/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result
+++ b/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result
@@ -389,9 +389,9 @@ INSERT INTO t8 VALUES (99,99,99);
INSERT INTO t8 VALUES (99,22,33);
ERROR 23000: Duplicate entry '99' for key 'PRIMARY'
INSERT INTO t8 VALUES (11,99,33);
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry '99' for key 'b'
INSERT INTO t8 VALUES (11,22,99);
-ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
+ERROR 23000: Duplicate entry '99' for key 'c'
SELECT * FROM t8 ORDER BY a;
a b c
99 99 99
diff --git a/mysql-test/suite/rpl_ndb/t/disabled.def b/mysql-test/suite/rpl_ndb/t/disabled.def
index 60bfa559953..bb701b9dc3e 100644
--- a/mysql-test/suite/rpl_ndb/t/disabled.def
+++ b/mysql-test/suite/rpl_ndb/t/disabled.def
@@ -14,7 +14,6 @@
rpl_ndb_2innodb : Bug #32648 Test failure between NDB Cluster and other engines
rpl_ndb_2myisam : Bug #32648 Test failure between NDB Cluster and other engines
rpl_ndb_2other : Bug #32648 Test failure between NDB Cluster and other engines
-rpl_ndb_ddl : BUG#28798 2007-05-31 lars Valgrind failure in NDB
rpl_ndb_ctype_ucs2_def : BUG#27404 util thd mysql_parse sig11 when mysqld default multibyte charset
rpl_ndb_extraColMaster : BUG#30854 : Tables name show as binary in slave err msg on vm-win2003-64-b and Solaris
rpl_ndb_mix_innodb : Bug #32720 Test rpl_ndb_mix_innodb fails on SPARC and PowerPC
diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test
index a1158dbfd3b..b42c8446a32 100644
--- a/mysql-test/t/archive.test
+++ b/mysql-test/t/archive.test
@@ -1589,3 +1589,12 @@ SELECT * FROM t1 ORDER BY a;
--enable_result_log
DROP TABLE t1;
+
+#
+# BUG#31833 - ORDER BY leads to wrong result when ARCHIVE, BLOB and table
+# cache is full
+#
+CREATE TABLE t1(a INT NOT NULL AUTO_INCREMENT, b BLOB, KEY(a)) ENGINE=archive;
+INSERT INTO t1 VALUES (NULL, NULL),(NULL, NULL);
+FLUSH TABLE t1;
+SELECT * FROM t1 ORDER BY a;
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index 45ee4c1c88d..dff6bf3fcff 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -1328,4 +1328,17 @@ create table t2 as select f1() from t1;
drop table t1,t2;
drop function f1;
+#
+# Bug#25629 CREATE TABLE LIKE does not work with INFORMATION_SCHEMA
+#
+create table t1 like information_schema.processlist;
+show create table t1;
+drop table t1;
+create temporary table t1 like information_schema.processlist;
+show create table t1;
+drop table t1;
+create table t1 like information_schema.character_sets;
+show create table t1;
+drop table t1;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test
index 6c83fbfdc9c..7b4f95bbf8a 100644
--- a/mysql-test/t/csv.test
+++ b/mysql-test/t/csv.test
@@ -1755,9 +1755,9 @@ insert into t1 values();
select BIN(a) from t1;
drop table t1;
# We prevent creation of table with nullable ENUM
---error ER_CANT_CREATE_TABLE
+--error ER_CHECK_NOT_IMPLEMENTED
create table t1(a enum('foo','bar') default null) engine=csv;
---error ER_CANT_CREATE_TABLE
+--error ER_CHECK_NOT_IMPLEMENTED
create table t1(a enum('foo','bar') default 'foo') engine=csv;
# Enum columns must be specified as NOT NULL
create table t1(a enum('foo','bar') default 'foo' not null) engine=csv;
@@ -1765,5 +1765,12 @@ insert into t1 values();
select * from t1;
drop table t1;
+#
+# BUG#32817 - though CSV is marked as supported create table is rejected
+# with error 1005.
+#
+--error ER_CHECK_NOT_IMPLEMENTED
+CREATE TABLE t1(a INT) ENGINE=CSV;
+SHOW WARNINGS;
--echo End of 5.1 tests
diff --git a/mysql-test/t/delayed.test b/mysql-test/t/delayed.test
index b542027207f..ce57645bd4b 100644
--- a/mysql-test/t/delayed.test
+++ b/mysql-test/t/delayed.test
@@ -244,6 +244,16 @@ SELECT HEX(a) FROM t1;
DROP TABLE t1;
#
+# Bug #32676: insert delayed crash with wrong column and function specified
+#
+CREATE TABLE t1 (a INT);
+--error ER_BAD_FIELD_ERROR
+INSERT DELAYED INTO t1 SET b= b();
+DROP TABLE t1;
+
+--echo End of 5.0 tests
+
+#
# Bug#27358 INSERT DELAYED does not honour SQL_MODE of the client
#
--disable_warnings
@@ -275,3 +285,4 @@ INSERT DELAYED INTO t2 VALUES (0,'0000-00-00');
INSERT DELAYED INTO t2 VALUES (0,'2007-00-00');
DROP TABLE t1,t2;
+--echo End of 5.1 tests
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 42fa242c7e1..3f9ec52ca36 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -16,11 +16,10 @@ ctype_big5 : BUG#26711 2007-06-21 Lars Test has never worked on Do
federated_transactions : Bug#29523 Transactions do not work
events : Bug#32664 events.test fails randomly
-events_scheduling : Bug#29830 Test case 'events_scheduling' fails on Mac OS X and Windows
lowercase_table3 : Bug#32667 lowercase_table3.test reports to error log
kill : Bug#29149: Test "kill" fails on Windows
innodb_mysql : Bug#32724: innodb_mysql.test fails randomly
wait_timeout : Bug#32801 wait_timeout.test fails randomly
-kill : Bug#29149 Test "kill" fails on Windows
ctype_create : Bug#32965 main.ctype_create fails
status : Bug#32966 main.status fails
+ps_ddl : Bug#12093 2007-12-14 pending WL#4165 / WL#4166
diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test
index a1451773e90..a79044436eb 100644
--- a/mysql-test/t/drop.test
+++ b/mysql-test/t/drop.test
@@ -122,3 +122,16 @@ disconnect addconroot2;
connection default;
--echo End of 5.0 tests
+
+#
+# Bug#30152 MySQLD crash duing alter table causes DROP DATABASE to FAIL due to temp file
+#
+create database mysql_test;
+create table mysql_test.t1(f1 int);
+create table mysql_test.`#sql-347f_7` (f1 int);
+create table mysql_test.`#sql-347f_8` (f1 int);
+drop table mysql_test.`#sql-347f_8`;
+copy_file $MYSQLTEST_VARDIR/master-data/mysql_test/t1.frm $MYSQLTEST_VARDIR/master-data/mysql_test/#sql-347f_6.frm;
+drop database mysql_test;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/events_scheduling.test b/mysql-test/t/events_scheduling.test
index b1eeae1e020..226cad0f3eb 100644
--- a/mysql-test/t/events_scheduling.test
+++ b/mysql-test/t/events_scheduling.test
@@ -87,7 +87,7 @@ SELECT IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR')
FROM INFORMATION_SCHEMA.EVENTS
WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='event_2';
-SELECT IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR')
+SELECT IF(LAST_EXECUTED-ENDS <= 0, 'OK', 'ERROR')
FROM INFORMATION_SCHEMA.EVENTS
WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='event_2';
diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test
index 04cf37f457a..c9ae8aceaf6 100644
--- a/mysql-test/t/explain.test
+++ b/mysql-test/t/explain.test
@@ -66,4 +66,32 @@ explain extended select * from t1 having 1;
drop view v1;
drop table t1;
+#
+# Bug #32241: memory corruption due to large index map in 'Range checked for
+# each record'
+#
+
+CREATE TABLE t1(c INT);
+INSERT INTO t1 VALUES (),();
+
+CREATE TABLE t2 (b INT,
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
+KEY(b),KEY(b),KEY(b),KEY(b),KEY(b));
+
+INSERT INTO t2 VALUES (),(),();
+
+# We only need to make sure that there is no buffer overrun and the index map
+# is displayed correctly
+--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X
+EXPLAIN SELECT 1 FROM
+ (SELECT 1 FROM t2,t1 WHERE b < c GROUP BY 1 LIMIT 1) AS d2;
+DROP TABLE t2;
+DROP TABLE t1;
+
# End of 5.0 tests.
diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test
index 90f1fa36bb4..76cb5fd4793 100644
--- a/mysql-test/t/federated.test
+++ b/mysql-test/t/federated.test
@@ -1764,6 +1764,35 @@ DROP TABLE federated.t1;
connection slave;
DROP TABLE federated.t1;
---echo End of 5.1 tests
+#
+# Bug #32374 crash with filesort when selecting from federated table and view
+#
+connection slave;
+create table t1 (a varchar(256));
+--disable_warnings
+drop view if exists v1;
+--enable_warnings
+create view v1 as select a from t1;
+--disable_query_log
+let $n= 100;
+while ($n)
+{
+ insert into t1 values (repeat('a',200));
+ dec $n;
+}
+--enable_query_log
+connection master;
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval create table t1
+ (a varchar(256)) engine=federated
+ connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/v1';
+
+select 1 from t1 order by a;
+drop table t1;
+connection slave;
+drop table t1;
+drop view v1;
+
+--echo End of 5.1 tests
source include/federated_cleanup.inc;
diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test
index fb85cdfb27d..7a579088d23 100644
--- a/mysql-test/t/func_misc.test
+++ b/mysql-test/t/func_misc.test
@@ -3,7 +3,7 @@
#
--disable_warnings
-DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t1, t2;
--enable_warnings
select format(1.5555,0),format(123.5555,1),format(1234.5555,2),format(12345.55555,3),format(123456.5555,4),format(1234567.5555,5),format("12345.2399",2);
@@ -214,6 +214,31 @@ SELECT NAME_CONST('test', -1.0);
SELECT NAME_CONST('test', 'test');
#
+# Bug #27545: erroneous usage of NAME_CONST with a name as the first parameter
+# resolved against a column name of a derived table hangs the client
+#
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (5), (2);
+
+--error ER_WRONG_ARGUMENTS
+SELECT NAME_CONST(x,2) FROM (SELECT a x FROM t1) t;
+
+DROP TABLE t1;
+
+
+#
+# Bug #32559: connection hangs on query with name_const
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (), (), ();
+--error ER_WRONG_ARGUMENTS
+SELECT NAME_CONST(a, '1') FROM t1;
+--error ER_WRONG_ARGUMENTS
+SET INSERT_ID= NAME_CONST(a, a);
+DROP TABLE t1;
+
+#
# Bug #31349: ERROR 1062 (23000): Duplicate entry '' for key 'group_key'
#
create table t1 (a int not null);
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 5c1a5c2200b..97087abd668 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -766,6 +766,16 @@ select concat(a,ifnull(min(date_format(now(), '%Y-%m-%d')),' ull')) from t1;
set lc_time_names=en_US;
drop table t1;
+#
+# Bug#32180: DATE_ADD treats datetime numeric argument as DATE
+# instead of DATETIME
+#
+
+select DATE_ADD('20071108181000', INTERVAL 1 DAY);
+select DATE_ADD(20071108181000, INTERVAL 1 DAY);
+select DATE_ADD('20071108', INTERVAL 1 DAY);
+select DATE_ADD(20071108, INTERVAL 1 DAY);
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index b4c515d2e8c..e6b8b91783c 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -440,6 +440,48 @@ INSERT INTO `t1` VALUES ('','0000-00-00');
select geomfromtext(col9,col89) as a from t1;
DROP TABLE t1;
+#
+# Bug #31158 Spatial, Union, LONGBLOB vs BLOB bug (crops data)
+#
+
+CREATE TABLE t1 (
+ geomdata polygon NOT NULL,
+ SPATIAL KEY index_geom (geomdata)
+) ENGINE=MyISAM DEFAULT CHARSET=latin2 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED;
+
+CREATE TABLE t2 (
+ geomdata polygon NOT NULL,
+ SPATIAL KEY index_geom (geomdata)
+) ENGINE=MyISAM DEFAULT CHARSET=latin2 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED;
+
+CREATE TABLE t3
+select
+ aswkb(ws.geomdata) AS geomdatawkb
+ from
+ t1 ws
+union
+ select
+ aswkb(ws.geomdata) AS geomdatawkb
+ from
+ t2 ws;
+
+describe t3;
+
+drop table t1;
+drop table t2;
+drop table t3;
+
+#
+# Bug #30284 spatial key corruption
+#
+
+create table t1(col1 geometry default null,col15 geometrycollection not
+null,spatial index(col15),index(col1(15)))engine=myisam;
+insert into t1 set col15 = GeomFromText('POINT(6 5)');
+insert into t1 set col15 = GeomFromText('POINT(6 5)');
+check table t1 extended;
+drop table t1;
+
--echo End of 4.1 tests
#
@@ -601,6 +643,15 @@ SELECT 1;
-- source include/gis_keys.inc
+#
+# Bug #31155 gis types in union'd select cause crash
+#
+
+create table `t1` (`col002` point)engine=myisam;
+insert into t1 values (),(),();
+select min(`col002`) from t1 union select `col002` from t1;
+drop table t1;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index d9ee38d0c14..16cccd1a1f4 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -1362,6 +1362,7 @@ use test;
#
--echo FLUSH PRIVILEGES without procs_priv table.
RENAME TABLE mysql.procs_priv TO mysql.procs_gone;
+--error ER_NO_SUCH_TABLE
FLUSH PRIVILEGES;
--echo Assigning privileges without procs_priv table.
CREATE DATABASE mysqltest1;
diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test
index 9d1e065797d..7ec7e58ee19 100644
--- a/mysql-test/t/group_min_max.test
+++ b/mysql-test/t/group_min_max.test
@@ -914,7 +914,31 @@ SELECT SQL_BIG_RESULT DISTINCT(a) FROM t1;
DROP TABLE t1;
+#
+# Bug #32268: Indexed queries give bogus MIN and MAX results
+#
+
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 (a, b) VALUES (1,1), (1,2), (1,3);
+INSERT INTO t1 SELECT a + 1, b FROM t1;
+INSERT INTO t1 SELECT a + 2, b FROM t1;
+EXPLAIN
+SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC;
+SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC;
+CREATE INDEX break_it ON t1 (a, b);
+EXPLAIN
+SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a;
+SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a;
+EXPLAIN
+SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC;
+SELECT a, MIN(b), MAX(b) FROM t1 GROUP BY a ORDER BY a DESC;
+
+EXPLAIN
+SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC;
+SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC;
+
+DROP TABLE t1;
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index f08d216da27..2a9319fe010 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -1239,4 +1239,13 @@ select * from `information_schema`.`VIEWS` where `TABLE_NAME` = NULL;
#
explain extended select 1 from information_schema.tables;
+#
+# Bug#32775 problems with SHOW EVENTS and Information_Schema
+#
+use information_schema;
+show events;
+show events from information_schema;
+show events where Db= 'information_schema';
+use test;
+
--echo End of 5.1 tests.
diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test
index 93495538141..a907866f726 100644
--- a/mysql-test/t/innodb_mysql.test
+++ b/mysql-test/t/innodb_mysql.test
@@ -10,5 +10,6 @@ let $engine_type= InnoDB;
let $other_engine_type= MEMORY;
# InnoDB does support FOREIGN KEYFOREIGN KEYs
let $test_foreign_keys= 1;
-
+set global innodb_support_xa=default;
+set session innodb_support_xa=default;
--source include/mix1.inc
diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test
index b2266c9bff1..0d36b79df78 100644
--- a/mysql-test/t/lock_multi.test
+++ b/mysql-test/t/lock_multi.test
@@ -150,7 +150,7 @@ send SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
connection locker;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
- where state = "Locked" and info =
+ where state = "Waiting for table" and info =
"SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1";
--source include/wait_condition.inc
# Make test case independent from earlier grants.
@@ -343,4 +343,100 @@ handler t1 open;
connection default;
drop table t1;
+#
+# Bug#32395 Alter table under a impending global read lock causes a server crash
+#
+
+#
+# Test ALTER TABLE under LOCK TABLES and FLUSH TABLES WITH READ LOCK
+#
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (i int);
+connect (flush,localhost,root,,test,,);
+connection default;
+--echo connection: default
+lock tables t1 write;
+connection flush;
+--echo connection: flush
+--send flush tables with read lock;
+connection default;
+--echo connection: default
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+alter table t1 add column j int;
+connect (insert,localhost,root,,test,,);
+connection insert;
+--echo connection: insert
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+--send insert into t1 values (1,2);
+--echo connection: default
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for release of readlock";
+--source include/wait_condition.inc
+unlock tables;
+connection flush;
+--echo connection: flush
+--reap
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Waiting for release of readlock";
+--source include/wait_condition.inc
+select * from t1;
+unlock tables;
+connection insert;
+--reap
+connection default;
+select * from t1;
+drop table t1;
+disconnect flush;
+disconnect insert;
+
+#
+# Test that FLUSH TABLES under LOCK TABLES protects write locked tables
+# from a impending FLUSH TABLES WITH READ LOCK
+#
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (i int);
+connect (flush,localhost,root,,test,,);
+connection default;
+--echo connection: default
+lock tables t1 write;
+connection flush;
+--echo connection: flush
+--send flush tables with read lock;
+connection default;
+--echo connection: default
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+flush tables;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+unlock tables;
+let $wait_condition=
+ select count(*) = 0 from information_schema.processlist
+ where state = "Flushing tables";
+--source include/wait_condition.inc
+connection flush;
+--reap
+connection default;
+disconnect flush;
+drop table t1;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index 3b71dc6fde1..e49297dd06c 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -1,5 +1,5 @@
#
-# test of MERGE TABLES
+# Test of MERGE TABLES
#
--disable_warnings
@@ -578,6 +578,28 @@ CREATE TABLE t2 (c1 INT) ENGINE=MERGE UNION=(t1) INSERT_METHOD=FIRST;
CREATE TABLE IF NOT EXISTS t1 SELECT * FROM t2;
DROP TABLE t1, t2;
+#
+# Bug #28837: MyISAM storage engine error (134) doing delete with self-join
+#
+
+CREATE TABLE t1 (id INT NOT NULL, ref INT NOT NULL, INDEX (id)) ENGINE=MyISAM;
+CREATE TABLE t2 LIKE t1;
+
+INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4);
+INSERT INTO t1 SELECT * FROM t2;
+INSERT INTO t1 SELECT * FROM t2;
+
+CREATE TABLE t3 (id INT NOT NULL, ref INT NOT NULL, INDEX (id)) ENGINE=MERGE
+ UNION(t1);
+
+SELECT * FROM t3 AS a INNER JOIN t3 AS b USING (id) WHERE a.ref < b.ref;
+SELECT * FROM t3;
+DELETE FROM a USING t3 AS a INNER JOIN t3 AS b USING (id) WHERE a.ref < b.ref;
+SELECT * FROM t3;
+
+DROP TABLE t1, t2, t3;
+
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/t/merge_innodb.test b/mysql-test/t/merge_innodb.test
new file mode 100644
index 00000000000..7f0b1a0c36e
--- /dev/null
+++ b/mysql-test/t/merge_innodb.test
@@ -0,0 +1,41 @@
+# t/merge_innodb.test
+#
+# Tests with MERGE tables over InnoDB tables
+#
+
+--source include/have_innodb.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2, t3, t4, t5;
+--enable_warnings
+
+#
+# Bug#30491 - MERGE doesn't report error when one table is Innodb
+#
+CREATE TABLE t1 (c1 varchar(100)) ENGINE=MyISAM;
+CREATE TABLE t2 (c1 varchar(100)) ENGINE=MyISAM;
+CREATE TABLE t3 (c1 varchar(100)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('Ann'), ('Alice');
+INSERT INTO t2 VALUES ('Bob'), ('Brian');
+INSERT INTO t3 VALUES ('Chris'), ('Charlie');
+CREATE TABLE t4 (c1 varchar(100)) ENGINE=MRG_MYISAM UNION=(t1,t2)
+ INSERT_METHOD=LAST;
+CREATE TABLE t5 (c1 varchar(100)) ENGINE=MRG_MYISAM UNION=(t1,t3)
+ INSERT_METHOD=LAST;
+--error ER_WRONG_MRG_TABLE
+SELECT * FROM t5;
+SELECT * FROM t4;
+ALTER TABLE t2 ENGINE=InnoDB;
+--error ER_WRONG_MRG_TABLE
+SELECT * FROM t4;
+DELETE FROM t2 LIMIT 1;
+--error ER_WRONG_MRG_TABLE
+SELECT * FROM t4;
+--error ER_WRONG_MRG_TABLE
+INSERT INTO t4 VALUES ('Beware');
+--error ER_WRONG_MRG_TABLE
+SELECT * FROM t4;
+SELECT * FROM t2;
+SELECT * FROM t1;
+DROP TABLE t1, t2, t3, t4, t5;
+
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index cadab8b3b70..fbd0a5ac4e7 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -1152,6 +1152,23 @@ SET @@myisam_repair_threads=1;
CHECK TABLE t1 EXTENDED;
DROP TABLE t1;
+#
+# Bug#28837: MyISAM storage engine error (134) doing delete with self-join
+#
+
+CREATE TABLE t1 (id int NOT NULL, ref int NOT NULL, INDEX (id)) ENGINE=MyISAM;
+CREATE TABLE t2 LIKE t1;
+
+INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4);
+INSERT INTO t1 SELECT * FROM t2;
+
+SELECT * FROM t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref;
+SELECT * FROM t1;
+DELETE FROM a USING t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref;
+SELECT * FROM t1;
+
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/no-threads.test b/mysql-test/t/no-threads.test
index 31ea6406ee9..fd8365e5678 100644
--- a/mysql-test/t/no-threads.test
+++ b/mysql-test/t/no-threads.test
@@ -4,3 +4,13 @@
select 1+1;
select 1+2;
SHOW GLOBAL VARIABLES LIKE 'thread_handling';
+
+#
+# Bug #30651 Problems with thread_handling system variable
+#
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.thread_handling;
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set GLOBAL thread_handling='one-thread';
diff --git a/mysql-test/t/order_fill_sortbuf-master.opt b/mysql-test/t/order_fill_sortbuf-master.opt
index 116494d4588..9aa3cc76221 100644
--- a/mysql-test/t/order_fill_sortbuf-master.opt
+++ b/mysql-test/t/order_fill_sortbuf-master.opt
@@ -1 +1 @@
---set-variable=sort_buffer=0
+--set-variable=sort_buffer=32804
diff --git a/mysql-test/t/outfile_loaddata.test b/mysql-test/t/outfile_loaddata.test
index 2f6ac998b3d..2a120871e7d 100644
--- a/mysql-test/t/outfile_loaddata.test
+++ b/mysql-test/t/outfile_loaddata.test
@@ -86,4 +86,28 @@ DROP TABLE t2;
DROP TABLE t1;
+--echo #
+--echo # Bug#32533: SELECT INTO OUTFILE never escapes multibyte character
+--echo #
+
+CREATE TABLE t1 (c1 VARCHAR(256));
+INSERT INTO t1 VALUES (0xC3);
+SELECT HEX(c1) FROM t1;
+
+--let $file=$MYSQLTEST_VARDIR/tmp/bug32533.txt
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--eval SELECT * INTO OUTFILE '$file' FIELDS ENCLOSED BY 0xC3 FROM t1
+TRUNCATE t1;
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--eval SELECT HEX(LOAD_FILE('$file'))
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--eval LOAD DATA INFILE '$file' INTO TABLE t1 FIELDS ENCLOSED BY 0xC3
+SELECT HEX(c1) FROM t1;
+
+--remove_file $file
+DROP TABLE t1;
+
--echo # End of 5.0 tests.
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index f2fed63c833..23d6c5f8865 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -1543,6 +1543,24 @@ while ($cnt)
drop table t1;
#
+# BUG#32272: partition crash 1: enum column
+#
+create table t1 (
+ c0 int,
+ c1 bigint,
+ c2 set('sweet'),
+ key (c2,c1,c0),
+ key(c0)
+) engine=myisam partition by hash (month(c0)) partitions 5;
+
+--disable_warnings
+insert ignore into t1 set c0 = -6502262, c1 = 3992917, c2 = 35019;
+insert ignore into t1 set c0 = 241221, c1 = -6862346, c2 = 56644;
+--enable_warnings
+# This must not fail assert:
+select c1 from t1 group by (select c0 from t1 limit 1);
+drop table t1;
+
# Bug #30495: optimize table t1,t2,t3 extended errors
#
CREATE TABLE t1(a int)
@@ -1556,4 +1574,89 @@ ALTER TABLE t1 OPTIMIZE PARTITION p1 EXTENDED;
ALTER TABLE t1 ANALYZE PARTITION p1 EXTENDED;
DROP TABLE t1;
+#
+# Bug #29258: Partitions: search fails for maximum unsigned bigint
+#
+CREATE TABLE t1 (s1 BIGINT UNSIGNED)
+ PARTITION BY RANGE (s1) (
+ PARTITION p0 VALUES LESS THAN (0),
+ PARTITION p1 VALUES LESS THAN (1),
+ PARTITION p2 VALUES LESS THAN (18446744073709551615)
+);
+INSERT INTO t1 VALUES (0), (18446744073709551614);
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
+INSERT INTO t1 VALUES (18446744073709551615);
+DROP TABLE t1;
+
+CREATE TABLE t1 (s1 BIGINT UNSIGNED)
+ PARTITION BY RANGE (s1) (
+ PARTITION p0 VALUES LESS THAN (0),
+ PARTITION p1 VALUES LESS THAN (1),
+ PARTITION p2 VALUES LESS THAN (18446744073709551614),
+ PARTITION p3 VALUES LESS THAN MAXVALUE
+);
+INSERT INTO t1 VALUES (-1), (0), (18446744073709551613),
+ (18446744073709551614), (18446744073709551615);
+SELECT * FROM t1;
+SELECT * FROM t1 WHERE s1 = 0;
+SELECT * FROM t1 WHERE s1 = 18446744073709551614;
+SELECT * FROM t1 WHERE s1 = 18446744073709551615;
+DROP TABLE t1;
+
+CREATE TABLE t1 (s1 BIGINT UNSIGNED)
+ PARTITION BY RANGE (s1) (
+ PARTITION p0 VALUES LESS THAN (0),
+ PARTITION p1 VALUES LESS THAN (1),
+ PARTITION p2 VALUES LESS THAN (18446744073709551615),
+ PARTITION p3 VALUES LESS THAN MAXVALUE
+);
+DROP TABLE t1;
+
+#
+# Bug #31890 Partitions: ORDER BY DESC in InnoDB not working
+#
+
+CREATE TABLE t1
+(int_column INT, char_column CHAR(5),
+PRIMARY KEY(char_column,int_column))
+PARTITION BY KEY(char_column,int_column)
+PARTITIONS 101;
+INSERT INTO t1 (int_column, char_column) VALUES
+( 39868 ,'zZZRW'),
+( 545592 ,'zZzSD'),
+( 4936 ,'zzzsT'),
+( 9274 ,'ZzZSX'),
+( 970185 ,'ZZzTN'),
+( 786036 ,'zZzTO'),
+( 37240 ,'zZzTv'),
+( 313801 ,'zzzUM'),
+( 782427 ,'ZZZva'),
+( 907955 ,'zZZvP'),
+( 453491 ,'zzZWV'),
+( 756594 ,'ZZZXU'),
+( 718061 ,'ZZzZH');
+SELECT * FROM t1 ORDER BY char_column DESC;
+DROP TABLE t1;
+
+#
+# Bug #32247 Test reports wrong value of "AUTO_INCREMENT" (on a partitioned InnoDB table)
+#
+
+CREATE TABLE t1(id MEDIUMINT NOT NULL AUTO_INCREMENT,
+ user CHAR(25), PRIMARY KEY(id))
+ PARTITION BY RANGE(id)
+ SUBPARTITION BY hash(id) subpartitions 2
+ (PARTITION pa1 values less than (10),
+ PARTITION pa2 values less than (20),
+ PARTITION pa11 values less than MAXVALUE);
+--disable_query_log
+let $n= 15;
+while ($n)
+{
+ insert into t1 (user) values ('mysql');
+ dec $n;
+}
+--enable_query_log
+show create table t1;
+drop table t1;
--echo End of 5.1 tests
diff --git a/mysql-test/t/partition_archive.test b/mysql-test/t/partition_archive.test
index 3109894d9c9..fad57107b7d 100644
--- a/mysql-test/t/partition_archive.test
+++ b/mysql-test/t/partition_archive.test
@@ -16,7 +16,9 @@
#
--disable_warnings
drop database if exists db99;
+drop table if exists t1;
--enable_warnings
+
create database db99;
use db99;
create table t1 (a int not null)
@@ -30,3 +32,76 @@ alter table t1 add partition (partition p2 values in (3));
alter table t1 drop partition p2;
use test;
drop database db99;
+
+create table t1 (f1 integer) engine= ARCHIVE partition by list(f1)
+(
+ partition p1 values in (1),
+ partition p2 values in (NULL),
+ partition p3 values in (2),
+ partition p4 values in (3),
+ partition p5 values in (4)
+);
+
+insert into t1 values (1),(2),(3),(4),(null);
+select * from t1;
+select * from t1 where f1 < 3;
+drop table t1;
+
+CREATE TABLE t1 (
+a int not null,
+b int not null,
+c int not null) engine=ARCHIVE
+partition by hash (a + 2)
+partitions 3
+(partition x1 tablespace ts1,
+ partition x2 tablespace ts2,
+ partition x3 tablespace ts3);
+
+insert into t1 values (1,1,1);
+insert into t1 values (2,1,1);
+insert into t1 values (3,1,1);
+insert into t1 values (4,1,1);
+insert into t1 values (5,1,1);
+
+select * from t1;
+
+drop table t1;
+
+#
+# Bug #32247 Test reports wrong value of "AUTO_INCREMENT" (on a partitioned InnoDB table)
+# (though reported as InnoDB bug, requires some ARCHIVE tests
+
+create table t1 (a int) engine=archive partition by hash(a);
+show create table t1;
+drop table t1;
+
+CREATE TABLE t1(id MEDIUMINT NOT NULL AUTO_INCREMENT,
+ f1 VARCHAR(25),
+ PRIMARY KEY(id)) ENGINE=ARCHIVE
+ PARTITION BY RANGE(id)
+ SUBPARTITION BY hash(id) subpartitions 2
+ (PARTITION pa1 values less than (10),
+ PARTITION pa2 values less than (20),
+ PARTITION pa3 values less than (30),
+ PARTITION pa4 values less than (40),
+ PARTITION pa5 values less than (50),
+ PARTITION pa6 values less than (60),
+ PARTITION pa7 values less than (70),
+ PARTITION pa8 values less than (80),
+ PARTITION pa9 values less than (90),
+ PARTITION pa10 values less than (100),
+ PARTITION pa11 values less than MAXVALUE);
+
+--disable_query_log
+let $n= 100;
+while ($n)
+{
+ insert into t1 (f1) values (repeat('a',25));
+ dec $n;
+}
+--enable_query_log
+
+show create table t1;
+select count(*) from t1;
+drop table t1;
+
diff --git a/mysql-test/t/partition_hash.test b/mysql-test/t/partition_hash.test
index 52caaa8c8e9..362d5f747e9 100644
--- a/mysql-test/t/partition_hash.test
+++ b/mysql-test/t/partition_hash.test
@@ -10,6 +10,22 @@ drop table if exists t1;
--enable_warnings
#
+# Bug#30822: crash when COALESCE
+#
+CREATE TABLE t1 (c1 INT)
+ PARTITION BY HASH (c1)
+ PARTITIONS 15;
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
+ALTER TABLE t1 COALESCE PARTITION 13;
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT)
+ PARTITION BY LINEAR HASH (c1)
+ PARTITIONS 5;
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
+ALTER TABLE t1 COALESCE PARTITION 3;
+DROP TABLE t1;
+
+#
# More partition pruning tests, especially on interval walking
#
create table t1 (a int unsigned)
diff --git a/mysql-test/t/partition_innodb.test b/mysql-test/t/partition_innodb.test
index 6b73d0b2c5e..58010f85ecf 100644
--- a/mysql-test/t/partition_innodb.test
+++ b/mysql-test/t/partition_innodb.test
@@ -1,6 +1,21 @@
--source include/have_partition.inc
--source include/have_innodb.inc
+# Bug#32948 - FKs allowed to reference partitioned table
+#
+-- echo # Bug#32948
+CREATE TABLE t1 (c1 INT, PRIMARY KEY (c1)) ENGINE=INNODB;
+CREATE TABLE t2 (c1 INT, PRIMARY KEY (c1),
+ FOREIGN KEY (c1) REFERENCES t1 (c1)
+ ON DELETE CASCADE)
+ENGINE=INNODB;
+--error ER_ROW_IS_REFERENCED
+ALTER TABLE t1 PARTITION BY HASH(c1) PARTITIONS 5;
+--error ER_ROW_IS_REFERENCED
+ALTER TABLE t1 ENGINE=MyISAM;
+DROP TABLE t2;
+DROP TABLE t1;
+
#
# Bug #14673: Wrong InnoDB default row format
#
diff --git a/mysql-test/t/partition_range.test b/mysql-test/t/partition_range.test
index 50d850913bc..6ed3abab46a 100644
--- a/mysql-test/t/partition_range.test
+++ b/mysql-test/t/partition_range.test
@@ -6,7 +6,7 @@
-- source include/have_partition.inc
--disable_warnings
-drop table if exists t1;
+drop table if exists t1, t2;
--enable_warnings
#
@@ -757,3 +757,29 @@ DROP TABLE t1;
# a = "C2345678901234567890";
#select * from t1 where a = "12345678901234567890";
#drop table t1;
+
+
+#
+# BUG#30573: get wrong result with "group by" on PARTITIONed table
+#
+#create table t1 (a int);
+#insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+#CREATE TABLE t2 (
+# defid int(10) unsigned NOT NULL,
+# day int(10) unsigned NOT NULL,
+# count int(10) unsigned NOT NULL,
+# filler char(200),
+# KEY (defid,day)
+#)
+#PARTITION BY RANGE (day) (
+# PARTITION p7 VALUES LESS THAN (20070401) ,
+# PARTITION p8 VALUES LESS THAN (20070501));
+
+#insert into t2 select 20, 20070311, 1, 'filler' from t1 A, t1 B;
+#insert into t2 select 20, 20070411, 1, 'filler' from t1 A, t1 B;
+#insert into t2 values(52, 20070321, 123, 'filler') ;
+#insert into t2 values(52, 20070322, 456, 'filler') ;
+
+#select sum(count) from t2 ch where ch.defid in (50,52) and ch.day between 20070320 and 20070401 group by defid;
+#drop table t1, t2;
+
diff --git a/mysql-test/t/ps_ddl.test b/mysql-test/t/ps_ddl.test
new file mode 100644
index 00000000000..abb6563f052
--- /dev/null
+++ b/mysql-test/t/ps_ddl.test
@@ -0,0 +1,1851 @@
+#
+# Testing the behavior of 'PREPARE', 'DDL', 'EXECUTE' scenarios
+#
+# Background:
+# In a statement like "select * from t1", t1 can be:
+# - nothing (the table does not exist)
+# - a real table
+# - a temporary table
+# - a view
+#
+# Changing the nature of "t1" between a PREPARE and an EXECUTE
+# can invalidate the internal state of a prepared statement, so that,
+# during the execute, the server should:
+# - detect state changes and fail to execute a statement,
+# instead of crashing the server or returning wrong results
+# - "RE-PREPARE" the statement to restore a valid internal state.
+#
+# Also, changing the physical structure of "t1", by:
+# - changing the definition of t1 itself (DDL on tables, views)
+# - changing TRIGGERs associated with a table
+# - changing PROCEDURE, FUNCTION referenced by a TRIGGER body,
+# - changing PROCEDURE, FUNCTION referenced by a VIEW body,
+# impacts the internal structure of a prepared statement, and should
+# cause the same verifications at execute time to be performed.
+#
+# This test provided in this file cover the different state transitions
+# between a PREPARE and an EXECUTE, and are organized as follows:
+# - Part 1: NOTHING -> TABLE
+# - Part 2: NOTHING -> TEMPORARY TABLE
+# - Part 3: NOTHING -> VIEW
+# - Part 4: TABLE -> NOTHING
+# - Part 5: TABLE -> TABLE (DDL)
+# - Part 6: TABLE -> TABLE (TRIGGER)
+# - Part 7: TABLE -> TABLE (TRIGGER dependencies)
+# - Part 8: TABLE -> TEMPORARY TABLE
+# - Part 9: TABLE -> VIEW
+# - Part 10: TEMPORARY TABLE -> NOTHING
+# - Part 11: TEMPORARY TABLE -> TABLE
+# - Part 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL)
+# - Part 13: TEMPORARY TABLE -> VIEW
+# - Part 14: VIEW -> NOTHING
+# - Part 15: VIEW -> TABLE
+# - Part 16: VIEW -> TEMPORARY TABLE
+# - Part 17: VIEW -> VIEW (DDL)
+# - Part 18: VIEW -> VIEW (VIEW dependencies)
+# - Part 19: Special tables (INFORMATION_SCHEMA)
+# - Part 20: Special tables (log tables)
+# - Part 21: Special tables (system tables)
+# - Part 22: Special tables (views temp tables)
+# - Part 23: Special tables (internal join tables)
+# - Part 24: Special statements
+# - Part 25: Testing the strength of TABLE_SHARE version
+
+let $base_count = SELECT VARIABLE_VALUE from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE'
+into @base_count ;
+
+let $reprepared = SELECT VARIABLE_VALUE - @base_count AS REPREPARED from
+INFORMATION_SCHEMA.SESSION_STATUS where variable_name='COM_STMT_REPREPARE' ;
+
+--echo =====================================================================
+--echo Testing 1: NOTHING -> TABLE transitions
+--echo =====================================================================
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+eval $base_count;
+
+# can not be tested since prepare failed
+--error ER_NO_SUCH_TABLE
+prepare stmt from 'select * from t1';
+
+--echo =====================================================================
+--echo Testing 2: NOTHING -> TEMPORARY TABLE transitions
+--echo =====================================================================
+
+# can not be tested
+
+--echo =====================================================================
+--echo Testing 3: NOTHING -> VIEW transitions
+--echo =====================================================================
+
+# can not be tested
+
+--echo =====================================================================
+--echo Testing 4: TABLE -> NOTHING transitions
+--echo =====================================================================
+
+--disable_warnings
+drop table if exists t4;
+--enable_warnings
+
+eval $base_count;
+
+create table t4(a int);
+
+prepare stmt from 'select * from t4';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t4;
+--error ER_NO_SUCH_TABLE
+execute stmt;
+eval $reprepared;
+--error ER_NO_SUCH_TABLE
+execute stmt;
+eval $reprepared;
+
+--echo =====================================================================
+--echo Testing 5: TABLE -> TABLE (DDL) transitions
+--echo =====================================================================
+
+--disable_warnings
+drop table if exists t5;
+--enable_warnings
+
+eval $base_count;
+
+create table t5(a int);
+
+prepare stmt from 'select * from t5';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+alter table t5 add column (b int);
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t5;
+
+--echo =====================================================================
+--echo Testing 6: TABLE -> TABLE (TRIGGER) transitions
+--echo =====================================================================
+
+#
+# Test 6-a: adding a relevant trigger
+# Test 6-b: adding an irrelevant trigger
+# Test 6-c: changing a relevant trigger
+# Test 6-d: changing an irrelevant trigger
+# Test 6-e: removing a relevant trigger
+# Test 6-f: removing an irrelevant trigger
+#
+
+--disable_warnings
+drop table if exists t6;
+--enable_warnings
+
+eval $base_count;
+
+create table t6(a int);
+
+prepare stmt from 'insert into t6(a) value (?)';
+set @val=1;
+execute stmt using @val;
+eval $reprepared;
+set @val=2;
+execute stmt using @val;
+eval $reprepared;
+
+# Relevant trigger: execute should reprepare
+delimiter $$;
+create trigger t6_bi before insert on t6 for each row
+ begin
+ set @message= "t6_bi";
+ end
+$$
+delimiter ;$$
+
+set @message="none";
+set @val=3;
+# REPREPARED +1
+execute stmt using @val;
+eval $reprepared;
+select @message;
+set @val=4;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+
+prepare stmt from 'insert into t6(a) value (?)';
+set @message="none";
+set @val=5;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+set @message="none";
+set @val=6;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+
+# Unrelated trigger: execute can pass of fail, implementation dependent
+delimiter $$;
+create trigger t6_bd before delete on t6 for each row
+ begin
+ set @message= "t6_bd";
+ end
+$$
+delimiter ;$$
+
+set @message="none";
+set @val=7;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+set @message="none";
+set @val=8;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+
+prepare stmt from 'insert into t6(a) value (?)';
+set @message="none";
+set @val=9;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+set @message="none";
+set @val=10;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+
+# Relevant trigger: execute should reprepare
+drop trigger t6_bi;
+delimiter $$;
+create trigger t6_bi before insert on t6 for each row
+ begin
+ set @message= "t6_bi (2)";
+ end
+$$
+delimiter ;$$
+
+set @message="none";
+set @val=11;
+# REPREPARED +1
+execute stmt using @val;
+eval $reprepared;
+select @message;
+set @val=12;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+
+prepare stmt from 'insert into t6(a) value (?)';
+set @message="none";
+set @val=13;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+set @message="none";
+set @val=14;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+
+# Unrelated trigger: execute can pass of fail, implementation dependent
+drop trigger t6_bd;
+delimiter $$;
+create trigger t6_bd before delete on t6 for each row
+ begin
+ set @message= "t6_bd (2)";
+ end
+$$
+delimiter ;$$
+
+set @message="none";
+set @val=15;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+set @message="none";
+set @val=16;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+
+prepare stmt from 'insert into t6(a) value (?)';
+set @message="none";
+set @val=17;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+set @message="none";
+set @val=18;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+
+drop trigger t6_bi;
+
+set @message="none";
+set @val=19;
+# safe to re-execute
+execute stmt using @val;
+eval $reprepared;
+select @message;
+set @val=20;
+# safe to re-execute
+execute stmt using @val;
+eval $reprepared;
+select @message;
+
+prepare stmt from 'insert into t6(a) value (?)';
+set @message="none";
+set @val=21;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+set @val=22;
+execute stmt using @val;
+eval $reprepared;
+select @message;
+
+drop trigger t6_bd;
+
+set @val=23;
+# safe to re-execute
+execute stmt using @val;
+eval $reprepared;
+select @message;
+set @val=24;
+# safe to re-execute
+execute stmt using @val;
+eval $reprepared;
+select @message;
+
+select * from t6 order by a;
+drop table t6;
+
+--echo =====================================================================
+--echo Testing 7: TABLE -> TABLE (TRIGGER dependencies) transitions
+--echo =====================================================================
+
+#
+# Test 7-a: dependent PROCEDURE has changed
+# Test 7-b: dependent FUNCTION has changed
+# Test 7-c: dependent VIEW has changed
+# Test 7-d: dependent TABLE has changed
+# Test 7-e: dependent TABLE TRIGGER has changed
+#
+
+--disable_warnings
+drop table if exists t7_proc;
+drop table if exists t7_func;
+drop table if exists t7_view;
+drop table if exists t7_table;
+drop table if exists t7_dependent_table;
+drop table if exists t7_table_trigger;
+drop table if exists t7_audit;
+drop procedure if exists audit_proc;
+drop function if exists audit_func;
+drop view if exists audit_view;
+--enable_warnings
+
+eval $base_count;
+
+create table t7_proc(a int);
+create table t7_func(a int);
+create table t7_view(a int);
+create table t7_table(a int);
+create table t7_table_trigger(a int);
+
+create table t7_audit(old_a int, new_a int, reason varchar(50));
+create table t7_dependent_table(old_a int, new_a int, reason varchar(50));
+
+create procedure audit_proc(a int)
+ insert into t7_audit values (NULL, a, "proc v1");
+
+create function audit_func() returns varchar(50)
+ return "func v1";
+
+create view audit_view as select "view v1" as reason from dual;
+
+create trigger t7_proc_bi before insert on t7_proc for each row
+ call audit_proc(NEW.a);
+
+create trigger t7_func_bi before insert on t7_func for each row
+ insert into t7_audit values (NULL, NEW.a, audit_func());
+
+create trigger t7_view_bi before insert on t7_view for each row
+ insert into t7_audit values (NULL, NEW.a, (select reason from audit_view));
+
+create trigger t7_table_bi before insert on t7_table for each row
+ insert into t7_dependent_table values (NULL, NEW.a, "dependent table");
+
+create trigger t7_table_trigger_bi before insert on t7_dependent_table
+ for each row set NEW.reason="trigger v1";
+
+prepare stmt_proc from 'insert into t7_proc(a) value (?)';
+set @val=101;
+execute stmt_proc using @val;
+eval $reprepared;
+set @val=102;
+execute stmt_proc using @val;
+eval $reprepared;
+
+drop procedure audit_proc;
+
+create procedure audit_proc(a int)
+ insert into t7_audit values (NULL, a, "proc v2");
+
+set @val=103;
+execute stmt_proc using @val;
+eval $reprepared;
+set @val=104;
+execute stmt_proc using @val;
+eval $reprepared;
+
+
+prepare stmt_func from 'insert into t7_func(a) value (?)';
+set @val=201;
+execute stmt_func using @val;
+eval $reprepared;
+set @val=202;
+execute stmt_func using @val;
+eval $reprepared;
+
+drop function audit_func;
+
+create function audit_func() returns varchar(50)
+ return "func v2";
+
+set @val=203;
+execute stmt_func using @val;
+eval $reprepared;
+set @val=204;
+execute stmt_func using @val;
+eval $reprepared;
+
+prepare stmt_view from 'insert into t7_view(a) value (?)';
+set @val=301;
+execute stmt_view using @val;
+eval $reprepared;
+set @val=302;
+execute stmt_view using @val;
+eval $reprepared;
+
+drop view audit_view;
+
+create view audit_view as select "view v2" as reason from dual;
+
+# Because of Bug#33255, the wrong result is still produced for cases
+# 303 and 304, even after re-preparing the statement.
+# This is because the table trigger is cached and is not invalidated.
+
+set @val=303;
+# REPREPARED +1
+execute stmt_view using @val;
+eval $reprepared;
+set @val=304;
+execute stmt_view using @val;
+eval $reprepared;
+
+
+prepare stmt_table from 'insert into t7_table(a) value (?)';
+set @val=401;
+execute stmt_table using @val;
+eval $reprepared;
+set @val=402;
+execute stmt_table using @val;
+eval $reprepared;
+
+alter table t7_dependent_table add column comments varchar(100) default NULL;
+
+set @val=403;
+# REPREPARED +1
+--error ER_WRONG_VALUE_COUNT_ON_ROW
+execute stmt_table using @val;
+eval $reprepared;
+set @val=404;
+--error ER_WRONG_VALUE_COUNT_ON_ROW
+execute stmt_table using @val;
+eval $reprepared;
+
+alter table t7_dependent_table drop column comments;
+
+set @val=405;
+# REPREPARED +1
+execute stmt_table using @val;
+eval $reprepared;
+set @val=406;
+execute stmt_table using @val;
+eval $reprepared;
+
+
+prepare stmt_table_trigger from 'insert into t7_table(a) value (?)';
+set @val=501;
+execute stmt_table_trigger using @val;
+eval $reprepared;
+set @val=502;
+execute stmt_table_trigger using @val;
+eval $reprepared;
+
+drop trigger t7_table_trigger_bi;
+
+create trigger t7_table_trigger_bi before insert on t7_dependent_table
+ for each row set NEW.reason="trigger v2";
+
+set @val=503;
+# REPREPARED +1
+execute stmt_table_trigger using @val;
+eval $reprepared;
+set @val=504;
+execute stmt_table_trigger using @val;
+eval $reprepared;
+
+select * from t7_audit order by new_a;
+
+select * from t7_dependent_table order by new_a;
+
+drop table t7_proc;
+drop table t7_func;
+drop table t7_view;
+drop table t7_table;
+drop table t7_dependent_table;
+drop table t7_table_trigger;
+drop table t7_audit;
+drop procedure audit_proc;
+drop function audit_func;
+drop view audit_view;
+
+--echo =====================================================================
+--echo Testing 8: TABLE -> TEMPORARY TABLE transitions
+--echo =====================================================================
+
+--disable_warnings
+drop table if exists t8;
+--enable_warnings
+
+eval $base_count;
+
+create table t8(a int);
+
+prepare stmt from 'select * from t8';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t8;
+create temporary table t8(a int);
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t8;
+
+--echo =====================================================================
+--echo Testing 9: TABLE -> VIEW transitions
+--echo =====================================================================
+
+--disable_warnings
+drop table if exists t9;
+drop table if exists t9_b;
+--enable_warnings
+
+eval $base_count;
+
+create table t9(a int);
+create table t9_b(a int);
+
+prepare stmt from 'select * from t9';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t9;
+create view t9 as select * from t9_b;
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop view t9;
+drop table t9_b;
+
+--echo =====================================================================
+--echo Testing 10: TEMPORARY TABLE -> NOTHING transitions
+--echo =====================================================================
+
+--disable_warnings
+drop temporary table if exists t10;
+--enable_warnings
+
+eval $base_count;
+
+create temporary table t10(a int);
+
+prepare stmt from 'select * from t10';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop temporary table t10;
+--error ER_NO_SUCH_TABLE
+execute stmt;
+eval $reprepared;
+--error ER_NO_SUCH_TABLE
+execute stmt;
+eval $reprepared;
+
+--echo =====================================================================
+--echo Testing 11: TEMPORARY TABLE -> TABLE transitions
+--echo =====================================================================
+
+--disable_warnings
+drop table if exists t11;
+drop temporary table if exists t11;
+--enable_warnings
+
+eval $base_count;
+
+create table t11(a int);
+insert into t11(a) value (1);
+create temporary table t11(a int);
+
+prepare stmt from 'select * from t11';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop temporary table t11;
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+select * from t11;
+drop table t11;
+
+--echo =====================================================================
+--echo Testing 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL) transitions
+--echo =====================================================================
+
+--disable_warnings
+drop temporary table if exists t12;
+--enable_warnings
+
+eval $base_count;
+
+create temporary table t12(a int);
+
+prepare stmt from 'select * from t12';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop temporary table t12;
+create temporary table t12(a int, b int);
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+select * from t12;
+drop table t12;
+
+--echo =====================================================================
+--echo Testing 13: TEMPORARY TABLE -> VIEW transitions
+--echo =====================================================================
+
+--disable_warnings
+drop temporary table if exists t13;
+drop table if exists t13_b;
+--enable_warnings
+
+eval $base_count;
+
+create temporary table t13(a int);
+create table t13_b(a int);
+
+prepare stmt from 'select * from t13';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop temporary table t13;
+create view t13 as select * from t13_b;
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop view t13;
+drop table t13_b;
+
+--echo =====================================================================
+--echo Testing 14: VIEW -> NOTHING transitions
+--echo =====================================================================
+
+--disable_warnings
+drop view if exists t14;
+drop table if exists t14_b;
+--enable_warnings
+
+eval $base_count;
+
+create table t14_b(a int);
+create view t14 as select * from t14_b;
+
+prepare stmt from 'select * from t14';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop view t14;
+
+# REPREPARED +1
+--error ER_NO_SUCH_TABLE
+execute stmt;
+eval $reprepared;
+--error ER_NO_SUCH_TABLE
+execute stmt;
+eval $reprepared;
+
+drop table t14_b;
+
+--echo =====================================================================
+--echo Testing 15: VIEW -> TABLE transitions
+--echo =====================================================================
+
+--disable_warnings
+drop view if exists t15;
+drop table if exists t15_b;
+--enable_warnings
+
+eval $base_count;
+
+create table t15_b(a int);
+create view t15 as select * from t15_b;
+
+prepare stmt from 'select * from t15';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop view t15;
+create table t15(a int);
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t15_b;
+drop table t15;
+
+--echo =====================================================================
+--echo Testing 16: VIEW -> TEMPORARY TABLE transitions
+--echo =====================================================================
+
+--disable_warnings
+drop view if exists t16;
+drop table if exists t16_b;
+--enable_warnings
+
+eval $base_count;
+
+create table t16_b(a int);
+create view t16 as select * from t16_b;
+
+prepare stmt from 'select * from t16';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop view t16;
+create temporary table t16(a int);
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t16_b;
+drop temporary table t16;
+
+--echo =====================================================================
+--echo Testing 17: VIEW -> VIEW (DDL) transitions
+--echo =====================================================================
+
+--disable_warnings
+drop view if exists t17;
+drop table if exists t17_b;
+--enable_warnings
+
+eval $base_count;
+
+create table t17_b(a int);
+insert into t17_b values (10), (20), (30);
+
+create view t17 as select a, 2*a as b, 3*a as c from t17_b;
+select * from t17;
+
+prepare stmt from 'select * from t17';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop view t17;
+create view t17 as select a, 2*a as b, 10*a as c from t17_b;
+select * from t17;
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t17_b;
+drop view t17;
+
+--echo =====================================================================
+--echo Testing 18: VIEW -> VIEW (VIEW dependencies) transitions
+--echo =====================================================================
+
+#
+# Test 18-a: dependent PROCEDURE has changed (via a trigger)
+# Test 18-b: dependent FUNCTION has changed
+# Test 18-c: dependent VIEW has changed
+# Test 18-d: dependent TABLE has changed
+# Test 18-e: dependent TABLE TRIGGER has changed
+#
+
+--disable_warnings
+drop table if exists t18;
+drop table if exists t18_dependent_table;
+drop view if exists t18_func;
+drop view if exists t18_view;
+drop view if exists t18_table;
+drop function if exists view_func;
+drop view if exists view_view;
+--enable_warnings
+
+eval $base_count;
+
+# TODO: insertable view -> trigger
+# TODO: insertable view -> trigger -> proc ?
+
+create table t18(a int);
+insert into t18 values (1), (2), (3);
+
+create function view_func(x int) returns int
+ return x+1;
+
+create view view_view as select "view v1" as reason from dual;
+
+create table t18_dependent_table(a int);
+
+create view t18_func as select a, view_func(a) as b from t18;
+create view t18_view as select a, reason as b from t18, view_view;
+create view t18_table as select * from t18;
+
+prepare stmt_func from 'select * from t18_func';
+execute stmt_func;
+eval $reprepared;
+execute stmt_func;
+eval $reprepared;
+
+drop function view_func;
+create function view_func(x int) returns int
+ return x*x;
+
+execute stmt_func;
+eval $reprepared;
+execute stmt_func;
+eval $reprepared;
+
+prepare stmt_view from 'select * from t18_view';
+execute stmt_view;
+eval $reprepared;
+execute stmt_view;
+eval $reprepared;
+
+drop view view_view;
+create view view_view as select "view v2" as reason from dual;
+
+# REPREPARED +1
+execute stmt_view;
+eval $reprepared;
+execute stmt_view;
+eval $reprepared;
+
+prepare stmt_table from 'select * from t18_table';
+execute stmt_table;
+eval $reprepared;
+execute stmt_table;
+eval $reprepared;
+
+alter table t18 add column comments varchar(50) default NULL;
+
+# REPREPARED +1
+execute stmt_table;
+eval $reprepared;
+execute stmt_table;
+eval $reprepared;
+
+drop table t18;
+drop table t18_dependent_table;
+drop view t18_func;
+drop view t18_view;
+drop view t18_table;
+drop function view_func;
+drop view view_view;
+
+--echo =====================================================================
+--echo Testing 19: Special tables (INFORMATION_SCHEMA)
+--echo =====================================================================
+
+--disable_warnings
+drop procedure if exists proc_19;
+--enable_warnings
+
+eval $base_count;
+
+# Using a temporary table internally should not confuse the prepared
+# statement code, and should not raise ER_PS_INVALIDATED errors
+prepare stmt from
+ 'select ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE
+ from INFORMATION_SCHEMA.ROUTINES where
+ routine_name=\'proc_19\'';
+
+create procedure proc_19() select "hi there";
+
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop procedure proc_19;
+create procedure proc_19() select "hi there, again";
+
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop procedure proc_19;
+
+--echo =====================================================================
+--echo Testing 20: Special tables (log tables)
+--echo =====================================================================
+
+eval $base_count;
+
+prepare stmt from
+ 'select * from mysql.general_log where argument=\'IMPOSSIBLE QUERY STRING\'';
+
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+--echo =====================================================================
+--echo Testing 21: Special tables (system tables)
+--echo =====================================================================
+
+--disable_warnings
+drop procedure if exists proc_21;
+--enable_warnings
+
+eval $base_count;
+
+prepare stmt from
+ 'select type, db, name from mysql.proc where name=\'proc_21\'';
+
+create procedure proc_21() select "hi there";
+
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop procedure proc_21;
+create procedure proc_21() select "hi there, again";
+
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop procedure proc_21;
+
+--echo =====================================================================
+--echo Testing 22: Special tables (views temp tables)
+--echo =====================================================================
+
+--disable_warnings
+drop table if exists t22_b;
+drop view if exists t22;
+--enable_warnings
+
+eval $base_count;
+
+create table t22_b(a int);
+
+create algorithm=temptable view t22 as select a*a as a2 from t22_b;
+
+# Using a temporary table internally should not confuse the prepared
+# statement code, and should not raise ER_PS_INVALIDATED errors
+show create view t22;
+
+prepare stmt from 'select * from t22';
+
+insert into t22_b values (1), (2), (3);
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+insert into t22_b values (4), (5), (6);
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t22_b;
+drop view t22;
+
+--echo =====================================================================
+--echo Testing 23: Special tables (internal join tables)
+--echo =====================================================================
+
+--disable_warnings
+drop table if exists t23_a;
+drop table if exists t23_b;
+--enable_warnings
+
+eval $base_count;
+
+create table t23_a(a int);
+create table t23_b(b int);
+
+# Using a temporary table internally should not confuse the prepared
+# statement code, and should not raise ER_PS_INVALIDATED errors
+prepare stmt from 'select * from t23_a join t23_b';
+
+insert into t23_a values (1), (2), (3);
+insert into t23_b values (10), (20), (30);
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+insert into t23_a values (4);
+insert into t23_b values (40);
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t23_a;
+drop table t23_b;
+
+--echo =====================================================================
+--echo Testing 24: Special statements
+--echo =====================================================================
+
+# SQLCOM_ALTER_TABLE:
+
+--disable_warnings
+drop table if exists t24_alter;
+--enable_warnings
+
+eval $base_count;
+
+create table t24_alter(a int);
+
+prepare stmt from 'alter table t24_alter add column b int';
+execute stmt;
+eval $reprepared;
+
+drop table t24_alter;
+create table t24_alter(a1 int, a2 int);
+
+# t24_alter has changed, and it's not a problem
+execute stmt;
+eval $reprepared;
+
+alter table t24_alter drop column b;
+execute stmt;
+eval $reprepared;
+
+alter table t24_alter drop column b;
+execute stmt;
+eval $reprepared;
+
+drop table t24_alter;
+
+# SQLCOM_REPAIR:
+
+--disable_warnings
+drop table if exists t24_repair;
+--enable_warnings
+
+create table t24_repair(a int);
+insert into t24_repair values (1), (2), (3);
+
+prepare stmt from 'repair table t24_repair';
+execute stmt;
+eval $reprepared;
+
+drop table t24_repair;
+create table t24_repair(a1 int, a2 int);
+insert into t24_repair values (1, 10), (2, 20), (3, 30);
+
+# t24_repair has changed, and it's not a problem
+execute stmt;
+eval $reprepared;
+
+alter table t24_repair add column b varchar(50) default NULL;
+execute stmt;
+eval $reprepared;
+
+alter table t24_repair drop column b;
+execute stmt;
+eval $reprepared;
+
+drop table t24_repair;
+
+# SQLCOM_ANALYZE:
+
+--disable_warnings
+drop table if exists t24_analyze;
+--enable_warnings
+
+create table t24_analyze(a int);
+insert into t24_analyze values (1), (2), (3);
+
+prepare stmt from 'analyze table t24_analyze';
+execute stmt;
+eval $reprepared;
+
+drop table t24_analyze;
+create table t24_analyze(a1 int, a2 int);
+insert into t24_analyze values (1, 10), (2, 20), (3, 30);
+
+# t24_analyze has changed, and it's not a problem
+execute stmt;
+eval $reprepared;
+
+alter table t24_analyze add column b varchar(50) default NULL;
+execute stmt;
+eval $reprepared;
+
+alter table t24_analyze drop column b;
+execute stmt;
+eval $reprepared;
+
+drop table t24_analyze;
+
+# SQLCOM_OPTIMIZE:
+
+--disable_warnings
+drop table if exists t24_optimize;
+--enable_warnings
+
+create table t24_optimize(a int);
+insert into t24_optimize values (1), (2), (3);
+
+prepare stmt from 'optimize table t24_optimize';
+execute stmt;
+eval $reprepared;
+
+drop table t24_optimize;
+create table t24_optimize(a1 int, a2 int);
+insert into t24_optimize values (1, 10), (2, 20), (3, 30);
+
+# t24_optimize has changed, and it's not a problem
+execute stmt;
+eval $reprepared;
+
+alter table t24_optimize add column b varchar(50) default NULL;
+execute stmt;
+eval $reprepared;
+
+alter table t24_optimize drop column b;
+execute stmt;
+eval $reprepared;
+
+drop table t24_optimize;
+
+# SQLCOM_SHOW_CREATE_PROC:
+
+--disable_warnings
+drop procedure if exists changing_proc;
+--enable_warnings
+
+prepare stmt from 'show create procedure changing_proc';
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+eval $reprepared;
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+eval $reprepared;
+
+create procedure changing_proc() begin end;
+
+# changing_proc has changed, and it's not a problem
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop procedure changing_proc;
+create procedure changing_proc(x int, y int) begin end;
+
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop procedure changing_proc;
+
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+eval $reprepared;
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+eval $reprepared;
+
+# SQLCOM_SHOW_CREATE_FUNC:
+
+--disable_warnings
+drop function if exists changing_func;
+--enable_warnings
+
+prepare stmt from 'show create function changing_func';
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+eval $reprepared;
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+eval $reprepared;
+
+create function changing_func() returns int return 0;
+
+# changing_proc has changed, and it's not a problem
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop function changing_func;
+create function changing_func(x int, y int) returns int return x+y;
+
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop function changing_func;
+
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+eval $reprepared;
+--error ER_SP_DOES_NOT_EXIST
+execute stmt;
+eval $reprepared;
+
+# SQLCOM_SHOW_CREATE_TRIGGER:
+
+--disable_warnings
+drop table if exists t24_trigger;
+--enable_warnings
+
+create table t24_trigger(a int);
+
+prepare stmt from 'show create trigger t24_bi;';
+--error ER_TRG_DOES_NOT_EXIST
+execute stmt;
+eval $reprepared;
+--error ER_TRG_DOES_NOT_EXIST
+execute stmt;
+eval $reprepared;
+
+delimiter $$;
+create trigger t24_bi before insert on t24_trigger for each row
+ begin
+ set @message= "t24_bi";
+ end
+$$
+delimiter ;$$
+
+# t24_bi has changed, and it's not a problem
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop trigger t24_bi;
+delimiter $$;
+create trigger t24_bi before insert on t24_trigger for each row
+ begin
+ set @message= "t24_bi (2)";
+ end
+$$
+delimiter ;$$
+
+# t24_bi has changed, and it's not a problem
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop trigger t24_bi;
+
+--error ER_TRG_DOES_NOT_EXIST
+execute stmt;
+eval $reprepared;
+--error ER_TRG_DOES_NOT_EXIST
+execute stmt;
+eval $reprepared;
+
+drop table t24_trigger;
+
+--echo =====================================================================
+--echo Testing 25: Testing the strength of TABLE_SHARE version
+--echo =====================================================================
+
+# Test 25-a: number of columns
+
+--disable_warnings
+drop table if exists t25_num_col;
+--enable_warnings
+
+eval $base_count;
+
+create table t25_num_col(a int);
+
+prepare stmt from 'select * from t25_num_col';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+alter table t25_num_col add column b varchar(50) default NULL;
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t25_num_col;
+
+# Test 25-b: column name
+
+--disable_warnings
+drop table if exists t25_col_name;
+--enable_warnings
+
+create table t25_col_name(a int);
+
+prepare stmt from 'select * from t25_col_name';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+alter table t25_col_name change a b int;
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t25_col_name;
+
+# Test 25-c: column type
+
+--disable_warnings
+drop table if exists t25_col_type;
+--enable_warnings
+
+create table t25_col_type(a int);
+
+prepare stmt from 'select * from t25_col_type';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+alter table t25_col_type change a a varchar(10);
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t25_col_type;
+
+# Test 25-d: column type length
+
+--disable_warnings
+drop table if exists t25_col_type_length;
+--enable_warnings
+
+create table t25_col_type_length(a varchar(10));
+
+prepare stmt from 'select * from t25_col_type_length';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+alter table t25_col_type_length change a a varchar(20);
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t25_col_type_length;
+
+# Test 25-e: column NULL property
+
+--disable_warnings
+drop table if exists t25_col_null;
+--enable_warnings
+
+create table t25_col_null(a varchar(10));
+
+prepare stmt from 'select * from t25_col_null';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+alter table t25_col_null change a a varchar(10) NOT NULL;
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t25_col_null;
+
+# Test 25-f: column DEFAULT
+
+--disable_warnings
+drop table if exists t25_col_default;
+--enable_warnings
+
+create table t25_col_default(a int, b int DEFAULT 10);
+
+prepare stmt from 'insert into t25_col_default(a) values (?)';
+set @val=1;
+execute stmt using @val;
+eval $reprepared;
+set @val=2;
+execute stmt using @val;
+eval $reprepared;
+
+alter table t25_col_default change b b int DEFAULT 20;
+
+set @val=3;
+# Must insert the correct default value for b
+execute stmt using @val;
+eval $reprepared;
+
+set @val=4;
+# Must insert the correct default value for b
+execute stmt using @val;
+eval $reprepared;
+
+select * from t25_col_default;
+
+drop table t25_col_default;
+
+# Test 25-g: number of keys
+
+--disable_warnings
+drop table if exists t25_index;
+--enable_warnings
+
+create table t25_index(a varchar(10));
+
+prepare stmt from 'select * from t25_index';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+create index i1 on t25_index(a);
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t25_index;
+
+# Test 25-h: changing index uniqueness
+
+--disable_warnings
+drop table if exists t25_index_unique;
+--enable_warnings
+
+create table t25_index_unique(a varchar(10), b varchar(10));
+create index i1 on t25_index_unique(a, b);
+
+show create table t25_index_unique;
+
+prepare stmt from 'select * from t25_index_unique';
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+alter table t25_index_unique drop index i1;
+create unique index i1 on t25_index_unique(a, b);
+
+show create table t25_index_unique;
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t25_index_unique;
+
+--echo =====================================================================
+--echo Testing reported bugs
+--echo =====================================================================
+
+#
+# Bug#12093 (SP not found on second PS execution if another thread drops
+# other SP in between)
+#
+
+--disable_warnings
+drop table if exists table_12093;
+drop function if exists func_12093;
+drop function if exists func_12093_unrelated;
+drop procedure if exists proc_12093;
+--enable_warnings
+
+eval $base_count;
+
+connect (con1,localhost,root,,);
+
+connection default;
+
+create table table_12093(a int);
+
+delimiter //;
+
+create function func_12093()
+returns int
+begin
+ return (select count(*) from table_12093);
+end//
+
+create procedure proc_12093(a int)
+begin
+ select * from table_12093;
+end//
+
+delimiter ;//
+
+create function func_12093_unrelated() returns int return 2;
+create procedure proc_12093_unrelated() begin end;
+
+prepare stmt_sf from 'select func_12093();';
+prepare stmt_sp from 'call proc_12093(func_12093())';
+
+execute stmt_sf;
+eval $reprepared;
+execute stmt_sp;
+eval $reprepared;
+
+connection con1;
+
+drop function func_12093_unrelated;
+drop procedure proc_12093_unrelated;
+
+connection default;
+
+# previously, failed with --error 1305
+execute stmt_sf;
+eval $reprepared;
+# previously, failed with --error 1305
+execute stmt_sp;
+eval $reprepared;
+
+# previously, failed with --error 1305
+execute stmt_sf;
+eval $reprepared;
+# previously, failed with --error 1305
+execute stmt_sp;
+eval $reprepared;
+
+deallocate prepare stmt_sf;
+deallocate prepare stmt_sp;
+
+disconnect con1;
+
+drop table table_12093;
+drop function func_12093;
+drop procedure proc_12093;
+
+#
+# Bug#21294 (executing a prepared statement that executes a stored function
+# which was recreat)
+#
+
+--disable_warnings
+drop function if exists func_21294;
+--enable_warnings
+
+eval $base_count;
+
+create function func_21294() returns int return 10;
+
+prepare stmt from "select func_21294()";
+execute stmt;
+eval $reprepared;
+
+drop function func_21294;
+create function func_21294() returns int return 10;
+
+# might pass or fail, implementation dependent
+execute stmt;
+eval $reprepared;
+
+drop function func_21294;
+create function func_21294() returns int return 20;
+
+execute stmt;
+eval $reprepared;
+
+deallocate prepare stmt;
+drop function func_21294;
+
+#
+# Bug#27420 (A combination of PS and view operations cause error + assertion
+# on shutdown)
+#
+
+--disable_warnings
+drop table if exists t_27420_100;
+drop table if exists t_27420_101;
+drop view if exists v_27420;
+--enable_warnings
+
+eval $base_count;
+
+connect (con1,localhost,root,,);
+
+connection default;
+
+create table t_27420_100(a int);
+insert into t_27420_100 values (1), (2);
+
+create table t_27420_101(a int);
+insert into t_27420_101 values (1), (2);
+
+create view v_27420 as select t_27420_100.a X, t_27420_101.a Y
+ from t_27420_100, t_27420_101
+ where t_27420_100.a=t_27420_101.a;
+
+prepare stmt from 'select * from v_27420';
+
+execute stmt;
+eval $reprepared;
+
+connection con1;
+
+drop view v_27420;
+create table v_27420(X int, Y int);
+
+connection default;
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+
+connection con1;
+
+drop table v_27420;
+# passes in 5.0, fails in 5.1, should pass
+create table v_27420 (a int, b int, filler char(200));
+
+connection default;
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+
+disconnect con1;
+
+deallocate prepare stmt;
+drop table t_27420_100;
+drop table t_27420_101;
+drop table v_27420;
+
+#
+# Bug#27430 (Crash in subquery code when in PS and table DDL changed after
+# PREPARE)
+#
+
+--disable_warnings
+drop table if exists t_27430_1;
+drop table if exists t_27430_2;
+--enable_warnings
+
+eval $base_count;
+
+create table t_27430_1 (a int not null, oref int not null, key(a));
+insert into t_27430_1 values
+ (1, 1),
+ (1, 1234),
+ (2, 3),
+ (2, 1234),
+ (3, 1234);
+
+create table t_27430_2 (a int not null, oref int not null);
+insert into t_27430_2 values
+ (1, 1),
+ (2, 2),
+ (1234, 3),
+ (1234, 4);
+
+prepare stmt from
+ 'select oref, a, a in (select a from t_27430_1 where oref=t_27430_2.oref) Z from t_27430_2';
+
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table t_27430_1, t_27430_2;
+
+create table t_27430_1 (a int, oref int, key(a));
+insert into t_27430_1 values
+ (1, 1),
+ (1, NULL),
+ (2, 3),
+ (2, NULL),
+ (3, NULL);
+
+create table t_27430_2 (a int, oref int);
+insert into t_27430_2 values
+ (1, 1),
+ (2,2),
+ (NULL, 3),
+ (NULL, 4);
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+deallocate prepare stmt;
+drop table t_27430_1;
+drop table t_27430_2;
+
+#
+# Bug#27690 (Re-execution of prepared statement after table was replaced
+# with a view crashes)
+#
+
+--disable_warnings
+drop table if exists t_27690_1;
+drop view if exists v_27690_1;
+drop table if exists v_27690_2;
+--enable_warnings
+
+eval $base_count;
+
+create table t_27690_1 (a int, b int);
+insert into t_27690_1 values (1,1),(2,2);
+
+create table v_27690_1 as select * from t_27690_1;
+create table v_27690_2 as select * from t_27690_1;
+
+prepare stmt from 'select * from v_27690_1, v_27690_2';
+
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+drop table v_27690_1;
+
+--error ER_NO_SUCH_TABLE
+execute stmt;
+eval $reprepared;
+
+--error ER_NO_SUCH_TABLE
+execute stmt;
+eval $reprepared;
+
+create view v_27690_1 as select A.a, A.b from t_27690_1 A, t_27690_1 B;
+
+# REPREPARED +1
+execute stmt;
+eval $reprepared;
+execute stmt;
+eval $reprepared;
+
+deallocate prepare stmt;
+drop table t_27690_1;
+drop view v_27690_1;
+drop table v_27690_2;
+
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index 06c2ef248c4..e20f0370e2c 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -935,6 +935,26 @@ SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
DROP TABLE t1;
+--echo
+--echo BUG#32198 "Comparison of DATE with DATETIME still not using indexes correctly"
+--echo
+CREATE TABLE t1 (
+ id int(11) NOT NULL auto_increment,
+ dateval date default NULL,
+ PRIMARY KEY (id),
+ KEY dateval (dateval)
+) AUTO_INCREMENT=173;
+
+INSERT INTO t1 VALUES
+(1,'2007-01-01'),(2,'2007-01-02'),(3,'2007-01-03'),(4,'2007-01-04'),
+(5,'2007-01-05'),(6,'2007-01-06'),(7,'2007-01-07'),(8,'2007-01-08'),
+(9,'2007-01-09'),(10,'2007-01-10'),(11,'2007-01-11');
+
+--echo This must use range access:
+explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '2007-01-02 23:59:59';
+
+drop table t1;
+
# End of 5.0 tests
# BUG#22393 fix: Adjust 'ref' estimate if we have 'range' estimate for
diff --git a/mysql-test/t/read_only.test b/mysql-test/t/read_only.test
index 709238c3d76..fd41a3225a6 100644
--- a/mysql-test/t/read_only.test
+++ b/mysql-test/t/read_only.test
@@ -225,3 +225,38 @@ connection default;
set global read_only=0;
drop table t1,t2;
drop user test@localhost;
+--echo #
+--echo # Bug #27440 read_only allows create and drop database
+--echo #
+set global read_only= 1;
+--disable_warnings
+drop database if exists mysqltest_db1;
+drop database if exists mysqltest_db2;
+--enable_warnings
+
+delete from mysql.user where User like 'mysqltest_%';
+delete from mysql.db where User like 'mysqltest_%';
+delete from mysql.tables_priv where User like 'mysqltest_%';
+delete from mysql.columns_priv where User like 'mysqltest_%';
+flush privileges;
+
+grant all on mysqltest_db2.* to `mysqltest_u1`@`%`;
+create database mysqltest_db1;
+grant all on mysqltest_db1.* to `mysqltest_u1`@`%`;
+flush privileges;
+connect (con_bug27440,127.0.0.1,mysqltest_u1,,test,$MASTER_MYPORT,);
+connection con_bug27440;
+--error ER_OPTION_PREVENTS_STATEMENT
+create database mysqltest_db2;
+show databases like '%mysqltest_db2%';
+--error ER_OPTION_PREVENTS_STATEMENT
+drop database mysqltest_db1;
+disconnect con_bug27440;
+connection default;
+delete from mysql.user where User like 'mysqltest_%';
+delete from mysql.db where User like 'mysqltest_%';
+delete from mysql.tables_priv where User like 'mysqltest_%';
+delete from mysql.columns_priv where User like 'mysqltest_%';
+flush privileges;
+drop database mysqltest_db1;
+set global read_only=0;
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 65e7f212732..bc0e4ae307f 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -3650,6 +3650,17 @@ DROP TABLE t2;
###########################################################################
+#
+# Bug #32335: Error on BIGINT > NULL + 1
+#
+
+CREATE TABLE t1 (c1 BIGINT NOT NULL);
+INSERT INTO t1 (c1) VALUES (1);
+SELECT * FROM t1 WHERE c1 > NULL + 1;
+DROP TABLE t1;
+
+--echo
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test
index 6a11791924a..25bf2a6ee61 100644
--- a/mysql-test/t/status.test
+++ b/mysql-test/t/status.test
@@ -242,4 +242,23 @@ let $tmp_table2 = `show global status like 'Created_tmp_tables'`;
eval select substring_index('$rnd_next2',0x9,-1)-substring_index('$rnd_next',0x9,-1) as rnd_diff, substring_index('$tmp_table2',0x9,-1)-substring_index('$tmp_table',0x9,-1) as tmp_table_diff;
--enable_query_log
+#
+# Bug#30252 Com_create_function is not incremented.
+#
+show global status like 'Com%function%';
+
+DELIMITER //;
+create function f1 (x INTEGER) returns integer
+ begin
+ declare ret integer;
+ set ret = x * 10;
+ return ret;
+ end //
+DELIMITER ;//
+
+drop function f1;
+
+show global status like 'Com%function%';
+
+
# End of 5.1 tests
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index df51239b256..077e00a4c6e 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -32,7 +32,9 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
-- error 1108
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
+-- error ER_BAD_FIELD_ERROR
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
+-- error ER_BAD_FIELD_ERROR
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
SELECT (SELECT 1,2,3) = ROW(1,2,3);
SELECT (SELECT 1,2,3) = ROW(1,2,1);
@@ -1346,17 +1348,20 @@ drop table t1,t2;
CREATE TABLE t1 ( a int, b int );
CREATE TABLE t2 ( c int, d int );
INSERT INTO t1 VALUES (1,2), (2,3), (3,4);
-SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);
-INSERT INTO t2 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);
+SELECT a AS abc, b FROM t1 outr WHERE b =
+ (SELECT MIN(b) FROM t1 WHERE a=outr.a);
+INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b =
+ (SELECT MIN(b) FROM t1 WHERE a=outr.a);
select * from t2;
-CREATE TABLE t3 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);
+CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b =
+ (SELECT MIN(b) FROM t1 WHERE a=outr.a);
select * from t3;
-prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);";
+prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
execute stmt1;
deallocate prepare stmt1;
select * from t2;
drop table t3;
-prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 WHERE b = (SELECT MIN(b) FROM t1 WHERE a=abc);";
+prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
execute stmt1;
select * from t3;
deallocate prepare stmt1;
@@ -1529,7 +1534,9 @@ INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,680
INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
/*!40000 ALTER TABLE t1 ENABLE KEYS */;
-SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
+SELECT DISTINCT Continent AS c FROM t1 outr WHERE
+ Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND
+ Population < 200);
drop table t1;
#
@@ -2448,12 +2455,16 @@ DROP TABLE t1, t2;
CREATE TABLE t1 (i INT);
(SELECT i FROM t1) UNION (SELECT i FROM t1);
+#TODO:not supported
+--error ER_PARSE_ERROR
SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
(
(SELECT i FROM t1) UNION
(SELECT i FROM t1)
);
+#TODO:not supported
+--error ER_PARSE_ERROR
SELECT * FROM t1
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
@@ -2461,7 +2472,9 @@ WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
--error 1064
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
from t1;
-#supported
+
+#TODO:not supported
+--error ER_PARSE_ERROR
explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
@@ -3044,6 +3057,86 @@ SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3;
SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
DROP TABLE t1, t2, t3;
+#
+# Bug #30788: Inconsistent retrieval of char/varchar
+#
+
+CREATE TABLE t1 (a CHAR(1), b VARCHAR(10));
+INSERT INTO t1 VALUES ('a', 'aa');
+INSERT INTO t1 VALUES ('a', 'aaa');
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+CREATE INDEX I1 ON t1 (a);
+CREATE INDEX I2 ON t1 (b);
+EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+
+CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10));
+INSERT INTO t2 SELECT * FROM t1;
+CREATE INDEX I1 ON t2 (a);
+CREATE INDEX I2 ON t2 (b);
+EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
+SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
+EXPLAIN
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
+
+DROP TABLE t1,t2;
+
+#
+# Bug #32400: Complex SELECT query returns correct result only on some
+# occasions
+#
+
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4);
+
+--error ER_BAD_FIELD_ERROR
+EXPLAIN
+SELECT a AS out_a, MIN(b) FROM t1
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
+GROUP BY a;
+
+--error ER_BAD_FIELD_ERROR
+SELECT a AS out_a, MIN(b) FROM t1
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
+GROUP BY a;
+
+EXPLAIN
+SELECT a AS out_a, MIN(b) FROM t1 t1_outer
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
+GROUP BY a;
+
+SELECT a AS out_a, MIN(b) FROM t1 t1_outer
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
+GROUP BY a;
+
+DROP TABLE t1;
+
+
+#
+# Bug #32036: EXISTS within a WHERE clause with a UNION crashes MySQL 5.122
+#
+
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+
+INSERT INTO t1 VALUES (1),(2);
+INSERT INTO t2 VALUES (1),(2);
+
+SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
+EXPLAIN EXTENDED
+SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
+
+
+#TODO:not supported
+--error ER_PARSE_ERROR
+EXPLAIN EXTENDED
+SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
+ (SELECT 1 FROM t2 WHERE t1.a = t2.a));
+
+DROP TABLE t1,t2;
+
+
--echo End of 5.0 tests.
#
diff --git a/mysql-test/t/subselect_notembedded.test b/mysql-test/t/subselect_notembedded.test
index c112272e8ad..040c90452b9 100644
--- a/mysql-test/t/subselect_notembedded.test
+++ b/mysql-test/t/subselect_notembedded.test
@@ -7,3 +7,99 @@
--error 1064
purge master logs before (select adddate(current_timestamp(), interval -4 day));
purge master logs before adddate(current_timestamp(), interval -4 day);
+
+#
+# Bug31048: Many nested subqueries may cause server crash.
+#
+create table t1(a int,b int,key(a),key(b));
+insert into t1(a,b) values (1,2),(2,1),(2,3),(3,4),(5,4),(5,5),
+ (6,7),(7,4),(5,3);
+# test for the stack overflow bug
+select sum(a),a from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1
+ )group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1)
+group by a;
+--replace_regex /overrun.*$/overrun detected/
+--error 1436
+select sum(a),a from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1)
+group by a;
+# test for the memory consumption & subquery slowness bug
+explain select sum(a),a from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1
+ )group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1)
+group by a;
+--replace_regex /overrun.*$/overrun detected/
+--error 1436
+explain select sum(a),a from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1 where a> ( select sum(a) from t1 where a> (
+ select sum(a) from t1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1
+ )group by b limit 1)group by b limit 1)group by b limit 1)
+group by a;
+drop table t1;
+
+
diff --git a/mysql-test/t/trigger_notembedded.test b/mysql-test/t/trigger_notembedded.test
index 748ae6e1c27..5d2ab84adaf 100644
--- a/mysql-test/t/trigger_notembedded.test
+++ b/mysql-test/t/trigger_notembedded.test
@@ -880,8 +880,9 @@ USE test;
# Bug#23713 LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock
#
-# Test temporarily disable due to Bug#32395
---disable_parsing
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
create table t1 (i int);
connect (flush,localhost,root,,test,,);
connection default;
@@ -906,6 +907,5 @@ connection default;
select * from t1;
drop table t1;
disconnect flush;
---enable_parsing
--echo End of 5.1 tests.
diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test
index b9d93c28115..44780fb9d01 100644
--- a/mysql-test/t/type_bit.test
+++ b/mysql-test/t/type_bit.test
@@ -318,6 +318,21 @@ INSERT INTO t2 VALUES (3, 2, 'two'), (2, 3, 'three'), (2, 0, 'zero'),
SELECT COUNT(DISTINCT b,c) FROM t2 GROUP BY a;
DROP TABLE t2;
+#
+# BUG#32556 assert in "using index for group-by" : is_last_prefix <= 0,
+# file .\opt_range.cc
+
+CREATE TABLE t1(a BIT(13), KEY(a));
+--disable_warnings
+INSERT INTO t1(a) VALUES
+(65535),(65525),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535);
+--enable_warnings
+
+EXPLAIN SELECT 1 FROM t1 GROUP BY a;
+SELECT 1 FROM t1 GROUP BY a;
+
+DROP TABLE t1;
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test
index b6febf8e76d..afb70b0bd0c 100644
--- a/mysql-test/t/type_blob.test
+++ b/mysql-test/t/type_blob.test
@@ -436,4 +436,15 @@ set @@sql_mode='TRADITIONAL';
create table t1 (a text default '');
set @@sql_mode='';
+#
+# Bug #32282: TEXT silently truncates when value is exactly 65536 bytes
+#
+
+CREATE TABLE t (c TEXT CHARSET ASCII);
+INSERT INTO t (c) VALUES (REPEAT('1',65537));
+INSERT INTO t (c) VALUES (REPEAT('2',65536));
+INSERT INTO t (c) VALUES (REPEAT('3',65535));
+SELECT LENGTH(c), CHAR_LENGTH(c) FROM t;
+DROP TABLE t;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test
index 14854406eb8..d714229c217 100644
--- a/mysql-test/t/type_date.test
+++ b/mysql-test/t/type_date.test
@@ -193,6 +193,26 @@ INSERT INTO t1 VALUES ('0000-00-00');
SET SQL_MODE=DEFAULT;
DROP TABLE t1,t2;
+#
+# Bug #31928: Search fails on '1000-00-00' date after sql_mode change
+#
+
+CREATE TABLE t1 (a DATE);
+CREATE TABLE t2 (a DATE);
+CREATE INDEX i ON t1 (a);
+INSERT INTO t1 VALUES ('1000-00-00'),('1000-00-00');
+INSERT INTO t2 VALUES ('1000-00-00'),('1000-00-00');
+SELECT * FROM t1 WHERE a = '1000-00-00';
+SELECT * FROM t2 WHERE a = '1000-00-00';
+SET SQL_MODE=TRADITIONAL;
+EXPLAIN SELECT * FROM t1 WHERE a = '1000-00-00';
+SELECT * FROM t1 WHERE a = '1000-00-00';
+SELECT * FROM t2 WHERE a = '1000-00-00';
+--error ER_TRUNCATED_WRONG_VALUE
+INSERT INTO t1 VALUES ('1000-00-00');
+SET SQL_MODE=DEFAULT;
+DROP TABLE t1,t2;
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test
index 747aab21ca6..4fdd96b8729 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -351,6 +351,43 @@ insert into t1 values (), (), ();
select sum(a) from t1 group by convert(a, datetime);
drop table t1;
+#
+# Bug #32694: NOT NULL table field in a subquery produces invalid results
+#
+create table t1 (id int(10) not null, cur_date datetime not null);
+create table t2 (id int(10) not null, cur_date date not null);
+insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22');
+insert into t2 (id, cur_date) values (1, '2007-04-25');
+
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+
+insert into t1 (id, cur_date) values (2, '2007-04-26 18:30:22');
+insert into t2 (id, cur_date) values (2, '2007-04-26');
+
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+
+drop table t1,t2;
+
--echo End of 5.0 tests
#
# Test of storing datetime into date fields
diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test
index 32cfca57546..e9ae1a31079 100644
--- a/mysql-test/t/udf.test
+++ b/mysql-test/t/udf.test
@@ -415,4 +415,25 @@ DROP PROCEDURE check_const_len_sp;
DROP TRIGGER check_const_len_trigger;
DROP TABLE const_len_bug;
+
+#
+# Bug #30355: Incorrect ordering of UDF results
+#
+
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
+eval CREATE FUNCTION sequence RETURNS INTEGER SONAME "$UDF_EXAMPLE_LIB";
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT PRIMARY KEY);
+INSERT INTO t1 VALUES (4),(3),(2),(1);
+INSERT INTO t2 SELECT * FROM t1;
+
+SELECT sequence() AS seq, a FROM t1 ORDER BY seq ASC;
+SELECT sequence() AS seq, a FROM t1 ORDER BY seq DESC;
+
+SELECT * FROM t1 WHERE a = sequence();
+SELECT * FROM t2 WHERE a = sequence();
+
+DROP FUNCTION sequence;
+DROP TABLE t1,t2;
+
--echo End of 5.0 tests.
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index a2f12bb495c..f2699ab03d3 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -239,6 +239,12 @@ select @a:=f4, count(f4) from t1 group by 1 desc;
drop table t1;
#
+# Bug#32482: Crash for a query with ORDER BY a user variable.
+#
+create table t1 (f1 int);
+insert into t1 values (2), (1);
+select @i := f1 as j from t1 order by 1;
+drop table t1;
# Bug #32260: User variables in query cause server crash
#
create table t1(a int);
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index c1580390f63..dd332a4f528 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -141,9 +141,9 @@ set GLOBAL myisam_max_sort_file_size=2000000;
show global variables like 'myisam_max_sort_file_size';
select * from information_schema.global_variables where variable_name like 'myisam_max_sort_file_size';
set GLOBAL myisam_max_sort_file_size=default;
---replace_result 2147483647 FILE_SIZE 9223372036854775807 FILE_SIZE
-show variables like 'myisam_max_sort_file_size';
---replace_result 2147483647 FILE_SIZE 9223372036854775807 FILE_SIZE
+--replace_result 9223372036853727232 FILE_SIZE 2146435072 FILE_SIZE
+show global variables like 'myisam_max_sort_file_size';
+--replace_result 9223372036853727232 FILE_SIZE 2146435072 FILE_SIZE
select * from information_schema.session_variables where variable_name like 'myisam_max_sort_file_size';
set global net_retry_count=10, session net_retry_count=10;
diff --git a/mysql-test/t/windows.test b/mysql-test/t/windows.test
index 0be81a95b9a..92ca0c3a3ec 100644
--- a/mysql-test/t/windows.test
+++ b/mysql-test/t/windows.test
@@ -36,6 +36,9 @@ EXPLAIN SELECT * FROM t1 WHERE b = (SELECT max(2));
--echo End of 5.0 tests.
+--disable_warnings
+drop procedure if exists proc_1;
+--enable_warnings
#
# Bug #20665: All commands supported in Stored Procedures should work in
# Prepared Statements
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index 3aad6152dfd..5132ac820b8 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -86,6 +86,7 @@ static void default_reporter(enum loglevel level,
fprintf(stderr, "%s", "Info: ");
vfprintf(stderr, format, args);
va_end(args);
+ fputc('\n', stderr);
fflush(stderr);
}
@@ -153,7 +154,7 @@ int handle_options(int *argc, char ***argv,
{
if (my_getopt_print_errors)
my_getopt_error_reporter(ERROR_LEVEL,
- "%s: Option '-O' requires an argument\n",
+ "%s: Option '-O' requires an argument",
my_progname);
return EXIT_ARGUMENT_REQUIRED;
}
@@ -171,7 +172,7 @@ int handle_options(int *argc, char ***argv,
{
if (my_getopt_print_errors)
my_getopt_error_reporter(ERROR_LEVEL,
- "%s: Option '--set-variable' requires an argument\n",
+ "%s: Option '--set-variable' requires an argument",
my_progname);
return EXIT_ARGUMENT_REQUIRED;
}
@@ -185,7 +186,7 @@ int handle_options(int *argc, char ***argv,
{
if (my_getopt_print_errors)
my_getopt_error_reporter(ERROR_LEVEL,
- "%s: Option '--set-variable' requires an argument\n",
+ "%s: Option '--set-variable' requires an argument",
my_progname);
return EXIT_ARGUMENT_REQUIRED;
}
@@ -247,7 +248,7 @@ int handle_options(int *argc, char ***argv,
{
if (my_getopt_print_errors)
my_getopt_error_reporter(ERROR_LEVEL,
- "%s: ambiguous option '--%s-%s' (--%s-%s)\n",
+ "%s: ambiguous option '--%s-%s' (--%s-%s)",
my_progname, special_opt_prefix[i],
cur_arg, special_opt_prefix[i],
prev_found);
@@ -298,7 +299,7 @@ int handle_options(int *argc, char ***argv,
if (my_getopt_print_errors)
my_getopt_error_reporter(option_is_loose ?
WARNING_LEVEL : ERROR_LEVEL,
- "%s: unknown variable '%s'\n",
+ "%s: unknown variable '%s'",
my_progname, cur_arg);
if (!option_is_loose)
return EXIT_UNKNOWN_VARIABLE;
@@ -308,7 +309,7 @@ int handle_options(int *argc, char ***argv,
if (my_getopt_print_errors)
my_getopt_error_reporter(option_is_loose ?
WARNING_LEVEL : ERROR_LEVEL,
- "%s: unknown option '--%s'\n",
+ "%s: unknown option '--%s'",
my_progname, cur_arg);
if (!option_is_loose)
return EXIT_UNKNOWN_OPTION;
@@ -326,7 +327,7 @@ int handle_options(int *argc, char ***argv,
{
if (my_getopt_print_errors)
my_getopt_error_reporter(ERROR_LEVEL,
- "%s: variable prefix '%s' is not unique\n",
+ "%s: variable prefix '%s' is not unique",
my_progname, opt_str);
return EXIT_VAR_PREFIX_NOT_UNIQUE;
}
@@ -334,7 +335,7 @@ int handle_options(int *argc, char ***argv,
{
if (my_getopt_print_errors)
my_getopt_error_reporter(ERROR_LEVEL,
- "%s: ambiguous option '--%s' (%s, %s)\n",
+ "%s: ambiguous option '--%s' (%s, %s)",
my_progname, opt_str, prev_found,
optp->name);
return EXIT_AMBIGUOUS_OPTION;
@@ -357,7 +358,7 @@ int handle_options(int *argc, char ***argv,
{
if (my_getopt_print_errors)
my_getopt_error_reporter(ERROR_LEVEL,
- "%s: option '%s' cannot take an argument\n",
+ "%s: option '%s' cannot take an argument",
my_progname, optp->name);
return EXIT_NO_ARGUMENT_ALLOWED;
}
@@ -370,7 +371,7 @@ int handle_options(int *argc, char ***argv,
{
if (my_getopt_print_errors)
my_getopt_error_reporter(ERROR_LEVEL,
- "%s: option '--%s' cannot take an argument\n",
+ "%s: option '--%s' cannot take an argument",
my_progname, optp->name);
return EXIT_NO_ARGUMENT_ALLOWED;
}
@@ -392,7 +393,7 @@ int handle_options(int *argc, char ***argv,
{
my_getopt_error_reporter(WARNING_LEVEL,
"%s: ignoring option '--%s' due to \
-invalid value '%s'\n",
+invalid value '%s'",
my_progname, optp->name, optend);
continue;
}
@@ -423,7 +424,7 @@ invalid value '%s'\n",
{
if (my_getopt_print_errors)
my_getopt_error_reporter(ERROR_LEVEL,
- "%s: option '--%s' requires an argument\n",
+ "%s: option '--%s' requires an argument",
my_progname, optp->name);
return EXIT_ARGUMENT_REQUIRED;
}
@@ -483,7 +484,7 @@ invalid value '%s'\n",
{
if (my_getopt_print_errors)
my_getopt_error_reporter(ERROR_LEVEL,
- "%s: option '-%c' requires an argument\n",
+ "%s: option '-%c' requires an argument",
my_progname, optp->id);
return EXIT_ARGUMENT_REQUIRED;
}
@@ -496,7 +497,7 @@ invalid value '%s'\n",
set_maximum_value)))
{
my_getopt_error_reporter(ERROR_LEVEL,
- "%s: Error while setting value '%s' to '%s'\n",
+ "%s: Error while setting value '%s' to '%s'",
my_progname, argument, optp->name);
return error;
}
@@ -508,7 +509,7 @@ invalid value '%s'\n",
{
if (my_getopt_print_errors)
my_getopt_error_reporter(ERROR_LEVEL,
- "%s: unknown option '-%c'\n",
+ "%s: unknown option '-%c'",
my_progname, *optend);
return EXIT_UNKNOWN_OPTION;
}
@@ -519,7 +520,7 @@ invalid value '%s'\n",
if ((error= setval(optp, value, argument, set_maximum_value)))
{
my_getopt_error_reporter(ERROR_LEVEL,
- "%s: Error while setting value '%s' to '%s'\n",
+ "%s: Error while setting value '%s' to '%s'",
my_progname, argument, optp->name);
return error;
}
@@ -608,13 +609,17 @@ static int setval(const struct my_option *opts, uchar* *value, char *argument,
*((my_bool*) result_pos)= (my_bool) atoi(argument) != 0;
break;
case GET_INT:
- case GET_UINT: /* fall through */
*((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
break;
+ case GET_UINT:
+ *((uint*) result_pos)= (uint) getopt_ull(argument, opts, &err);
+ break;
case GET_LONG:
- case GET_ULONG: /* fall through */
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
break;
+ case GET_ULONG:
+ *((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
+ break;
case GET_LL:
*((longlong*) result_pos)= getopt_ll(argument, opts, &err);
break;
@@ -778,23 +783,70 @@ static longlong eval_num_suffix(char *argument, int *error, char *option_name)
static longlong getopt_ll(char *arg, const struct my_option *optp, int *err)
{
- longlong num;
+ longlong num=eval_num_suffix(arg, err, (char*) optp->name);
+ return getopt_ll_limit_value(num, optp, NULL);
+}
+
+/*
+ function: getopt_ll_limit_value
+
+ Applies min/max/block_size to a numeric value of an option.
+ Returns "fixed" value.
+*/
+
+longlong getopt_ll_limit_value(longlong num, const struct my_option *optp,
+ bool *fix)
+{
+ longlong old= num;
+ bool adjusted= FALSE;
+ char buf1[255], buf2[255];
ulonglong block_size= (optp->block_size ? (ulonglong) optp->block_size : 1L);
-
- num= eval_num_suffix(arg, err, (char*) optp->name);
- if (num > 0 && (ulonglong) num > (ulonglong) optp->max_value &&
+
+ if (num > 0 && ((ulonglong) num > (ulonglong) optp->max_value) &&
optp->max_value) /* if max value is not set -> no upper limit */
{
- char buf[22];
- my_getopt_error_reporter(WARNING_LEVEL,
- "Truncated incorrect %s value: '%s'",
- optp->name, llstr(num, buf));
-
num= (ulonglong) optp->max_value;
+ adjusted= TRUE;
}
+
+ switch ((optp->var_type & GET_TYPE_MASK)) {
+ case GET_INT:
+ if (num > (longlong) INT_MAX)
+ {
+ num= ((longlong) INT_MAX);
+ adjusted= TRUE;
+ }
+ break;
+ case GET_LONG:
+#if SIZEOF_LONG < SIZEOF_LONG_LONG
+ if (num > (longlong) LONG_MAX)
+ {
+ num= ((longlong) LONG_MAX);
+ adjusted= TRUE;
+ }
+#endif
+ break;
+ default:
+ DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_LL);
+ break;
+ }
+
num= ((num - optp->sub_size) / block_size);
num= (longlong) (num * block_size);
- return max(num, optp->min_value);
+
+ if (num < optp->min_value)
+ {
+ num= optp->min_value;
+ adjusted= TRUE;
+ }
+
+ if (fix)
+ *fix= adjusted;
+ else if (adjusted)
+ my_getopt_error_reporter(WARNING_LEVEL,
+ "option '%s': signed value %s adjusted to %s",
+ optp->name, llstr(old, buf1), llstr(num, buf2));
+ return num;
}
/*
@@ -806,25 +858,66 @@ static longlong getopt_ll(char *arg, const struct my_option *optp, int *err)
static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err)
{
- ulonglong num;
-
- num= eval_num_suffix(arg, err, (char*) optp->name);
- return getopt_ull_limit_value(num, optp);
+ ulonglong num= eval_num_suffix(arg, err, (char*) optp->name);
+ return getopt_ull_limit_value(num, optp, NULL);
}
-ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp)
+ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp,
+ bool *fix)
{
+ bool adjusted= FALSE;
+ ulonglong old= num;
+ char buf1[255], buf2[255];
+
if ((ulonglong) num > (ulonglong) optp->max_value &&
optp->max_value) /* if max value is not set -> no upper limit */
+ {
num= (ulonglong) optp->max_value;
+ adjusted= TRUE;
+ }
+
+ switch ((optp->var_type & GET_TYPE_MASK)) {
+ case GET_UINT:
+ if (num > (ulonglong) UINT_MAX)
+ {
+ num= ((ulonglong) UINT_MAX);
+ adjusted= TRUE;
+ }
+ break;
+ case GET_ULONG:
+#if SIZEOF_LONG < SIZEOF_LONG_LONG
+ if (num > (ulonglong) ULONG_MAX)
+ {
+ num= ((ulonglong) ULONG_MAX);
+ adjusted= TRUE;
+ }
+#endif
+ break;
+ default:
+ DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_ULL);
+ break;
+ }
+
if (optp->block_size > 1)
{
num/= (ulonglong) optp->block_size;
num*= (ulonglong) optp->block_size;
}
+
if (num < (ulonglong) optp->min_value)
+ {
num= (ulonglong) optp->min_value;
+ adjusted= TRUE;
+ }
+
+ if (fix)
+ *fix= adjusted;
+ else if (adjusted)
+ my_getopt_error_reporter(WARNING_LEVEL,
+ "option '%s': unsigned value %s adjusted to %s",
+ optp->name, ullstr(old, buf1), ullstr(num, buf2));
+
return num;
}
diff --git a/mysys/queues.c b/mysys/queues.c
index bc7f0b74b4f..94f49ab8f9c 100644
--- a/mysys/queues.c
+++ b/mysys/queues.c
@@ -61,7 +61,7 @@ int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
queue->first_cmp_arg=first_cmp_arg;
queue->max_elements=max_elements;
queue->offset_to_key=offset_to_key;
- queue->max_at_top= max_at_top ? (-1 ^ 1) : 0;
+ queue_set_max_at_top(queue, max_at_top);
DBUG_RETURN(0);
}
@@ -137,7 +137,7 @@ int reinit_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
queue->compare=compare;
queue->first_cmp_arg=first_cmp_arg;
queue->offset_to_key=offset_to_key;
- queue->max_at_top= max_at_top ? (-1 ^ 1) : 0;
+ queue_set_max_at_top(queue, max_at_top);
resize_queue(queue, max_elements);
DBUG_RETURN(0);
}
@@ -208,16 +208,14 @@ void delete_queue(QUEUE *queue)
void queue_insert(register QUEUE *queue, uchar *element)
{
reg2 uint idx, next;
- int cmp;
DBUG_ASSERT(queue->elements < queue->max_elements);
queue->root[0]= element;
idx= ++queue->elements;
/* max_at_top swaps the comparison if we want to order by desc */
- while ((cmp= queue->compare(queue->first_cmp_arg,
- element + queue->offset_to_key,
- queue->root[(next= idx >> 1)] +
- queue->offset_to_key)) &&
- (cmp ^ queue->max_at_top) < 0)
+ while ((queue->compare(queue->first_cmp_arg,
+ element + queue->offset_to_key,
+ queue->root[(next= idx >> 1)] +
+ queue->offset_to_key) * queue->max_at_top) < 0)
{
queue->root[idx]= queue->root[next];
idx= next;
@@ -287,19 +285,17 @@ void _downheap(register QUEUE *queue, uint idx)
while (idx <= half_queue)
{
- int cmp;
next_index=idx+idx;
if (next_index < elements &&
(queue->compare(queue->first_cmp_arg,
queue->root[next_index]+offset_to_key,
- queue->root[next_index+1]+offset_to_key) ^
+ queue->root[next_index+1]+offset_to_key) *
queue->max_at_top) > 0)
next_index++;
if (first &&
- (((cmp=queue->compare(queue->first_cmp_arg,
- queue->root[next_index]+offset_to_key,
- element+offset_to_key)) == 0) ||
- ((cmp ^ queue->max_at_top) > 0)))
+ (((queue->compare(queue->first_cmp_arg,
+ queue->root[next_index]+offset_to_key,
+ element+offset_to_key) * queue->max_at_top) >= 0)))
{
queue->root[idx]= element;
return;
@@ -314,7 +310,7 @@ void _downheap(register QUEUE *queue, uint idx)
{
if ((queue->compare(queue->first_cmp_arg,
queue->root[next_index]+offset_to_key,
- element+offset_to_key) ^
+ element+offset_to_key) *
queue->max_at_top) < 0)
break;
queue->root[idx]=queue->root[next_index];
@@ -334,7 +330,6 @@ void _downheap(register QUEUE *queue, uint idx)
{
uchar *element;
uint elements,half_queue,next_index,offset_to_key;
- int cmp;
offset_to_key=queue->offset_to_key;
element=queue->root[idx];
@@ -346,13 +341,12 @@ void _downheap(register QUEUE *queue, uint idx)
if (next_index < elements &&
(queue->compare(queue->first_cmp_arg,
queue->root[next_index]+offset_to_key,
- queue->root[next_index+1]+offset_to_key) ^
+ queue->root[next_index+1]+offset_to_key) *
queue->max_at_top) > 0)
next_index++;
- if ((cmp=queue->compare(queue->first_cmp_arg,
- queue->root[next_index]+offset_to_key,
- element+offset_to_key)) == 0 ||
- (cmp ^ queue->max_at_top) > 0)
+ if ((queue->compare(queue->first_cmp_arg,
+ queue->root[next_index]+offset_to_key,
+ element+offset_to_key) * queue->max_at_top) >= 0)
break;
queue->root[idx]=queue->root[next_index];
idx=next_index;
diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist
index 957a5a6768d..a5b73ecc6c3 100755
--- a/scripts/make_win_bin_dist
+++ b/scripts/make_win_bin_dist
@@ -152,7 +152,6 @@ if [ x"$TARGET" != x"release" ] ; then
cp server-tools/instance-manager/$TARGET/*.pdb $DESTDIR/bin/
fi
cp tests/$TARGET/*.exe $DESTDIR/bin/
-cp libmysql/$TARGET/*.exe $DESTDIR/bin/
cp libmysql/$TARGET/libmysql.dll $DESTDIR/bin/
# FIXME really needed?!
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 260c372c802..3c1d3ae0fab 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -19,6 +19,7 @@
# All unrecognized arguments to this script are passed to mysqld.
basedir=""
+builddir=""
ldata="@localstatedir@"
srcdir=""
@@ -30,13 +31,18 @@ user=""
force=0
in_rpm=0
ip_only=0
-windows=0
+cross_bootstrap=0
usage()
{
cat <<EOF
Usage: $0 [OPTIONS]
--basedir=path The path to the MySQL installation directory.
+ --builddir=path If using --srcdir with out-of-directory builds, you
+ will need to set this to the location of the build
+ directory where built files reside.
+ --cross-bootstrap For internal use. Used when building the MySQL system
+ tables on a different host than the target.
--datadir=path The path to the MySQL data directory.
--force Causes mysql_install_db to run even if DNS does not
work. In that case, grant table entries that normally
@@ -56,8 +62,6 @@ Usage: $0 [OPTIONS]
user. You must be root to use this option. By default
mysqld runs using your current login name and files and
directories that it creates will be owned by you.
- --windows For internal use. This option is used for creating
- Windows distributions.
All other options are passed to the mysqld program
@@ -67,7 +71,7 @@ EOF
s_echo()
{
- if test "$in_rpm" -eq 0 -a "$windows" -eq 0
+ if test "$in_rpm" -eq 0 -a "$cross_bootstrap" -eq 0
then
echo "$1"
fi
@@ -95,6 +99,7 @@ parse_arguments()
case "$arg" in
--force) force=1 ;;
--basedir=*) basedir=`parse_arg "$arg"` ;;
+ --builddir=*) builddir=`parse_arg "$arg"` ;;
--srcdir=*) srcdir=`parse_arg "$arg"` ;;
--ldata=*|--datadir=*) ldata=`parse_arg "$arg"` ;;
--user=*)
@@ -109,16 +114,17 @@ parse_arguments()
--no-defaults|--defaults-file=*|--defaults-extra-file=*)
defaults="$arg" ;;
- --windows)
- # This is actually a "cross bootstrap" argument used when
- # building the MySQL system tables on a different host
- # than the target. The platform independent
- # files that are created in --datadir on the host can
- # be copied to the target system, the most common use for
- # this feature is in the windows installer which will take
- # the files from datadir and include them as part of the install
- # package.
- windows=1 ;;
+ --cross-bootstrap|--windows)
+ # Used when building the MySQL system tables on a different host than
+ # the target. The platform-independent files that are created in
+ # --datadir on the host can be copied to the target system.
+ #
+ # The most common use for this feature is in the Windows installer
+ # which will take the files from datadir and include them as part of
+ # the install package. See top-level 'dist-hook' make target.
+ #
+ # --windows is a deprecated alias
+ cross_bootstrap=1 ;;
*)
if test -n "$pick_args"
@@ -189,9 +195,18 @@ parse_arguments PICK-ARGS-FROM-ARGV "$@"
#
# or default to compiled-in locations.
#
+if test -n "$srcdir" && test -n "$basedir"
+then
+ echo "ERROR: Specify either --basedir or --srcdir, not both."
+ exit 1
+fi
if test -n "$srcdir"
then
- print_defaults="$srcdir/extra/my_print_defaults"
+ if test -z "$builddir"
+ then
+ builddir="$srcdir"
+ fi
+ print_defaults="$builddir/extra/my_print_defaults"
elif test -n "$basedir"
then
print_defaults=`find_in_basedir my_print_defaults bin extra`
@@ -213,10 +228,10 @@ parse_arguments PICK-ARGS-FROM-ARGV "$@"
# Configure paths to support files
if test -n "$srcdir"
then
- basedir="$srcdir"
- bindir="$srcdir/client"
- extra_bindir="$srcdir/extra"
- mysqld="$srcdir/sql/mysqld"
+ basedir="$builddir"
+ bindir="$basedir/client"
+ extra_bindir="$basedir/extra"
+ mysqld="$basedir/sql/mysqld"
mysqld_opt="--language=$srcdir/sql/share/english"
pkgdatadir="$srcdir/scripts"
scriptdir="$srcdir/scripts"
@@ -260,7 +275,7 @@ fi
hostname=`@HOSTNAME@`
# Check if hostname is valid
-if test "$windows" -eq 0 -a "$in_rpm" -eq 0 -a "$force" -eq 0
+if test "$cross_bootstrap" -eq 0 -a "$in_rpm" -eq 0 -a "$force" -eq 0
then
resolved=`$extra_bindir/resolveip $hostname 2>&1`
if test $? -ne 0
@@ -318,7 +333,7 @@ mysqld_install_cmd_line="$mysqld_bootstrap $defaults $mysqld_opt --bootstrap \
# Create the system and help tables by passing them to "mysqld --bootstrap"
s_echo "Installing MySQL system tables..."
-if `(echo "use mysql;"; cat $create_system_tables $fill_system_tables) | $mysqld_install_cmd_line`
+if { echo "use mysql;"; cat $create_system_tables $fill_system_tables; } | eval "$filter_cmd_line" | $mysqld_install_cmd_line > /dev/null
then
s_echo "OK"
else
@@ -363,12 +378,11 @@ fi
# Don't output verbose information if running inside bootstrap or using
# --srcdir for testing.
-if test "$windows" -eq 0 && test -z "$srcdir"
+if test "$cross_bootstrap" -eq 0 && test -z "$srcdir"
then
s_echo
s_echo "To start mysqld at boot time you have to copy"
s_echo "support-files/mysql.server to the right place for your system"
-
echo
echo "PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !"
echo "To do so, start the server, then issue the following commands:"
@@ -387,10 +401,8 @@ then
if test "$in_rpm" -eq 0
then
- echo
echo "You can start the MySQL daemon with:"
echo "cd $basedir ; $bindir/mysqld_safe &"
- echo
echo "You can test the MySQL daemon with mysql-test-run.pl"
echo "cd $basedir/mysql-test ; perl mysql-test-run.pl"
fi
diff --git a/scripts/mysql_system_tables_data.sql b/scripts/mysql_system_tables_data.sql
index 89558f99603..6db9430b972 100644
--- a/scripts/mysql_system_tables_data.sql
+++ b/scripts/mysql_system_tables_data.sql
@@ -2,6 +2,12 @@
-- The inital data for system tables of MySQL Server
--
+-- When setting up a "cross bootstrap" database (e.g., creating data on a Unix
+-- host which will later be included in a Windows zip file), any lines
+-- containing "@current_hostname" are filtered out by mysql_install_db.
+set @current_hostname= @@hostname;
+
+
-- Fill "db" table with default grants for anyone to
-- access database 'test' and 'test_%' if "db" table didn't exist
CREATE TEMPORARY TABLE tmp_db LIKE db;
@@ -14,11 +20,11 @@ DROP TABLE tmp_db;
-- Fill "users" table with default users allowing root access
-- from local machine if "users" table didn't exist before
CREATE TEMPORARY TABLE tmp_user LIKE user;
-set @hostname= @@hostname;
+set @current_hostname= @@hostname;
INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
-REPLACE INTO tmp_user VALUES (@hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
+REPLACE INTO tmp_user VALUES (@current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
INSERT INTO tmp_user (host,user) VALUES ('localhost','');
-INSERT INTO tmp_user (host,user) VALUES (@@hostname,'');
+INSERT INTO tmp_user (host,user) VALUES (@current_hostname,'');
INSERT INTO user SELECT * FROM tmp_user WHERE @had_user_table=0;
DROP TABLE tmp_user;
diff --git a/server-tools/instance-manager/mysql_connection.cc b/server-tools/instance-manager/mysql_connection.cc
index bf08f963aa3..3233b7513a1 100644
--- a/server-tools/instance-manager/mysql_connection.cc
+++ b/server-tools/instance-manager/mysql_connection.cc
@@ -257,7 +257,7 @@ int Mysql_connection::do_command()
return 1;
if (thread_registry->is_shutdown())
return 1;
- net_send_error(&net, net.last_errno);
+ net_send_error(&net, net.client_last_errno);
net.error= 0;
return 0;
}
diff --git a/sql-common/client.c b/sql-common/client.c
index f149442f12e..1a0f9c64d7d 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -289,8 +289,8 @@ void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate)
DBUG_ASSERT(mysql != 0);
net= &mysql->net;
- net->last_errno= errcode;
- strmov(net->last_error, ER(errcode));
+ net->client_last_errno= errcode;
+ strmov(net->client_last_error, ER(errcode));
strmov(net->sqlstate, sqlstate);
DBUG_VOID_RETURN;
@@ -304,8 +304,8 @@ void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate)
void net_clear_error(NET *net)
{
- net->last_errno= 0;
- net->last_error[0]= '\0';
+ net->client_last_errno= 0;
+ net->client_last_error[0]= '\0';
strmov(net->sqlstate, not_error_sqlstate);
}
@@ -331,9 +331,9 @@ static void set_mysql_extended_error(MYSQL *mysql, int errcode,
DBUG_ASSERT(mysql != 0);
net= &mysql->net;
- net->last_errno= errcode;
+ net->client_last_errno= errcode;
va_start(args, format);
- my_vsnprintf(net->last_error, sizeof(net->last_error)-1,
+ my_vsnprintf(net->client_last_error, sizeof(net->client_last_error)-1,
format, args);
va_end(args);
strmov(net->sqlstate, sqlstate);
@@ -667,7 +667,7 @@ cli_safe_read(MYSQL *mysql)
return (packet_error);
#endif /*MYSQL_SERVER*/
end_server(mysql);
- set_mysql_error(mysql, net->last_errno == ER_NET_PACKET_TOO_LARGE ?
+ set_mysql_error(mysql, net->client_last_errno == ER_NET_PACKET_TOO_LARGE ?
CR_NET_PACKET_TOO_LARGE: CR_SERVER_LOST, unknown_sqlstate);
return (packet_error);
}
@@ -676,7 +676,7 @@ cli_safe_read(MYSQL *mysql)
if (len > 3)
{
char *pos=(char*) net->read_pos+1;
- net->last_errno=uint2korr(pos);
+ net->client_last_errno=uint2korr(pos);
pos+=2;
len-=2;
if (protocol_41(mysql) && pos[0] == '#')
@@ -684,8 +684,8 @@ cli_safe_read(MYSQL *mysql)
strmake(net->sqlstate, pos+1, SQLSTATE_LENGTH);
pos+= SQLSTATE_LENGTH+1;
}
- (void) strmake(net->last_error,(char*) pos,
- min((uint) len,(uint) sizeof(net->last_error)-1));
+ (void) strmake(net->client_last_error,(char*) pos,
+ min((uint) len,(uint) sizeof(net->client_last_error)-1));
}
else
set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
@@ -701,7 +701,9 @@ cli_safe_read(MYSQL *mysql)
mysql->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
DBUG_PRINT("error",("Got error: %d/%s (%s)",
- net->last_errno, net->sqlstate, net->last_error));
+ net->client_last_errno,
+ net->sqlstate,
+ net->client_last_error));
return(packet_error);
}
return len;
@@ -744,7 +746,6 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
}
net_clear_error(net);
- net->report_error=0;
mysql->info=0;
mysql->affected_rows= ~(my_ulonglong) 0;
/*
@@ -759,7 +760,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
{
DBUG_PRINT("error",("Can't send command to server. Error: %d",
socket_errno));
- if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
+ if (net->client_last_errno == ER_NET_PACKET_TOO_LARGE)
{
set_mysql_error(mysql, CR_NET_PACKET_TOO_LARGE, unknown_sqlstate);
goto end;
@@ -836,16 +837,15 @@ static my_bool is_NT(void)
#ifdef CHECK_LICENSE
-/*
+/**
Check server side variable 'license'.
- If the variable does not exist or does not contain 'Commercial',
+
+ If the variable does not exist or does not contain 'Commercial',
we're talking to non-commercial server from commercial client.
- SYNOPSIS
- check_license()
- RETURN VALUE
- 0 success
- !0 network error or the server is not commercial.
- Error code is saved in mysql->net.last_errno.
+
+ @retval 0 success
+ @retval !0 network error or the server is not commercial.
+ Error code is saved in mysql->net.client_last_errno.
*/
static int check_license(MYSQL *mysql)
@@ -858,7 +858,7 @@ static int check_license(MYSQL *mysql)
if (mysql_real_query(mysql, query, sizeof(query)-1))
{
- if (net->last_errno == ER_UNKNOWN_SYSTEM_VARIABLE)
+ if (net->client_last_errno == ER_UNKNOWN_SYSTEM_VARIABLE)
{
set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
ER(CR_WRONG_LICENSE), required_license);
@@ -873,7 +873,7 @@ static int check_license(MYSQL *mysql)
two is ever true for server variables now), or column value
mismatch, set wrong license error.
*/
- if (!net->last_errno &&
+ if (!net->client_last_errno &&
(!row || !row[0] ||
strncmp(row[0], required_license, sizeof(required_license))))
{
@@ -881,7 +881,7 @@ static int check_license(MYSQL *mysql)
ER(CR_WRONG_LICENSE), required_license);
}
mysql_free_result(res);
- return net->last_errno;
+ return net->client_last_errno;
}
#endif /* CHECK_LICENSE */
@@ -2090,7 +2090,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
if ((pkt_length=cli_safe_read(mysql)) == packet_error)
{
- if (mysql->net.last_errno == CR_SERVER_LOST)
+ if (mysql->net.client_last_errno == CR_SERVER_LOST)
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
ER(CR_SERVER_LOST_EXTENDED),
"reading initial communication packet",
@@ -2324,7 +2324,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
if ((pkt_length=cli_safe_read(mysql)) == packet_error)
{
- if (mysql->net.last_errno == CR_SERVER_LOST)
+ if (mysql->net.client_last_errno == CR_SERVER_LOST)
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
ER(CR_SERVER_LOST_EXTENDED),
"reading authorization packet",
@@ -2352,7 +2352,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
/* Read what server thinks about out new auth message report */
if (cli_safe_read(mysql) == packet_error)
{
- if (mysql->net.last_errno == CR_SERVER_LOST)
+ if (mysql->net.client_last_errno == CR_SERVER_LOST)
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
ER(CR_SERVER_LOST_EXTENDED),
"reading final connect information",
@@ -2371,7 +2371,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
if (db && mysql_select_db(mysql, db))
{
- if (mysql->net.last_errno == CR_SERVER_LOST)
+ if (mysql->net.client_last_errno == CR_SERVER_LOST)
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
ER(CR_SERVER_LOST_EXTENDED),
"Setting intital database",
@@ -2415,7 +2415,9 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
error:
reset_sigpipe(mysql);
DBUG_PRINT("error",("message: %u/%s (%s)",
- net->last_errno, net->sqlstate, net->last_error));
+ net->client_last_errno,
+ net->sqlstate,
+ net->client_last_error));
{
/* Free alloced memory */
end_server(mysql);
@@ -2473,8 +2475,8 @@ my_bool mysql_reconnect(MYSQL *mysql)
mysql->db, mysql->port, mysql->unix_socket,
mysql->client_flag | CLIENT_REMEMBER_OPTIONS))
{
- mysql->net.last_errno= tmp_mysql.net.last_errno;
- strmov(mysql->net.last_error, tmp_mysql.net.last_error);
+ mysql->net.client_last_errno= tmp_mysql.net.client_last_errno;
+ strmov(mysql->net.client_last_error, tmp_mysql.net.client_last_error);
strmov(mysql->net.sqlstate, tmp_mysql.net.sqlstate);
DBUG_RETURN(1);
}
@@ -2483,8 +2485,8 @@ my_bool mysql_reconnect(MYSQL *mysql)
DBUG_PRINT("error", ("mysql_set_character_set() failed"));
bzero((char*) &tmp_mysql.options,sizeof(tmp_mysql.options));
mysql_close(&tmp_mysql);
- mysql->net.last_errno= tmp_mysql.net.last_errno;
- strmov(mysql->net.last_error, tmp_mysql.net.last_error);
+ mysql->net.client_last_errno= tmp_mysql.net.client_last_errno;
+ strmov(mysql->net.client_last_error, tmp_mysql.net.client_last_error);
strmov(mysql->net.sqlstate, tmp_mysql.net.sqlstate);
DBUG_RETURN(1);
}
@@ -3077,13 +3079,13 @@ unsigned int STDCALL mysql_num_fields(MYSQL_RES *res)
uint STDCALL mysql_errno(MYSQL *mysql)
{
- return mysql->net.last_errno;
+ return mysql->net.client_last_errno;
}
const char * STDCALL mysql_error(MYSQL *mysql)
{
- return mysql->net.last_error;
+ return mysql->net.client_last_error;
}
@@ -3152,7 +3154,7 @@ int STDCALL mysql_set_character_set(MYSQL *mysql, const char *cs_name)
ER(CR_CANT_READ_CHARSET), cs_name, cs_dir_name);
}
charsets_dir= save_csdir;
- return mysql->net.last_errno;
+ return mysql->net.client_last_errno;
}
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index 48d1b198dfc..543a925681b 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -1105,9 +1105,14 @@ longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
long part1,part2;
*was_cut= 0;
+ bzero((char*) time_res, sizeof(*time_res));
+ time_res->time_type=MYSQL_TIMESTAMP_DATE;
if (nr == LL(0) || nr >= LL(10000101000000))
+ {
+ time_res->time_type=MYSQL_TIMESTAMP_DATETIME;
goto ok;
+ }
if (nr < 101)
goto err;
if (nr <= (YY_PART_YEAR-1)*10000L+1231L)
@@ -1131,6 +1136,9 @@ longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
}
if (nr < 101000000L)
goto err;
+
+ time_res->time_type=MYSQL_TIMESTAMP_DATETIME;
+
if (nr <= (YY_PART_YEAR-1)*LL(10000000000)+LL(1231235959))
{
nr= nr+LL(20000000000000); /* YYMMDDHHMMSS, 2000-2069 */
@@ -1144,7 +1152,6 @@ 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/Makefile.am b/sql/Makefile.am
index 1d7655fd639..194b6ab29ef 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -163,6 +163,7 @@ link_sources:
@LN_CP_F@ $(top_srcdir)/sql-common/my_time.c my_time.c
rm -f my_user.c
@LN_CP_F@ $(top_srcdir)/sql-common/my_user.c my_user.c
+ echo timestamp > link_sources
# This generates lex_hash.h
# NOTE Built sources should depend on their sources not the tool
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index adac2b596c1..f4b64ab3012 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -1649,8 +1649,6 @@ err:
void
Event_queue_element::mark_last_executed(THD *thd)
{
- thd->set_current_time();
-
last_executed= (my_time_t) thd->query_start();
last_executed_changed= TRUE;
diff --git a/sql/events.cc b/sql/events.cc
index 73b8f2cda84..87385082a82 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -825,8 +825,8 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */)
if (thd->lex->sql_command == SQLCOM_SHOW_EVENTS)
{
DBUG_ASSERT(thd->lex->select_lex.db);
- if (check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
- is_schema_db(thd->lex->select_lex.db)))
+ if (!is_schema_db(thd->lex->select_lex.db) && // There is no events in I_S
+ check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0, 0))
DBUG_RETURN(1);
db= thd->lex->select_lex.db;
}
diff --git a/sql/field.cc b/sql/field.cc
index 432b78da3e0..16217e69de9 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5698,6 +5698,9 @@ void Field_date::sql_type(String &res) const
1 Value was cut during conversion
2 Wrong date string
3 Datetime value that was cut (warning level NOTE)
+ This is used by opt_range.cc:get_mm_leaf(). Note that there is a
+ nearly-identical class Field_date doesn't ever return 3 from its
+ store function.
*/
int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
diff --git a/sql/field.h b/sql/field.h
index 4b09f50a59a..9f76deb18bc 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -25,6 +25,7 @@
#define NOT_FIXED_DEC 31
#define DATETIME_DEC 6
+const uint32 max_field_size= (uint32) 4294967295U;
class Send_field;
class Protocol;
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index b0ddc95a38b..441da21bf1c 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -580,7 +580,7 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans)
bzero((char*) &table_list,sizeof(table_list));
table_list.db= m_dbname;
table_list.alias= table_list.table_name= m_tabname;
- close_cached_tables(thd, 0, &table_list);
+ close_cached_tables(thd, &table_list, FALSE, FALSE, FALSE);
break;
}
default:
@@ -591,6 +591,24 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans)
err.code, res));
if (res == HA_ERR_FOUND_DUPP_KEY)
{
+ char *error_data= err.details;
+ uint dupkey= MAX_KEY;
+
+ for (uint i= 0; i < MAX_KEY; i++)
+ {
+ if (m_index[i].type == UNIQUE_INDEX ||
+ m_index[i].type == UNIQUE_ORDERED_INDEX)
+ {
+ const NDBINDEX *unique_index=
+ (const NDBINDEX *) m_index[i].unique_index;
+ if (unique_index &&
+ (char *) unique_index->getObjectId() == error_data)
+ {
+ dupkey= i;
+ break;
+ }
+ }
+ }
if (m_rows_to_insert == 1)
{
/*
@@ -598,7 +616,7 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans)
violations here, so we need to return MAX_KEY for non-primary
to signal that key is unknown
*/
- m_dupkey= err.code == 630 ? table_share->primary_key : MAX_KEY;
+ m_dupkey= err.code == 630 ? table_share->primary_key : dupkey;
}
else
{
@@ -621,7 +639,7 @@ bool ha_ndbcluster::get_error_message(int error,
DBUG_ENTER("ha_ndbcluster::get_error_message");
DBUG_PRINT("enter", ("error: %d", error));
- Ndb *ndb= get_ndb();
+ Ndb *ndb= check_ndb_in_thd(current_thd);
if (!ndb)
DBUG_RETURN(FALSE);
@@ -829,12 +847,12 @@ NdbBlob::ActiveHook g_get_ndb_blobs_value;
/**
Callback to read all blob values.
- - not done in unpack_record because unpack_record is valid
- after execute(Commit) but reading blobs is not
- - may only generate read operations; they have to be executed
- somewhere before the data is available
- - due to single buffer for all blobs, we let the last blob
- process all blobs (last so that all are active)
+ - not done in unpack_record because unpack_record is valid
+ after execute(Commit) but reading blobs is not
+ - may only generate read operations; they have to be executed
+ somewhere before the data is available
+ - due to single buffer for all blobs, we let the last blob
+ process all blobs (last so that all are active)
- null bit is still set in unpack_record.
@todo
@@ -2708,6 +2726,29 @@ int ha_ndbcluster::full_table_scan(uchar *buf)
DBUG_RETURN(next_result(buf));
}
+int
+ha_ndbcluster::set_auto_inc(Field *field)
+{
+ DBUG_ENTER("ha_ndbcluster::set_auto_inc");
+ Ndb *ndb= get_ndb();
+ bool read_bit= bitmap_is_set(table->read_set, field->field_index);
+ bitmap_set_bit(table->read_set, field->field_index);
+ Uint64 next_val= (Uint64) field->val_int() + 1;
+ if (!read_bit)
+ bitmap_clear_bit(table->read_set, field->field_index);
+#ifndef DBUG_OFF
+ char buff[22];
+ DBUG_PRINT("info",
+ ("Trying to set next auto increment value to %s",
+ llstr(next_val, buff)));
+#endif
+ Ndb_tuple_id_range_guard g(m_share);
+ if (ndb->setAutoIncrementValue(m_table, g.range, next_val, TRUE)
+ == -1)
+ ERR_RETURN(ndb->getNdbError());
+ DBUG_RETURN(0);
+}
+
/**
Insert one record into NDB.
*/
@@ -2914,18 +2955,11 @@ int ha_ndbcluster::write_row(uchar *record)
}
if ((has_auto_increment) && (m_skip_auto_increment))
{
- Ndb *ndb= get_ndb();
- Uint64 next_val= (Uint64) table->next_number_field->val_int() + 1;
-#ifndef DBUG_OFF
- char buff[22];
- DBUG_PRINT("info",
- ("Trying to set next auto increment value to %s",
- llstr(next_val, buff)));
-#endif
- Ndb_tuple_id_range_guard g(m_share);
- if (ndb->setAutoIncrementValue(m_table, g.range, next_val, TRUE)
- == -1)
- ERR_RETURN(ndb->getNdbError());
+ int ret_val;
+ if ((ret_val= set_auto_inc(table->next_number_field)))
+ {
+ DBUG_RETURN(ret_val);
+ }
}
m_skip_auto_increment= TRUE;
@@ -3052,6 +3086,17 @@ int ha_ndbcluster::update_row(const uchar *old_data, uchar *new_data)
// Insert new row
DBUG_PRINT("info", ("delete succeded"));
m_primary_key_update= TRUE;
+ /*
+ If we are updating a primary key with auto_increment
+ then we need to update the auto_increment counter
+ */
+ if (table->found_next_number_field &&
+ bitmap_is_set(table->write_set,
+ table->found_next_number_field->field_index) &&
+ (error= set_auto_inc(table->found_next_number_field)))
+ {
+ DBUG_RETURN(error);
+ }
insert_res= write_row(new_data);
m_primary_key_update= FALSE;
if (insert_res)
@@ -3074,7 +3119,17 @@ int ha_ndbcluster::update_row(const uchar *old_data, uchar *new_data)
DBUG_PRINT("info", ("delete+insert succeeded"));
DBUG_RETURN(0);
}
-
+ /*
+ If we are updating a unique key with auto_increment
+ then we need to update the auto_increment counter
+ */
+ if (table->found_next_number_field &&
+ bitmap_is_set(table->write_set,
+ table->found_next_number_field->field_index) &&
+ (error= set_auto_inc(table->found_next_number_field)))
+ {
+ DBUG_RETURN(error);
+ }
if (cursor)
{
/*
@@ -4481,9 +4536,11 @@ int ha_ndbcluster::init_handler_for_statement(THD *thd, Thd_ndb *thd_ndb)
// store thread specific data first to set the right context
m_force_send= thd->variables.ndb_force_send;
m_ha_not_exact_count= !thd->variables.ndb_use_exact_count;
- m_autoincrement_prefetch=
- (ha_rows) thd->variables.ndb_autoincrement_prefetch_sz;
-
+ m_autoincrement_prefetch=
+ (thd->variables.ndb_autoincrement_prefetch_sz >
+ NDB_DEFAULT_AUTO_PREFETCH) ?
+ (ha_rows) thd->variables.ndb_autoincrement_prefetch_sz
+ : (ha_rows) NDB_DEFAULT_AUTO_PREFETCH;
m_active_trans= thd_ndb->trans;
DBUG_ASSERT(m_active_trans);
// Start of transaction
@@ -6171,8 +6228,9 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment,
ulonglong *first_value,
ulonglong *nb_reserved_values)
{
- int cache_size;
+ uint cache_size;
Uint64 auto_value;
+ THD *thd= current_thd;
DBUG_ENTER("get_auto_increment");
DBUG_PRINT("enter", ("m_tabname: %s", m_tabname));
Ndb *ndb= get_ndb();
@@ -6182,11 +6240,14 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment,
/* We guessed too low */
m_rows_to_insert+= m_autoincrement_prefetch;
}
- cache_size=
- (int) ((m_rows_to_insert - m_rows_inserted < m_autoincrement_prefetch) ?
- m_rows_to_insert - m_rows_inserted :
- ((m_rows_to_insert > m_autoincrement_prefetch) ?
- m_rows_to_insert : m_autoincrement_prefetch));
+ uint remaining= m_rows_to_insert - m_rows_inserted;
+ uint min_prefetch=
+ (remaining < thd->variables.ndb_autoincrement_prefetch_sz) ?
+ thd->variables.ndb_autoincrement_prefetch_sz
+ : remaining;
+ cache_size= ((remaining < m_autoincrement_prefetch) ?
+ min_prefetch
+ : remaining);
uint retries= NDB_AUTO_INCREMENT_RETRIES;
int retry_sleep= 30; /* 30 milliseconds, transaction */
for (;;)
@@ -6273,7 +6334,7 @@ ha_ndbcluster::ha_ndbcluster(handlerton *hton, TABLE_SHARE *table_arg):
m_dupkey((uint) -1),
m_ha_not_exact_count(FALSE),
m_force_send(TRUE),
- m_autoincrement_prefetch((ha_rows) 32),
+ m_autoincrement_prefetch((ha_rows) NDB_DEFAULT_AUTO_PREFETCH),
m_transaction_on(TRUE),
m_cond(NULL),
m_multi_cursor(NULL)
@@ -8078,7 +8139,7 @@ int handle_trailing_share(NDB_SHARE *share)
table_list.db= share->db;
table_list.alias= table_list.table_name= share->table_name;
safe_mutex_assert_owner(&LOCK_open);
- close_cached_tables(thd, 0, &table_list, TRUE);
+ close_cached_tables(thd, &table_list, TRUE, FALSE, FALSE);
pthread_mutex_lock(&ndbcluster_mutex);
/* ndb_share reference temporary free */
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index fd337303853..cc79402fe92 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -31,6 +31,8 @@
#include <ndbapi_limits.h>
#define NDB_HIDDEN_PRIMARY_KEY_LENGTH 8
+#define NDB_DEFAULT_AUTO_PREFETCH 32
+
class Ndb; // Forward declaration
class NdbOperation; // Forward declaration
@@ -446,6 +448,7 @@ private:
uint errcode);
int peek_indexed_rows(const uchar *record, NDB_WRITE_OP write_op);
int fetch_next(NdbScanOperation* op);
+ int set_auto_inc(Field *field);
int next_result(uchar *buf);
int define_read_attrs(uchar* buf, NdbOperation* op);
int filtered_scan(const uchar *key, uint key_len,
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index be75eff2575..07b0d907229 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -241,22 +241,30 @@ static void dbug_print_table(const char *info, TABLE *table)
static void run_query(THD *thd, char *buf, char *end,
const int *no_print_error, my_bool disable_binlog)
{
- ulong save_query_length= thd->query_length;
- char *save_query= thd->query;
+ ulong save_thd_query_length= thd->query_length;
+ char *save_thd_query= thd->query;
ulong save_thread_id= thd->variables.pseudo_thread_id;
+ struct system_status_var save_thd_status_var= thd->status_var;
+ THD_TRANS save_thd_transaction_all= thd->transaction.all;
+ THD_TRANS save_thd_transaction_stmt= thd->transaction.stmt;
ulonglong save_thd_options= thd->options;
DBUG_ASSERT(sizeof(save_thd_options) == sizeof(thd->options));
- NET save_net= thd->net;
+ NET save_thd_net= thd->net;
const char* found_semicolon= NULL;
bzero((char*) &thd->net, sizeof(NET));
thd->query_length= end - buf;
thd->query= buf;
thd->variables.pseudo_thread_id= thread_id;
+ thd->transaction.stmt.modified_non_trans_table= FALSE;
if (disable_binlog)
thd->options&= ~OPTION_BIN_LOG;
DBUG_PRINT("query", ("%s", thd->query));
+
+ DBUG_ASSERT(!thd->in_sub_stmt);
+ DBUG_ASSERT(!thd->prelocked_mode);
+
mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
if (no_print_error && thd->is_slave_error)
@@ -265,20 +273,36 @@ static void run_query(THD *thd, char *buf, char *end,
Thd_ndb *thd_ndb= get_thd_ndb(thd);
for (i= 0; no_print_error[i]; i++)
if ((thd_ndb->m_error_code == no_print_error[i]) ||
- (thd->net.last_errno == (unsigned)no_print_error[i]))
+ (thd->main_da.sql_errno() == (unsigned) no_print_error[i]))
break;
if (!no_print_error[i])
sql_print_error("NDB: %s: error %s %d(ndb: %d) %d %d",
- buf, thd->net.last_error, thd->net.last_errno,
+ buf,
+ thd->main_da.message(),
+ thd->main_da.sql_errno(),
thd_ndb->m_error_code,
(int) thd->is_error(), thd->is_slave_error);
}
+ /*
+ XXX: this code is broken. mysql_parse()/mysql_reset_thd_for_next_command()
+ can not be called from within a statement, and
+ run_query() can be called from anywhere, including from within
+ a sub-statement.
+ This particular reset is a temporary hack to avoid an assert
+ for double assignment of the diagnostics area when run_query()
+ is called from ndbcluster_reset_logs(), which is called from
+ mysql_flush().
+ */
+ thd->main_da.reset_diagnostics_area();
thd->options= save_thd_options;
- thd->query_length= save_query_length;
- thd->query= save_query;
+ thd->query_length= save_thd_query_length;
+ thd->query= save_thd_query;
thd->variables.pseudo_thread_id= save_thread_id;
- thd->net= save_net;
+ thd->status_var= save_thd_status_var;
+ thd->transaction.all= save_thd_transaction_all;
+ thd->transaction.stmt= save_thd_transaction_stmt;
+ thd->net= save_thd_net;
if (thd == injector_thd)
{
@@ -777,8 +801,9 @@ static int ndbcluster_create_ndb_apply_status_table(THD *thd)
" end_pos BIGINT UNSIGNED NOT NULL, "
" PRIMARY KEY USING HASH (server_id) ) ENGINE=NDB");
- const int no_print_error[4]= {ER_TABLE_EXISTS_ERROR,
+ const int no_print_error[5]= {ER_TABLE_EXISTS_ERROR,
701,
+ 702,
4009,
0}; // do not print error 701 etc
run_query(thd, buf, end, no_print_error, TRUE);
@@ -837,8 +862,9 @@ static int ndbcluster_create_schema_table(THD *thd)
" type INT UNSIGNED NOT NULL,"
" PRIMARY KEY USING HASH (db,name) ) ENGINE=NDB");
- const int no_print_error[4]= {ER_TABLE_EXISTS_ERROR,
+ const int no_print_error[5]= {ER_TABLE_EXISTS_ERROR,
701,
+ 702,
4009,
0}; // do not print error 701 etc
run_query(thd, buf, end, no_print_error, TRUE);
@@ -883,7 +909,7 @@ int ndbcluster_setup_binlog_table_shares(THD *thd)
{
if (ndb_extra_logging)
sql_print_information("NDB Binlog: ndb tables writable");
- close_cached_tables((THD*) 0, 0, (TABLE_LIST*) 0, TRUE);
+ close_cached_tables(NULL, NULL, TRUE, FALSE, FALSE);
}
pthread_mutex_unlock(&LOCK_open);
/* Signal injector thread that all is setup */
@@ -1683,7 +1709,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
bzero((char*) &table_list,sizeof(table_list));
table_list.db= (char *)dbname;
table_list.alias= table_list.table_name= (char *)tabname;
- close_cached_tables(thd, 0, &table_list, TRUE);
+ close_cached_tables(thd, &table_list, TRUE, FALSE, FALSE);
if ((error= ndbcluster_binlog_open_table(thd, share,
table_share, table, 1)))
@@ -1789,7 +1815,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
bzero((char*) &table_list,sizeof(table_list));
table_list.db= (char *)dbname;
table_list.alias= table_list.table_name= (char *)tabname;
- close_cached_tables(thd, 0, &table_list);
+ close_cached_tables(thd, &table_list, FALSE, FALSE, FALSE);
/* ndb_share reference create free */
DBUG_PRINT("NDB_SHARE", ("%s create free use_count: %u",
share->key, share->use_count));
@@ -1908,7 +1934,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
bzero((char*) &table_list,sizeof(table_list));
table_list.db= schema->db;
table_list.alias= table_list.table_name= schema->name;
- close_cached_tables(thd, 0, &table_list, FALSE);
+ close_cached_tables(thd, &table_list, FALSE, FALSE, FALSE);
}
/* ndb_share reference temporary free */
if (share)
@@ -2032,7 +2058,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
pthread_mutex_unlock(&ndb_schema_share_mutex);
/* end protect ndb_schema_share */
- close_cached_tables((THD*) 0, 0, (TABLE_LIST*) 0, FALSE);
+ close_cached_tables(NULL, NULL, FALSE, FALSE, FALSE);
// fall through
case NDBEVENT::TE_ALTER:
ndb_handle_schema_change(thd, ndb, pOp, tmp_share);
@@ -2189,7 +2215,7 @@ ndb_binlog_thread_handle_schema_event_post_epoch(THD *thd,
bzero((char*) &table_list,sizeof(table_list));
table_list.db= schema->db;
table_list.alias= table_list.table_name= schema->name;
- close_cached_tables(thd, 0, &table_list, FALSE);
+ close_cached_tables(thd, &table_list, FALSE, FALSE, FALSE);
}
if (schema_type != SOT_ALTER_TABLE)
break;
@@ -2300,9 +2326,12 @@ static int open_ndb_binlog_index(THD *thd, TABLE_LIST *tables,
thd->clear_error();
if (open_tables(thd, &tables, &counter, MYSQL_LOCK_IGNORE_FLUSH))
{
- sql_print_error("NDB Binlog: Opening ndb_binlog_index: %d, '%s'",
- thd->net.last_errno,
- thd->net.last_error ? thd->net.last_error : "");
+ if (thd->killed)
+ sql_print_error("NDB Binlog: Opening ndb_binlog_index: killed");
+ else
+ sql_print_error("NDB Binlog: Opening ndb_binlog_index: %d, '%s'",
+ thd->main_da.sql_errno(),
+ thd->main_da.message());
thd->proc_info= save_proc_info;
return -1;
}
@@ -3587,6 +3616,7 @@ pthread_handler_t ndb_binlog_thread_func(void *arg)
Thd_ndb *thd_ndb=0;
int ndb_update_ndb_binlog_index= 1;
injector *inj= injector::instance();
+ uint incident_id= 0;
#ifdef RUN_NDB_BINLOG_TIMER
Timer main_timer;
@@ -3693,18 +3723,64 @@ pthread_handler_t ndb_binlog_thread_func(void *arg)
pthread_mutex_unlock(&injector_mutex);
pthread_cond_signal(&injector_cond);
+ /*
+ wait for mysql server to start (so that the binlog is started
+ and thus can receive the first GAP event)
+ */
+ pthread_mutex_lock(&LOCK_server_started);
+ while (!mysqld_server_started)
+ {
+ struct timespec abstime;
+ set_timespec(abstime, 1);
+ pthread_cond_timedwait(&COND_server_started, &LOCK_server_started,
+ &abstime);
+ if (ndbcluster_terminating)
+ {
+ pthread_mutex_unlock(&LOCK_server_started);
+ pthread_mutex_lock(&LOCK_ndb_util_thread);
+ goto err;
+ }
+ }
+ pthread_mutex_unlock(&LOCK_server_started);
restart:
/*
Main NDB Injector loop
*/
+ while (ndb_binlog_running)
{
/*
- Always insert a GAP event as we cannot know what has happened in the cluster
- while not being connected.
+ check if it is the first log, if so we do not insert a GAP event
+ as there is really no log to have a GAP in
+ */
+ if (incident_id == 0)
+ {
+ LOG_INFO log_info;
+ mysql_bin_log.get_current_log(&log_info);
+ int len= strlen(log_info.log_file_name);
+ uint no= 0;
+ if ((sscanf(log_info.log_file_name + len - 6, "%u", &no) == 1) &&
+ no == 1)
+ {
+ /* this is the fist log, so skip GAP event */
+ break;
+ }
+ }
+
+ /*
+ Always insert a GAP event as we cannot know what has happened
+ in the cluster while not being connected.
*/
- LEX_STRING const msg= { C_STRING_WITH_LEN("Cluster connect") };
- inj->record_incident(thd, INCIDENT_LOST_EVENTS, msg);
+ LEX_STRING const msg[2]=
+ {
+ { C_STRING_WITH_LEN("mysqld startup") },
+ { C_STRING_WITH_LEN("cluster disconnect")}
+ };
+ IF_DBUG(int error=)
+ inj->record_incident(thd, INCIDENT_LOST_EVENTS, msg[incident_id]);
+ DBUG_ASSERT(!error);
+ break;
}
+ incident_id= 1;
{
thd->proc_info= "Waiting for ndbcluster to start";
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 1400d9da753..3f1634a6ad1 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1531,6 +1531,14 @@ int ha_partition::copy_partitions(ulonglong *copied, ulonglong *deleted)
longlong func_value;
DBUG_ENTER("ha_partition::copy_partitions");
+ if (m_part_info->linear_hash_ind)
+ {
+ if (m_part_info->part_type == HASH_PARTITION)
+ set_linear_hash_mask(m_part_info, m_part_info->no_parts);
+ else
+ set_linear_hash_mask(m_part_info, m_part_info->no_subparts);
+ }
+
while (reorg_part < m_reorged_parts)
{
handler *file= m_reorged_file[reorg_part];
@@ -1598,7 +1606,11 @@ error:
void ha_partition::update_create_info(HA_CREATE_INFO *create_info)
{
- m_file[0]->update_create_info(create_info);
+ info(HA_STATUS_AUTO);
+
+ if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
+ create_info->auto_increment_value= stats.auto_increment_value;
+
create_info->data_file_name= create_info->index_file_name = NULL;
return;
}
@@ -1753,6 +1765,7 @@ partition_element *ha_partition::find_partition_element(uint part_id)
return part_elem;
}
DBUG_ASSERT(0);
+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
current_thd->fatal_error(); // Abort
return NULL;
}
@@ -3413,14 +3426,17 @@ int ha_partition::index_init(uint inx, bool sorted)
*/
if (m_lock_type == F_WRLCK)
bitmap_union(table->read_set, &m_part_info->full_part_field_set);
- else if (sorted && m_table_flags & HA_PARTIAL_COLUMN_READ)
+ else if (sorted)
{
/*
- An ordered scan is requested and necessary fields aren't in read_set.
- This may happen e.g. with SELECT COUNT(*) FROM t1. We must ensure
- that all fields of current key are included into read_set, as
- partitioning requires them for sorting
- (see ha_partition::handle_ordered_index_scan).
+ An ordered scan is requested. We must make sure all fields of the
+ used index are in the read set, as partitioning requires them for
+ sorting (see ha_partition::handle_ordered_index_scan).
+
+ The SQL layer may request an ordered index scan without having index
+ fields in the read set when
+ - it needs to do an ordered scan over an index prefix.
+ - it evaluates ORDER BY with SELECT COUNT(*) FROM t1.
TODO: handle COUNT(*) queries via unordered scan.
*/
@@ -3983,7 +3999,8 @@ int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same)
}
else if (!(error= file->index_next(buf)))
{
- if (compare_key(end_range) <= 0)
+ if (!(file->table_flags() & HA_READ_ORDER) ||
+ compare_key(end_range) <= 0)
{
m_last_part= m_part_spec.start_part;
DBUG_RETURN(0); // Row was in range
@@ -4060,7 +4077,8 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf)
}
if (!error)
{
- if (compare_key(end_range) <= 0)
+ if (!(file->table_flags() & HA_READ_ORDER) ||
+ compare_key(end_range) <= 0)
{
m_last_part= i;
DBUG_RETURN(0);
diff --git a/sql/handler.h b/sql/handler.h
index b91d8a39b88..c5b867e315f 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -959,11 +959,11 @@ uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map);
*/
#define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1)
-/*
+/**
The handler class is the interface for dynamically loadable
storage engines. Do not add ifdefs and take care when adding or
changing virtual functions to avoid vtable confusion
- */
+*/
class handler :public Sql_alloc
{
@@ -973,32 +973,12 @@ class handler :public Sql_alloc
public:
typedef ulonglong Table_flags;
-
- protected:
+protected:
struct st_table_share *table_share; /* The table definition */
struct st_table *table; /* The current open table */
Table_flags cached_table_flags; /* Set on init() and open() */
- virtual int index_init(uint idx, bool sorted) { active_index=idx; return 0; }
- virtual int index_end() { active_index=MAX_KEY; return 0; }
- /*
- rnd_init() can be called two times without rnd_end() in between
- (it only makes sense if scan=1).
- then the second call should prepare for the new table scan (e.g
- if rnd_init allocates the cursor, second call should position it
- to the start of the table, no need to deallocate and allocate it again
- */
- virtual int rnd_init(bool scan) =0;
- virtual int rnd_end() { return 0; }
- virtual Table_flags table_flags(void) const =0;
-
- void ha_statistic_increment(ulong SSV::*offset) const;
- void **ha_data(THD *) const;
- THD *ha_thd(void) const;
-
ha_rows estimation_rows_to_insert;
- virtual void start_bulk_insert(ha_rows rows) {}
- virtual int end_bulk_insert() {return 0; }
public:
handlerton *ht; /* storage engine of this handler */
uchar *ref; /* Pointer to current row */
@@ -1006,13 +986,13 @@ public:
ha_statistics stats;
- /* The following are for read_multi_range */
+ /** The following are for read_multi_range */
bool multi_range_sorted;
KEY_MULTI_RANGE *multi_range_curr;
KEY_MULTI_RANGE *multi_range_end;
HANDLER_BUFFER *multi_range_buffer;
- /* The following are for read_range() */
+ /** The following are for read_range() */
key_range save_end_range, *end_range;
KEY_PART_INFO *range_key_part;
int key_compare_result_on_equal;
@@ -1021,14 +1001,14 @@ public:
uint errkey; /* Last dup key */
uint key_used_on_scan;
uint active_index;
- /* Length of ref (1-8 or the clustered key length) */
+ /** Length of ref (1-8 or the clustered key length) */
uint ref_length;
FT_INFO *ft_handler;
enum {NONE=0, INDEX, RND} inited;
bool locked;
bool implicit_emptied; /* Can be !=0 only if HEAP */
const COND *pushed_cond;
- /*
+ /**
next_insert_id is the next value which should be inserted into the
auto_increment column: in a inserting-multi-row statement (like INSERT
SELECT), for the first row where the autoinc value is not specified by the
@@ -1038,14 +1018,14 @@ public:
get_auto_increment().
*/
ulonglong next_insert_id;
- /*
+ /**
insert id for the current row (*autogenerated*; if not
autogenerated, it's 0).
At first successful insertion, this variable is stored into
THD::first_successful_insert_id_in_cur_stmt.
*/
ulonglong insert_id_for_cur_row;
- /*
+ /**
Interval returned by get_auto_increment() and being consumed by the
inserter.
*/
@@ -1066,12 +1046,79 @@ public:
/* TODO: DBUG_ASSERT(inited == NONE); */
}
virtual handler *clone(MEM_ROOT *mem_root);
- /* This is called after create to allow us to set up cached variables */
+ /** This is called after create to allow us to set up cached variables */
void init()
{
cached_table_flags= table_flags();
}
+ /* ha_ methods: pubilc wrappers for private virtual API */
+
int ha_open(TABLE *table, const char *name, int mode, int test_if_locked);
+ int ha_index_init(uint idx, bool sorted)
+ {
+ int result;
+ DBUG_ENTER("ha_index_init");
+ DBUG_ASSERT(inited==NONE);
+ if (!(result= index_init(idx, sorted)))
+ inited=INDEX;
+ DBUG_RETURN(result);
+ }
+ int ha_index_end()
+ {
+ DBUG_ENTER("ha_index_end");
+ DBUG_ASSERT(inited==INDEX);
+ inited=NONE;
+ DBUG_RETURN(index_end());
+ }
+ int ha_rnd_init(bool scan)
+ {
+ int result;
+ DBUG_ENTER("ha_rnd_init");
+ DBUG_ASSERT(inited==NONE || (inited==RND && scan));
+ inited= (result= rnd_init(scan)) ? NONE: RND;
+ DBUG_RETURN(result);
+ }
+ int ha_rnd_end()
+ {
+ DBUG_ENTER("ha_rnd_end");
+ DBUG_ASSERT(inited==RND);
+ inited=NONE;
+ DBUG_RETURN(rnd_end());
+ }
+ int ha_reset();
+ /* this is necessary in many places, e.g. in HANDLER command */
+ int ha_index_or_rnd_end()
+ {
+ return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
+ }
+ Table_flags ha_table_flags() const { return cached_table_flags; }
+ /**
+ These functions represent the public interface to *users* of the
+ handler class, hence they are *not* virtual. For the inheritance
+ interface, see the (private) functions write_row(), update_row(),
+ and delete_row() below.
+ */
+ int ha_external_lock(THD *thd, int lock_type);
+ int ha_write_row(uchar * buf);
+ int ha_update_row(const uchar * old_data, uchar * new_data);
+ int ha_delete_row(const uchar * buf);
+ void ha_release_auto_increment();
+
+ int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
+ /** to be actually called to get 'check()' functionality*/
+ int ha_check(THD *thd, HA_CHECK_OPT *check_opt);
+ int ha_repair(THD* thd, HA_CHECK_OPT* check_opt);
+ void ha_start_bulk_insert(ha_rows rows)
+ {
+ estimation_rows_to_insert= rows;
+ start_bulk_insert(rows);
+ }
+ int ha_end_bulk_insert()
+ {
+ estimation_rows_to_insert= 0;
+ return end_bulk_insert();
+ }
+
void adjust_next_insert_id_after_explicit_value(ulonglong nr);
int update_auto_increment();
void print_keydup_error(uint key_nr, const char *msg);
@@ -1092,7 +1139,7 @@ public:
{ return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0; }
virtual uint extra_rec_buf_length() const { return 0; }
- /*
+ /**
This method is used to analyse the error to see whether the error
is ignorable or not, certain handlers can have more error that are
ignorable than others. E.g. the partition handler can get inserts
@@ -1112,12 +1159,12 @@ public:
return TRUE;
}
- /*
+ /**
Number of rows in table. It will only be called if
(table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
*/
virtual ha_rows records() { return stats.records; }
- /*
+ /**
Return upper bound of current number of records in the table
(max. of how many records one will retrieve when doing a full table scan)
If upper bound is not known, HA_POS_ERROR should be returned as a max
@@ -1126,7 +1173,7 @@ public:
virtual ha_rows estimate_rows_upper_bound()
{ return stats.records+EXTRA_RECORDS; }
- /*
+ /**
Get the row type from the storage engine. If this method returns
ROW_TYPE_NOT_USED, the information in HA_CREATE_INFO should be used.
*/
@@ -1134,47 +1181,8 @@ public:
virtual const char *index_type(uint key_number) { DBUG_ASSERT(0); return "";}
- int ha_index_init(uint idx, bool sorted)
- {
- int result;
- DBUG_ENTER("ha_index_init");
- DBUG_ASSERT(inited==NONE);
- if (!(result= index_init(idx, sorted)))
- inited=INDEX;
- DBUG_RETURN(result);
- }
- int ha_index_end()
- {
- DBUG_ENTER("ha_index_end");
- DBUG_ASSERT(inited==INDEX);
- inited=NONE;
- DBUG_RETURN(index_end());
- }
- int ha_rnd_init(bool scan)
- {
- int result;
- DBUG_ENTER("ha_rnd_init");
- DBUG_ASSERT(inited==NONE || (inited==RND && scan));
- inited= (result= rnd_init(scan)) ? NONE: RND;
- DBUG_RETURN(result);
- }
- int ha_rnd_end()
- {
- DBUG_ENTER("ha_rnd_end");
- DBUG_ASSERT(inited==RND);
- inited=NONE;
- DBUG_RETURN(rnd_end());
- }
- int ha_reset();
-
- /* this is necessary in many places, e.g. in HANDLER command */
- int ha_index_or_rnd_end()
- {
- return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
- }
- Table_flags ha_table_flags() const { return cached_table_flags; }
- /*
+ /**
Signal that the table->read_set and table->write_set table maps changed
The handler is allowed to set additional bits in the above map in this
call. Normally the handler should ignore all calls until we have done
@@ -1183,50 +1191,30 @@ public:
*/
virtual void column_bitmaps_signal();
uint get_index(void) const { return active_index; }
- virtual int open(const char *name, int mode, uint test_if_locked)=0;
virtual int close(void)=0;
- /*
- These functions represent the public interface to *users* of the
- handler class, hence they are *not* virtual. For the inheritance
- interface, see the (private) functions write_row(), update_row(),
- and delete_row() below.
- */
- int ha_external_lock(THD *thd, int lock_type);
- int ha_write_row(uchar * buf);
- int ha_update_row(const uchar * old_data, uchar * new_data);
- int ha_delete_row(const uchar * buf);
-
- /*
- SYNOPSIS
- start_bulk_update()
- RETURN
- 0 Bulk update used by handler
- 1 Bulk update not used, normal operation used
+ /**
+ @retval 0 Bulk update used by handler
+ @retval 1 Bulk update not used, normal operation used
*/
virtual bool start_bulk_update() { return 1; }
- /*
- SYNOPSIS
- start_bulk_delete()
- RETURN
- 0 Bulk delete used by handler
- 1 Bulk delete not used, normal operation used
+ /**
+ @retval 0 Bulk delete used by handler
+ @retval 1 Bulk delete not used, normal operation used
*/
virtual bool start_bulk_delete() { return 1; }
- /*
- SYNOPSIS
+ /**
This method is similar to update_row, however the handler doesn't need
to execute the updates at this point in time. The handler can be certain
that another call to bulk_update_row will occur OR a call to
exec_bulk_update before the set of updates in this query is concluded.
- bulk_update_row()
- old_data Old record
- new_data New record
- dup_key_found Number of duplicate keys found
- RETURN
- 0 Bulk delete used by handler
- 1 Bulk delete not used, normal operation used
+ @param old_data Old record
+ @param new_data New record
+ @param dup_key_found Number of duplicate keys found
+
+ @retval 0 Bulk delete used by handler
+ @retval 1 Bulk delete not used, normal operation used
*/
virtual int bulk_update_row(const uchar *old_data, uchar *new_data,
uint *dup_key_found)
@@ -1234,53 +1222,38 @@ public:
DBUG_ASSERT(FALSE);
return HA_ERR_WRONG_COMMAND;
}
- /*
- SYNOPSIS
+ /**
After this call all outstanding updates must be performed. The number
of duplicate key errors are reported in the duplicate key parameter.
It is allowed to continue to the batched update after this call, the
handler has to wait until end_bulk_update with changing state.
- exec_bulk_update()
- dup_key_found Number of duplicate keys found
- RETURN
- 0 Success
- >0 Error code
+ @param dup_key_found Number of duplicate keys found
+
+ @retval 0 Success
+ @retval >0 Error code
*/
virtual int exec_bulk_update(uint *dup_key_found)
{
DBUG_ASSERT(FALSE);
return HA_ERR_WRONG_COMMAND;
}
- /*
- SYNOPSIS
+ /**
Perform any needed clean-up, no outstanding updates are there at the
moment.
-
- end_bulk_update()
- RETURN
- Nothing
*/
virtual void end_bulk_update() { return; }
- /*
- SYNOPSIS
+ /**
Execute all outstanding deletes and close down the bulk delete.
- end_bulk_delete()
- RETURN
- 0 Success
- >0 Error code
+ @retval 0 Success
+ @retval >0 Error code
*/
virtual int end_bulk_delete()
{
DBUG_ASSERT(FALSE);
return HA_ERR_WRONG_COMMAND;
}
- private:
- virtual int index_read(uchar * buf, const uchar * key, uint key_len,
- enum ha_rkey_function find_flag)
- { return HA_ERR_WRONG_COMMAND; }
- public:
/**
@brief
Positions an index cursor to the index specified in the handle. Fetches the
@@ -1312,10 +1285,6 @@ public:
virtual int index_last(uchar * buf)
{ return HA_ERR_WRONG_COMMAND; }
virtual int index_next_same(uchar *buf, const uchar *key, uint keylen);
- private:
- virtual int index_read_last(uchar * buf, const uchar * key, uint key_len)
- { return (my_errno=HA_ERR_WRONG_COMMAND); }
- public:
/**
@brief
The following functions works like index_read, but it find the last
@@ -1343,11 +1312,11 @@ public:
virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
virtual int rnd_next(uchar *buf)=0;
virtual int rnd_pos(uchar * buf, uchar *pos)=0;
- /*
- one has to use this method when to find
+ /**
+ One has to use this method when to find
random position by record as the plain
position() call doesn't work for some
- handlers for random position
+ handlers for random position.
*/
virtual int rnd_pos_by_record(uchar *record)
{
@@ -1355,9 +1324,9 @@ public:
return rnd_pos(record, ref);
}
virtual int read_first_row(uchar *buf, uint primary_key);
- /*
+ /**
The following function is only needed for tables that may be temporary
- tables during joins
+ tables during joins.
*/
virtual int restart_rnd_next(uchar *buf, uchar *pos)
{ return HA_ERR_WRONG_COMMAND; }
@@ -1374,13 +1343,7 @@ public:
virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
{ return extra(operation); }
- /*
- Reset state of file to after 'open'
- This function is called after every statement for all tables used
- by that statement.
- */
- virtual int reset() { return 0; }
- /*
+ /**
In an UPDATE or DELETE, if the row under the cursor was locked by another
transaction, and the engine used an optimistic read of the last
committed row value under the cursor, then the engine returns 1 from this
@@ -1393,7 +1356,7 @@ public:
engine that the next read will be a locking re-read of the row.
*/
virtual bool was_semi_consistent_read() { return 0; }
- /*
+ /**
Tell the engine whether it should avoid unnecessary lock waits.
If yes, in an UPDATE or DELETE, if the row under the cursor was locked
by another transaction, the engine may try an optimistic read of
@@ -1402,7 +1365,7 @@ public:
virtual void try_semi_consistent_read(bool) {}
virtual void unlock_row() {}
virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
- /*
+ /**
This is called to delete all rows in a table
If the handler don't support this, then this function will
return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
@@ -1414,10 +1377,6 @@ public:
ulonglong nb_desired_values,
ulonglong *first_value,
ulonglong *nb_reserved_values);
-private:
- virtual void release_auto_increment() { return; };
-public:
- void ha_release_auto_increment();
void set_next_insert_id(ulonglong id)
{
DBUG_PRINT("info",("auto_increment: next value %lu", (ulong)id));
@@ -1438,7 +1397,7 @@ public:
next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
insert_id_for_cur_row;
}
- /*
+ /**
Reset the auto-increment counter to the given value, i.e. the next row
inserted will get the given value. This is called e.g. after TRUNCATE
is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is
@@ -1448,39 +1407,15 @@ public:
{ return HA_ERR_WRONG_COMMAND; }
virtual void update_create_info(HA_CREATE_INFO *create_info) {}
-protected:
- /* to be implemented in handlers */
-
- /* admin commands - called from mysql_admin_table */
- virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
- { return HA_ADMIN_NOT_IMPLEMENTED; }
-
- /*
- in these two methods check_opt can be modified
- to specify CHECK option to use to call check()
- upon the table
- */
- virtual int check_for_upgrade(HA_CHECK_OPT *check_opt)
- { return 0; }
-public:
- int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
int check_old_types();
- /* to be actually called to get 'check()' functionality*/
- int ha_check(THD *thd, HA_CHECK_OPT *check_opt);
-
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt)
{ return HA_ADMIN_NOT_IMPLEMENTED; }
- /*
- restore assumes .frm file must exist, and that generate_table() has been
+ /**
+ Restore assumes .frm file must exist, and that generate_table() has been
called; It will just copy the data file and run repair.
*/
virtual int restore(THD* thd, HA_CHECK_OPT* check_opt)
{ return HA_ADMIN_NOT_IMPLEMENTED; }
-protected:
- virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
- { return HA_ADMIN_NOT_IMPLEMENTED; }
-public:
- int ha_repair(THD* thd, HA_CHECK_OPT* check_opt);
virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt)
{ return HA_ADMIN_NOT_IMPLEMENTED; }
virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt)
@@ -1496,33 +1431,21 @@ public:
virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
virtual int indexes_are_disabled(void) {return 0;}
- void ha_start_bulk_insert(ha_rows rows)
- {
- estimation_rows_to_insert= rows;
- start_bulk_insert(rows);
- }
- int ha_end_bulk_insert()
- {
- estimation_rows_to_insert= 0;
- return end_bulk_insert();
- }
virtual int discard_or_import_tablespace(my_bool discard)
{return HA_ERR_WRONG_COMMAND;}
virtual int net_read_dump(NET* net) { return HA_ERR_WRONG_COMMAND; }
virtual char *update_table_comment(const char * comment)
{ return (char*) comment;}
virtual void append_create_info(String *packet) {}
- /*
- SYNOPSIS
- is_fk_defined_on_table_or_index()
- index Index to check if foreign key uses it
- RETURN VALUE
- TRUE Foreign key defined on table or index
- FALSE No foreign key defined
- DESCRIPTION
- If index == MAX_KEY then a check for table is made and if index <
- MAX_KEY then a check is made if the table has foreign keys and if
- a foreign key uses this index (and thus the index cannot be dropped).
+ /**
+ If index == MAX_KEY then a check for table is made and if index <
+ MAX_KEY then a check is made if the table has foreign keys and if
+ a foreign key uses this index (and thus the index cannot be dropped).
+
+ @param index Index to check if foreign key uses it
+
+ @retval TRUE Foreign key defined on table or index
+ @retval FALSE No foreign key defined
*/
virtual bool is_fk_defined_on_table_or_index(uint index)
{ return FALSE; }
@@ -1530,18 +1453,18 @@ public:
{ return(NULL);} /* gets foreign key create string from InnoDB */
virtual char* get_tablespace_name(THD *thd, char *name, uint name_len)
{ return(NULL);} /* gets tablespace name from handler */
- /* used in ALTER TABLE; 1 if changing storage engine is allowed */
+ /** used in ALTER TABLE; 1 if changing storage engine is allowed */
virtual bool can_switch_engines() { return 1; }
- /* used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */
+ /** used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */
virtual int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
{ return 0; }
virtual uint referenced_by_foreign_key() { return 0;}
virtual void init_table_handle_for_HANDLER()
{ return; } /* prepare InnoDB for HANDLER */
virtual void free_foreign_key_create_info(char* str) {}
- /* The following can be called without an open handler */
+ /** The following can be called without an open handler */
virtual const char *table_type() const =0;
- /*
+ /**
If frm_error() is called then we will use this to find out what file
extentions exist for the storage engine. This is also used by the default
rename_table and delete_table method in handler.cc.
@@ -1598,14 +1521,14 @@ public:
virtual bool is_crashed() const { return 0; }
virtual bool auto_repair() const { return 0; }
- /*
+ /**
default rename_table() and delete_table() rename/delete files with a
given name and extensions from bas_ext()
*/
virtual int rename_table(const char *from, const char *to);
virtual int delete_table(const char *name);
virtual void drop_table(const char *name);
-
+
virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
#define CHF_CREATE_FLAG 0
@@ -1637,19 +1560,28 @@ public:
virtual int repair_partitions(THD *thd)
{ return HA_ERR_WRONG_COMMAND; }
- /* lock_count() can be more than one if the table is a MERGE */
+ /**
+ @note lock_count() can return > 1 if the table is MERGE or partitioned.
+ */
virtual uint lock_count(void) const { return 1; }
/**
Is not invoked for non-transactional temporary tables.
+ @note store_lock() can return more than one lock if the table is MERGE
+ or partitioned.
+
@note that one can NOT rely on table->in_use in store_lock(). It may
refer to a different thread if called from mysql_lock_abort_for_thread().
+
+ @note If the table is MERGE, store_lock() can return less locks
+ than lock_count() claimed. This can happen when the MERGE children
+ are not attached when this is called from another thread.
*/
virtual THR_LOCK_DATA **store_lock(THD *thd,
THR_LOCK_DATA **to,
enum thr_lock_type lock_type)=0;
- /* Type of table for caching query */
+ /** Type of table for caching query */
virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; }
@@ -1695,56 +1627,54 @@ public:
/*
- RETURN
- true Primary key (if there is one) is clustered key covering all fields
- false otherwise
+ @retval TRUE Primary key (if there is one) is clustered
+ key covering all fields
+ @retval FALSE otherwise
*/
virtual bool primary_key_is_clustered() { return FALSE; }
virtual int cmp_ref(const uchar *ref1, const uchar *ref2)
{
return memcmp(ref1, ref2, ref_length);
}
-
+
/*
Condition pushdown to storage engines
*/
- /*
+ /**
Push condition down to the table handler.
- SYNOPSIS
- cond_push()
- cond Condition to be pushed. The condition tree must not be
- modified by the by the caller.
- RETURN
+ @param cond Condition to be pushed. The condition tree must not be
+ modified by the by the caller.
+
+ @return
The 'remainder' condition that caller must use to filter out records.
NULL means the handler will not return rows that do not match the
passed condition.
- NOTES
+ @note
The pushed conditions form a stack (from which one can remove the
last pushed condition using cond_pop).
The table handler filters out rows using (pushed_cond1 AND pushed_cond2
AND ... AND pushed_condN)
or less restrictive condition, depending on handler's capabilities.
-
+
handler->ha_reset() call empties the condition stack.
Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
condition stack.
*/
virtual const COND *cond_push(const COND *cond) { return cond; };
- /*
+ /**
Pop the top condition from the condition stack of the handler instance.
- SYNOPSIS
- cond_pop()
- Pops the top if condition stack, if stack is not empty
+
+ Pops the top if condition stack, if stack is not empty.
*/
virtual void cond_pop() { return; };
virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes)
{ return COMPATIBLE_DATA_NO; }
- /* These are only called from sql_select for internal temporary tables */
+ /** These are only called from sql_select for internal temporary tables */
virtual int write_row(uchar *buf __attribute__((unused)))
{
return HA_ERR_WRONG_COMMAND;
@@ -1760,20 +1690,44 @@ public:
{
return HA_ERR_WRONG_COMMAND;
}
- /*
+ /**
use_hidden_primary_key() is called in case of an update/delete when
(table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
but we don't have a primary key
*/
virtual void use_hidden_primary_key();
+protected:
+ /* Service methods for use by storage engines. */
+ void ha_statistic_increment(ulong SSV::*offset) const;
+ void **ha_data(THD *) const;
+ THD *ha_thd(void) const;
private:
/*
- Row-level primitives for storage engines. These should be
+ Low-level primitives for storage engines. These should be
overridden by the storage engine class. To call these methods, use
the corresponding 'ha_*' method above.
*/
+ virtual int open(const char *name, int mode, uint test_if_locked)=0;
+ virtual int index_init(uint idx, bool sorted) { active_index= idx; return 0; }
+ virtual int index_end() { active_index= MAX_KEY; return 0; }
+ /**
+ rnd_init() can be called two times without rnd_end() in between
+ (it only makes sense if scan=1).
+ then the second call should prepare for the new table scan (e.g
+ if rnd_init allocates the cursor, second call should position it
+ to the start of the table, no need to deallocate and allocate it again
+ */
+ virtual int rnd_init(bool scan)= 0;
+ virtual int rnd_end() { return 0; }
+ /**
+ Reset state of file to after 'open'.
+ This function is called after every statement for all tables used
+ by that statement.
+ */
+ virtual int reset() { return 0; }
+ virtual Table_flags table_flags(void) const= 0;
/**
Is not invoked for non-transactional temporary tables.
@@ -1801,8 +1755,30 @@ private:
{
return 0;
}
+ virtual void release_auto_increment() { return; };
+ /** admin commands - called from mysql_admin_table */
+ virtual int check_for_upgrade(HA_CHECK_OPT *check_opt)
+ { return 0; }
+ virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
+ { return HA_ADMIN_NOT_IMPLEMENTED; }
+
+ /**
+ In this method check_opt can be modified
+ to specify CHECK option to use to call check()
+ upon the table.
+ */
+ virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
+ { return HA_ADMIN_NOT_IMPLEMENTED; }
+ virtual void start_bulk_insert(ha_rows rows) {}
+ virtual int end_bulk_insert() { return 0; }
+ virtual int index_read(uchar * buf, const uchar * key, uint key_len,
+ enum ha_rkey_function find_flag)
+ { return HA_ERR_WRONG_COMMAND; }
+ virtual int index_read_last(uchar * buf, const uchar * key, uint key_len)
+ { return (my_errno= HA_ERR_WRONG_COMMAND); }
};
+
/* Some extern variables used with handlers */
extern const char *ha_row_type[];
diff --git a/sql/item.cc b/sql/item.cc
index e5b17271e13..c33e5da0ca4 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1238,7 +1238,17 @@ bool Item_name_const::is_null()
Item::Type Item_name_const::type() const
{
- return value_item->type();
+ /*
+ As
+ 1. one can try to create the Item_name_const passing non-constant
+ arguments, although it's incorrect and
+ 2. the type() method can be called before the fix_fields() to get
+ type information for a further type cast, e.g.
+ if (item->type() == FIELD_ITEM)
+ ((Item_field *) item)->...
+ we return NULL_ITEM in the case to avoid wrong casting.
+ */
+ return valid_args ? value_item->type() : NULL_ITEM;
}
@@ -1250,14 +1260,14 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref)
s.length(0);
if (value_item->fix_fields(thd, &value_item) ||
- name_item->fix_fields(thd, &name_item))
- return TRUE;
- if (!(value_item->const_item() && name_item->const_item()))
+ name_item->fix_fields(thd, &name_item) ||
+ !value_item->const_item() ||
+ !name_item->const_item() ||
+ !(item_name= name_item->val_str(&s))) // Can't have a NULL name
+ {
+ my_error(ER_RESERVED_SYNTAX, MYF(0), "NAME_CONST");
return TRUE;
-
- if (!(item_name= name_item->val_str(&s)))
- return TRUE; /* Can't have a NULL name */
-
+ }
set_name(item_name->ptr(), (uint) item_name->length(), system_charset_info);
max_length= value_item->max_length;
decimals= value_item->decimals;
@@ -3683,7 +3693,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
}
/* Search in SELECT and GROUP lists of the outer select. */
- if (outer_context->resolve_in_select_list)
+ if (place != IN_WHERE && place != IN_ON)
{
if (!(ref= resolve_ref_in_select_and_group(thd, this, select)))
return -1; /* Some error occurred (e.g. ambiguous names). */
diff --git a/sql/item.h b/sql/item.h
index 379eb8a24be..b98389bc8d4 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1242,11 +1242,13 @@ class Item_name_const : public Item
{
Item *value_item;
Item *name_item;
+ bool valid_args;
public:
Item_name_const(Item *name_arg, Item *val):
value_item(val), name_item(name_arg)
{
- if(!value_item->basic_const_item())
+ if (!(valid_args= name_item->basic_const_item() &
+ value_item->basic_const_item()))
my_error(ER_WRONG_ARGUMENTS, MYF(0), "NAME_CONST");
Item::maybe_null= TRUE;
}
@@ -2620,16 +2622,23 @@ class Item_cache: public Item
protected:
Item *example;
table_map used_table_map;
+ /*
+ Field that this object will get value from. This is set/used by
+ index-based subquery engines to detect and remove the equality injected
+ by IN->EXISTS transformation.
+ For all other uses of Item_cache, cached_field doesn't matter.
+ */
+ Field *cached_field;
enum enum_field_types cached_field_type;
public:
Item_cache():
- example(0), used_table_map(0), cached_field_type(MYSQL_TYPE_STRING)
+ example(0), used_table_map(0), cached_field(0), cached_field_type(MYSQL_TYPE_STRING)
{
fixed= 1;
null_value= 1;
}
Item_cache(enum_field_types field_type_arg):
- example(0), used_table_map(0), cached_field_type(field_type_arg)
+ example(0), used_table_map(0), cached_field(0), cached_field_type(field_type_arg)
{
fixed= 1;
null_value= 1;
@@ -2645,6 +2654,8 @@ public:
decimals= item->decimals;
collation.set(item->collation);
unsigned_flag= item->unsigned_flag;
+ if (item->type() == FIELD_ITEM)
+ cached_field= ((Item_field *)item)->field;
return 0;
};
virtual void store(Item *)= 0;
@@ -2656,6 +2667,14 @@ public:
// to prevent drop fixed flag (no need parent cleanup call)
void cleanup() {}
void print(String *str);
+ bool eq_def(Field *field)
+ {
+ return cached_field ? cached_field->eq_def (field) : FALSE;
+ }
+ bool eq(const Item *item, bool binary_cmp) const
+ {
+ return this == item;
+ }
};
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 2175787cbd7..62ac7bc4751 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -29,7 +29,7 @@
#include <m_ctype.h>
#include "sql_select.h"
-static bool convert_constant_item(THD *thd, Field *field, Item **item);
+static bool convert_constant_item(THD *, Item_field *, Item **);
static Item_result item_store_type(Item_result a, Item *item,
my_bool unsigned_flag)
@@ -378,13 +378,15 @@ longlong Item_func_nop_all::val_int()
table that has not been populated yet.
@retval
- 0 Can't convert item
+ 0 Can't convert item
@retval
- 1 Item was replaced with an integer version of the item
+ 1 Item was replaced with an integer version of the item
*/
-static bool convert_constant_item(THD *thd, Field *field, Item **item)
+static bool convert_constant_item(THD *thd, Item_field *field_item,
+ Item **item)
{
+ Field *field= field_item->field;
int result= 0;
if (!(*item)->with_subselect && (*item)->const_item())
@@ -394,9 +396,11 @@ static bool convert_constant_item(THD *thd, Field *field, Item **item)
enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
my_bitmap_map *old_write_map;
my_bitmap_map *old_read_map;
+ ulonglong orig_field_val; /* original field value if valid */
LINT_INIT(old_write_map);
LINT_INIT(old_read_map);
+ LINT_INIT(orig_field_val);
if (table)
{
@@ -407,7 +411,14 @@ static bool convert_constant_item(THD *thd, Field *field, Item **item)
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))
+
+ /*
+ Store the value of the field if it references an outer field because
+ the call to save_in_field below overrides that value.
+ */
+ if (field_item->depended_from)
+ orig_field_val= field->val_int();
+ if (!(*item)->is_null() && !(*item)->save_in_field(field, 1))
{
Item *tmp= new Item_int_with_ref(field->val_int(), *item,
test(field->flags & UNSIGNED_FLAG));
@@ -415,6 +426,13 @@ static bool convert_constant_item(THD *thd, Field *field, Item **item)
thd->change_item_tree(item, tmp);
result= 1; // Item was replaced
}
+ /* Restore the original field value. */
+ if (field_item->depended_from)
+ {
+ result= field->store(orig_field_val, TRUE);
+ /* orig_field_val must be a valid value that can be restored back. */
+ DBUG_ASSERT(!result);
+ }
thd->variables.sql_mode= orig_sql_mode;
thd->count_cuted_fields= orig_count_cuted_fields;
if (table)
@@ -471,15 +489,14 @@ void Item_bool_func2::fix_length_and_dec()
thd= current_thd;
if (!thd->is_context_analysis_only())
{
- Item *arg_real_item= args[0]->real_item();
- if (arg_real_item->type() == FIELD_ITEM)
+ if (args[0]->real_item()->type() == FIELD_ITEM)
{
- Field *field=((Item_field*) arg_real_item)->field;
- if (field->can_be_compared_as_longlong() &&
- !(arg_real_item->is_datetime() &&
+ Item_field *field_item= (Item_field*) (args[0]->real_item());
+ if (field_item->field->can_be_compared_as_longlong() &&
+ !(field_item->is_datetime() &&
args[1]->result_type() == STRING_RESULT))
{
- if (convert_constant_item(thd, field,&args[1]))
+ if (convert_constant_item(thd, field_item, &args[1]))
{
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types.
@@ -488,15 +505,14 @@ void Item_bool_func2::fix_length_and_dec()
}
}
}
- arg_real_item= args[1]->real_item();
- if (arg_real_item->type() == FIELD_ITEM)
+ if (args[1]->real_item()->type() == FIELD_ITEM)
{
- Field *field=((Item_field*) arg_real_item)->field;
- if (field->can_be_compared_as_longlong() &&
- !(arg_real_item->is_datetime() &&
+ Item_field *field_item= (Item_field*) (args[1]->real_item());
+ if (field_item->field->can_be_compared_as_longlong() &&
+ !(field_item->is_datetime() &&
args[0]->result_type() == STRING_RESULT))
{
- if (convert_constant_item(thd, field,&args[0]))
+ if (convert_constant_item(thd, field_item, &args[0]))
{
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types.
@@ -1071,11 +1087,11 @@ int Arg_comparator::compare_string()
Compare strings byte by byte. End spaces are also compared.
@retval
- <0 *a < *b
+ <0 *a < *b
@retval
- 0 *b == *b
+ 0 *b == *b
@retval
- >0 *a > *b
+ >0 *a > *b
*/
int Arg_comparator::compare_binary_string()
@@ -1967,16 +1983,16 @@ void Item_func_between::fix_length_and_dec()
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())
+ Item_field *field_item= (Item_field*) (args[0]->real_item());
+ if (field_item->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]))
+ if (convert_constant_item(thd, field_item, &args[1]))
cmp_type=INT_RESULT; // Works for all types.
- if (convert_constant_item(thd, field,&args[2]))
+ if (convert_constant_item(thd, field_item, &args[2]))
cmp_type=INT_RESULT; // Works for all types.
}
}
@@ -3609,13 +3625,13 @@ void Item_func_in::fix_length_and_dec()
thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
cmp_type != INT_RESULT)
{
- Field *field= ((Item_field*) (args[0]->real_item()))->field;
- if (field->can_be_compared_as_longlong())
+ Item_field *field_item= (Item_field*) (args[0]->real_item());
+ if (field_item->field->can_be_compared_as_longlong())
{
bool all_converted= TRUE;
for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
{
- if (!convert_constant_item (thd, field, &arg[0]))
+ if (!convert_constant_item (thd, field_item, &arg[0]))
all_converted= FALSE;
}
if (all_converted)
@@ -3907,20 +3923,20 @@ bool Item_cond::walk(Item_processor processor, bool walk_subquery, uchar *arg)
/**
Transform an Item_cond object with a transformer callback function.
-
+
The function recursively applies the transform method to each
- member item of the condition list.
+ member item of the condition list.
If the call of the method for a member item returns a new item
the old item is substituted for a new one.
After this the transformer is applied to the root node
- of the Item_cond object.
-
+ of the Item_cond object.
+
@param transformer the transformer callback function to be applied to
the nodes of the tree of the object
@param arg parameter to be passed to the transformer
@return
- Item returned as the result of transformation of the root node
+ Item returned as the result of transformation of the root node
*/
Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
@@ -3951,7 +3967,7 @@ Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
/**
Compile Item_cond object with a processor and a transformer
callback functions.
-
+
First the function applies the analyzer to the root node of
the Item_func object. Then if the analyzer succeeeds (returns TRUE)
the function recursively applies the compile method to member
@@ -3960,7 +3976,7 @@ Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
the old item is substituted for a new one.
After this the transformer is applied to the root node
of the Item_cond object.
-
+
@param analyzer the analyzer callback function to be applied to the
nodes of the tree of the object
@param[in,out] arg_p parameter to be passed to the analyzer
@@ -3969,7 +3985,7 @@ Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
@param arg_t parameter to be passed to the transformer
@return
- Item returned as the result of transformation of the root node
+ Item returned as the result of transformation of the root node
*/
Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
@@ -4117,7 +4133,7 @@ void Item_cond::neg_arguments(THD *thd)
1 If all expressions are true
@retval
0 If all expressions are false or if we find a NULL expression and
- 'abort_on_null' is set.
+ 'abort_on_null' is set.
@retval
NULL if all expression are either 1 or NULL
*/
@@ -4166,8 +4182,8 @@ longlong Item_cond_or::val_int()
@param a expression or NULL
@param b expression.
@param org_item Don't modify a if a == *org_item.
- If a == NULL, org_item is set to point at b,
- to ensure that future calls will not modify b.
+ If a == NULL, org_item is set to point at b,
+ to ensure that future calls will not modify b.
@note
This will not modify item pointed to by org_item or b
@@ -4685,7 +4701,7 @@ void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
/**
- Precomputation dependent on pattern_len.
+ Precomputation dependent on pattern_len.
*/
void Item_func_like::turboBM_compute_bad_character_shifts()
@@ -5043,7 +5059,7 @@ uint Item_equal::members()
@retval
1 if nultiple equality contains a reference to field
@retval
- 0 otherwise
+ 0 otherwise
*/
bool Item_equal::contains(Field *field)
@@ -5061,7 +5077,7 @@ bool Item_equal::contains(Field *field)
/**
Join members of another Item_equal object.
-
+
The function actually merges two multiple equalities.
After this operation the Item_equal object additionally contains
the field items of another item of the type Item_equal.
@@ -5090,15 +5106,15 @@ void Item_equal::merge(Item_equal *item)
/**
Order field items in multiple equality according to a sorting criteria.
- The function perform ordering of the field items in the Item_equal
- object according to the criteria determined by the cmp callback parameter.
- If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
- placed after item_fiel2.
+ The function perform ordering of the field items in the Item_equal
+ object according to the criteria determined by the cmp callback parameter.
+ If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
+ placed after item_fiel2.
- The function sorts field items by the exchange sort algorithm.
- The list of field items is looked through and whenever two neighboring
- members follow in a wrong order they are swapped. This is performed
- again and again until we get all members in a right order.
+ The function sorts field items by the exchange sort algorithm.
+ The list of field items is looked through and whenever two neighboring
+ members follow in a wrong order they are swapped. This is performed
+ again and again until we get all members in a right order.
@param cmp function to compare field item
@param arg context extra parameter for the cmp function
@@ -5139,11 +5155,11 @@ void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
/**
Check appearance of new constant items in the multiple equality object.
- The function checks appearance of new constant items among
- the members of multiple equalities. Each new constant item is
- compared with the designated constant item if there is any in the
- multiple equality. If there is none the first new constant item
- becomes designated.
+ The function checks appearance of new constant items among
+ the members of multiple equalities. Each new constant item is
+ compared with the designated constant item if there is any in the
+ multiple equality. If there is none the first new constant item
+ becomes designated.
*/
void Item_equal::update_const()
diff --git a/sql/item_func.cc b/sql/item_func.cc
index b46f58fde60..be8966598d6 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2937,7 +2937,6 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
}
}
}
- thd->net.last_error[0]=0;
Udf_func_init init= u_d->func_init;
if ((error=(uchar) init(&initid, &f_args, init_msg_buff)))
{
@@ -2949,6 +2948,12 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
func->max_length=min(initid.max_length,MAX_BLOB_WIDTH);
func->maybe_null=initid.maybe_null;
const_item_cache=initid.const_item;
+ /*
+ Keep used_tables_cache in sync with const_item_cache.
+ See the comment in Item_udf_func::update_used tables.
+ */
+ if (!const_item_cache && !used_tables_cache)
+ used_tables_cache= RAND_TABLE_BIT;
func->decimals=min(initid.decimals,NOT_FIXED_DEC);
}
initialized=1;
@@ -3836,10 +3841,12 @@ Item_func_set_user_var::fix_length_and_dec()
bool Item_func_set_user_var::register_field_in_read_map(uchar *arg)
{
- TABLE *table= (TABLE *) arg;
- if (result_field &&
- (!table || result_field->table == table))
- bitmap_set_bit(result_field->table->read_set, result_field->field_index);
+ if (result_field)
+ {
+ TABLE *table= (TABLE *) arg;
+ if (result_field->table == table || !table)
+ bitmap_set_bit(result_field->table->read_set, result_field->field_index);
+ }
return 0;
}
diff --git a/sql/item_func.h b/sql/item_func.h
index 629d0dbfdbc..e09b584de95 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1022,6 +1022,56 @@ public:
fixed= 1;
return res;
}
+ void update_used_tables()
+ {
+ /*
+ TODO: Make a member in UDF_INIT and return if a UDF is deterministic or
+ not.
+ Currently UDF_INIT has a member (const_item) that is an in/out
+ parameter to the init() call.
+ The code in udf_handler::fix_fields also duplicates the arguments
+ handling code in Item_func::fix_fields().
+
+ The lack of information if a UDF is deterministic makes writing
+ a correct update_used_tables() for UDFs impossible.
+ One solution to this would be :
+ - Add a is_deterministic member of UDF_INIT
+ - (optionally) deprecate the const_item member of UDF_INIT
+ - Take away the duplicate code from udf_handler::fix_fields() and
+ make Item_udf_func call Item_func::fix_fields() to process its
+ arguments as for any other function.
+ - Store the deterministic flag returned by <udf>_init into the
+ udf_handler.
+ - Don't implement Item_udf_func::fix_fields, implement
+ Item_udf_func::fix_length_and_dec() instead (similar to non-UDF
+ functions).
+ - Override Item_func::update_used_tables to call
+ Item_func::update_used_tables() and add a RAND_TABLE_BIT to the
+ result of Item_func::update_used_tables() if the UDF is
+ non-deterministic.
+ - (optionally) rename RAND_TABLE_BIT to NONDETERMINISTIC_BIT to
+ better describe its usage.
+
+ The above would require a change of the UDF API.
+ Until that change is done here's how the current code works:
+ We call Item_func::update_used_tables() only when we know that
+ the function depends on real non-const tables and is deterministic.
+ This can be done only because we know that the optimizer will
+ call update_used_tables() only when there's possibly a new const
+ table. So update_used_tables() can only make a Item_func more
+ constant than it is currently.
+ That's why we don't need to do anything if a function is guaranteed
+ to return non-constant (it's non-deterministic) or is already a
+ const.
+ */
+ if ((used_tables_cache & ~PSEUDO_TABLE_BITS) &&
+ !(used_tables_cache & RAND_TABLE_BIT))
+ {
+ Item_func::update_used_tables();
+ if (!const_item_cache && !used_tables_cache)
+ used_tables_cache= RAND_TABLE_BIT;
+ }
+ }
void cleanup();
Item_result result_type () const { return udf.result_type(); }
table_map not_null_tables() const { return 0; }
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index be132439f93..ac1b7738a27 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -42,7 +42,7 @@ void Item_geometry_func::fix_length_and_dec()
{
collation.set(&my_charset_bin);
decimals=0;
- max_length=MAX_BLOB_WIDTH;
+ max_length= max_field_size;
maybe_null= 1;
}
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 614f30c48d7..46b8d2e46cc 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1856,7 +1856,9 @@ int subselect_single_select_engine::exec()
DBUG_RETURN(1);
}
}
- if (select_lex->uncacheable && executed)
+ if (select_lex->uncacheable &&
+ select_lex->uncacheable != UNCACHEABLE_EXPLAIN
+ && executed)
{
if (join->reinit())
{
diff --git a/sql/key.cc b/sql/key.cc
index 95402d213cd..7f075674ab6 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -121,19 +121,6 @@ void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
key_part->null_bit);
key_length--;
}
- if (key_part->type == HA_KEYTYPE_BIT)
- {
- Field_bit *field= (Field_bit *) (key_part->field);
- if (field->bit_len)
- {
- uchar bits= get_rec_bits(from_record +
- key_part->null_offset +
- (key_part->null_bit == 128),
- field->bit_ofs, field->bit_len);
- *to_key++= bits;
- key_length--;
- }
- }
if (key_part->key_part_flag & HA_BLOB_PART ||
key_part->key_part_flag & HA_VAR_LENGTH_PART)
{
diff --git a/sql/lock.cc b/sql/lock.cc
index 8307e762c62..a0d6faa6604 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -845,9 +845,6 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1);
to= table_buf= sql_lock->table= (TABLE**) (locks + tables * 2);
sql_lock->table_count=lock_count;
- sql_lock->lock_count=tables;
- DBUG_PRINT("info", ("sql_lock->table_count %d sql_lock->lock_count %d",
- sql_lock->table_count, sql_lock->lock_count));
for (i=0 ; i < count ; i++)
{
@@ -887,6 +884,23 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
for ( ; org_locks != locks ; org_locks++)
(*org_locks)->debug_print_param= (void *) table;
}
+ /*
+ We do not use 'tables', because there are cases where store_lock()
+ returns less locks than lock_count() claimed. This can happen when
+ a FLUSH TABLES tries to abort locks from a MERGE table of another
+ thread. When that thread has just opened the table, but not yet
+ attached its children, it cannot return the locks. lock_count()
+ always returns the number of locks that an attached table has.
+ This is done to avoid the reverse situation: If lock_count() would
+ return 0 for a non-attached MERGE table, and that table becomes
+ attached between the calls to lock_count() and store_lock(), then
+ we would have allocated too little memory for the lock data. Now
+ we may allocate too much, but better safe than memory overrun.
+ And in the FLUSH case, the memory is released quickly anyway.
+ */
+ sql_lock->lock_count= locks - locks_buf;
+ DBUG_PRINT("info", ("sql_lock->table_count %d sql_lock->lock_count %d",
+ sql_lock->table_count, sql_lock->lock_count));
DBUG_RETURN(sql_lock);
}
diff --git a/sql/log.cc b/sql/log.cc
index 0c86b0e29ea..ba457b3e10b 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -287,29 +287,34 @@ void Log_to_csv_event_handler::cleanup()
/* log event handlers */
-/*
+/**
Log command to the general log table
- SYNOPSIS
- log_general()
-
- event_time command start timestamp
- user_host the pointer to the string with user@host info
- user_host_len length of the user_host string. this is computed once
- and passed to all general log event handlers
- thread_id Id of the thread, issued a query
- command_type the type of the command being logged
- command_type_len the length of the string above
- sql_text the very text of the query being executed
- sql_text_len the length of sql_text string
-
- DESCRIPTION
-
- Log given command to the general log table
-
- RETURN
- FALSE - OK
- TRUE - error occured
+ Log given command to the general log table.
+
+ @param event_time command start timestamp
+ @param user_host the pointer to the string with user@host info
+ @param user_host_len length of the user_host string. this is computed
+ once and passed to all general log event handlers
+ @param thread_id Id of the thread, issued a query
+ @param command_type the type of the command being logged
+ @param command_type_len the length of the string above
+ @param sql_text the very text of the query being executed
+ @param sql_text_len the length of sql_text string
+
+
+ @return This function attempts to never call my_error(). This is
+ necessary, because general logging happens already after a statement
+ status has been sent to the client, so the client can not see the
+ error anyway. Besides, the error is not related to the statement
+ being executed and is internal, and thus should be handled
+ internally (@todo: how?).
+ If a write to the table has failed, the function attempts to
+ write to a short error message to the file. The failure is also
+ indicated in the return value.
+
+ @retval FALSE OK
+ @retval TRUE error occured
*/
bool Log_to_csv_event_handler::
@@ -349,6 +354,20 @@ bool Log_to_csv_event_handler::
table_list.db= MYSQL_SCHEMA_NAME.str;
table_list.db_length= MYSQL_SCHEMA_NAME.length;
+ /*
+ 1) open_performance_schema_table generates an error of the
+ table can not be opened or is corrupted.
+ 2) "INSERT INTO general_log" can generate warning sometimes.
+
+ Suppress these warnings and errors, they can't be dealt with
+ properly anyway.
+
+ QQ: this problem needs to be studied in more detail.
+ Comment this 2 lines and run "cast.test" to see what's happening.
+ */
+ thd->push_internal_handler(& error_handler);
+ need_pop= TRUE;
+
if (!(table= open_performance_schema_table(thd, & table_list,
& open_tables_backup)))
goto err;
@@ -365,14 +384,6 @@ bool Log_to_csv_event_handler::
table->next_number_field= table->found_next_number_field;
/*
- "INSERT INTO general_log" can generate warning sometimes.
- QQ: this problem needs to be studied in more details.
- Comment this 2 lines and run "cast.test" to see what's happening:
- */
- thd->push_internal_handler(& error_handler);
- need_pop= TRUE;
-
- /*
NOTE: we do not call restore_record() here, as all fields are
filled by the Logger (=> no need to load default ones).
*/
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 1ecb314c2cd..cf03dd5bf44 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1604,7 +1604,8 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
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 :
+ (killed_status_arg == THD::NOT_KILLED) ?
+ (thd_arg->is_error() ? thd_arg->main_da.sql_errno() : 0) :
((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ? 0 :
thd_arg->killed_errno());
@@ -2343,7 +2344,7 @@ START SLAVE; . Query: '%s'", expected_error, thd->query);
}
/* If the query was not ignored, it is printed to the general log */
- if (thd->net.last_errno != ER_SLAVE_IGNORED_TABLE)
+ if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE)
general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
compare_errors:
@@ -2352,9 +2353,10 @@ compare_errors:
If we expected a non-zero error code, and we don't get the same error
code, and none of them should be ignored.
*/
- DBUG_PRINT("info",("expected_error: %d last_errno: %d",
- expected_error, thd->net.last_errno));
- if ((expected_error != (actual_error= thd->net.last_errno)) &&
+ actual_error= thd->is_error() ? thd->main_da.sql_errno() : 0;
+ DBUG_PRINT("info",("expected_error: %d sql_errno: %d",
+ expected_error, actual_error));
+ if ((expected_error != actual_error) &&
expected_error &&
!ignored_error_code(actual_error) &&
!ignored_error_code(expected_error))
@@ -2366,7 +2368,7 @@ Error on master: '%s' (%d), Error on slave: '%s' (%d). \
Default database: '%s'. Query: '%s'",
ER_SAFE(expected_error),
expected_error,
- actual_error ? thd->net.last_error: "no error",
+ actual_error ? thd->main_da.message() : "no error",
actual_error,
print_slave_db_safe(db), query_arg);
thd->is_slave_error= 1;
@@ -2388,7 +2390,7 @@ Default database: '%s'. Query: '%s'",
{
rli->report(ERROR_LEVEL, actual_error,
"Error '%s' on query. Default database: '%s'. Query: '%s'",
- (actual_error ? thd->net.last_error :
+ (actual_error ? thd->main_da.message() :
"unexpected success or fatal error"),
print_slave_db_safe(thd->db), query_arg);
thd->is_slave_error= 1;
@@ -3730,8 +3732,11 @@ error:
/* this err/sql_errno code is copy-paste from net_send_error() */
const char *err;
int sql_errno;
- if ((err=thd->net.last_error)[0])
- sql_errno=thd->net.last_errno;
+ if (thd->is_error())
+ {
+ err= thd->main_da.message();
+ sql_errno= thd->main_da.sql_errno();
+ }
else
{
sql_errno=ER_UNKNOWN_ERROR;
@@ -6232,10 +6237,10 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
*/
- uint actual_error= thd->net.last_errno;
+ uint actual_error= thd->main_da.sql_errno();
rli->report(ERROR_LEVEL, actual_error,
"Error '%s' in %s event: when locking tables",
- (actual_error ? thd->net.last_error :
+ (actual_error ? thd->main_da.message():
"unexpected success or fatal error"),
get_type_str());
thd->is_fatal_error= 1;
@@ -6276,10 +6281,10 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
*/
- uint actual_error= thd->net.last_errno;
+ uint actual_error= thd->main_da.sql_errno();
rli->report(ERROR_LEVEL, actual_error,
"Error '%s' on reopening tables",
- (actual_error ? thd->net.last_error :
+ (actual_error ? thd->main_da.message() :
"unexpected success or fatal error"));
thd->is_slave_error= 1;
}
@@ -6435,10 +6440,11 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
break;
default:
- rli->report(ERROR_LEVEL, thd->net.last_errno,
+ rli->report(ERROR_LEVEL,
+ thd->is_error() ? thd->main_da.sql_errno() : 0,
"Error in %s event: row application failed. %s",
get_type_str(),
- thd->net.last_error ? thd->net.last_error : "");
+ thd->is_error() ? thd->main_da.message() : "");
thd->is_slave_error= 1;
break;
}
@@ -6485,12 +6491,13 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
if (error)
{ /* error has occured during the transaction */
- rli->report(ERROR_LEVEL, thd->net.last_errno,
+ rli->report(ERROR_LEVEL,
+ thd->is_error() ? thd->main_da.sql_errno() : 0,
"Error in %s event: error during transaction execution "
"on table %s.%s. %s",
get_type_str(), table->s->db.str,
table->s->table_name.str,
- thd->net.last_error ? thd->net.last_error : "");
+ thd->is_error() ? thd->main_da.message() : "");
/*
If one day we honour --skip-slave-errors in row-based replication, and
@@ -7105,10 +7112,10 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
*/
- uint actual_error= thd->net.last_errno;
+ uint actual_error= thd->main_da.sql_errno();
rli->report(ERROR_LEVEL, actual_error,
"Error '%s' on opening table `%s`.`%s`",
- (actual_error ? thd->net.last_error :
+ (actual_error ? thd->main_da.message() :
"unexpected success or fatal error"),
table_list->db, table_list->table_name);
thd->is_slave_error= 1;
@@ -7636,8 +7643,11 @@ Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
DBUG_ASSERT(m_table != NULL);
int error= write_row(rli, TRUE /* overwrite */);
- if (error && !thd->net.last_errno)
- thd->net.last_errno= error;
+ if (error && !thd->is_error())
+ {
+ DBUG_ASSERT(0);
+ my_error(ER_UNKNOWN_ERROR, MYF(0));
+ }
return error;
}
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index c6b691ec010..6d5d86e42fe 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -74,10 +74,10 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
*/
- uint actual_error= thd->net.last_errno;
+ uint actual_error= thd->main_da.sql_errno();
rli->report(ERROR_LEVEL, actual_error,
"Error '%s' in %s event: when locking tables",
- (actual_error ? thd->net.last_error :
+ (actual_error ? thd->main_da.message() :
"unexpected success or fatal error"),
ev->get_type_str());
thd->is_fatal_error= 1;
@@ -118,10 +118,10 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli
Error reporting borrowed from Query_log_event with many excessive
simplifications (we don't honour --slave-skip-errors)
*/
- uint actual_error= thd->net.last_errno;
+ uint actual_error= thd->main_da.sql_errno();
rli->report(ERROR_LEVEL, actual_error,
"Error '%s' on reopening tables",
- (actual_error ? thd->net.last_error :
+ (actual_error ? thd->main_da.message() :
"unexpected success or fatal error"));
thd->is_slave_error= 1;
}
@@ -251,10 +251,10 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli
break;
default:
- rli->report(ERROR_LEVEL, thd->net.last_errno,
+ rli->report(ERROR_LEVEL, thd->main_da.sql_errno(),
"Error in %s event: row application failed. %s",
ev->get_type_str(),
- thd->net.last_error ? thd->net.last_error : "");
+ thd->is_error() ? thd->main_da.message() : "");
thd->is_slave_error= 1;
break;
}
@@ -280,12 +280,12 @@ Old_rows_log_event::do_apply_event(Rows_log_event *ev, const Relay_log_info *rli
if (error)
{ /* error has occured during the transaction */
- rli->report(ERROR_LEVEL, thd->net.last_errno,
+ rli->report(ERROR_LEVEL, thd->main_da.sql_errno(),
"Error in %s event: error during transaction execution "
"on table %s.%s. %s",
ev->get_type_str(), table->s->db.str,
table->s->table_name.str,
- thd->net.last_error ? thd->net.last_error : "");
+ thd->is_error() ? thd->main_da.message() : "");
/*
If one day we honour --skip-slave-errors in row-based replication, and
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index bf1f78a409e..0adf90dc258 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -269,7 +269,7 @@ protected:
#define QUERY_ALLOC_PREALLOC_SIZE 8192
#define TRANS_ALLOC_BLOCK_SIZE 4096
#define TRANS_ALLOC_PREALLOC_SIZE 4096
-#define RANGE_ALLOC_BLOCK_SIZE 2048
+#define RANGE_ALLOC_BLOCK_SIZE 4096
#define ACL_ALLOC_BLOCK_SIZE 1024
#define UDF_ALLOC_BLOCK_SIZE 1024
#define TABLE_ALLOC_BLOCK_SIZE 1024
@@ -699,6 +699,8 @@ void free_items(Item *item);
void cleanup_items(Item *item);
class THD;
void close_thread_tables(THD *thd);
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables);
bool check_single_table_access(THD *thd, ulong privilege,
TABLE_LIST *tables, bool no_errors);
@@ -706,6 +708,24 @@ bool check_routine_access(THD *thd,ulong want_access,char *db,char *name,
bool is_proc, bool no_errors);
bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table);
bool check_some_routine_access(THD *thd, const char *db, const char *name, bool is_proc);
+#else
+inline bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables)
+{ return false; }
+inline bool check_single_table_access(THD *thd, ulong privilege,
+ TABLE_LIST *tables, bool no_errors)
+{ return false; }
+inline bool check_routine_access(THD *thd,ulong want_access,char *db,
+ char *name, bool is_proc, bool no_errors)
+{ return false; }
+inline bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table)
+{ return false; }
+inline bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list)
+{ return false; }
+inline bool check_some_routine_access(THD *thd, const char *db,
+ const char *name, bool is_proc)
+{ return false; }
+#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
+
bool multi_update_precheck(THD *thd, TABLE_LIST *tables);
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables);
bool mysql_multi_update_prepare(THD *thd);
@@ -1010,11 +1030,27 @@ void kill_mysql(void);
void close_connection(THD *thd, uint errcode, bool lock);
bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
bool *write_to_binlog);
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
bool check_access(THD *thd, ulong access, const char *db, ulong *save_priv,
bool no_grant, bool no_errors, bool schema_db);
bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables,
bool no_errors);
bool check_global_access(THD *thd, ulong want_access);
+#else
+inline bool check_access(THD *thd, ulong access, const char *db,
+ ulong *save_priv, bool no_grant, bool no_errors,
+ bool schema_db)
+{
+ if (save_priv)
+ *save_priv= GLOBAL_ACLS;
+ return false;
+}
+inline bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables,
+ bool no_errors)
+{ return false; }
+inline bool check_global_access(THD *thd, ulong want_access)
+{ return false; }
+#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
/*
Support routine for SQL parser on partitioning syntax
@@ -1614,7 +1650,8 @@ TABLE *open_performance_schema_table(THD *thd, TABLE_LIST *one_table,
Open_tables_state *backup);
void close_performance_schema_table(THD *thd, Open_tables_state *backup);
-bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables, bool have_lock = FALSE);
+bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
+ bool wait_for_refresh, bool wait_for_placeholders);
bool close_cached_connection_tables(THD *thd, bool wait_for_refresh,
LEX_STRING *connect_string,
bool have_lock = FALSE);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 634c5b886c1..d7644aebdc8 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -174,7 +174,7 @@ typedef fp_except fp_except_t;
We can't handle floating point exceptions with threads, so disable
this on freebsd.
*/
-inline void reset_floating_point_exceptions()
+inline void set_proper_floating_point_mode()
{
/* Don't fall for overflow, underflow,divide-by-zero or loss of precision */
#if defined(__i386__)
@@ -185,8 +185,22 @@ inline void reset_floating_point_exceptions()
FP_X_IMP));
#endif
}
+#elif defined(__sgi)
+/* for IRIX to use set_fpc_csr() */
+#include <sys/fpu.h>
+
+inline void set_proper_floating_point_mode()
+{
+ /* Enable denormalized DOUBLE values support for IRIX */
+ {
+ union fpc_csr n;
+ n.fc_word = get_fpc_csr();
+ n.fc_struct.flush = 0;
+ set_fpc_csr(n.fc_word);
+ }
+}
#else
-#define reset_floating_point_exceptions()
+#define set_proper_floating_point_mode()
#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
} /* cplusplus */
@@ -478,7 +492,7 @@ ulong thread_id=1L,current_pid;
ulong slow_launch_threads = 0, sync_binlog_period;
ulong expire_logs_days = 0;
ulong rpl_recovery_rank=0;
-const char *log_output_str= "TABLE";
+const char *log_output_str= "FILE";
time_t server_start_time, flush_status_time;
@@ -1158,6 +1172,8 @@ void clean_up(bool print_message)
if (cleanup_done++)
return; /* purecov: inspected */
+ release_ddl_log();
+
/*
make sure that handlers finish up
what they have that is dependent on the binlog
@@ -1352,7 +1368,6 @@ static void set_ports()
char *env;
if (!mysqld_port && !opt_disable_networking)
{ // Get port if not from commandline
- struct servent *serv_ptr;
mysqld_port= MYSQL_PORT;
/*
@@ -1366,6 +1381,7 @@ static void set_ports()
*/
#if MYSQL_PORT_DEFAULT == 0
+ struct servent *serv_ptr;
if ((serv_ptr= getservbyname("mysql", "tcp")))
mysqld_port= ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */
#endif
@@ -2570,21 +2586,8 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
MYSQL_ERROR::WARN_LEVEL_ERROR))
DBUG_RETURN(0);
- if (thd->spcont &&
- thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
- {
- DBUG_RETURN(0);
- }
-
thd->is_slave_error= 1; // needed to catch query errors during replication
- if (!thd->no_warnings_for_error)
- {
- thd->no_warnings_for_error= TRUE;
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
- thd->no_warnings_for_error= FALSE;
- }
-
/*
thd->lex->current_select == 0 if lex structure is not inited
(not query command (COM_QUERY))
@@ -2601,14 +2604,39 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
}
else
{
- NET *net= &thd->net;
- net->report_error= 1;
- query_cache_abort(net);
- if (!net->last_error[0]) // Return only first message
+ if (! thd->main_da.is_error()) // Return only first message
{
- strmake(net->last_error, str, sizeof(net->last_error)-1);
- net->last_errno= error ? error : ER_UNKNOWN_ERROR;
+ if (error == 0)
+ error= ER_UNKNOWN_ERROR;
+ if (str == NULL)
+ str= ER(error);
+ thd->main_da.set_error_status(thd, error, str);
}
+ query_cache_abort(&thd->net);
+ }
+ /*
+ If a continue handler is found, the error message will be cleared
+ by the stored procedures code.
+ */
+ if (thd->spcont &&
+ thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
+ {
+ /*
+ Do not push any warnings, a handled error must be completely
+ silenced.
+ */
+ DBUG_RETURN(0);
+ }
+
+ if (!thd->no_warnings_for_error)
+ {
+ /*
+ Suppress infinite recursion if there a memory allocation error
+ inside push_warning.
+ */
+ thd->no_warnings_for_error= TRUE;
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
+ thd->no_warnings_for_error= FALSE;
}
}
if (!thd || MyFlags & ME_NOREFRESH)
@@ -2717,6 +2745,154 @@ static bool init_global_datetime_format(timestamp_type format_type,
return 0;
}
+SHOW_VAR com_status_vars[]= {
+ {"admin_commands", (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS},
+ {"assign_to_keycache", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ASSIGN_TO_KEYCACHE]), SHOW_LONG_STATUS},
+ {"alter_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
+ {"alter_db_upgrade", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB_UPGRADE]), SHOW_LONG_STATUS},
+ {"alter_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_EVENT]), SHOW_LONG_STATUS},
+ {"alter_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_FUNCTION]), SHOW_LONG_STATUS},
+ {"alter_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_PROCEDURE]), SHOW_LONG_STATUS},
+ {"alter_server", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_SERVER]), SHOW_LONG_STATUS},
+ {"alter_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
+ {"alter_tablespace", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLESPACE]), SHOW_LONG_STATUS},
+ {"analyze", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
+ {"backup_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BACKUP_TABLE]), SHOW_LONG_STATUS},
+ {"begin", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BEGIN]), SHOW_LONG_STATUS},
+ {"binlog", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BINLOG_BASE64_EVENT]), SHOW_LONG_STATUS},
+ {"call_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CALL]), SHOW_LONG_STATUS},
+ {"change_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_DB]), SHOW_LONG_STATUS},
+ {"change_master", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_MASTER]), SHOW_LONG_STATUS},
+ {"check", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECK]), SHOW_LONG_STATUS},
+ {"checksum", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
+ {"commit", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
+ {"create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
+ {"create_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_EVENT]), SHOW_LONG_STATUS},
+ {"create_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_SPFUNCTION]), SHOW_LONG_STATUS},
+ {"create_index", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
+ {"create_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_PROCEDURE]), SHOW_LONG_STATUS},
+ {"create_server", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_SERVER]), SHOW_LONG_STATUS},
+ {"create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
+ {"create_trigger", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TRIGGER]), SHOW_LONG_STATUS},
+ {"create_udf", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_FUNCTION]), SHOW_LONG_STATUS},
+ {"create_user", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_USER]), SHOW_LONG_STATUS},
+ {"create_view", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_VIEW]), SHOW_LONG_STATUS},
+ {"dealloc_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DEALLOCATE_PREPARE]), SHOW_LONG_STATUS},
+ {"delete", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE]), SHOW_LONG_STATUS},
+ {"delete_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE_MULTI]), SHOW_LONG_STATUS},
+ {"do", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DO]), SHOW_LONG_STATUS},
+ {"drop_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
+ {"drop_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_EVENT]), SHOW_LONG_STATUS},
+ {"drop_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_FUNCTION]), SHOW_LONG_STATUS},
+ {"drop_index", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
+ {"drop_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_PROCEDURE]), SHOW_LONG_STATUS},
+ {"drop_server", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_SERVER]), SHOW_LONG_STATUS},
+ {"drop_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
+ {"drop_trigger", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TRIGGER]), SHOW_LONG_STATUS},
+ {"drop_user", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_USER]), SHOW_LONG_STATUS},
+ {"drop_view", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_VIEW]), SHOW_LONG_STATUS},
+ {"empty_query", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
+ {"execute_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXECUTE]), SHOW_LONG_STATUS},
+ {"flush", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
+ {"grant", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT]), SHOW_LONG_STATUS},
+ {"ha_close", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_CLOSE]), SHOW_LONG_STATUS},
+ {"ha_open", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_OPEN]), SHOW_LONG_STATUS},
+ {"ha_read", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_READ]), SHOW_LONG_STATUS},
+ {"help", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HELP]), SHOW_LONG_STATUS},
+ {"insert", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT]), SHOW_LONG_STATUS},
+ {"insert_select", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
+ {"install_plugin", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSTALL_PLUGIN]), SHOW_LONG_STATUS},
+ {"kill", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_KILL]), SHOW_LONG_STATUS},
+ {"load", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD]), SHOW_LONG_STATUS},
+ {"load_master_data", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD_MASTER_DATA]), SHOW_LONG_STATUS},
+ {"load_master_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD_MASTER_TABLE]), SHOW_LONG_STATUS},
+ {"lock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOCK_TABLES]), SHOW_LONG_STATUS},
+ {"optimize", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_OPTIMIZE]), SHOW_LONG_STATUS},
+ {"preload_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PRELOAD_KEYS]), SHOW_LONG_STATUS},
+ {"prepare_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PREPARE]), SHOW_LONG_STATUS},
+ {"purge", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE]), SHOW_LONG_STATUS},
+ {"purge_before_date", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE_BEFORE]), SHOW_LONG_STATUS},
+ {"release_savepoint", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
+ {"rename_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
+ {"rename_user", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_USER]), SHOW_LONG_STATUS},
+ {"repair", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPAIR]), SHOW_LONG_STATUS},
+ {"replace", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
+ {"replace_select", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
+ {"reset", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESET]), SHOW_LONG_STATUS},
+ {"restore_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESTORE_TABLE]), SHOW_LONG_STATUS},
+ {"revoke", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE]), SHOW_LONG_STATUS},
+ {"revoke_all", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE_ALL]), SHOW_LONG_STATUS},
+ {"rollback", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
+ {"rollback_to_savepoint",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK_TO_SAVEPOINT]), SHOW_LONG_STATUS},
+ {"savepoint", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
+ {"select", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SELECT]), SHOW_LONG_STATUS},
+ {"set_option", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS},
+ {"show_authors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_AUTHORS]), SHOW_LONG_STATUS},
+ {"show_binlog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS},
+ {"show_binlogs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS},
+ {"show_charsets", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]), SHOW_LONG_STATUS},
+ {"show_collations", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS},
+ {"show_column_types", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLUMN_TYPES]), SHOW_LONG_STATUS},
+ {"show_contributors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CONTRIBUTORS]), SHOW_LONG_STATUS},
+ {"show_create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
+ {"show_create_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_EVENT]), SHOW_LONG_STATUS},
+ {"show_create_func", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_FUNC]), SHOW_LONG_STATUS},
+ {"show_create_proc", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_PROC]), SHOW_LONG_STATUS},
+ {"show_create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
+ {"show_create_trigger", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_TRIGGER]), SHOW_LONG_STATUS},
+ {"show_databases", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_DATABASES]), SHOW_LONG_STATUS},
+ {"show_engine_logs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_LOGS]), SHOW_LONG_STATUS},
+ {"show_engine_mutex", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_MUTEX]), SHOW_LONG_STATUS},
+ {"show_engine_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_STATUS]), SHOW_LONG_STATUS},
+ {"show_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_EVENTS]), SHOW_LONG_STATUS},
+ {"show_errors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
+ {"show_fields", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FIELDS]), SHOW_LONG_STATUS},
+#ifndef DBUG_OFF
+ {"show_function_code", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FUNC_CODE]), SHOW_LONG_STATUS},
+#endif
+ {"show_function_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_FUNC]), SHOW_LONG_STATUS},
+ {"show_grants", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS},
+ {"show_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
+ {"show_master_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
+ {"show_new_master", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NEW_MASTER]), SHOW_LONG_STATUS},
+ {"show_open_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
+ {"show_plugins", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PLUGINS]), SHOW_LONG_STATUS},
+ {"show_privileges", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PRIVILEGES]), SHOW_LONG_STATUS},
+#ifndef DBUG_OFF
+ {"show_procedure_code", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROC_CODE]), SHOW_LONG_STATUS},
+#endif
+ {"show_procedure_status",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_PROC]), SHOW_LONG_STATUS},
+ {"show_processlist", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROCESSLIST]), SHOW_LONG_STATUS},
+ {"show_slave_hosts", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_HOSTS]), SHOW_LONG_STATUS},
+ {"show_slave_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
+ {"show_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
+ {"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
+ {"show_table_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
+ {"show_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
+ {"show_triggers", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
+ {"show_variables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
+ {"show_warnings", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
+ {"slave_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
+ {"slave_stop", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_STOP]), SHOW_LONG_STATUS},
+ {"stmt_close", (char*) offsetof(STATUS_VAR, com_stmt_close), SHOW_LONG_STATUS},
+ {"stmt_execute", (char*) offsetof(STATUS_VAR, com_stmt_execute), SHOW_LONG_STATUS},
+ {"stmt_fetch", (char*) offsetof(STATUS_VAR, com_stmt_fetch), SHOW_LONG_STATUS},
+ {"stmt_prepare", (char*) offsetof(STATUS_VAR, com_stmt_prepare), SHOW_LONG_STATUS},
+ {"stmt_reset", (char*) offsetof(STATUS_VAR, com_stmt_reset), SHOW_LONG_STATUS},
+ {"stmt_send_long_data", (char*) offsetof(STATUS_VAR, com_stmt_send_long_data), SHOW_LONG_STATUS},
+ {"truncate", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
+ {"uninstall_plugin", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNINSTALL_PLUGIN]), SHOW_LONG_STATUS},
+ {"unlock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
+ {"update", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
+ {"update_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE_MULTI]), SHOW_LONG_STATUS},
+ {"xa_commit", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_COMMIT]),SHOW_LONG_STATUS},
+ {"xa_end", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_END]),SHOW_LONG_STATUS},
+ {"xa_prepare", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_PREPARE]),SHOW_LONG_STATUS},
+ {"xa_recover", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_RECOVER]),SHOW_LONG_STATUS},
+ {"xa_rollback", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_ROLLBACK]),SHOW_LONG_STATUS},
+ {"xa_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_START]),SHOW_LONG_STATUS},
+ {NullS, NullS, SHOW_LONG}
+};
static int init_common_variables(const char *conf_file_name, int argc,
char **argv, const char **groups)
@@ -2730,7 +2906,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
server_start_time= flush_status_time= my_time(0);
rpl_filter= new Rpl_filter;
binlog_filter= new Rpl_filter;
- if (!rpl_filter || !binlog_filter)
+ if (!rpl_filter || !binlog_filter)
{
sql_perror("Could not allocate replication and binlog filters");
exit(1);
@@ -2750,13 +2926,13 @@ static int init_common_variables(const char *conf_file_name, int argc,
}
#endif
/*
- We set SYSTEM time zone as reasonable default and
+ We set SYSTEM time zone as reasonable default and
also for failure of my_tz_init() and bootstrap mode.
If user explicitly set time zone with --default-time-zone
option we will change this value in my_tz_init().
*/
global_system_variables.time_zone= my_tz_SYSTEM;
-
+
/*
Init mutexes for the global MYSQL_BIN_LOG objects.
As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
@@ -2785,6 +2961,31 @@ static int init_common_variables(const char *conf_file_name, int argc,
if (add_status_vars(status_vars))
return 1; // an error was already reported
+#ifndef DBUG_OFF
+ /*
+ We have few debug-only commands in com_status_vars, only visible in debug
+ builds. for simplicity we enable the assert only in debug builds
+
+ There are 7 Com_ variables which don't have corresponding SQLCOM_ values:
+ (TODO strictly speaking they shouldn't be here, should not have Com_ prefix
+ that is. Perhaps Stmt_ ? Comstmt_ ? Prepstmt_ ?)
+
+ Com_admin_commands => com_other
+ Com_stmt_close => com_stmt_close
+ Com_stmt_execute => com_stmt_execute
+ Com_stmt_fetch => com_stmt_fetch
+ Com_stmt_prepare => com_stmt_prepare
+ Com_stmt_reset => com_stmt_reset
+ Com_stmt_send_long_data => com_stmt_send_long_data
+
+ With this correction the number of Com_ variables (number of elements in
+ the array, excluding the last element - terminator) must match the number
+ of SQLCOM_ constants.
+ */
+ compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 ==
+ SQLCOM_END + 7);
+#endif
+
load_defaults(conf_file_name, groups, &argc, &argv);
defaults_argv=argv;
defaults_argc=argc;
@@ -2841,7 +3042,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
*/
table_cache_size= (ulong) min(max((files-10-max_connections)/2,
TABLE_OPEN_CACHE_MIN),
- table_cache_size);
+ table_cache_size);
DBUG_PRINT("warning",
("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
files, max_connections, table_cache_size));
@@ -3228,7 +3429,7 @@ static int init_server_components()
query_cache_init();
query_cache_resize(query_cache_size);
randominit(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
- reset_floating_point_exceptions();
+ set_proper_floating_point_mode();
init_thr_lock();
#ifdef HAVE_REPLICATION
init_slave_list();
@@ -3981,7 +4182,6 @@ we force server id to 2, but this MySQL server will not act as a slave.");
pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
(void) pthread_mutex_unlock(&LOCK_thread_count);
- release_ddl_log();
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
if (Service.IsNT() && start_mode)
Service.Stop();
@@ -5203,7 +5403,7 @@ struct my_option my_long_options[] =
{"concurrent-insert", OPT_CONCURRENT_INSERT,
"Use concurrent insert with MyISAM. Disable with --concurrent-insert=0",
(uchar**) &myisam_concurrent_insert, (uchar**) &myisam_concurrent_insert,
- 0, GET_LONG, OPT_ARG, 1, 0, 2, 0, 0, 0},
+ 0, GET_ULONG, OPT_ARG, 1, 0, 2, 0, 0, 0},
{"console", OPT_CONSOLE, "Write error output on screen; Don't remove the console window on windows.",
(uchar**) &opt_console, (uchar**) &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
@@ -5407,7 +5607,8 @@ Disable with --skip-large-pages.",
#ifdef HAVE_MMAP
{"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.",
(uchar**) &opt_tc_log_size, (uchar**) &opt_tc_log_size, 0, GET_ULONG,
- REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ~0L, 0, TC_LOG_PAGE_SIZE, 0},
+ REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ULONG_MAX, 0,
+ TC_LOG_PAGE_SIZE, 0},
#endif
{"log-update", OPT_UPDATE_LOG,
"The update log is deprecated since version 5.0, is replaced by the binary \
@@ -5508,13 +5709,8 @@ master-ssl",
{"ndb-autoincrement-prefetch-sz", OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
"Specify number of autoincrement values that are prefetched.",
(uchar**) &global_system_variables.ndb_autoincrement_prefetch_sz,
- (uchar**) &global_system_variables.ndb_autoincrement_prefetch_sz,
- 0, GET_ULONG, REQUIRED_ARG, 32, 1, 256, 0, 0, 0},
- {"ndb-distribution", OPT_NDB_DISTRIBUTION,
- "Default distribution for new tables in ndb",
- (uchar**) &opt_ndb_distribution,
- (uchar**) &opt_ndb_distribution,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ (uchar**) &max_system_variables.ndb_autoincrement_prefetch_sz,
+ 0, GET_ULONG, REQUIRED_ARG, 1, 1, 256, 0, 0, 0},
{"ndb-force-send", OPT_NDB_FORCE_SEND,
"Force send of buffers to ndb immediately without waiting for "
"other threads.",
@@ -5874,8 +6070,8 @@ log and this option does nothing anymore.",
NO_ARG, 0, 0, 0, 0, 0, 0},
{"warnings", 'W', "Deprecated; use --log-warnings instead.",
(uchar**) &global_system_variables.log_warnings,
- (uchar**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, ~0L,
- 0, 0, 0},
+ (uchar**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG,
+ 1, 0, ULONG_MAX, 0, 0, 0},
{ "back_log", OPT_BACK_LOG,
"The number of outstanding connection requests MySQL can have. This comes into play when the main MySQL thread gets very many connection requests in a very short time.",
(uchar**) &back_log, (uchar**) &back_log, 0, GET_ULONG,
@@ -5883,12 +6079,12 @@ log and this option does nothing anymore.",
{"binlog_cache_size", OPT_BINLOG_CACHE_SIZE,
"The size of the cache to hold the SQL statements for the binary log during a transaction. If you often use big, multi-statement transactions you can increase this to get more performance.",
(uchar**) &binlog_cache_size, (uchar**) &binlog_cache_size, 0, GET_ULONG,
- REQUIRED_ARG, 32*1024L, IO_SIZE, ~0L, 0, IO_SIZE, 0},
+ REQUIRED_ARG, 32*1024L, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0},
{"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
"Size of tree cache used in bulk insert optimisation. Note that this is a limit per thread!",
(uchar**) &global_system_variables.bulk_insert_buff_size,
(uchar**) &max_system_variables.bulk_insert_buff_size,
- 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ~0L, 0, 1, 0},
+ 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
{"connect_timeout", OPT_CONNECT_TIMEOUT,
"The number of seconds the mysqld server is waiting for a connect packet before responding with 'Bad handshake'.",
(uchar**) &connect_timeout, (uchar**) &connect_timeout,
@@ -5911,7 +6107,7 @@ log and this option does nothing anymore.",
{"delayed_insert_limit", OPT_DELAYED_INSERT_LIMIT,
"After inserting delayed_insert_limit rows, the INSERT DELAYED handler will check if there are any SELECT statements pending. If so, it allows these to execute before continuing.",
(uchar**) &delayed_insert_limit, (uchar**) &delayed_insert_limit, 0, GET_ULONG,
- REQUIRED_ARG, DELAYED_LIMIT, 1, ~0L, 0, 1, 0},
+ REQUIRED_ARG, DELAYED_LIMIT, 1, ULONG_MAX, 0, 1, 0},
{"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT,
"How long a INSERT DELAYED thread should wait for INSERT statements before terminating.",
(uchar**) &delayed_insert_timeout, (uchar**) &delayed_insert_timeout, 0,
@@ -5919,7 +6115,7 @@ log and this option does nothing anymore.",
{ "delayed_queue_size", OPT_DELAYED_QUEUE_SIZE,
"What size queue (in rows) should be allocated for handling INSERT DELAYED. If the queue becomes full, any client that does INSERT DELAYED will wait until there is room in the queue again.",
(uchar**) &delayed_queue_size, (uchar**) &delayed_queue_size, 0, GET_ULONG,
- REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1, 0},
+ REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ULONG_MAX, 0, 1, 0},
{"div_precision_increment", OPT_DIV_PRECINCREMENT,
"Precision of the result of '/' operator will be increased on that value.",
(uchar**) &global_system_variables.div_precincrement,
@@ -5959,7 +6155,7 @@ log and this option does nothing anymore.",
"The maximum length of the result of function group_concat.",
(uchar**) &global_system_variables.group_concat_max_len,
(uchar**) &max_system_variables.group_concat_max_len, 0, GET_ULONG,
- REQUIRED_ARG, 1024, 4, (long) ~0, 0, 1, 0},
+ REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0},
{"interactive_timeout", OPT_INTERACTIVE_TIMEOUT,
"The number of seconds the server waits for activity on an interactive connection before closing it.",
(uchar**) &global_system_variables.net_interactive_timeout,
@@ -5969,8 +6165,8 @@ log and this option does nothing anymore.",
"The size of the buffer that is used for full joins.",
(uchar**) &global_system_variables.join_buff_size,
(uchar**) &max_system_variables.join_buff_size, 0, GET_ULONG,
- REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD,
- IO_SIZE, 0},
+ REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
+ MALLOC_OVERHEAD, IO_SIZE, 0},
{"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
"Don't overwrite stale .MYD and .MYI even if no directory is specified.",
(uchar**) &global_system_variables.keep_files_on_create,
@@ -5988,7 +6184,7 @@ log and this option does nothing anymore.",
(uchar**) &dflt_key_cache_var.param_age_threshold,
(uchar**) 0,
0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
- 300, 100, ~0L, 0, 100, 0},
+ 300, 100, ULONG_MAX, 0, 100, 0},
{"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
"The default size of key cache blocks",
(uchar**) &dflt_key_cache_var.param_block_size,
@@ -6024,7 +6220,7 @@ log and this option does nothing anymore.",
{"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE,
"Can be used to restrict the total size used to cache a multi-transaction query.",
(uchar**) &max_binlog_cache_size, (uchar**) &max_binlog_cache_size, 0,
- GET_ULONG, REQUIRED_ARG, ~0L, IO_SIZE, ~0L, 0, IO_SIZE, 0},
+ GET_ULONG, REQUIRED_ARG, ULONG_MAX, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0},
{"max_binlog_size", OPT_MAX_BINLOG_SIZE,
"Binary log will be rotated automatically when the size exceeds this \
value. Will also apply to relay logs if max_relay_log_size is 0. \
@@ -6034,7 +6230,7 @@ The minimum value for this variable is 4096.",
{"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
"If there is more than this number of interrupted connections from a host this host will be blocked from further connections.",
(uchar**) &max_connect_errors, (uchar**) &max_connect_errors, 0, GET_ULONG,
- REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ~0L, 0, 1, 0},
+ REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0},
// Default max_connections of 151 is larger than Apache's default max
// children, to avoid "too many connections" error in a common setup
{"max_connections", OPT_MAX_CONNECTIONS,
@@ -6079,7 +6275,7 @@ The minimum value for this variable is 4096.",
"Limit assumed max number of seeks when looking up rows based on a key",
(uchar**) &global_system_variables.max_seeks_for_key,
(uchar**) &max_system_variables.max_seeks_for_key, 0, GET_ULONG,
- REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0 },
+ REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
{"max_sort_length", OPT_MAX_SORT_LENGTH,
"The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored).",
(uchar**) &global_system_variables.max_sort_length,
@@ -6094,25 +6290,25 @@ The minimum value for this variable is 4096.",
"Maximum number of temporary tables a client can keep open at a time.",
(uchar**) &global_system_variables.max_tmp_tables,
(uchar**) &max_system_variables.max_tmp_tables, 0, GET_ULONG,
- REQUIRED_ARG, 32, 1, ~0L, 0, 1, 0},
+ REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0},
{"max_user_connections", OPT_MAX_USER_CONNECTIONS,
"The maximum number of active connections for a single user (0 = no limit).",
(uchar**) &max_user_connections, (uchar**) &max_user_connections, 0, GET_UINT,
- REQUIRED_ARG, 0, 1, ~0, 0, 1, 0},
+ REQUIRED_ARG, 0, 1, UINT_MAX, 0, 1, 0},
{"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
"After this many write locks, allow some read locks to run in between.",
(uchar**) &max_write_lock_count, (uchar**) &max_write_lock_count, 0, GET_ULONG,
- REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0},
+ REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0},
{"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
"Don't log queries which examine less than min_examined_row_limit rows to file.",
(uchar**) &global_system_variables.min_examined_row_limit,
(uchar**) &max_system_variables.min_examined_row_limit, 0, GET_ULONG,
- REQUIRED_ARG, 0, 0, ~0L, 0, 1L, 0},
+ REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
{"multi_range_count", OPT_MULTI_RANGE_COUNT,
"Number of key ranges to request at once.",
(uchar**) &global_system_variables.multi_range_count,
(uchar**) &max_system_variables.multi_range_count, 0,
- GET_ULONG, REQUIRED_ARG, 256, 1, ~0L, 0, 1, 0},
+ GET_ULONG, REQUIRED_ARG, 256, 1, ULONG_MAX, 0, 1, 0},
{"myisam_block_size", OPT_MYISAM_BLOCK_SIZE,
"Block size to be used for MyISAM index pages.",
(uchar**) &opt_myisam_block_size,
@@ -6140,7 +6336,7 @@ The minimum value for this variable is 4096.",
"Number of threads to use when repairing MyISAM tables. The value of 1 disables parallel repair.",
(uchar**) &global_system_variables.myisam_repair_threads,
(uchar**) &max_system_variables.myisam_repair_threads, 0,
- GET_ULONG, REQUIRED_ARG, 1, 1, ~0L, 0, 1, 0},
+ GET_ULONG, REQUIRED_ARG, 1, 1, ULONG_MAX, 0, 1, 0},
{"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE,
"The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.",
(uchar**) &global_system_variables.myisam_sort_buff_size,
@@ -6171,7 +6367,7 @@ The minimum value for this variable is 4096.",
"If a read on a communication port is interrupted, retry this many times before giving up.",
(uchar**) &global_system_variables.net_retry_count,
(uchar**) &max_system_variables.net_retry_count,0,
- GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1, 0},
+ GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ULONG_MAX, 0, 1, 0},
{"net_write_timeout", OPT_NET_WRITE_TIMEOUT,
"Number of seconds to wait for a block to be written to a connection before aborting the write.",
(uchar**) &global_system_variables.net_write_timeout,
@@ -6213,17 +6409,17 @@ The minimum value for this variable is 4096.",
"Allocation block size for query parsing and execution",
(uchar**) &global_system_variables.query_alloc_block_size,
(uchar**) &max_system_variables.query_alloc_block_size, 0, GET_ULONG,
- REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0},
+ REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
#ifdef HAVE_QUERY_CACHE
{"query_cache_limit", OPT_QUERY_CACHE_LIMIT,
"Don't cache results that are bigger than this.",
(uchar**) &query_cache_limit, (uchar**) &query_cache_limit, 0, GET_ULONG,
- REQUIRED_ARG, 1024*1024L, 0, (longlong) ULONG_MAX, 0, 1, 0},
+ REQUIRED_ARG, 1024*1024L, 0, ULONG_MAX, 0, 1, 0},
{"query_cache_min_res_unit", OPT_QUERY_CACHE_MIN_RES_UNIT,
"minimal size of unit in wich space for results is allocated (last unit will be trimed after writing all result data.",
(uchar**) &query_cache_min_res_unit, (uchar**) &query_cache_min_res_unit,
0, GET_ULONG, REQUIRED_ARG, QUERY_CACHE_MIN_RESULT_DATA_SIZE,
- 0, (longlong) ULONG_MAX, 0, 1, 0},
+ 0, ULONG_MAX, 0, 1, 0},
#endif /*HAVE_QUERY_CACHE*/
{"query_cache_size", OPT_QUERY_CACHE_SIZE,
"The memory allocated to store results from old queries.",
@@ -6246,12 +6442,13 @@ The minimum value for this variable is 4096.",
(uchar**) &global_system_variables.query_prealloc_size,
(uchar**) &max_system_variables.query_prealloc_size, 0, GET_ULONG,
REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
- ~0L, 0, 1024, 0},
+ ULONG_MAX, 0, 1024, 0},
{"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
"Allocation block size for storing ranges during optimization",
(uchar**) &global_system_variables.range_alloc_block_size,
(uchar**) &max_system_variables.range_alloc_block_size, 0, GET_ULONG,
- REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, 4096, ~0L, 0, 1024, 0},
+ REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, ULONG_MAX,
+ 0, 1024, 0},
{"read_buffer_size", OPT_RECORD_BUFFER,
"Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value.",
(uchar**) &global_system_variables.read_buff_size,
@@ -6315,7 +6512,7 @@ The minimum value for this variable is 4096.",
"Synchronously flush binary log to disk after every #th event. "
"Use 0 (default) to disable synchronous flushing.",
(uchar**) &sync_binlog_period, (uchar**) &sync_binlog_period, 0, GET_ULONG,
- REQUIRED_ARG, 0, 0, ~0L, 0, 1, 0},
+ REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1, 0},
{"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.",
(uchar**) &opt_sync_frm, (uchar**) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0,
0, 0, 0, 0},
@@ -6353,7 +6550,7 @@ The minimum value for this variable is 4096.",
{"thread_stack", OPT_THREAD_STACK,
"The stack size for each thread.", (uchar**) &thread_stack,
(uchar**) &thread_stack, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK,
- 1024L*128L, ~0L, 0, 1024, 0},
+ 1024L*128L, ULONG_MAX, 0, 1024, 0},
{ "time_format", OPT_TIME_FORMAT,
"The TIME format (for future).",
(uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
@@ -6369,12 +6566,12 @@ The minimum value for this variable is 4096.",
"Allocation block size for various transaction-related structures",
(uchar**) &global_system_variables.trans_alloc_block_size,
(uchar**) &max_system_variables.trans_alloc_block_size, 0, GET_ULONG,
- REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0},
+ REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
{"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
"Persistent buffer for various transaction-related structures",
(uchar**) &global_system_variables.trans_prealloc_size,
(uchar**) &max_system_variables.trans_prealloc_size, 0, GET_ULONG,
- REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ~0L, 0, 1024, 0},
+ REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
{"thread_handling", OPT_THREAD_HANDLING,
"Define threads usage for handling queries: "
"one-thread-per-connection or no-threads", 0, 0,
@@ -6762,115 +6959,7 @@ SHOW_VAR status_vars[]= {
{"Binlog_cache_use", (char*) &binlog_cache_use, SHOW_LONG},
{"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_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_EVENT]), 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},
- {"Com_checksum", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
- {"Com_commit", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
- {"Com_create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
- {"Com_create_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_EVENT]), SHOW_LONG_STATUS},
- {"Com_create_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_FUNCTION]), SHOW_LONG_STATUS},
- {"Com_create_index", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
- {"Com_create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
- {"Com_create_user", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_USER]), SHOW_LONG_STATUS},
- {"Com_dealloc_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DEALLOCATE_PREPARE]), SHOW_LONG_STATUS},
- {"Com_delete", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE]), SHOW_LONG_STATUS},
- {"Com_delete_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE_MULTI]), SHOW_LONG_STATUS},
- {"Com_do", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DO]), SHOW_LONG_STATUS},
- {"Com_drop_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
- {"Com_drop_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_EVENT]), SHOW_LONG_STATUS},
- {"Com_drop_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_FUNCTION]), SHOW_LONG_STATUS},
- {"Com_drop_index", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
- {"Com_drop_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
- {"Com_drop_user", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_USER]), SHOW_LONG_STATUS},
- {"Com_execute_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXECUTE]), SHOW_LONG_STATUS},
- {"Com_flush", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
- {"Com_grant", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT]), SHOW_LONG_STATUS},
- {"Com_ha_close", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_CLOSE]), SHOW_LONG_STATUS},
- {"Com_ha_open", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_OPEN]), SHOW_LONG_STATUS},
- {"Com_ha_read", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_READ]), SHOW_LONG_STATUS},
- {"Com_help", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HELP]), SHOW_LONG_STATUS},
- {"Com_insert", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT]), SHOW_LONG_STATUS},
- {"Com_insert_select", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
- {"Com_kill", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_KILL]), SHOW_LONG_STATUS},
- {"Com_load", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD]), SHOW_LONG_STATUS},
- {"Com_load_master_data", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD_MASTER_DATA]), SHOW_LONG_STATUS},
- {"Com_load_master_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD_MASTER_TABLE]), SHOW_LONG_STATUS},
- {"Com_lock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOCK_TABLES]), SHOW_LONG_STATUS},
- {"Com_optimize", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_OPTIMIZE]), SHOW_LONG_STATUS},
- {"Com_preload_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PRELOAD_KEYS]), SHOW_LONG_STATUS},
- {"Com_prepare_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PREPARE]), SHOW_LONG_STATUS},
- {"Com_purge", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE]), SHOW_LONG_STATUS},
- {"Com_purge_before_date", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE_BEFORE]), SHOW_LONG_STATUS},
- {"Com_rename_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
- {"Com_repair", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPAIR]), SHOW_LONG_STATUS},
- {"Com_replace", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
- {"Com_replace_select", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
- {"Com_reset", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESET]), SHOW_LONG_STATUS},
- {"Com_restore_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESTORE_TABLE]), SHOW_LONG_STATUS},
- {"Com_revoke", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE]), SHOW_LONG_STATUS},
- {"Com_revoke_all", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE_ALL]), SHOW_LONG_STATUS},
- {"Com_rollback", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
- {"Com_savepoint", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
- {"Com_select", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SELECT]), SHOW_LONG_STATUS},
- {"Com_set_option", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS},
- {"Com_show_binlog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS},
- {"Com_show_binlogs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS},
- {"Com_show_charsets", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]), SHOW_LONG_STATUS},
- {"Com_show_collations", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS},
- {"Com_show_column_types", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLUMN_TYPES]), SHOW_LONG_STATUS},
- {"Com_show_create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
- {"Com_show_create_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_EVENT]), SHOW_LONG_STATUS},
- {"Com_show_create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
- {"Com_show_databases", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_DATABASES]), SHOW_LONG_STATUS},
- {"Com_show_engine_logs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_LOGS]), SHOW_LONG_STATUS},
- {"Com_show_engine_mutex", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_MUTEX]), SHOW_LONG_STATUS},
- {"Com_show_engine_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_STATUS]), SHOW_LONG_STATUS},
- {"Com_show_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_EVENTS]), SHOW_LONG_STATUS},
- {"Com_show_errors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
- {"Com_show_fields", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FIELDS]), SHOW_LONG_STATUS},
- {"Com_show_grants", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS},
- {"Com_show_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
- {"Com_show_master_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
- {"Com_show_new_master", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NEW_MASTER]), SHOW_LONG_STATUS},
- {"Com_show_open_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
- {"Com_show_plugins", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PLUGINS]), SHOW_LONG_STATUS},
- {"Com_show_privileges", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PRIVILEGES]), SHOW_LONG_STATUS},
- {"Com_show_processlist", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROCESSLIST]), SHOW_LONG_STATUS},
- {"Com_show_slave_hosts", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_HOSTS]), SHOW_LONG_STATUS},
- {"Com_show_slave_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
- {"Com_show_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
- {"Com_show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
- {"Com_show_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
- {"Com_show_triggers", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
- {"Com_show_variables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
- {"Com_show_warnings", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
- {"Com_slave_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
- {"Com_slave_stop", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_STOP]), SHOW_LONG_STATUS},
- {"Com_stmt_close", (char*) offsetof(STATUS_VAR, com_stmt_close), SHOW_LONG_STATUS},
- {"Com_stmt_execute", (char*) offsetof(STATUS_VAR, com_stmt_execute), SHOW_LONG_STATUS},
- {"Com_stmt_fetch", (char*) offsetof(STATUS_VAR, com_stmt_fetch), SHOW_LONG_STATUS},
- {"Com_stmt_prepare", (char*) offsetof(STATUS_VAR, com_stmt_prepare), SHOW_LONG_STATUS},
- {"Com_stmt_reset", (char*) offsetof(STATUS_VAR, com_stmt_reset), SHOW_LONG_STATUS},
- {"Com_stmt_send_long_data", (char*) offsetof(STATUS_VAR, com_stmt_send_long_data), SHOW_LONG_STATUS},
- {"Com_truncate", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
- {"Com_unlock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
- {"Com_update", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
- {"Com_update_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE_MULTI]), SHOW_LONG_STATUS},
- {"Com_xa_commit", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_COMMIT]),SHOW_LONG_STATUS},
- {"Com_xa_end", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_END]),SHOW_LONG_STATUS},
- {"Com_xa_prepare", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_PREPARE]),SHOW_LONG_STATUS},
- {"Com_xa_recover", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_RECOVER]),SHOW_LONG_STATUS},
- {"Com_xa_rollback", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_ROLLBACK]),SHOW_LONG_STATUS},
- {"Com_xa_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_START]),SHOW_LONG_STATUS},
+ {"Com", (char*) com_status_vars, SHOW_ARRAY},
{"Compression", (char*) &show_net_compression, SHOW_FUNC},
{"Connections", (char*) &thread_id, SHOW_LONG_NOFLUSH},
{"Created_tmp_disk_tables", (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
@@ -7479,7 +7568,7 @@ mysqld_get_one_option(int optid,
{
if (!argument || !argument[0])
{
- log_output_options= LOG_TABLE;
+ log_output_options= LOG_FILE;
log_output_str= log_output_typelib.type_names[1];
}
else
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 0cf28fe5d3b..ad653a2267d 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -124,20 +124,18 @@ my_bool my_net_init(NET *net, Vio* vio)
MYF(MY_WME))))
DBUG_RETURN(1);
net->buff_end=net->buff+net->max_packet;
- net->no_send_ok= net->no_send_error= 0;
net->error=0; net->return_errno=0; net->return_status=0;
net->pkt_nr=net->compress_pkt_nr=0;
net->write_pos=net->read_pos = net->buff;
- net->last_error[0]=0;
+ net->client_last_error[0]=0;
net->compress=0; net->reading_or_writing=0;
net->where_b = net->remain_in_buf=0;
- net->last_errno=0;
+ net->client_last_errno=0;
#ifdef USE_QUERY_CACHE
query_cache_init_query(net);
#else
net->query_cache_query= 0;
#endif
- net->report_error= 0;
if (vio != 0) /* If real connection */
{
@@ -177,9 +175,12 @@ my_bool net_realloc(NET *net, size_t length)
{
DBUG_PRINT("error", ("Packet too large. Max size: %lu",
net->max_packet_size));
+ /* @todo: 1 and 2 codes are identical. */
net->error= 1;
- net->report_error= 1;
- net->last_errno= ER_NET_PACKET_TOO_LARGE;
+ net->client_last_errno= ER_NET_PACKET_TOO_LARGE;
+#ifdef MYSQL_SERVER
+ my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
+#endif
DBUG_RETURN(1);
}
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
@@ -191,9 +192,10 @@ my_bool net_realloc(NET *net, size_t length)
NET_HEADER_SIZE + COMP_HEADER_SIZE,
MYF(MY_WME))))
{
+ /* @todo: 1 and 2 codes are identical. */
net->error= 1;
- net->report_error= 1;
- net->last_errno= ER_OUT_OF_RESOURCES;
+ net->client_last_errno= ER_OUT_OF_RESOURCES;
+ /* In the server the error is reported by MY_WME flag. */
DBUG_RETURN(1);
}
net->buff=net->write_pos=buff;
@@ -576,12 +578,9 @@ net_real_write(NET *net,const uchar *packet, size_t len)
if (!(b= (uchar*) my_malloc(len + NET_HEADER_SIZE +
COMP_HEADER_SIZE, MYF(MY_WME))))
{
-#ifdef MYSQL_SERVER
- net->last_errno= ER_OUT_OF_RESOURCES;
net->error= 2;
- /* TODO is it needed to set this variable if we have no socket */
- net->report_error= 1;
-#endif
+ net->client_last_errno= ER_OUT_OF_RESOURCES;
+ /* In the server, the error is reported by MY_WME flag. */
net->reading_or_writing= 0;
DBUG_RETURN(1);
}
@@ -632,11 +631,11 @@ net_real_write(NET *net,const uchar *packet, size_t len)
"%s: my_net_write: fcntl returned error %d, aborting thread\n",
my_progname,vio_errno(net->vio));
#endif /* EXTRA_DEBUG */
-#ifdef MYSQL_SERVER
- net->last_errno= ER_NET_ERROR_ON_WRITE;
-#endif
net->error= 2; /* Close socket */
- net->report_error= 1;
+ net->client_last_errno= ER_NET_PACKET_TOO_LARGE;
+#ifdef MYSQL_SERVER
+ my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
+#endif
goto end;
}
retry_count=0;
@@ -663,10 +662,10 @@ net_real_write(NET *net,const uchar *packet, size_t len)
}
#endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */
net->error= 2; /* Close socket */
- net->report_error= 1;
+ net->client_last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
+ ER_NET_ERROR_ON_WRITE);
#ifdef MYSQL_SERVER
- net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
- ER_NET_ERROR_ON_WRITE);
+ my_error(net->client_last_errno, MYF(0));
#endif /* MYSQL_SERVER */
break;
}
@@ -845,9 +844,9 @@ my_real_read(NET *net, size_t *complen)
#endif /* EXTRA_DEBUG */
len= packet_error;
net->error= 2; /* Close socket */
- net->report_error= 1;
+ net->client_last_errno= ER_NET_FCNTL_ERROR;
#ifdef MYSQL_SERVER
- net->last_errno= ER_NET_FCNTL_ERROR;
+ my_error(ER_NET_FCNTL_ERROR, MYF(0));
#endif
goto end;
}
@@ -877,10 +876,11 @@ my_real_read(NET *net, size_t *complen)
remain, vio_errno(net->vio), (long) length));
len= packet_error;
net->error= 2; /* Close socket */
- net->report_error= 1;
+ net->client_last_errno= (vio_was_interrupted(net->vio) ?
+ ER_NET_READ_INTERRUPTED :
+ ER_NET_READ_ERROR);
#ifdef MYSQL_SERVER
- net->last_errno= (vio_was_interrupted(net->vio) ? ER_NET_READ_INTERRUPTED :
- ER_NET_READ_ERROR);
+ my_error(net->client_last_errno, MYF(0));
#endif
goto end;
}
@@ -911,9 +911,9 @@ my_real_read(NET *net, size_t *complen)
#endif
}
len= packet_error;
- net->report_error= 1;
+ /* Not a NET error on the client. XXX: why? */
#ifdef MYSQL_SERVER
- net->last_errno=ER_NET_PACKETS_OUT_OF_ORDER;
+ my_error(ER_NET_PACKETS_OUT_OF_ORDER, MYF(0));
#endif
goto end;
}
@@ -1100,9 +1100,9 @@ my_net_read(NET *net)
&complen))
{
net->error= 2; /* caller will close socket */
- net->report_error= 1;
+ net->client_last_errno= ER_NET_UNCOMPRESS_ERROR;
#ifdef MYSQL_SERVER
- net->last_errno=ER_NET_UNCOMPRESS_ERROR;
+ my_error(ER_NET_UNCOMPRESS_ERROR, MYF(0));
#endif
return packet_error;
}
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 761897f21b5..b8bdb604eea 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -276,6 +276,9 @@ public:
Field *field;
uchar *min_value,*max_value; // Pointer to range
+ /*
+ eq_tree() requires that left == right == 0 if the type is MAYBE_KEY.
+ */
SEL_ARG *left,*right; /* R-B tree children */
SEL_ARG *next,*prev; /* Links for bi-directional interval list */
SEL_ARG *parent; /* R-B tree parent */
@@ -291,7 +294,7 @@ public:
SEL_ARG(Field *field, uint8 part, uchar *min_value, uchar *max_value,
uint8 min_flag, uint8 max_flag, uint8 maybe_flag);
SEL_ARG(enum Type type_arg)
- :min_flag(0),elements(1),use_count(1),left(0),next_key_part(0),
+ :min_flag(0),elements(1),use_count(1),left(0),right(0),next_key_part(0),
color(BLACK), type(type_arg)
{}
inline bool is_same(SEL_ARG *arg)
@@ -1271,7 +1274,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
the storage engine calls in question happen to never fail with the
existing storage engines.
*/
- thd->net.report_error= 1; /* purecov: inspected */
+ my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */
/* Caller will free the memory */
goto failure; /* purecov: inspected */
}
@@ -2161,12 +2164,18 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
keys_to_use.intersect(head->keys_in_use_for_query);
if (!keys_to_use.is_clear_all())
{
+#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
+ uchar buff[STACK_BUFF_ALLOC];
+#endif
MEM_ROOT alloc;
SEL_TREE *tree= NULL;
KEY_PART *key_parts;
KEY *key_info;
PARAM param;
+ if (check_stack_overrun(thd, 2*STACK_MIN_SIZE, buff))
+ DBUG_RETURN(0); // Fatal error flag is set
+
/* set up parameter that is passed to all functions */
param.thd= thd;
param.baseflag= head->file->ha_table_flags();
@@ -5726,6 +5735,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
{
tree= new (alloc) SEL_ARG(field, 0, 0);
tree->type= SEL_ARG::IMPOSSIBLE;
+ goto end;
}
else
{
@@ -5734,8 +5744,32 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
for the cases like int_field > 999999999999999999999999 as well.
*/
tree= 0;
+ if (err == 3 && field->type() == FIELD_TYPE_DATE &&
+ (type == Item_func::GT_FUNC || type == Item_func::GE_FUNC ||
+ type == Item_func::LT_FUNC || type == Item_func::LE_FUNC) )
+ {
+ /*
+ We were saving DATETIME into a DATE column, the conversion went ok
+ but a non-zero time part was cut off.
+
+ In MySQL's SQL dialect, DATE and DATETIME are compared as datetime
+ values. Index over a DATE column uses DATE comparison. Changing
+ from one comparison to the other is possible:
+
+ datetime(date_col)< '2007-12-10 12:34:55' -> date_col<='2007-12-10'
+ datetime(date_col)<='2007-12-10 12:34:55' -> date_col<='2007-12-10'
+
+ datetime(date_col)> '2007-12-10 12:34:55' -> date_col>='2007-12-10'
+ datetime(date_col)>='2007-12-10 12:34:55' -> date_col>='2007-12-10'
+
+ but we'll need to convert '>' to '>=' and '<' to '<='. This will
+ be done together with other types at the end of this function
+ (grep for field_is_equal_to_item)
+ */
+ }
+ else
+ goto end;
}
- goto end;
}
if (err < 0)
{
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 1d705d716ea..42d36756845 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -175,6 +175,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
if(error)
{
tl->table->file->print_error(error, MYF(0));
+ tl->table->in_use->fatal_error();
return error;
}
count*= tl->table->file->stats.records;
@@ -423,6 +424,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE
/* HA_ERR_LOCK_DEADLOCK or some other error */
table->file->print_error(error, MYF(0));
+ table->in_use->fatal_error();
return(error);
}
removed_tables|= table->map;
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 86d50cdf524..3b580422da1 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -524,6 +524,13 @@ bool partition_info::check_range_constants()
current_largest= part_range_value;
range_int_array[i]= part_range_value;
}
+ else if (defined_max_value &&
+ current_largest == part_range_value &&
+ part_range_value == LONGLONG_MAX &&
+ i == (no_parts - 1))
+ {
+ range_int_array[i]= part_range_value;
+ }
else
{
my_error(ER_RANGE_NOT_INCREASING_ERROR, MYF(0));
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 872ae016ad4..9e1b3c65538 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -25,13 +25,16 @@
#endif
#include "mysql_priv.h"
-#include "sp_rcontext.h"
#include <stdarg.h>
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
+/* Declared non-static only because of the embedded library. */
void net_send_error_packet(THD *thd, uint sql_errno, const char *err);
+void net_send_ok(THD *, uint, uint, ha_rows, ulonglong, const char *);
+void net_send_eof(THD *thd, uint server_status, uint total_warn_count);
#ifndef EMBEDDED_LIBRARY
-static void write_eof_packet(THD *thd, NET *net);
+static void write_eof_packet(THD *thd, NET *net,
+ uint server_status, uint total_warn_count);
#endif
#ifndef EMBEDDED_LIBRARY
@@ -70,62 +73,27 @@ bool Protocol_binary::net_store_data(const uchar *from, size_t length)
*/
void net_send_error(THD *thd, uint sql_errno, const char *err)
{
- NET *net= &thd->net;
- bool generate_warning= thd->killed != THD::KILL_CONNECTION;
DBUG_ENTER("net_send_error");
- DBUG_PRINT("enter",("sql_errno: %d err: %s", sql_errno,
- err ? err : net->last_error[0] ?
- net->last_error : "NULL"));
DBUG_ASSERT(!thd->spcont);
+ DBUG_ASSERT(sql_errno);
+ DBUG_ASSERT(err && err[0]);
- if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
- {
- thd->killed= THD::NOT_KILLED;
- thd->mysys_var->abort= 0;
- }
-
- if (net && net->no_send_error)
- {
- thd->clear_error();
- thd->is_fatal_error= 0; // Error message is given
- DBUG_PRINT("info", ("sending error messages prohibited"));
- DBUG_VOID_RETURN;
- }
+ DBUG_PRINT("enter",("sql_errno: %d err: %s", sql_errno, err));
- thd->is_slave_error= 1; // needed to catch query errors during replication
- if (!err)
- {
- if (sql_errno)
- err=ER(sql_errno);
- else
- {
- if ((err=net->last_error)[0])
- {
- sql_errno=net->last_errno;
- generate_warning= 0; // This warning has already been given
- }
- else
- {
- sql_errno=ER_UNKNOWN_ERROR;
- err=ER(sql_errno); /* purecov: inspected */
- }
- }
- }
+ /*
+ It's one case when we can push an error even though there
+ is an OK or EOF already.
+ */
+ thd->main_da.can_overwrite_status= TRUE;
- if (generate_warning)
- {
- /* Error that we have not got with my_error() */
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, sql_errno, err);
- }
+ /* Abort multi-result sets */
+ thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
net_send_error_packet(thd, sql_errno, err);
- thd->is_fatal_error= 0; // Error message is given
- thd->net.report_error= 0;
+ thd->main_da.can_overwrite_status= FALSE;
- /* Abort multi-result sets */
- thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
DBUG_VOID_RETURN;
}
@@ -154,17 +122,17 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
#ifndef EMBEDDED_LIBRARY
void
-send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
+net_send_ok(THD *thd,
+ uint server_status, uint total_warn_count,
+ ha_rows affected_rows, ulonglong id, const char *message)
{
NET *net= &thd->net;
uchar buff[MYSQL_ERRMSG_SIZE+10],*pos;
DBUG_ENTER("send_ok");
- if (net->no_send_ok || !net->vio) // hack for re-parsing queries
+ if (! net->vio) // hack for re-parsing queries
{
- DBUG_PRINT("info", ("no send ok: %s, vio present: %s",
- (net->no_send_ok ? "YES" : "NO"),
- (net->vio ? "YES" : "NO")));
+ DBUG_PRINT("info", ("vio present: NO"));
DBUG_VOID_RETURN;
}
@@ -177,28 +145,29 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
("affected_rows: %lu id: %lu status: %u warning_count: %u",
(ulong) affected_rows,
(ulong) id,
- (uint) (thd->server_status & 0xffff),
- (uint) thd->total_warn_count));
- int2store(pos,thd->server_status);
+ (uint) (server_status & 0xffff),
+ (uint) total_warn_count));
+ int2store(pos, server_status);
pos+=2;
/* We can only return up to 65535 warnings in two bytes */
- uint tmp= min(thd->total_warn_count, 65535);
+ uint tmp= min(total_warn_count, 65535);
int2store(pos, tmp);
pos+= 2;
}
else if (net->return_status) // For 4.0 protocol
{
- int2store(pos,thd->server_status);
+ int2store(pos, server_status);
pos+=2;
}
- if (message)
+ thd->main_da.can_overwrite_status= TRUE;
+
+ if (message && message[0])
pos= net_store_data(pos, (uchar*) message, strlen(message));
VOID(my_net_write(net, buff, (size_t) (pos-buff)));
VOID(net_flush(net));
- /* We can't anymore send an error to the client */
- thd->net.report_error= 0;
- thd->net.no_send_error= 1;
+
+ thd->main_da.can_overwrite_status= FALSE;
DBUG_PRINT("info", ("OK sent, so no more error sending allowed"));
DBUG_VOID_RETURN;
@@ -223,18 +192,20 @@ static uchar eof_buff[1]= { (uchar) 254 }; /* Marker for end of fields */
@param thd Thread handler
@param no_flush Set to 1 if there will be more data to the client,
like in send_fields().
-*/
+*/
void
-send_eof(THD *thd)
+net_send_eof(THD *thd, uint server_status, uint total_warn_count)
{
NET *net= &thd->net;
- DBUG_ENTER("send_eof");
+ DBUG_ENTER("net_send_eof");
+ /* Set to TRUE if no active vio, to work well in case of --init-file */
if (net->vio != 0)
{
- write_eof_packet(thd, net);
+ thd->main_da.can_overwrite_status= TRUE;
+ write_eof_packet(thd, net, server_status, total_warn_count);
VOID(net_flush(net));
- thd->net.no_send_error= 1;
+ thd->main_da.can_overwrite_status= FALSE;
DBUG_PRINT("info", ("EOF sent, so no more error sending allowed"));
}
DBUG_VOID_RETURN;
@@ -246,7 +217,9 @@ send_eof(THD *thd)
write it to the network output buffer.
*/
-static void write_eof_packet(THD *thd, NET *net)
+static void write_eof_packet(THD *thd, NET *net,
+ uint server_status,
+ uint total_warn_count)
{
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{
@@ -255,7 +228,7 @@ static void write_eof_packet(THD *thd, NET *net)
Don't send warn count during SP execution, as the warn_list
is cleared between substatements, and mysqltest gets confused
*/
- uint tmp= (thd->spcont ? 0 : min(thd->total_warn_count, 65535));
+ uint tmp= min(total_warn_count, 65535);
buff[0]= 254;
int2store(buff+1, tmp);
/*
@@ -264,8 +237,8 @@ static void write_eof_packet(THD *thd, NET *net)
other queries (see the if test in dispatch_command / COM_QUERY)
*/
if (thd->is_fatal_error)
- thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
- int2store(buff+3, thd->server_status);
+ server_status&= ~SERVER_MORE_RESULTS_EXISTS;
+ int2store(buff + 3, server_status);
VOID(my_net_write(net, buff, 5));
}
else
@@ -274,13 +247,13 @@ static void write_eof_packet(THD *thd, NET *net)
/**
Please client to send scrambled_password in old format.
-
+
@param thd thread handle
@retval
- 0 ok
+ 0 ok
@retval
- !0 error
+ !0 error
*/
bool send_old_password_request(THD *thd)
@@ -294,7 +267,10 @@ void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
{
NET *net= &thd->net;
uint length;
- uchar buff[MYSQL_ERRMSG_SIZE+2], *pos;
+ /*
+ buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + MYSQL_ERRMSG_SIZE:512
+ */
+ uchar buff[2+1+SQLSTATE_LENGTH+MYSQL_ERRMSG_SIZE], *pos;
DBUG_ENTER("send_error_packet");
@@ -357,6 +333,96 @@ static uchar *net_store_length_fast(uchar *packet, uint length)
return packet+2;
}
+/**
+ Send the status of the current statement execution over network.
+
+ @param thd in fact, carries two parameters, NET for the transport and
+ Diagnostics_area as the source of status information.
+
+ In MySQL, there are two types of SQL statements: those that return
+ a result set and those that return status information only.
+
+ If a statement returns a result set, it consists of 3 parts:
+ - result set meta-data
+ - variable number of result set rows (can be 0)
+ - followed and terminated by EOF or ERROR packet
+
+ Once the client has seen the meta-data information, it always
+ expects an EOF or ERROR to terminate the result set. If ERROR is
+ received, the result set rows are normally discarded (this is up
+ to the client implementation, libmysql at least does discard them).
+ EOF, on the contrary, means "successfully evaluated the entire
+ result set". Since we don't know how many rows belong to a result
+ set until it's evaluated, EOF/ERROR is the indicator of the end
+ of the row stream. Note, that we can not buffer result set rows
+ on the server -- there may be an arbitrary number of rows. But
+ we do buffer the last packet (EOF/ERROR) in the Diagnostics_area and
+ delay sending it till the very end of execution (here), to be able to
+ change EOF to an ERROR if commit failed or some other error occurred
+ during the last cleanup steps taken after execution.
+
+ A statement that does not return a result set doesn't send result
+ set meta-data either. Instead it returns one of:
+ - OK packet
+ - ERROR packet.
+ Similarly to the EOF/ERROR of the previous statement type, OK/ERROR
+ packet is "buffered" in the diagnostics area and sent to the client
+ in the end of statement.
+
+ @pre The diagnostics area is assigned or disabled. It can not be empty
+ -- we assume that every SQL statement or COM_* command
+ generates OK, ERROR, or EOF status.
+
+ @post The status information is encoded to protocol format and sent to the
+ client.
+
+ @return We conventionally return void, since the only type of error
+ that can happen here is a NET (transport) error, and that one
+ will become visible when we attempt to read from the NET the
+ next command.
+ Diagnostics_area::is_sent is set for debugging purposes only.
+*/
+
+void net_end_statement(THD *thd)
+{
+ DBUG_ASSERT(! thd->main_da.is_sent);
+
+ /* Can not be true, but do not take chances in production. */
+ if (thd->main_da.is_sent)
+ return;
+
+ switch (thd->main_da.status()) {
+ case Diagnostics_area::DA_ERROR:
+ /* The query failed, send error to log and abort bootstrap. */
+ net_send_error(thd,
+ thd->main_da.sql_errno(),
+ thd->main_da.message());
+ break;
+ case Diagnostics_area::DA_EOF:
+ net_send_eof(thd,
+ thd->main_da.server_status(),
+ thd->main_da.total_warn_count());
+ break;
+ case Diagnostics_area::DA_OK:
+ net_send_ok(thd,
+ thd->main_da.server_status(),
+ thd->main_da.total_warn_count(),
+ thd->main_da.affected_rows(),
+ thd->main_da.last_insert_id(),
+ thd->main_da.message());
+ break;
+ case Diagnostics_area::DA_DISABLED:
+ break;
+ case Diagnostics_area::DA_EMPTY:
+ default:
+ DBUG_ASSERT(0);
+ net_send_ok(thd, thd->server_status, thd->total_warn_count,
+ 0, 0, NULL);
+ break;
+ }
+ thd->main_da.is_sent= TRUE;
+}
+
/****************************************************************************
Functions used by the protocol functions (like send_ok) to store strings
@@ -405,6 +471,17 @@ void Protocol::init(THD *thd_arg)
#endif
}
+/**
+ Finish the result set with EOF packet, as is expected by the client,
+ if there is an error evaluating the next row and a continue handler
+ for the error.
+*/
+
+void Protocol::end_partial_result_set(THD *thd)
+{
+ net_send_eof(thd, thd->server_status, 0 /* no warnings, we're inside SP */);
+}
+
bool Protocol::flush()
{
@@ -569,7 +646,14 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
}
if (flags & SEND_EOF)
- write_eof_packet(thd, &thd->net);
+ {
+ /*
+ Mark the end of meta-data result set, and store thd->server_status,
+ to show that there is no cursor.
+ Send no warning information, as it will be sent at statement end.
+ */
+ write_eof_packet(thd, &thd->net, thd->server_status, thd->total_warn_count);
+ }
DBUG_RETURN(prepare_for_send(list));
err:
@@ -843,8 +927,8 @@ bool Protocol_text::store(Field *field)
/**
@todo
- Second_part format ("%06") needs to change when
- we support 0-6 decimals for time.
+ Second_part format ("%06") needs to change when
+ we support 0-6 decimals for time.
*/
bool Protocol_text::store(MYSQL_TIME *tm)
@@ -886,8 +970,8 @@ bool Protocol_text::store_date(MYSQL_TIME *tm)
/**
@todo
- Second_part format ("%06") needs to change when
- we support 0-6 decimals for time.
+ Second_part format ("%06") needs to change when
+ we support 0-6 decimals for time.
*/
bool Protocol_text::store_time(MYSQL_TIME *tm)
diff --git a/sql/protocol.h b/sql/protocol.h
index 7c0ba858ea3..a4770e9b6e3 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -75,6 +75,7 @@ public:
return 0;
}
virtual bool flush();
+ virtual void end_partial_result_set(THD *thd);
virtual void prepare_for_resend()=0;
virtual bool store_null()=0;
@@ -173,9 +174,7 @@ public:
void send_warning(THD *thd, uint sql_errno, const char *err=0);
void net_send_error(THD *thd, uint sql_errno=0, const char *err=0);
-void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L,
- const char *info=0);
-void send_eof(THD *thd);
+void net_end_statement(THD *thd);
bool send_old_password_request(THD *thd);
uchar *net_store_data(uchar *to,const uchar *from, size_t length);
uchar *net_store_data(uchar *to,int32 from);
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index 9bdbfafe6bc..d33c81b55e8 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -699,7 +699,7 @@ int connect_to_master(THD *thd, MYSQL* mysql, Master_info* mi)
if (!mi->host || !*mi->host) /* empty host */
{
- strmov(mysql->net.last_error, "Master is not configured");
+ strmov(mysql->net.client_last_error, "Master is not configured");
DBUG_RETURN(1);
}
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *) &slave_net_timeout);
@@ -899,6 +899,8 @@ bool load_master_data(THD* thd)
cleanup_mysql_results(db_res, cur_table_res - 1, table_res);
goto err;
}
+ /* Clear the result of mysql_create_db(). */
+ thd->main_da.reset_diagnostics_area();
if (mysql_select_db(&mysql, db) ||
mysql_real_query(&mysql, STRING_WITH_LEN("SHOW TABLES")) ||
diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc
index ed0dc82cf01..eb32897f937 100644
--- a/sql/rpl_record.cc
+++ b/sql/rpl_record.cc
@@ -338,12 +338,13 @@ int prepare_record(const Slave_reporting_capability *const log,
if (check && ((f->flags & mask) == mask))
{
DBUG_ASSERT(log);
- log->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD,
+ error= ER_NO_DEFAULT_FOR_FIELD;
+ log->report(ERROR_LEVEL, error,
"Field `%s` of table `%s`.`%s` "
"has no default value and cannot be NULL",
f->field_name, table->s->db.str,
table->s->table_name.str);
- error = ER_NO_DEFAULT_FOR_FIELD;
+ my_error(error, MYF(0), f->field_name);
}
else
f->set_default();
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 15d7d97affd..3467f6fd67c 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -166,7 +166,7 @@ int init_relay_log_info(Relay_log_info* rli,
{
sql_print_error("Failed to create a new relay log info file (\
file '%s', errno %d)", fname, my_errno);
- msg= current_thd->net.last_error;
+ msg= current_thd->main_da.message();
goto err;
}
if (init_io_cache(&rli->info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0,
@@ -174,7 +174,7 @@ file '%s', errno %d)", fname, my_errno);
{
sql_print_error("Failed to create a cache on relay log info file '%s'",
fname);
- msg= current_thd->net.last_error;
+ msg= current_thd->main_da.message();
goto err;
}
diff --git a/sql/set_var.cc b/sql/set_var.cc
index fde0a673d46..5e8d6b0aad2 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -125,6 +125,9 @@ static int check_max_delayed_threads(THD *thd, set_var *var);
static void fix_thd_mem_root(THD *thd, enum_var_type type);
static void fix_trans_mem_root(THD *thd, enum_var_type type);
static void fix_server_id(THD *thd, enum_var_type type);
+static ulonglong fix_unsigned(THD *, ulonglong, const struct my_option *);
+static bool get_unsigned(THD *thd, set_var *var);
+static void throw_bounds_warning(THD *thd, const char *name, ulonglong num);
static KEY_CACHE *create_key_cache(const char *name, uint length);
void fix_sql_mode_var(THD *thd, enum_var_type type);
static uchar *get_error_count(THD *thd);
@@ -390,7 +393,7 @@ static sys_var_thd_ulong sys_trans_alloc_block_size(&vars, "transaction_alloc_bl
static sys_var_thd_ulong sys_trans_prealloc_size(&vars, "transaction_prealloc_size",
&SV::trans_prealloc_size,
0, fix_trans_mem_root);
-sys_var_thd_enum sys_thread_handling(&vars, "thread_handling",
+sys_var_enum_const sys_thread_handling(&vars, "thread_handling",
&SV::thread_handling,
&thread_handling_typelib,
NULL);
@@ -1115,6 +1118,39 @@ static void fix_server_id(THD *thd, enum_var_type type)
}
+static void throw_bounds_warning(THD *thd, const char *name, ulonglong num)
+{
+ char buf[22];
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE), name,
+ ullstr(num, buf));
+}
+
+static ulonglong fix_unsigned(THD *thd, ulonglong num,
+ const struct my_option *option_limits)
+{
+ bool fixed= FALSE;
+ ulonglong out= getopt_ull_limit_value(num, option_limits, &fixed);
+
+ if (fixed)
+ throw_bounds_warning(thd, option_limits->name, num);
+ return out;
+}
+
+static bool get_unsigned(THD *thd, set_var *var)
+{
+ if (var->value->unsigned_flag)
+ var->save_result.ulonglong_value= (ulonglong) var->value->val_int();
+ else
+ {
+ longlong v= var->value->val_int();
+ var->save_result.ulonglong_value= (ulonglong) ((v < 0) ? 0 : v);
+ }
+ return 0;
+}
+
+
sys_var_long_ptr::
sys_var_long_ptr(sys_var_chain *chain, const char *name_arg, ulong *value_ptr_arg,
sys_after_update_func after_update_arg)
@@ -1125,9 +1161,7 @@ sys_var_long_ptr(sys_var_chain *chain, const char *name_arg, ulong *value_ptr_ar
bool sys_var_long_ptr_global::check(THD *thd, set_var *var)
{
- longlong v= var->value->val_int();
- var->save_result.ulonglong_value= v < 0 ? 0 : v;
- return 0;
+ return get_unsigned(thd, var);
}
bool sys_var_long_ptr_global::update(THD *thd, set_var *var)
@@ -1135,9 +1169,20 @@ bool sys_var_long_ptr_global::update(THD *thd, set_var *var)
ulonglong tmp= var->save_result.ulonglong_value;
pthread_mutex_lock(guard);
if (option_limits)
- *value= (ulong) getopt_ull_limit_value(tmp, option_limits);
+ *value= (ulong) fix_unsigned(thd, tmp, option_limits);
else
+ {
+#if SIZEOF_LONG < SIZEOF_LONG_LONG
+ /* Avoid overflows on 32 bit systems */
+ if (tmp > ULONG_MAX)
+ {
+ tmp= ULONG_MAX;
+ throw_bounds_warning(thd, name, var->save_result.ulonglong_value);
+ }
+#endif
*value= (ulong) tmp;
+ }
+
pthread_mutex_unlock(guard);
return 0;
}
@@ -1145,8 +1190,10 @@ bool sys_var_long_ptr_global::update(THD *thd, set_var *var)
void sys_var_long_ptr_global::set_default(THD *thd, enum_var_type type)
{
+ bool not_used;
pthread_mutex_lock(guard);
- *value= (ulong) option_limits->def_value;
+ *value= (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
+ option_limits, &not_used);
pthread_mutex_unlock(guard);
}
@@ -1156,7 +1203,7 @@ bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var)
ulonglong tmp= var->save_result.ulonglong_value;
pthread_mutex_lock(&LOCK_global_system_variables);
if (option_limits)
- *value= (ulonglong) getopt_ull_limit_value(tmp, option_limits);
+ *value= (ulonglong) fix_unsigned(thd, tmp, option_limits);
else
*value= (ulonglong) tmp;
pthread_mutex_unlock(&LOCK_global_system_variables);
@@ -1166,8 +1213,10 @@ bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var)
void sys_var_ulonglong_ptr::set_default(THD *thd, enum_var_type type)
{
+ bool not_used;
pthread_mutex_lock(&LOCK_global_system_variables);
- *value= (ulonglong) option_limits->def_value;
+ *value= getopt_ull_limit_value((ulonglong) option_limits->def_value,
+ option_limits, &not_used);
pthread_mutex_unlock(&LOCK_global_system_variables);
}
@@ -1197,47 +1246,45 @@ uchar *sys_var_enum::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
return (uchar*) enum_names->type_names[*value];
}
+
+uchar *sys_var_enum_const::value_ptr(THD *thd, enum_var_type type,
+ LEX_STRING *base)
+{
+ return (uchar*) enum_names->type_names[global_system_variables.*offset];
+}
+
bool sys_var_thd_ulong::check(THD *thd, set_var *var)
{
- return (sys_var_thd::check(thd, var) ||
+ return (get_unsigned(thd, var) ||
(check_func && (*check_func)(thd, var)));
}
bool sys_var_thd_ulong::update(THD *thd, set_var *var)
{
ulonglong tmp= var->save_result.ulonglong_value;
- char buf[22];
- bool truncated= false;
/* Don't use bigger value than given with --maximum-variable-name=.. */
if ((ulong) tmp > max_system_variables.*offset)
{
- truncated= true;
- llstr(tmp, buf);
+ throw_bounds_warning(thd, name, tmp);
tmp= max_system_variables.*offset;
}
-#if SIZEOF_LONG == 4
- /* Avoid overflows on 32 bit systems */
- if (tmp > (ulonglong) ~(ulong) 0)
+ if (option_limits)
+ tmp= (ulong) fix_unsigned(thd, tmp, option_limits);
+#if SIZEOF_LONG < SIZEOF_LONG_LONG
+ else if (tmp > ULONG_MAX)
{
- truncated= true;
- llstr(tmp, buf);
- tmp= ((ulonglong) ~(ulong) 0);
+ tmp= ULONG_MAX;
+ throw_bounds_warning(thd, name, var->save_result.ulonglong_value);
}
#endif
- if (truncated)
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_TRUNCATED_WRONG_VALUE,
- ER(ER_TRUNCATED_WRONG_VALUE), name,
- buf);
- if (option_limits)
- tmp= (ulong) getopt_ull_limit_value(tmp, option_limits);
if (var->type == OPT_GLOBAL)
global_system_variables.*offset= (ulong) tmp;
else
thd->variables.*offset= (ulong) tmp;
+
return 0;
}
@@ -1246,8 +1293,11 @@ void sys_var_thd_ulong::set_default(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
{
+ bool not_used;
/* We will not come here if option_limits is not set */
- global_system_variables.*offset= (ulong) option_limits->def_value;
+ global_system_variables.*offset=
+ getopt_ull_limit_value((ulong) option_limits->def_value,
+ option_limits, &not_used);
}
else
thd->variables.*offset= global_system_variables.*offset;
@@ -1272,7 +1322,7 @@ bool sys_var_thd_ha_rows::update(THD *thd, set_var *var)
tmp= max_system_variables.*offset;
if (option_limits)
- tmp= (ha_rows) getopt_ull_limit_value(tmp, option_limits);
+ tmp= (ha_rows) fix_unsigned(thd, tmp, option_limits);
if (var->type == OPT_GLOBAL)
{
/* Lock is needed to make things safe on 32 bit systems */
@@ -1290,9 +1340,12 @@ void sys_var_thd_ha_rows::set_default(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
{
+ bool not_used;
/* We will not come here if option_limits is not set */
pthread_mutex_lock(&LOCK_global_system_variables);
- global_system_variables.*offset= (ha_rows) option_limits->def_value;
+ global_system_variables.*offset=
+ (ha_rows) getopt_ull_limit_value((ha_rows) option_limits->def_value,
+ option_limits, &not_used);
pthread_mutex_unlock(&LOCK_global_system_variables);
}
else
@@ -1308,6 +1361,11 @@ uchar *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type,
return (uchar*) &(thd->variables.*offset);
}
+bool sys_var_thd_ulonglong::check(THD *thd, set_var *var)
+{
+ return get_unsigned(thd, var);
+}
+
bool sys_var_thd_ulonglong::update(THD *thd, set_var *var)
{
ulonglong tmp= var->save_result.ulonglong_value;
@@ -1316,7 +1374,7 @@ bool sys_var_thd_ulonglong::update(THD *thd, set_var *var)
tmp= max_system_variables.*offset;
if (option_limits)
- tmp= getopt_ull_limit_value(tmp, option_limits);
+ tmp= fix_unsigned(thd, tmp, option_limits);
if (var->type == OPT_GLOBAL)
{
/* Lock is needed to make things safe on 32 bit systems */
@@ -1334,8 +1392,11 @@ void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
{
+ bool not_used;
pthread_mutex_lock(&LOCK_global_system_variables);
- global_system_variables.*offset= (ulonglong) option_limits->def_value;
+ global_system_variables.*offset=
+ getopt_ull_limit_value((ulonglong) option_limits->def_value,
+ option_limits, &not_used);
pthread_mutex_unlock(&LOCK_global_system_variables);
}
else
@@ -1526,7 +1587,7 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
pthread_mutex_lock(&LOCK_global_system_variables);
value= *(ha_rows*) value_ptr(thd, var_type, base);
pthread_mutex_unlock(&LOCK_global_system_variables);
- return new Item_int((longlong) value);
+ return new Item_int((ulonglong) value);
}
case SHOW_MY_BOOL:
{
@@ -2044,7 +2105,7 @@ bool sys_var_key_buffer_size::update(THD *thd, set_var *var)
}
key_cache->param_buff_size=
- (ulonglong) getopt_ull_limit_value(tmp, option_limits);
+ (ulonglong) fix_unsigned(thd, tmp, option_limits);
/* If key cache didn't existed initialize it, else resize it */
key_cache->in_init= 1;
@@ -2098,7 +2159,7 @@ bool sys_var_key_cache_long::update(THD *thd, set_var *var)
goto end;
*((ulong*) (((char*) key_cache) + offset))=
- (ulong) getopt_ull_limit_value(tmp, option_limits);
+ (ulong) fix_unsigned(thd, tmp, option_limits);
/*
Don't create a new key cache if it didn't exist
@@ -3738,7 +3799,7 @@ bool sys_var_opt_readonly::update(THD *thd, set_var *var)
can cause to wait on a read lock, it's required for the client application
to unlock everything, and acceptable for the server to wait on all locks.
*/
- if (result= close_cached_tables(thd, true, NULL, false))
+ if (result= close_cached_tables(thd, NULL, FALSE, TRUE, TRUE))
goto end_with_read_lock;
if (result= make_global_read_lock_block_commit(thd))
diff --git a/sql/set_var.h b/sql/set_var.h
index 0e282212a3f..5be54200c7d 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -305,6 +305,24 @@ public:
};
+class sys_var_enum_const :public sys_var
+{
+ ulong SV::*offset;
+ TYPELIB *enum_names;
+public:
+ sys_var_enum_const(sys_var_chain *chain, const char *name_arg, ulong SV::*offset_arg,
+ TYPELIB *typelib, sys_after_update_func func)
+ :sys_var(name_arg,func), offset(offset_arg), enum_names(typelib)
+ { chain_sys_var(chain); }
+ bool check(THD *thd, set_var *var) { return 1; }
+ bool update(THD *thd, set_var *var) { return 1; }
+ SHOW_TYPE show_type() { return SHOW_CHAR; }
+ bool check_update_type(Item_result type) { return 1; }
+ bool is_readonly() const { return 1; }
+ uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+};
+
+
class sys_var_thd :public sys_var
{
public:
@@ -379,6 +397,7 @@ public:
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE show_type() { return SHOW_LONGLONG; }
uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+ bool check(THD *thd, set_var *var);
bool check_default(enum_var_type type)
{
return type == OPT_GLOBAL && !option_limits;
diff --git a/sql/slave.cc b/sql/slave.cc
index 0d1a785578e..45e3d4da090 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -137,6 +137,7 @@ static int terminate_slave_thread(THD *thd,
pthread_cond_t* term_cond,
volatile uint *slave_running,
bool skip_lock);
+static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info);
/*
Find out which replications threads are running
@@ -821,7 +822,7 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
mi->clock_diff_with_master=
(long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10));
}
- else
+ else if (!check_io_slave_killed(mi->io_thd, mi, NULL))
{
mi->clock_diff_with_master= 0; /* The "most sensible" value */
sql_print_warning("\"SELECT UNIX_TIMESTAMP()\" failed on master, "
@@ -981,17 +982,24 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
}
thd->query= query;
thd->is_slave_error = 0;
- thd->net.no_send_ok = 1;
bzero((char*) &tables,sizeof(tables));
tables.db = (char*)db;
tables.alias= tables.table_name= (char*)table_name;
/* Drop the table if 'overwrite' is true */
- if (overwrite && mysql_rm_table(thd,&tables,1,0)) /* drop if exists */
+ if (overwrite)
{
- sql_print_error("create_table_from_dump: failed to drop the table");
- goto err;
+ if (mysql_rm_table(thd,&tables,1,0)) /* drop if exists */
+ {
+ sql_print_error("create_table_from_dump: failed to drop the table");
+ goto err;
+ }
+ else
+ {
+ /* Clear the OK result of mysql_rm_table(). */
+ thd->main_da.reset_diagnostics_area();
+ }
}
/* Create the table. We do not want to log the "create table" statement */
@@ -1013,6 +1021,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
goto err; // mysql_parse took care of the error send
thd_proc_info(thd, "Opening master dump table");
+ thd->main_da.reset_diagnostics_area(); /* cleanup from CREATE_TABLE */
/*
Note: If this function starts to fail for MERGE tables,
change the next two lines to these:
@@ -1055,7 +1064,6 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
err:
close_thread_tables(thd);
- thd->net.no_send_ok = 0;
DBUG_RETURN(error);
}
@@ -1107,7 +1115,6 @@ int fetch_master_table(THD *thd, const char *db_name, const char *table_name,
error = 0;
err:
- thd->net.no_send_ok = 0; // Clear up garbage after create_table_from_dump
if (!called_connected)
mysql_close(mysql);
if (errmsg && thd->vio_ok())
@@ -1229,7 +1236,7 @@ int register_slave_on_master(MYSQL* mysql, Master_info *mi,
{
*suppress_warnings= TRUE; // Suppress reconnect warning
}
- else
+ else if (!check_io_slave_killed(mi->io_thd, mi, NULL))
{
char buf[256];
my_snprintf(buf, sizeof(buf), "%s (Errno: %d)", mysql_error(mysql),
@@ -1721,26 +1728,31 @@ static int has_temporary_error(THD *thd)
DBUG_ENTER("has_temporary_error");
if (thd->is_fatal_error)
- {
- DBUG_PRINT("info", ("thd->net.last_errno: %s", ER(thd->net.last_errno)));
DBUG_RETURN(0);
- }
DBUG_EXECUTE_IF("all_errors_are_temporary_errors",
- if (thd->net.last_errno)
- thd->net.last_errno= ER_LOCK_DEADLOCK;);
+ if (thd->main_da.is_error())
+ {
+ thd->clear_error();
+ my_error(ER_LOCK_DEADLOCK, MYF(0));
+ });
+
+ /*
+ If there is no message in THD, we can't say if it's a temporary
+ error or not. This is currently the case for Incident_log_event,
+ which sets no message. Return FALSE.
+ */
+ if (!thd->is_error())
+ DBUG_RETURN(0);
/*
Temporary error codes:
currently, InnoDB deadlock detected by InnoDB or lock
wait timeout (innodb_lock_wait_timeout exceeded
*/
- if (thd->net.last_errno == ER_LOCK_DEADLOCK ||
- thd->net.last_errno == ER_LOCK_WAIT_TIMEOUT)
- {
- DBUG_PRINT("info", ("thd->net.last_errno: %s", ER(thd->net.last_errno)));
+ if (thd->main_da.sql_errno() == ER_LOCK_DEADLOCK ||
+ thd->main_da.sql_errno() == ER_LOCK_WAIT_TIMEOUT)
DBUG_RETURN(1);
- }
#ifdef HAVE_NDB_BINLOG
/*
@@ -2006,7 +2018,7 @@ static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info)
{
if (io_slave_killed(thd, mi))
{
- if (global_system_variables.log_warnings)
+ if (info && global_system_variables.log_warnings)
sql_print_information(info);
return TRUE;
}
@@ -2191,11 +2203,15 @@ connected:
thd_proc_info(thd, "Registering slave on master");
if (register_slave_on_master(mysql, mi, &suppress_warnings))
{
- sql_print_error("Slave I/O thread couldn't register on master");
- if (check_io_slave_killed(thd, mi, "Slave I/O thread killed while \
-registering slave on master") ||
- try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
- reconnect_messages[SLAVE_RECON_ACT_REG]))
+ if (!check_io_slave_killed(thd, mi, "Slave I/O thread killed "
+ "while registering slave on master"))
+ {
+ sql_print_error("Slave I/O thread couldn't register on master");
+ if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
+ reconnect_messages[SLAVE_RECON_ACT_REG]))
+ goto err;
+ }
+ else
goto err;
goto connected;
}
@@ -2551,20 +2567,21 @@ Slave SQL thread aborted. Can't execute init_slave query");
*/
uint32 const last_errno= rli->last_error().number;
- DBUG_PRINT("info", ("thd->net.last_errno=%d; rli->last_error.number=%d",
- thd->net.last_errno, last_errno));
- if (thd->net.last_errno != 0)
+ if (thd->is_error())
{
- char const *const errmsg=
- thd->net.last_error ? thd->net.last_error : "<no message>";
+ char const *const errmsg= thd->main_da.message();
+
+ DBUG_PRINT("info",
+ ("thd->main_da.sql_errno()=%d; rli->last_error.number=%d",
+ thd->main_da.sql_errno(), last_errno));
if (last_errno == 0)
{
- rli->report(ERROR_LEVEL, thd->net.last_errno, errmsg);
+ rli->report(ERROR_LEVEL, thd->main_da.sql_errno(), errmsg);
}
- else if (last_errno != thd->net.last_errno)
+ else if (last_errno != thd->main_da.sql_errno())
{
sql_print_error("Slave (additional info): %s Error_code: %d",
- errmsg, thd->net.last_errno);
+ errmsg, thd->main_da.sql_errno());
}
}
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 80192d74f1c..387596263b1 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1220,12 +1220,6 @@ sp_head::execute(THD *thd)
err_status= i->execute(thd, &ip);
- /*
- If this SP instruction have sent eof, it has caused no_send_error to be
- set. Clear it back to allow the next instruction to send error. (multi-
- statement execution code clears no_send_error between statements too)
- */
- thd->net.no_send_error= 0;
if (i->free_list)
cleanup_items(i->free_list);
@@ -2807,14 +2801,22 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
thd->query, thd->query_length) <= 0)
{
res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
+
+ if (thd->main_da.is_eof())
+ net_end_statement(thd);
+
+ query_cache_end_of_result(thd);
+
if (!res && unlikely(thd->enable_slow_log))
log_slow_statement(thd);
- query_cache_end_of_result(thd);
}
else
*nextp= m_ip+1;
thd->query= query;
thd->query_length= query_length;
+
+ if (!thd->is_error())
+ thd->main_da.reset_diagnostics_area();
}
DBUG_RETURN(res);
}
diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc
index 70a043c4fac..8395648689b 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -287,7 +287,6 @@ sp_rcontext::find_handler(THD *thd, uint sql_errno,
sql_errno The error code
level Warning level
thd The current thread
- - thd->net.report_error is an optional output.
RETURN
TRUE if a handler was found.
@@ -298,7 +297,6 @@ sp_rcontext::handle_error(uint sql_errno,
MYSQL_ERROR::enum_warning_level level,
THD *thd)
{
- bool handled= FALSE;
MYSQL_ERROR::enum_warning_level elevated_level= level;
@@ -310,25 +308,7 @@ sp_rcontext::handle_error(uint sql_errno,
elevated_level= MYSQL_ERROR::WARN_LEVEL_ERROR;
}
- if (find_handler(thd, sql_errno, elevated_level))
- {
- if (elevated_level == MYSQL_ERROR::WARN_LEVEL_ERROR)
- {
- /*
- Forces to abort the current instruction execution.
- NOTE: This code is altering the original meaning of
- the net.report_error flag (send an error to the client).
- In the context of stored procedures with error handlers,
- the flag is reused to cause error propagation,
- until the error handler is reached.
- No messages will be sent to the client in that context.
- */
- thd->net.report_error= 1;
- }
- handled= TRUE;
- }
-
- return handled;
+ return find_handler(thd, sql_errno, elevated_level);
}
void
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 58ba8c28fb7..d2d26da229a 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -695,7 +695,7 @@ my_bool acl_reload(THD *thd)
if (simple_open_n_lock_tables(thd, tables))
{
sql_print_error("Fatal error: Can't open and lock privilege tables: %s",
- thd->net.last_error);
+ thd->main_da.message());
goto end;
}
@@ -3800,11 +3800,11 @@ my_bool grant_reload(THD *thd)
close_thread_tables(thd);
/*
- It is ok failing to load procs_priv table because we may be
+ It is OK failing to load procs_priv table because we may be
working with 4.1 privilege tables.
*/
if (grant_reload_procs_priv(thd))
- my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), "mysql.procs_priv");
+ return_val= 1;
rw_wrlock(&LOCK_grant);
grant_version++;
@@ -5693,9 +5693,6 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
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));
-
write_bin_log(thd, FALSE, thd->query, thd->query_length);
rw_unlock(&LOCK_grant);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 486d815026f..9e4dceff87d 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -130,7 +130,7 @@ void table_cache_free(void)
DBUG_ENTER("table_cache_free");
if (table_def_inited)
{
- close_cached_tables((THD*) 0,0,(TABLE_LIST*) 0);
+ close_cached_tables(NULL, NULL, FALSE, FALSE, FALSE);
if (!open_cache.records) // Safety first
hash_free(&open_cache);
}
@@ -491,9 +491,28 @@ static TABLE_SHARE
int tmp;
DBUG_ENTER("get_table_share_with_create");
- if ((share= get_table_share(thd, table_list, key, key_length,
- db_flags, error)) ||
- thd->net.last_errno != ER_NO_SUCH_TABLE)
+ share= get_table_share(thd, table_list, key, key_length, db_flags, error);
+ /*
+ If share is not NULL, we found an existing share.
+
+ If share is NULL, and there is no error, we're inside
+ pre-locking, which silences 'ER_NO_SUCH_TABLE' errors
+ with the intention to silently drop non-existing tables
+ from the pre-locking list. In this case we still need to try
+ auto-discover before returning a NULL share.
+
+ If share is NULL and the error is ER_NO_SUCH_TABLE, this is
+ the same as above, only that the error was not silenced by
+ pre-locking. Once again, we need to try to auto-discover
+ the share.
+
+ Finally, if share is still NULL, it's a real error and we need
+ to abort.
+
+ @todo Rework alternative ways to deal with ER_NO_SUCH TABLE.
+ */
+ if (share || thd->is_error() && thd->main_da.sql_errno() != ER_NO_SUCH_TABLE)
+
DBUG_RETURN(share);
/* Table didn't exist. Check if some engine can provide it */
@@ -502,9 +521,13 @@ static TABLE_SHARE
{
/*
No such table in any engine.
- Hide "Table doesn't exist" errors if table belong to view
+ Hide "Table doesn't exist" errors if the table belongs to a view.
+ The check for thd->is_error() is necessary to not push an
+ unwanted error in case of pre-locking, which silences
+ "no such table" errors.
+ @todo Rework the alternative ways to deal with ER_NO_SUCH TABLE.
*/
- if (table_list->belong_to_view)
+ if (thd->is_error() && table_list->belong_to_view)
{
TABLE_LIST *view= table_list->belong_to_view;
thd->clear_error();
@@ -885,16 +908,24 @@ void free_io_cache(TABLE *table)
/*
Close all tables which aren't in use by any thread
- THD can be NULL, but then if_wait_for_refresh must be FALSE
- and tables must be NULL.
+ @param thd Thread context
+ @param tables List of tables to remove from the cache
+ @param have_lock If LOCK_open is locked
+ @param wait_for_refresh Wait for a impending flush
+ @param wait_for_placeholders Wait for tables being reopened so that the GRL
+ won't proceed while write-locked tables are being reopened by other
+ threads.
+
+ @remark THD can be NULL, but then wait_for_refresh must be FALSE
+ and tables must be NULL.
*/
-bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
- TABLE_LIST *tables, bool have_lock)
+bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
+ bool wait_for_refresh, bool wait_for_placeholders)
{
bool result=0;
DBUG_ENTER("close_cached_tables");
- DBUG_ASSERT(thd || (!if_wait_for_refresh && !tables));
+ DBUG_ASSERT(thd || (!wait_for_refresh && !tables));
if (!have_lock)
VOID(pthread_mutex_lock(&LOCK_open));
@@ -918,7 +949,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
}
DBUG_PRINT("tcache", ("incremented global refresh_version to: %lu",
refresh_version));
- if (if_wait_for_refresh)
+ if (wait_for_refresh)
{
/*
Other threads could wait in a loop in open_and_lock_tables(),
@@ -975,13 +1006,13 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
found=1;
}
if (!found)
- if_wait_for_refresh=0; // Nothing to wait for
+ wait_for_refresh=0; // Nothing to wait for
}
#ifndef EMBEDDED_LIBRARY
if (!tables)
kill_delayed_threads();
#endif
- if (if_wait_for_refresh)
+ if (wait_for_refresh)
{
/*
If there is any table that has a lower refresh_version, wait until
@@ -1004,6 +1035,9 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
for (uint idx=0 ; idx < open_cache.records ; idx++)
{
TABLE *table=(TABLE*) hash_element(&open_cache,idx);
+ /* Avoid a self-deadlock. */
+ if (table->in_use == thd)
+ continue;
/*
Note that we wait here only for tables which are actually open, and
not for placeholders with TABLE::open_placeholder set. Waiting for
@@ -1018,7 +1052,8 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
are employed by CREATE TABLE as in this case table simply does not
exist yet.
*/
- if (table->needs_reopen_or_name_lock() && table->db_stat)
+ if (table->needs_reopen_or_name_lock() && (table->db_stat ||
+ (table->open_placeholder && wait_for_placeholders)))
{
found=1;
DBUG_PRINT("signal", ("Waiting for COND_refresh"));
@@ -1037,11 +1072,18 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
thd->in_lock_tables=0;
/* Set version for table */
for (TABLE *table=thd->open_tables; table ; table= table->next)
- table->s->version= refresh_version;
+ {
+ /*
+ Preserve the version (0) of write locked tables so that a impending
+ global read lock won't sneak in.
+ */
+ if (table->reginfo.lock_type < TL_WRITE_ALLOW_WRITE)
+ table->s->version= refresh_version;
+ }
}
if (!have_lock)
VOID(pthread_mutex_unlock(&LOCK_open));
- if (if_wait_for_refresh)
+ if (wait_for_refresh)
{
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= 0;
@@ -1068,10 +1110,10 @@ bool close_cached_connection_tables(THD *thd, bool if_wait_for_refresh,
DBUG_ASSERT(thd);
bzero(&tmp, sizeof(TABLE_LIST));
-
+
if (!have_lock)
VOID(pthread_mutex_lock(&LOCK_open));
-
+
for (idx= 0; idx < table_def_cache.records; idx++)
{
TABLE_SHARE *share= (TABLE_SHARE *) hash_element(&table_def_cache, idx);
@@ -1100,11 +1142,11 @@ bool close_cached_connection_tables(THD *thd, bool if_wait_for_refresh,
}
if (tables)
- result= close_cached_tables(thd, FALSE, tables, TRUE);
-
+ result= close_cached_tables(thd, tables, TRUE, FALSE, FALSE);
+
if (!have_lock)
VOID(pthread_mutex_unlock(&LOCK_open));
-
+
if (if_wait_for_refresh)
{
pthread_mutex_lock(&thd->mysys_var->mutex);
@@ -2204,7 +2246,7 @@ void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond)
current thread.
@param thd current thread context
- @param tables able list containing one table to open.
+ @param tables table list containing one table to open.
@return FALSE on success, TRUE otherwise.
*/
@@ -3272,8 +3314,8 @@ static bool reattach_merge(THD *thd, TABLE **err_tables_p)
@param thd Thread context
@param get_locks Should we get locks after reopening tables ?
- @param in_refresh Are we in FLUSH TABLES ? TODO: It seems that
- we can remove this parameter.
+ @param mark_share_as_old Mark share as old to protect from a impending
+ global read lock.
@note Since this function can't properly handle prelocking and
create placeholders it should be used in very special
@@ -3287,13 +3329,17 @@ static bool reattach_merge(THD *thd, TABLE **err_tables_p)
@return FALSE in case of success, TRUE - otherwise.
*/
-bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
+bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old)
{
TABLE *table,*next,**prev;
TABLE **tables,**tables_ptr; // For locks
TABLE *err_tables= NULL;
bool error=0, not_used;
bool merge_table_found= FALSE;
+ const uint flags= MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN |
+ MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK |
+ MYSQL_LOCK_IGNORE_FLUSH;
+
DBUG_ENTER("reopen_tables");
if (!thd->open_tables)
@@ -3354,7 +3400,7 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
/* Do not handle locks of MERGE children. */
if (get_locks && !db_stat && !table->parent)
*tables_ptr++= table; // need new lock on this
- if (in_refresh)
+ if (mark_share_as_old)
{
table->s->version=0;
table->open_placeholder= 0;
@@ -3387,7 +3433,7 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
*/
thd->some_tables_deleted=0;
if ((lock= mysql_lock_tables(thd, tables, (uint) (tables_ptr - tables),
- MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN, &not_used)))
+ flags, &not_used)))
{
thd->locked_tables=mysql_lock_merge(thd->locked_tables,lock);
}
@@ -8414,7 +8460,7 @@ int abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt)
We also downgrade locks after the upgrade to WRITE_ONLY
*/
-/* purecov: begin unused */
+/* purecov: begin deadcode */
void close_open_tables_and_downgrade(ALTER_PARTITION_PARAM_TYPE *lpt)
{
VOID(pthread_mutex_lock(&LOCK_open));
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index fa6aa8f5881..77c5155b41b 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -40,13 +40,6 @@ void mysql_client_binlog_statement(THD* thd)
if (check_global_access(thd, SUPER_ACL))
DBUG_VOID_RETURN;
- /*
- Temporarily turn off send_ok, since different events handle this
- differently
- */
- my_bool nsok= thd->net.no_send_ok;
- thd->net.no_send_ok= TRUE;
-
size_t coded_len= thd->lex->comment.length + 1;
size_t decoded_len= base64_needed_decoded_length(coded_len);
DBUG_ASSERT(coded_len > 0);
@@ -193,20 +186,11 @@ void mysql_client_binlog_statement(THD* thd)
}
}
- /*
- Restore setting of no_send_ok
- */
- thd->net.no_send_ok= nsok;
DBUG_PRINT("info",("binlog base64 execution finished successfully"));
send_ok(thd);
end:
- /*
- Restore setting of no_send_ok
- */
- thd->net.no_send_ok= nsok;
-
delete desc;
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
DBUG_VOID_RETURN;
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 49ae10a5f45..e51c53f644e 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1410,6 +1410,7 @@ def_week_frmt: %lu",
thd->limit_found_rows = query->found_rows();
thd->status_var.last_query_cost= 0.0;
+ thd->main_da.disable_status();
BLOCK_UNLOCK_RD(query_block);
DBUG_RETURN(1); // Result sent to client
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index fe00db07321..75376c53f68 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -358,6 +358,124 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length,
return thd->strmake(str.ptr(), str.length());
}
+/**
+ Clear this diagnostics area.
+
+ Normally called at the end of a statement.
+*/
+
+void
+Diagnostics_area::reset_diagnostics_area()
+{
+#ifdef DBUG_OFF
+ can_overwrite_status= FALSE;
+ /** Don't take chances in production */
+ m_message[0]= '\0';
+ m_sql_errno= 0;
+ m_server_status= 0;
+ m_affected_rows= 0;
+ m_last_insert_id= 0;
+ m_total_warn_count= 0;
+#endif
+ is_sent= FALSE;
+ /** Tiny reset in debug mode to see garbage right away */
+ m_status= DA_EMPTY;
+}
+
+
+/**
+ Set OK status -- ends commands that do not return a
+ result set, e.g. INSERT/UPDATE/DELETE.
+*/
+
+void
+Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg,
+ ulonglong last_insert_id_arg,
+ const char *message_arg)
+{
+ DBUG_ASSERT(! is_set());
+#ifdef DBUG_OFF
+ /* In production, refuse to overwrite an error with an OK packet. */
+ if (is_error())
+ return;
+#endif
+ /** Only allowed to report success if has not yet reported an error */
+
+ m_server_status= thd->server_status;
+ m_total_warn_count= thd->total_warn_count;
+ m_affected_rows= affected_rows_arg;
+ m_last_insert_id= last_insert_id_arg;
+ if (message_arg)
+ strmake(m_message, message_arg, sizeof(m_message));
+ else
+ m_message[0]= '\0';
+ m_status= DA_OK;
+}
+
+
+/**
+ Set EOF status.
+*/
+
+void
+Diagnostics_area::set_eof_status(THD *thd)
+{
+ /** Only allowed to report eof if has not yet reported an error */
+
+ DBUG_ASSERT(! is_set());
+#ifdef DBUG_OFF
+ /* In production, refuse to overwrite an error with an EOF packet. */
+ if (is_error())
+ return;
+#endif
+
+ m_server_status= thd->server_status;
+ /*
+ If inside a stored procedure, do not return the total
+ number of warnings, since they are not available to the client
+ anyway.
+ */
+ m_total_warn_count= thd->spcont ? 0 : thd->total_warn_count;
+
+ m_status= DA_EOF;
+}
+
+/**
+ Set ERROR status.
+*/
+
+void
+Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg,
+ const char *message_arg)
+{
+ /*
+ Only allowed to report error if has not yet reported a success
+ The only exception is when we flush the message to the client,
+ an error can happen during the flush.
+ */
+ DBUG_ASSERT(! is_set() || can_overwrite_status);
+
+ m_sql_errno= sql_errno_arg;
+ strmake(m_message, message_arg, sizeof(m_message));
+
+ m_status= DA_ERROR;
+}
+
+
+/**
+ Mark the diagnostics area as 'DISABLED'.
+
+ This is used in rare cases when the COM_ command at hand sends a response
+ in a custom format. One example is the query cache, another is
+ COM_STMT_PREPARE.
+*/
+
+void
+Diagnostics_area::disable_status()
+{
+ DBUG_ASSERT(! is_set());
+ m_status= DA_DISABLED;
+}
THD::THD()
@@ -438,7 +556,6 @@ THD::THD()
net.vio=0;
#endif
client_capabilities= 0; // minimalistic client
- net.last_error[0]=0; // If error on boot
#ifdef HAVE_QUERY_CACHE
query_cache_init_query(&net); // If error on boot
#endif
@@ -1334,12 +1451,12 @@ void select_send::abort()
{
DBUG_ENTER("select_send::abort");
if (is_result_set_started && thd->spcont &&
- thd->spcont->find_handler(thd, thd->net.last_errno,
+ thd->spcont->find_handler(thd, thd->main_da.sql_errno(),
MYSQL_ERROR::WARN_LEVEL_ERROR))
{
/*
We're executing a stored procedure, have an open result
- set, an SQL exception conditiona and a handler for it.
+ set, an SQL exception condition and a handler for it.
In this situation we must abort the current statement,
silence the error and start executing the continue/exit
handler.
@@ -1347,9 +1464,7 @@ void select_send::abort()
otherwise the client will hang due to the violation of the
client/server protocol.
*/
- thd->net.report_error= 0;
- send_eof();
- thd->net.report_error= 1; // Abort SP
+ thd->protocol->end_partial_result_set(thd);
}
DBUG_VOID_RETURN;
}
@@ -1401,12 +1516,14 @@ bool select_send::send_data(List<Item> &items)
}
}
thd->sent_row_count++;
- if (!thd->vio_ok())
- DBUG_RETURN(0);
- if (! thd->is_error())
+ if (thd->is_error())
+ {
+ protocol->remove_last_row();
+ DBUG_RETURN(1);
+ }
+ if (thd->vio_ok())
DBUG_RETURN(protocol->write());
- protocol->remove_last_row();
- DBUG_RETURN(1);
+ DBUG_RETURN(0);
}
bool select_send::send_eof()
@@ -1424,14 +1541,9 @@ bool select_send::send_eof()
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
}
- if (! thd->is_error())
- {
- ::send_eof(thd);
- is_result_set_started= 0;
- return 0;
- }
- else
- return 1;
+ ::send_eof(thd);
+ is_result_set_started= 0;
+ return FALSE;
}
@@ -1600,16 +1712,18 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
}
}
field_term_length=exchange->field_term->length();
- field_term_char= field_term_length ? (*exchange->field_term)[0] : INT_MAX;
+ field_term_char= field_term_length ?
+ (int) (uchar) (*exchange->field_term)[0] : INT_MAX;
if (!exchange->line_term->length())
exchange->line_term=exchange->field_term; // Use this if it exists
- field_sep_char= (exchange->enclosed->length() ? (*exchange->enclosed)[0] :
- field_term_char);
- escape_char= (exchange->escaped->length() ? (*exchange->escaped)[0] : -1);
+ field_sep_char= (exchange->enclosed->length() ?
+ (int) (uchar) (*exchange->enclosed)[0] : field_term_char);
+ escape_char= (exchange->escaped->length() ?
+ (int) (uchar) (*exchange->escaped)[0] : -1);
is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char));
line_sep_char= (exchange->line_term->length() ?
- (*exchange->line_term)[0] : INT_MAX);
+ (int) (uchar) (*exchange->line_term)[0] : INT_MAX);
if (!field_term_length)
exchange->opt_enclosed=0;
if (!exchange->enclosed->length())
@@ -1766,10 +1880,11 @@ bool select_export::send_data(List<Item> &items)
Don't escape field_term_char by doubling - doubling is only
valid for ENCLOSED BY characters:
*/
- (enclosed || !is_ambiguous_field_term || *pos != field_term_char))
+ (enclosed || !is_ambiguous_field_term ||
+ (int) (uchar) *pos != field_term_char))
{
char tmp_buff[2];
- tmp_buff[0]= ((int) *pos == field_sep_char &&
+ tmp_buff[0]= ((int) (uchar) *pos == field_sep_char &&
is_ambiguous_field_sep) ?
field_sep_char : escape_char;
tmp_buff[1]= *pos ? *pos : '0';
@@ -2711,7 +2826,6 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
{
backup->options= options;
backup->in_sub_stmt= in_sub_stmt;
- backup->no_send_ok= net.no_send_ok;
backup->enable_slow_log= enable_slow_log;
backup->limit_found_rows= limit_found_rows;
backup->examined_row_count= examined_row_count;
@@ -2742,9 +2856,6 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
cuted_fields= 0;
transaction.savepoints= 0;
first_successful_insert_id_in_cur_stmt= 0;
-
- /* Surpress OK packets in case if we will execute statements */
- net.no_send_ok= TRUE;
}
@@ -2767,7 +2878,6 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
transaction.savepoints= backup->savepoints;
options= backup->options;
in_sub_stmt= backup->in_sub_stmt;
- net.no_send_ok= backup->no_send_ok;
enable_slow_log= backup->enable_slow_log;
first_successful_insert_id_in_prev_stmt=
backup->first_successful_insert_id_in_prev_stmt;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 7dc27818168..e8f28b19213 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -914,7 +914,6 @@ public:
uint in_sub_stmt;
bool enable_slow_log;
bool last_insert_id_used;
- my_bool no_send_ok;
SAVEPOINT *savepoints;
};
@@ -977,6 +976,123 @@ public:
/**
+ Stores status of the currently executed statement.
+ Cleared at the beginning of the statement, and then
+ can hold either OK, ERROR, or EOF status.
+ Can not be assigned twice per statement.
+*/
+
+class Diagnostics_area
+{
+public:
+ enum enum_diagnostics_status
+ {
+ /** The area is cleared at start of a statement. */
+ DA_EMPTY= 0,
+ /** Set whenever one calls send_ok(). */
+ DA_OK,
+ /** Set whenever one calls send_eof(). */
+ DA_EOF,
+ /** Set whenever one calls my_error() or my_message(). */
+ DA_ERROR,
+ /** Set in case of a custom response, such as one from COM_STMT_PREPARE. */
+ DA_DISABLED
+ };
+ /** True if status information is sent to the client. */
+ bool is_sent;
+ /** Set to make set_error_status after set_{ok,eof}_status possible. */
+ bool can_overwrite_status;
+
+ void set_ok_status(THD *thd, ha_rows affected_rows_arg,
+ ulonglong last_insert_id_arg,
+ const char *message);
+ void set_eof_status(THD *thd);
+ void set_error_status(THD *thd, uint sql_errno_arg, const char *message_arg);
+
+ void disable_status();
+
+ void reset_diagnostics_area();
+
+ bool is_set() const { return m_status != DA_EMPTY; }
+ bool is_error() const { return m_status == DA_ERROR; }
+ bool is_eof() const { return m_status == DA_EOF; }
+ bool is_ok() const { return m_status == DA_OK; }
+ bool is_disabled() const { return m_status == DA_DISABLED; }
+ enum_diagnostics_status status() const { return m_status; }
+
+ const char *message() const
+ { DBUG_ASSERT(m_status == DA_ERROR || m_status == DA_OK); return m_message; }
+
+ uint sql_errno() const
+ { DBUG_ASSERT(m_status == DA_ERROR); return m_sql_errno; }
+
+ uint server_status() const
+ {
+ DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF);
+ return m_server_status;
+ }
+
+ ha_rows affected_rows() const
+ { DBUG_ASSERT(m_status == DA_OK); return m_affected_rows; }
+
+ ulonglong last_insert_id() const
+ { DBUG_ASSERT(m_status == DA_OK); return m_last_insert_id; }
+
+ uint total_warn_count() const
+ {
+ DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF);
+ return m_total_warn_count;
+ }
+
+ Diagnostics_area() { reset_diagnostics_area(); }
+
+private:
+ /** Message buffer. Can be used by OK or ERROR status. */
+ char m_message[MYSQL_ERRMSG_SIZE];
+ /**
+ SQL error number. One of ER_ codes from share/errmsg.txt.
+ Set by set_error_status.
+ */
+ uint m_sql_errno;
+
+ /**
+ Copied from thd->server_status when the diagnostics area is assigned.
+ We need this member as some places in the code use the following pattern:
+ thd->server_status|= ...
+ send_eof(thd);
+ thd->server_status&= ~...
+ Assigned by OK, EOF or ERROR.
+ */
+ uint m_server_status;
+ /**
+ The number of rows affected by the last statement. This is
+ semantically close to thd->row_count_func, but has a different
+ life cycle. thd->row_count_func stores the value returned by
+ function ROW_COUNT() and is cleared only by statements that
+ update its value, such as INSERT, UPDATE, DELETE and few others.
+ This member is cleared at the beginning of the next statement.
+
+ We could possibly merge the two, but life cycle of thd->row_count_func
+ can not be changed.
+ */
+ ha_rows m_affected_rows;
+ /**
+ Similarly to the previous member, this is a replacement of
+ thd->first_successful_insert_id_in_prev_stmt, which is used
+ to implement LAST_INSERT_ID().
+ */
+ ulonglong m_last_insert_id;
+ /** The total number of warnings. */
+ uint m_total_warn_count;
+ enum_diagnostics_status m_status;
+ /**
+ @todo: the following THD members belong here:
+ - warn_list, warn_count,
+ */
+};
+
+
+/**
@class THD
For each client connection we create a separate thread with THD serving as
a thread/connection descriptor
@@ -1179,8 +1295,6 @@ public:
THD_TRANS all; // Trans since BEGIN WORK
THD_TRANS stmt; // Trans for current statement
bool on; // see ha_enable_transaction()
- XID xid; // transaction identifier
- enum xa_states xa_state; // used by external XA only
XID_STATE xid_state;
Rows_log_event *m_pending_rows_event;
@@ -1407,6 +1521,7 @@ public:
List <MYSQL_ERROR> warn_list;
uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
uint total_warn_count;
+ Diagnostics_area main_da;
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
PROFILING profiling;
#endif
@@ -1725,12 +1840,18 @@ public:
CHANGED_TABLE_LIST * changed_table_dup(const char *key, long key_length);
int send_explain_fields(select_result *result);
#ifndef EMBEDDED_LIBRARY
+ /**
+ Clear the current error, if any.
+ We do not clear is_fatal_error or is_fatal_sub_stmt_error since we
+ assume this is never called if the fatal error is set.
+ @todo: To silence an error, one should use Internal_error_handler
+ mechanism. In future this function will be removed.
+ */
inline void clear_error()
{
DBUG_ENTER("clear_error");
- net.last_error[0]= 0;
- net.last_errno= 0;
- net.report_error= 0;
+ if (main_da.is_error())
+ main_da.reset_diagnostics_area();
is_slave_error= 0;
DBUG_VOID_RETURN;
}
@@ -1739,10 +1860,14 @@ public:
void clear_error();
inline bool vio_ok() const { return true; }
#endif
+ /**
+ Mark the current error as fatal. Warning: this does not
+ set any error, it sets a property of the error, so must be
+ followed or prefixed with my_error().
+ */
inline void fatal_error()
{
is_fatal_error= 1;
- net.report_error= 1;
DBUG_PRINT("error",("Fatal error set"));
}
/**
@@ -1758,7 +1883,7 @@ public:
To raise this flag, use my_error().
*/
- inline bool is_error() const { return net.report_error; }
+ inline bool is_error() const { return main_da.is_error(); }
inline CHARSET_INFO *charset() { return variables.character_set_client; }
void update_charset();
@@ -1982,6 +2107,24 @@ private:
};
+/** A short cut for thd->main_da.set_ok_status(). */
+
+inline void
+send_ok(THD *thd, ha_rows affected_rows= 0, ulonglong id= 0,
+ const char *message= NULL)
+{
+ thd->main_da.set_ok_status(thd, affected_rows, id, message);
+}
+
+
+/** A short cut for thd->main_da.set_eof_status(). */
+
+inline void
+send_eof(THD *thd)
+{
+ thd->main_da.set_eof_status(thd);
+}
+
#define tmp_disable_binlog(A) \
{ulonglong tmp_disable_binlog__save_options= (A)->options; \
(A)->options&= ~OPTION_BIN_LOG
@@ -2170,14 +2313,13 @@ class select_insert :public select_result_interceptor {
ulonglong autoinc_value_of_last_inserted_row; // autogenerated or not
COPY_INFO info;
bool insert_into_view;
- bool is_bulk_insert_mode;
select_insert(TABLE_LIST *table_list_par,
TABLE *table_par, List<Item> *fields_par,
List<Item> *update_fields, List<Item> *update_values,
enum_duplicates duplic, bool ignore);
~select_insert();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- int prepare2(void);
+ virtual int prepare2(void);
bool send_data(List<Item> &items);
virtual void store_values(List<Item> &values);
virtual bool can_rollback_data() { return 0; }
@@ -2225,6 +2367,7 @@ public:
// Needed for access from local class MY_HOOKS in prepare(), since thd is proteted.
const THD *get_thd(void) { return thd; }
const HA_CREATE_INFO *get_create_info() { return create_info; };
+ int prepare2(void) { return 0; }
};
#include <myisam.h>
@@ -2519,6 +2662,7 @@ public:
void send_error(uint errcode,const char *err);
int do_deletes();
bool send_eof();
+ virtual void abort();
};
@@ -2559,8 +2703,9 @@ public:
bool send_data(List<Item> &items);
bool initialize_tables (JOIN *join);
void send_error(uint errcode,const char *err);
- int do_updates (bool from_send_error);
+ int do_updates();
bool send_eof();
+ virtual void abort();
};
class my_var : public Sql_alloc {
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 76237576764..309a1c7ab5d 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -948,19 +948,20 @@ bool setup_connection_thread_globals(THD *thd)
bool login_connection(THD *thd)
{
NET *net= &thd->net;
+ int error;
DBUG_ENTER("login_connection");
DBUG_PRINT("info", ("login_connection called by thread %lu",
thd->thread_id));
- net->no_send_error= 0;
-
/* Use "connect_timeout" value during connection phase */
my_net_set_read_timeout(net, connect_timeout);
my_net_set_write_timeout(net, connect_timeout);
- if (check_connection(thd))
+ error= check_connection(thd);
+ net_end_statement(thd);
+
+ if (error)
{ // Wrong permissions
- net_send_error(thd);
#ifdef __NT__
if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
my_sleep(1000); /* must wait after eof() */
@@ -989,13 +990,12 @@ void end_connection(THD *thd)
if (thd->user_connect)
decrease_user_connections(thd->user_connect);
- if (thd->killed ||
- net->error && net->vio != 0 && thd->is_error())
+ if (thd->killed || net->error && net->vio != 0)
{
statistic_increment(aborted_threads,&LOCK_status);
}
- if (net->error && net->vio != 0 && thd->is_error())
+ if (net->error && net->vio != 0)
{
if (!thd->killed && thd->variables.log_warnings > 1)
{
@@ -1005,11 +1005,9 @@ void end_connection(THD *thd)
thd->thread_id,(thd->db ? thd->db : "unconnected"),
sctx->user ? sctx->user : "unauthenticated",
sctx->host_or_ip,
- (net->last_errno ? ER(net->last_errno) :
+ (thd->main_da.is_error() ? thd->main_da.message() :
ER(ER_UNKNOWN_ERROR)));
}
-
- net_send_error(thd, net->last_errno, NullS);
}
}
@@ -1045,24 +1043,14 @@ static void prepare_new_connection_state(THD* thd)
if (sys_init_connect.value_length && !(sctx->master_access & SUPER_ACL))
{
execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
- /*
- execute_init_command calls net_send_error.
- If there was an error during execution of the init statements,
- the error at this moment is present in thd->net.last_error and also
- thd->is_slave_error and thd->net.report_error are set.
- net_send_error sends the contents of thd->net.last_error and
- clears thd->net.report_error. It doesn't, however, clean
- thd->is_slave_error or thd->net.last_error. Here we make use of this
- fact.
- */
- if (thd->is_slave_error)
+ if (thd->is_error())
{
thd->killed= THD::KILL_CONNECTION;
sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
thd->thread_id,(thd->db ? thd->db : "unconnected"),
sctx->user ? sctx->user : "unauthenticated",
sctx->host_or_ip, "init_connect command failed");
- sql_print_warning("%s", thd->net.last_error);
+ sql_print_warning("%s", thd->main_da.message());
}
thd->proc_info=0;
thd->set_time();
@@ -1129,7 +1117,6 @@ pthread_handler_t handle_one_connection(void *arg)
while (!net->error && net->vio != 0 &&
!(thd->killed == THD::KILL_CONNECTION))
{
- net->no_send_error= 0;
if (do_command(thd))
break;
}
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index ad4e0d803eb..f158b5488d0 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -921,6 +921,8 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
{
ha_drop_database(path);
query_cache_invalidate1(db);
+ (void) sp_drop_db_routines(thd, db); /* @todo Do not ignore errors */
+ Events::drop_schema_events(thd, db);
error = 0;
}
}
@@ -956,6 +958,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
/* These DDL methods and logging protected with LOCK_mysql_create_db */
mysql_bin_log.write(&qinfo);
}
+ thd->clear_error();
thd->server_status|= SERVER_STATUS_DB_DROPPED;
send_ok(thd, (ulong) deleted);
thd->server_status&= ~SERVER_STATUS_DB_DROPPED;
@@ -999,8 +1002,6 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
}
exit:
- (void)sp_drop_db_routines(thd, db); /* QQ Ignore errors for now */
- Events::drop_schema_events(thd, db);
/*
If this database was the client's selected database, we silently
change the client's selected database to nothing (to have an empty
@@ -1118,6 +1119,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
VOID(filename_to_tablename(file->name, table_list->table_name,
strlen(file->name) + 1));
table_list->alias= table_list->table_name; // If lower_case_table_names=2
+ table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix);
/* Link into list */
(*tot_list_next)= table_list;
tot_list_next= &table_list->next_local;
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index ff1fe8233df..56748772523 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -728,6 +728,14 @@ void multi_delete::send_error(uint errcode,const char *err)
/* First send error what ever it is ... */
my_message(errcode, err, MYF(0));
+ DBUG_VOID_RETURN;
+}
+
+
+void multi_delete::abort()
+{
+ DBUG_ENTER("multi_delete::abort");
+
/* the error was handled or nothing deleted and no side effects return */
if (error_handled ||
!thd->transaction.stmt.modified_non_trans_table && !deleted)
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index ea7545fe5cb..10b42e11b26 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -147,8 +147,9 @@ exit:
/* Hide "Unknown column" or "Unknown function" error */
if (orig_table_list->view)
{
- if (thd->net.last_errno == ER_BAD_FIELD_ERROR ||
- thd->net.last_errno == ER_SP_DOES_NOT_EXIST)
+ if (thd->is_error() &&
+ (thd->main_da.sql_errno() == ER_BAD_FIELD_ERROR ||
+ thd->main_da.sql_errno() == ER_SP_DOES_NOT_EXIST))
{
thd->clear_error();
my_error(ER_VIEW_INVALID, MYF(0), orig_table_list->db,
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 76cff8bd351..f9dbd402de7 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -574,7 +574,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
bool log_on= ((thd->options & OPTION_BIN_LOG) ||
(!(thd->security_ctx->master_access & SUPER_ACL)));
#endif
- thr_lock_type lock_type = table_list->lock_type;
+ thr_lock_type lock_type;
Item *unused_conds= 0;
DBUG_ENTER("mysql_insert");
@@ -609,6 +609,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
}
+ lock_type= table_list->lock_type;
thd_proc_info(thd, "init");
thd->used_tables=0;
@@ -626,7 +627,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
/* mysql_prepare_insert set table_list->table if it was not set */
table= table_list->table;
- lock_type= table_list->lock_type;
context= &thd->lex->select_lex.context;
/*
@@ -1916,7 +1916,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
main thread. Use of my_message will enable stored
procedures continue handlers.
*/
- my_message(di->thd.net.last_errno, di->thd.net.last_error,
+ my_message(di->thd.main_da.sql_errno(), di->thd.main_da.message(),
MYF(0));
}
di->unlock();
@@ -1993,7 +1993,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
goto error;
if (dead)
{
- my_message(thd.net.last_errno, thd.net.last_error, MYF(0));
+ my_message(thd.main_da.sql_errno(), thd.main_da.message(), MYF(0));
goto error;
}
}
@@ -2252,7 +2252,9 @@ pthread_handler_t handle_delayed_insert(void *arg)
#if !defined( __WIN__) /* Win32 calls this in pthread_create */
if (my_thread_init())
{
- strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES));
+ /* Can't use my_error since store_globals has not yet been called */
+ thd->main_da.set_error_status(thd, ER_OUT_OF_RESOURCES,
+ ER(ER_OUT_OF_RESOURCES));
goto end;
}
#endif
@@ -2261,8 +2263,10 @@ pthread_handler_t handle_delayed_insert(void *arg)
thd->thread_stack= (char*) &thd;
if (init_thr_lock() || thd->store_globals())
{
+ /* Can't use my_error since store_globals has perhaps failed */
+ thd->main_da.set_error_status(thd, ER_OUT_OF_RESOURCES,
+ ER(ER_OUT_OF_RESOURCES));
thd->fatal_error();
- strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES));
goto err;
}
@@ -2665,7 +2669,7 @@ bool Delayed_insert::handle_inserts(void)
{
/* This should never happen */
table->file->print_error(error,MYF(0));
- sql_print_error("%s",thd.net.last_error);
+ sql_print_error("%s", thd.main_da.message());
DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed in loop"));
goto err;
}
@@ -2706,7 +2710,7 @@ bool Delayed_insert::handle_inserts(void)
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
{ // This shouldn't happen
table->file->print_error(error,MYF(0));
- sql_print_error("%s",thd.net.last_error);
+ sql_print_error("%s", thd.main_da.message());
DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed after loop"));
goto err;
}
@@ -2798,8 +2802,7 @@ select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par,
bool ignore_check_option_errors)
:table_list(table_list_par), table(table_par), fields(fields_par),
autoinc_value_of_last_inserted_row(0),
- insert_into_view(table_list_par && table_list_par->view != 0),
- is_bulk_insert_mode(FALSE)
+ insert_into_view(table_list_par && table_list_par->view != 0)
{
bzero((char*) &info,sizeof(info));
info.handle_duplicates= duplic;
@@ -2912,14 +2915,14 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
Is table which we are changing used somewhere in other parts of
query
*/
- if (!(lex->current_select->options & OPTION_BUFFER_RESULT) &&
- unique_table(thd, table_list, table_list->next_global, 0))
+ if (unique_table(thd, table_list, table_list->next_global, 0))
{
/* Using same table for INSERT and SELECT */
lex->current_select->options|= OPTION_BUFFER_RESULT;
lex->current_select->join->select_options|= OPTION_BUFFER_RESULT;
}
- else if (!thd->prelocked_mode)
+ else if (!(lex->current_select->options & OPTION_BUFFER_RESULT) &&
+ !thd->prelocked_mode)
{
/*
We must not yet prepare the result table if it is the same as one of the
@@ -2985,11 +2988,8 @@ int select_insert::prepare2(void)
{
DBUG_ENTER("select_insert::prepare2");
if (thd->lex->current_select->options & OPTION_BUFFER_RESULT &&
- !thd->prelocked_mode && !is_bulk_insert_mode)
- {
+ !thd->prelocked_mode)
table->file->ha_start_bulk_insert((ha_rows) 0);
- is_bulk_insert_mode= TRUE;
- }
DBUG_RETURN(0);
}
@@ -3109,7 +3109,6 @@ bool select_insert::send_eof()
trans_table, table->file->table_type()));
error= (!thd->prelocked_mode) ? table->file->ha_end_bulk_insert():0;
- is_bulk_insert_mode= FALSE;
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
@@ -3561,10 +3560,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
if (info.handle_duplicates == DUP_UPDATE)
table->file->extra(HA_EXTRA_INSERT_WITH_UPDATE);
if (!thd->prelocked_mode)
- {
table->file->ha_start_bulk_insert((ha_rows) 0);
- is_bulk_insert_mode= TRUE;
- }
thd->abort_on_warning= (!info.ignore &&
(thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 7f7c08e7867..ecee3fcb97f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -331,7 +331,6 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
*/
save_vio= thd->net.vio;
thd->net.vio= 0;
- thd->net.no_send_error= 0;
dispatch_command(COM_QUERY, thd,
init_command_var->value,
init_command_var->value_length);
@@ -401,8 +400,8 @@ pthread_handler_t handle_bootstrap(void *arg)
/* purecov: begin tested */
if (net_realloc(&(thd->net), 2 * thd->net.max_packet))
{
- net_send_error(thd, ER_NET_PACKET_TOO_LARGE, NullS);
- thd->fatal_error();
+ net_end_statement(thd);
+ bootstrap_error= 1;
break;
}
buff= (char*) thd->net.buff;
@@ -410,7 +409,7 @@ pthread_handler_t handle_bootstrap(void *arg)
length+= (ulong) strlen(buff + length);
/* purecov: end */
}
- if (thd->is_fatal_error)
+ if (bootstrap_error)
break; /* purecov: inspected */
while (length && (my_isspace(thd->charset(), buff[length-1]) ||
@@ -441,16 +440,11 @@ pthread_handler_t handle_bootstrap(void *arg)
mysql_parse(thd, thd->query, length, & found_semicolon);
close_thread_tables(thd); // Free tables
- if (thd->is_fatal_error)
- break;
+ bootstrap_error= thd->is_error();
+ net_end_statement(thd);
- if (thd->is_error())
- {
- /* The query failed, send error to log and abort bootstrap */
- net_send_error(thd);
- thd->fatal_error();
+ if (bootstrap_error)
break;
- }
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
#ifdef USING_TRANSACTIONS
@@ -459,9 +453,6 @@ pthread_handler_t handle_bootstrap(void *arg)
}
end:
- /* Remember the exit code of bootstrap */
- bootstrap_error= thd->is_fatal_error;
-
net_end(&thd->net);
thd->cleanup();
delete thd;
@@ -495,7 +486,7 @@ end:
(CREATE TABLE, ALTER TABLE ... UNION=(...)). Set TL_WRITE for
every child. Set 'db' for every child if not present.
*/
-
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
static bool check_merge_table_access(THD *thd, char *db,
TABLE_LIST *table_list)
{
@@ -516,7 +507,7 @@ static bool check_merge_table_access(THD *thd, char *db,
}
return error;
}
-
+#endif
/* This works because items are allocated with sql_alloc() */
@@ -720,7 +711,12 @@ bool do_command(THD *thd)
*/
my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
+ /*
+ XXX: this code is here only to clear possible errors of init_connect.
+ Consider moving to init_connect() instead.
+ */
thd->clear_error(); // Clear error message
+ thd->main_da.reset_diagnostics_area();
net_new_transaction(net);
@@ -736,13 +732,16 @@ bool do_command(THD *thd)
/* Check if we can continue without closing the connection */
+ /* The error must be set. */
+ DBUG_ASSERT(thd->is_error());
+ net_end_statement(thd);
+
if (net->error != 3)
{
- return_value= TRUE; // We have to close it.
+ return_value= TRUE; // We have to close it.
goto out;
}
- net_send_error(thd, net->last_errno, NullS);
net->error= 0;
return_value= FALSE;
goto out;
@@ -789,6 +788,73 @@ out:
}
#endif /* EMBEDDED_LIBRARY */
+/**
+ @brief Determine if an attempt to update a non-temporary table while the
+ read-only option was enabled has been made.
+
+ This is a helper function to mysql_execute_command.
+
+ @note SQLCOM_MULTI_UPDATE is an exception and delt with elsewhere.
+
+ @see mysql_execute_command
+ @returns Status code
+ @retval TRUE The statement should be denied.
+ @retval FALSE The statement isn't updating any relevant tables.
+*/
+
+static my_bool deny_updates_if_read_only_option(THD *thd,
+ TABLE_LIST *all_tables)
+{
+ DBUG_ENTER("deny_updates_if_read_only_option");
+
+ if (!opt_readonly)
+ DBUG_RETURN(FALSE);
+
+ LEX *lex= thd->lex;
+
+ const my_bool user_is_super=
+ ((ulong)(thd->security_ctx->master_access & SUPER_ACL) ==
+ (ulong)SUPER_ACL);
+
+ if (user_is_super)
+ DBUG_RETURN(FALSE);
+
+ if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
+ DBUG_RETURN(FALSE);
+
+ /* Multi update is an exception and is dealt with later. */
+ if (lex->sql_command == SQLCOM_UPDATE_MULTI)
+ DBUG_RETURN(FALSE);
+
+ const my_bool create_temp_tables=
+ (lex->sql_command == SQLCOM_CREATE_TABLE) &&
+ (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
+
+ const my_bool drop_temp_tables=
+ (lex->sql_command == SQLCOM_DROP_TABLE) &&
+ lex->drop_temporary;
+
+ const my_bool update_real_tables=
+ some_non_temp_table_to_be_updated(thd, all_tables) &&
+ !(create_temp_tables || drop_temp_tables);
+
+
+ const my_bool create_or_drop_databases=
+ (lex->sql_command == SQLCOM_CREATE_DB) ||
+ (lex->sql_command == SQLCOM_DROP_DB);
+
+ if (update_real_tables || create_or_drop_databases)
+ {
+ /*
+ An attempt was made to modify one or more non-temporary tables.
+ */
+ DBUG_RETURN(TRUE);
+ }
+
+
+ /* Assuming that only temporary tables are modified. */
+ DBUG_RETURN(FALSE);
+}
/**
Perform one connection-level (COM_XXXX) command.
@@ -809,9 +875,8 @@ out:
0 ok
@retval
1 request of thread shutdown, i. e. if command is
- COM_QUIT/COM_SHUTDOWN
+ COM_QUIT/COM_SHUTDOWN
*/
-
bool dispatch_command(enum enum_server_command command, THD *thd,
char* packet, uint packet_length)
{
@@ -890,7 +955,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
db.length= db_len;
tbl_name= strmake(db.str, packet + 1, db_len)+1;
strmake(tbl_name, packet + db_len + 2, tbl_len);
- mysql_table_dump(thd, &db, tbl_name);
+ if (mysql_table_dump(thd, &db, tbl_name) == 0)
+ thd->main_da.disable_status();
break;
}
case COM_CHANGE_USER:
@@ -1057,7 +1123,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
{
char *beginning_of_next_stmt= (char*) end_of_stmt;
- net->no_send_error= 0;
+
+ net_end_statement(thd);
+ query_cache_end_of_result(thd);
/*
Multiple queries exits, execute them individually
*/
@@ -1165,6 +1233,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* We don't calculate statistics for this command */
general_log_print(thd, command, NullS);
net->error=0; // Don't give 'abort' message
+ thd->main_da.disable_status(); // Don't send anything back
error=TRUE; // End server
break;
@@ -1281,16 +1350,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
DBUG_PRINT("quit",("Got shutdown command for level %u", level));
general_log_print(thd, command, NullS);
send_eof(thd);
-#ifdef __WIN__
- sleep(1); // must wait after eof()
-#endif
- /*
- The client is next going to send a COM_QUIT request (as part of
- mysql_close()). Make the life simpler for the client by sending
- the response for the coming COM_QUIT in advance
- */
- send_eof(thd);
- close_connection(thd, 0, 1);
close_thread_tables(thd); // Free before kill
kill_mysql();
error=TRUE;
@@ -1303,13 +1362,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
ulong uptime;
uint length;
ulonglong queries_per_second1000;
-#ifndef EMBEDDED_LIBRARY
char buff[250];
uint buff_len= sizeof(buff);
-#else
- char *buff= thd->net.last_error;
- uint buff_len= sizeof(thd->net.last_error);
-#endif
general_log_print(thd, command, NullS);
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]);
@@ -1331,6 +1385,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
cached_open_tables(),
(uint) (queries_per_second1000 / 1000),
(uint) (queries_per_second1000 % 1000));
+#ifdef EMBEDDED_LIBRARY
+ /* Store the buffer in permanent memory */
+ send_ok(thd, 0, 0, buff);
+#endif
#ifdef SAFEMALLOC
if (sf_malloc_cur_memory) // Using SAFEMALLOC
{
@@ -1343,7 +1401,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif
#ifndef EMBEDDED_LIBRARY
VOID(my_net_write(net, (uchar*) buff, length));
- VOID(net_flush(net));
+ VOID(net_flush(net));
+ thd->main_da.disable_status();
#endif
break;
}
@@ -1423,10 +1482,19 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->transaction.xid_state.xid.null();
/* report error issued during command execution */
- if (thd->killed_errno() && ! thd->is_error())
- thd->send_kill_message();
- if (thd->is_error())
- net_send_error(thd);
+ if (thd->killed_errno())
+ {
+ if (! thd->main_da.is_set())
+ thd->send_kill_message();
+ }
+ if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
+ {
+ thd->killed= THD::NOT_KILLED;
+ thd->mysys_var->abort= 0;
+ }
+
+ net_end_statement(thd);
+ query_cache_end_of_result(thd);
log_slow_statement(thd);
@@ -1505,7 +1573,7 @@ void log_slow_statement(THD *thd)
0 success
@retval
1 out of memory or SHOW commands are not allowed
- in this version of the server.
+ in this version of the server.
*/
int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
@@ -1618,7 +1686,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
Read query from packet and store in thd->query.
Used in COM_QUERY and COM_STMT_PREPARE.
- Sets the following THD variables:
+ Sets the following THD variables:
- query
- query_length
@@ -1810,7 +1878,6 @@ mysql_execute_command(THD *thd)
SELECT_LEX_UNIT *unit= &lex->unit;
/* Saved variable value */
DBUG_ENTER("mysql_execute_command");
- thd->net.no_send_error= 0;
#ifdef WITH_PARTITION_STORAGE_ENGINE
thd->work_part_info= 0;
#endif
@@ -1923,14 +1990,7 @@ mysql_execute_command(THD *thd)
When option readonly is set deny operations which change non-temporary
tables. Except for the replication thread and the 'super' users.
*/
- if (opt_readonly &&
- !(thd->security_ctx->master_access & SUPER_ACL) &&
- (sql_command_flags[lex->sql_command] & CF_CHANGES_DATA) &&
- !((lex->sql_command == SQLCOM_CREATE_TABLE) &&
- (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
- !((lex->sql_command == SQLCOM_DROP_TABLE) && lex->drop_temporary) &&
- ((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
- some_non_temp_table_to_be_updated(thd, all_tables)))
+ if (deny_updates_if_read_only_option(thd, all_tables))
{
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
DBUG_RETURN(-1);
@@ -1944,10 +2004,6 @@ mysql_execute_command(THD *thd)
switch (lex->sql_command) {
case SQLCOM_SHOW_EVENTS:
- if ((res= check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
- is_schema_db(thd->lex->select_lex.db))))
- break;
- /* fall through */
case SQLCOM_SHOW_STATUS_PROC:
case SQLCOM_SHOW_STATUS_FUNC:
res= execute_sqlcom_select(thd, all_tables);
@@ -3060,13 +3116,9 @@ end_with_restore_list:
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
OPTION_SETUP_TABLES_DONE,
del_result, unit, select_lex);
- res|= thd->net.report_error;
- if (unlikely(res))
- {
- /* If we had a another error reported earlier then this will be ignored */
- del_result->send_error(ER_UNKNOWN_ERROR, "Execution of the query failed");
+ res|= thd->is_error();
+ if (res)
del_result->abort();
- }
delete del_result;
}
else
@@ -3999,8 +4051,6 @@ create_sp_error:
goto error;
}
- my_bool save_no_send_ok= thd->net.no_send_ok;
- thd->net.no_send_ok= TRUE;
if (sp->m_flags & sp_head::MULTI_RESULTS)
{
if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
@@ -4010,7 +4060,6 @@ create_sp_error:
back
*/
my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
- thd->net.no_send_ok= save_no_send_ok;
goto error;
}
/*
@@ -4022,14 +4071,11 @@ create_sp_error:
thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
}
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_routine_access(thd, EXECUTE_ACL,
sp->m_db.str, sp->m_name.str, TRUE, FALSE))
{
- thd->net.no_send_ok= save_no_send_ok;
goto error;
}
-#endif
select_limit= thd->variables.select_limit;
thd->variables.select_limit= HA_POS_ERROR;
@@ -4051,7 +4097,6 @@ create_sp_error:
thd->variables.select_limit= select_limit;
- thd->net.no_send_ok= save_no_send_ok;
thd->server_status&= ~bits_to_be_cleared;
if (!res)
@@ -4691,7 +4736,10 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_YES, str.ptr());
}
- result->send_eof();
+ if (res)
+ result->abort();
+ else
+ result->send_eof();
delete result;
}
else
@@ -4708,14 +4756,15 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
}
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
/**
Check grants for commands which work only with one table.
- @param thd Thread handler
- @param privilege requested privilege
- @param all_tables global table list of query
+ @param thd Thread handler
+ @param privilege requested privilege
+ @param all_tables global table list of query
@param no_errors FALSE/TRUE - report/don't report error to
- the client (using my_error() call).
+ the client (using my_error() call).
@retval
0 OK
@@ -4824,7 +4873,6 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
bool dont_check_global_grants, bool no_errors, bool schema_db)
{
Security_context *sctx= thd->security_ctx;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong db_access;
/*
GRANT command:
@@ -4837,7 +4885,6 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
*/
bool db_is_pattern= (test(want_access & GRANT_ACL) &&
dont_check_global_grants);
-#endif
ulong dummy;
DBUG_ENTER("check_access");
DBUG_PRINT("enter",("db: %s want_access: %lu master_access: %lu",
@@ -4877,9 +4924,6 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
}
}
-#ifdef NO_EMBEDDED_ACCESS_CHECKS
- DBUG_RETURN(0);
-#else
if ((sctx->master_access & want_access) == want_access)
{
/*
@@ -4937,7 +4981,6 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
thd->db :
"unknown"))); /* purecov: tested */
DBUG_RETURN(TRUE); /* purecov: tested */
-#endif /* NO_EMBEDDED_ACCESS_CHECKS */
}
@@ -4961,16 +5004,12 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
bool check_global_access(THD *thd, ulong want_access)
{
-#ifdef NO_EMBEDDED_ACCESS_CHECKS
- return 0;
-#else
char command[128];
if ((thd->security_ctx->master_access & want_access))
return 0;
get_privilege_desc(command, sizeof(command), want_access);
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
return 1;
-#endif /* NO_EMBEDDED_ACCESS_CHECKS */
}
@@ -5040,7 +5079,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
@param want_access Privileges requested
@param tables List of tables to be checked
@param no_errors FALSE/TRUE - report/don't report error to
- the client (using my_error() call).
+ the client (using my_error() call).
@note
Table privileges are cached in the table list for GRANT checking.
@@ -5059,9 +5098,7 @@ bool
check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
bool no_errors)
{
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
TABLE_LIST *org_tables= tables;
-#endif
TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
/*
@@ -5148,11 +5185,7 @@ check_routine_access(THD *thd, ulong want_access,char *db, char *name,
0, no_errors, 0))
return TRUE;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
return check_grant_routine(thd, want_access, tables, is_proc, no_errors);
-#else
- return FALSE;
-#endif
}
@@ -5219,6 +5252,7 @@ bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table)
DBUG_RETURN(1);
}
+#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
/****************************************************************************
Check stack size; Send error if there isn't enough stack to continue
@@ -5297,11 +5331,11 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
/**
- Reset THD part responsible for command processing state.
+ Reset THD part responsible for command processing state.
- This needs to be called before execution of every statement
- (prepared or conventional).
- It is not called by substatements of routines.
+ This needs to be called before execution of every statement
+ (prepared or conventional).
+ It is not called by substatements of routines.
@todo
Make it a method of THD and align its name with the rest of
@@ -5314,6 +5348,7 @@ void mysql_reset_thd_for_next_command(THD *thd)
{
DBUG_ENTER("mysql_reset_thd_for_next_command");
DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */
+ DBUG_ASSERT(! thd->in_sub_stmt);
thd->free_list= 0;
thd->select_number= 1;
/*
@@ -5340,18 +5375,18 @@ void mysql_reset_thd_for_next_command(THD *thd)
}
DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
thd->thread_specific_used= FALSE;
- if (!thd->in_sub_stmt)
+
+ if (opt_bin_log)
{
- if (opt_bin_log)
- {
- reset_dynamic(&thd->user_var_events);
- thd->user_var_events_alloc= thd->mem_root;
- }
- thd->clear_error();
- thd->total_warn_count=0; // Warnings for this query
- thd->rand_used= 0;
- thd->sent_row_count= thd->examined_row_count= 0;
+ reset_dynamic(&thd->user_var_events);
+ thd->user_var_events_alloc= thd->mem_root;
}
+ thd->clear_error();
+ thd->main_da.reset_diagnostics_area();
+ thd->total_warn_count=0; // Warnings for this query
+ thd->rand_used= 0;
+ thd->sent_row_count= thd->examined_row_count= 0;
+
/*
Because we come here only for start of top-statements, binlog format is
constant inside a complex statement (using stored functions) etc.
@@ -5586,7 +5621,6 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
/* Actually execute the query */
lex->set_trg_event_type_for_tables();
mysql_execute_command(thd);
- query_cache_end_of_result(thd);
}
}
}
@@ -5819,7 +5853,7 @@ bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
@param ignore_index List of indexed used in IGNORE INDEX
@retval
- 0 Error
+ 0 Error
@retval
\# Pointer to TABLE_LIST element added to the total table list
*/
@@ -6052,7 +6086,7 @@ TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
/**
Nest last join operation.
- The function nest last join operation as if it was enclosed in braces.
+ The function nest last join operation as if it was enclosed in braces.
@param thd current thread
@@ -6139,17 +6173,17 @@ void st_select_lex::add_joined_table(TABLE_LIST *table)
EXAMPLES
@verbatim
- SELECT * FROM t1 RIGHT JOIN t2 ON on_expr =>
- SELECT * FROM t2 LEFT JOIN t1 ON on_expr
+ SELECT * FROM t1 RIGHT JOIN t2 ON on_expr =>
+ SELECT * FROM t2 LEFT JOIN t1 ON on_expr
- SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr =>
- SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr
+ SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr =>
+ SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr
- SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr =>
- SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr
+ SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr =>
+ SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr
- SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3 ON on_expr2 =>
- SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
+ SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3 ON on_expr2 =>
+ SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
@endverbatim
@param thd current thread
@@ -6214,7 +6248,7 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
@varbatim
(SELECT ... ORDER BY LIMIT n) ORDER BY ...
@endvarbatim
-
+
@param thd_arg thread handle
@note
@@ -6303,7 +6337,7 @@ push_new_name_resolution_context(THD *thd,
/**
Add an ON condition to the second operand of a JOIN ... ON.
- Add an ON condition to the right operand of a JOIN ... ON clause.
+ Add an ON condition to the right operand of a JOIN ... ON clause.
@param b the second operand of a JOIN ... ON
@param expr the condition to be added to the ON clause
@@ -6349,17 +6383,17 @@ void add_join_on(TABLE_LIST *b, Item *expr)
EXAMPLE
@verbatim
- SELECT * FROM t1 NATURAL LEFT JOIN t2
- <=>
- SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
+ SELECT * FROM t1 NATURAL LEFT JOIN t2
+ <=>
+ SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
- SELECT * FROM t1 NATURAL JOIN t2 WHERE <some_cond>
- <=>
- SELECT * FROM t1, t2 WHERE (t1.i=t2.i and t1.j=t2.j and <some_cond>)
+ SELECT * FROM t1 NATURAL JOIN t2 WHERE <some_cond>
+ <=>
+ SELECT * FROM t1, t2 WHERE (t1.i=t2.i and t1.j=t2.j and <some_cond>)
- SELECT * FROM t1 JOIN t2 USING(j) WHERE <some_cond>
- <=>
- SELECT * FROM t1, t2 WHERE (t1.j=t2.j and <some_cond>)
+ SELECT * FROM t1 JOIN t2 USING(j) WHERE <some_cond>
+ <=>
+ SELECT * FROM t1, t2 WHERE (t1.j=t2.j and <some_cond>)
@endverbatim
@param a Left join argument
@@ -6418,8 +6452,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
}
if (thd)
{
- (void)acl_reload(thd);
- (void)grant_reload(thd);
+ if (acl_reload(thd))
+ result= 1;
+ if (grant_reload(thd))
+ result= 1;
}
if (tmp_thd)
{
@@ -6509,8 +6545,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
tmp_write_to_binlog= 0;
if (lock_global_read_lock(thd))
return 1; // Killed
- result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1,
- tables);
+ result= close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ?
+ FALSE : TRUE, TRUE);
if (make_global_read_lock_block_commit(thd)) // Killed
{
/* Don't leave things in a half-locked state */
@@ -6519,7 +6555,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
}
}
else
- result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables);
+ result= close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ?
+ FALSE : TRUE, FALSE);
my_dbopt_cleanup();
}
if (options & REFRESH_HOSTS)
@@ -6536,7 +6573,6 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
if (reset_master(thd))
{
result=1;
- thd->fatal_error(); // Ensure client get error
}
}
#endif
@@ -7148,7 +7184,7 @@ Item *negate_expression(THD *thd, Item *expr)
/**
Set the specified definer to the default value, which is the
current user in the thread.
-
+
@param[in] thd thread handler
@param[out] definer definer
*/
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 64f96f342df..ce70e177a85 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -1402,7 +1402,7 @@ static void set_up_partition_func_pointers(partition_info *part_info)
NONE
*/
-static void set_linear_hash_mask(partition_info *part_info, uint no_parts)
+void set_linear_hash_mask(partition_info *part_info, uint no_parts)
{
uint mask;
@@ -2068,6 +2068,7 @@ char *generate_partition_syntax(partition_info *part_info,
default:
DBUG_ASSERT(0);
/* We really shouldn't get here, no use in continuing from here */
+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
current_thd->fatal_error();
DBUG_RETURN(NULL);
}
@@ -2834,8 +2835,8 @@ int get_partition_id_range(partition_info *part_info,
loc_part_id++;
*part_id= (uint32)loc_part_id;
if (loc_part_id == max_partition &&
- range_array[loc_part_id] != LONGLONG_MAX &&
- part_func_value >= range_array[loc_part_id])
+ part_func_value >= range_array[loc_part_id] &&
+ !part_info->defined_max_value)
DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
DBUG_PRINT("exit",("partition: %d", *part_id));
@@ -2941,7 +2942,13 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
}
if (left_endpoint)
{
- if (part_func_value >= range_array[loc_part_id])
+ longlong bound= range_array[loc_part_id];
+ /*
+ In case of PARTITION p VALUES LESS THAN MAXVALUE
+ the maximum value is in the current partition.
+ */
+ if (part_func_value > bound ||
+ (part_func_value == bound && !part_info->defined_max_value))
loc_part_id++;
}
else
@@ -3984,6 +3991,7 @@ static int fast_end_partition(THD *thd, ulonglong copied,
DBUG_RETURN(FALSE);
}
table->file->print_error(error, MYF(0));
+ close_thread_tables(thd);
DBUG_RETURN(TRUE);
}
@@ -6106,7 +6114,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
(error= table->file->repair_partitions(thd))))
{
table->file->print_error(error, MYF(0));
- DBUG_RETURN(TRUE);
+ goto err;
}
}
else if (fast_alter_partition & HA_PARTITION_ONE_PHASE)
@@ -6153,7 +6161,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
if (mysql_write_frm(lpt, WFRM_WRITE_SHADOW | WFRM_PACK_FRM) ||
mysql_change_partitions(lpt))
{
- DBUG_RETURN(TRUE);
+ goto err;
}
}
else if (alter_info->flags == ALTER_DROP_PARTITION)
@@ -6246,7 +6254,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
(release_name_lock(lpt), FALSE))
{
handle_alter_part_error(lpt, not_completed, TRUE, frm_install);
- DBUG_RETURN(TRUE);
+ goto err;
}
}
else if ((alter_info->flags & ALTER_ADD_PARTITION) &&
@@ -6315,7 +6323,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
(release_name_lock(lpt), FALSE))
{
handle_alter_part_error(lpt, not_completed, FALSE, frm_install);
- DBUG_RETURN(TRUE);
+ goto err;
}
}
else
@@ -6408,7 +6416,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
(release_name_lock(lpt), FALSE))
{
handle_alter_part_error(lpt, not_completed, FALSE, frm_install);
- DBUG_RETURN(TRUE);
+ goto err;
}
}
/*
@@ -6418,6 +6426,9 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
DBUG_RETURN(fast_end_partition(thd, lpt->copied, lpt->deleted,
table, table_list, FALSE, NULL,
written_bin_log));
+err:
+ close_thread_tables(thd);
+ DBUG_RETURN(TRUE);
}
#endif
diff --git a/sql/sql_partition.h b/sql/sql_partition.h
index 56f24181b93..282e24f1853 100644
--- a/sql/sql_partition.h
+++ b/sql/sql_partition.h
@@ -65,6 +65,7 @@ int get_part_for_delete(const uchar *buf, const uchar *rec0,
void prune_partition_set(const TABLE *table, part_id_range *part_spec);
bool check_partition_info(partition_info *part_info,handlerton **eng_type,
TABLE *table, handler *file, HA_CREATE_INFO *info);
+void set_linear_hash_mask(partition_info *part_info, uint no_parts);
bool fix_partition_func(THD *thd, TABLE *table, bool create_table_ind);
char *generate_partition_syntax(partition_info *part_info,
uint *buf_length, bool use_sql_alloc,
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index ef4c63381e2..2a86844c8c6 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -181,6 +181,7 @@ public:
TYPELIB* plugin_var_typelib(void);
uchar* value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
bool check(THD *thd, set_var *var);
+ bool check_default(enum_var_type type) { return is_readonly(); }
void set_default(THD *thd, enum_var_type type);
bool update(THD *thd, set_var *var);
};
@@ -1875,11 +1876,26 @@ err:
static int check_func_int(THD *thd, struct st_mysql_sys_var *var,
void *save, st_mysql_value *value)
{
+ bool fixed;
long long tmp;
struct my_option options;
value->val_int(value, &tmp);
plugin_opt_set_limits(&options, var);
- *(int *)save= (int) getopt_ull_limit_value(tmp, &options);
+
+ if (var->flags & PLUGIN_VAR_UNSIGNED)
+ *(uint *)save= (uint) getopt_ull_limit_value((ulonglong) tmp, &options,
+ &fixed);
+ else
+ *(int *)save= (int) getopt_ll_limit_value(tmp, &options, &fixed);
+
+ if (fixed)
+ {
+ char buf[22];
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE), var->name,
+ ullstr(tmp, buf));
+ }
return (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES) &&
(*(int *)save != (int) tmp);
}
@@ -1888,24 +1904,55 @@ static int check_func_int(THD *thd, struct st_mysql_sys_var *var,
static int check_func_long(THD *thd, struct st_mysql_sys_var *var,
void *save, st_mysql_value *value)
{
+ bool fixed;
long long tmp;
struct my_option options;
value->val_int(value, &tmp);
plugin_opt_set_limits(&options, var);
- *(long *)save= (long) getopt_ull_limit_value(tmp, &options);
+
+ if (var->flags & PLUGIN_VAR_UNSIGNED)
+ *(ulong *)save= (ulong) getopt_ull_limit_value((ulonglong) tmp, &options,
+ &fixed);
+ else
+ *(long *)save= (long) getopt_ll_limit_value(tmp, &options, &fixed);
+
+ if (fixed)
+ {
+ char buf[22];
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE), var->name,
+ ullstr(tmp, buf));
+ }
return (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES) &&
(*(long *)save != (long) tmp);
}
static int check_func_longlong(THD *thd, struct st_mysql_sys_var *var,
- void *save, st_mysql_value *value)
+ void *save, st_mysql_value *value)
{
+ bool fixed;
long long tmp;
struct my_option options;
value->val_int(value, &tmp);
plugin_opt_set_limits(&options, var);
- *(ulonglong *)save= getopt_ull_limit_value(tmp, &options);
+ *(ulonglong *)save= getopt_ull_limit_value(tmp, &options, &fixed);
+
+ if (var->flags & PLUGIN_VAR_UNSIGNED)
+ *(ulonglong *)save= getopt_ull_limit_value((ulonglong) tmp, &options,
+ &fixed);
+ else
+ *(longlong *)save= getopt_ll_limit_value(tmp, &options, &fixed);
+
+ if (fixed)
+ {
+ char buf[22];
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE), var->name,
+ ullstr(tmp, buf));
+ }
return (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES) &&
(*(long long *)save != tmp);
}
@@ -2169,9 +2216,11 @@ static st_bookmark *register_var(const char *plugin, const char *name,
size= sizeof(int);
break;
case PLUGIN_VAR_LONG:
+ case PLUGIN_VAR_ENUM:
size= sizeof(long);
break;
case PLUGIN_VAR_LONGLONG:
+ case PLUGIN_VAR_SET:
size= sizeof(ulonglong);
break;
case PLUGIN_VAR_STR:
@@ -2612,6 +2661,7 @@ void sys_var_pluginvar::set_default(THD *thd, enum_var_type type)
if (is_readonly())
return;
+ pthread_mutex_lock(&LOCK_global_system_variables);
tgt= real_value_ptr(thd, type);
src= ((void **) (plugin_var + 1) + 1);
@@ -2628,12 +2678,14 @@ void sys_var_pluginvar::set_default(THD *thd, enum_var_type type)
if (!(plugin_var->flags & PLUGIN_VAR_THDLOCAL) || type == OPT_GLOBAL)
{
- pthread_mutex_lock(&LOCK_plugin);
plugin_var->update(thd, plugin_var, tgt, src);
- pthread_mutex_unlock(&LOCK_plugin);
+ pthread_mutex_unlock(&LOCK_global_system_variables);
}
else
+ {
+ pthread_mutex_unlock(&LOCK_global_system_variables);
plugin_var->update(thd, plugin_var, tgt, src);
+ }
}
@@ -2679,6 +2731,8 @@ bool sys_var_pluginvar::update(THD *thd, set_var *var)
static void plugin_opt_set_limits(struct my_option *options,
const struct st_mysql_sys_var *opt)
{
+ options->sub_size= 0;
+
switch (opt->flags & (PLUGIN_VAR_TYPEMASK |
PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_THDLOCAL)) {
/* global system variables */
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 46890c5d6ea..c0178a231c9 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -234,6 +234,8 @@ static bool send_prep_stmt(Prepared_statement *stmt, uint columns)
NET *net= &stmt->thd->net;
uchar buff[12];
uint tmp;
+ int error;
+ THD *thd= stmt->thd;
DBUG_ENTER("send_prep_stmt");
buff[0]= 0; /* OK packet indicator */
@@ -248,11 +250,16 @@ static bool send_prep_stmt(Prepared_statement *stmt, uint columns)
Send types and names of placeholders to the client
XXX: fix this nasty upcast from List<Item_param> to List<Item>
*/
- DBUG_RETURN(my_net_write(net, buff, sizeof(buff)) ||
- (stmt->param_count &&
- stmt->thd->protocol_text.send_fields((List<Item> *)
- &stmt->lex->param_list,
- Protocol::SEND_EOF)));
+ error= my_net_write(net, buff, sizeof(buff));
+ if (stmt->param_count && ! error)
+ {
+ error= thd->protocol_text.send_fields((List<Item> *)
+ &stmt->lex->param_list,
+ Protocol::SEND_EOF);
+ }
+ /* Flag that a response has already been sent */
+ thd->main_da.disable_status();
+ DBUG_RETURN(error);
}
#else
static bool send_prep_stmt(Prepared_statement *stmt,
@@ -263,6 +270,7 @@ static bool send_prep_stmt(Prepared_statement *stmt,
thd->client_stmt_id= stmt->id;
thd->client_param_count= stmt->param_count;
thd->clear_error();
+ thd->main_da.disable_status();
return 0;
}
@@ -2516,6 +2524,8 @@ void mysql_stmt_close(THD *thd, char *packet)
DBUG_ASSERT(! (stmt->flags & (uint) Prepared_statement::IS_IN_USE));
(void) stmt->deallocate();
+ thd->main_da.disable_status();
+
DBUG_VOID_RETURN;
}
@@ -2576,6 +2586,8 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
DBUG_ENTER("mysql_stmt_get_longdata");
status_var_increment(thd->status_var.com_stmt_send_long_data);
+
+ thd->main_da.disable_status();
#ifndef EMBEDDED_LIBRARY
/* Minimal size of long data packet is 6 bytes */
if (packet_length < MYSQL_LONG_DATA_HEADER)
@@ -2650,11 +2662,7 @@ bool Select_fetch_protocol_binary::send_fields(List<Item> &list, uint flags)
bool Select_fetch_protocol_binary::send_eof()
{
- Protocol *save_protocol= thd->protocol;
-
- thd->protocol= &protocol;
::send_eof(thd);
- thd->protocol= save_protocol;
return FALSE;
}
@@ -3076,7 +3084,6 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
thd->query_length) <= 0)
{
error= mysql_execute_command(thd);
- query_cache_end_of_result(thd);
}
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 6b3f28f09cd..c735f70529e 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -227,6 +227,7 @@ static void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
bool distinct, const char *message=NullS);
static Item *remove_additional_cond(Item* conds);
static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab);
+static bool test_if_ref(Item_field *left_item,Item *right_item);
/**
@@ -691,9 +692,6 @@ err:
without "checking NULL", remove the predicates that were pushed down
into the subquery.
- We can remove the equalities that will be guaranteed to be true by the
- fact that subquery engine will be using index lookup.
-
If the subquery compares scalar values, we can remove the condition that
was wrapped into trig_cond (it will be checked when needed by the subquery
engine)
@@ -703,6 +701,12 @@ err:
and non-NULL values, we'll do a full table scan and will rely on the
equalities corresponding to non-NULL parts of left tuple to filter out
non-matching records.
+
+ TODO: We can remove the equalities that will be guaranteed to be true by the
+ fact that subquery engine will be using index lookup. This must be done only
+ for cases where there are no conversion errors of significance, e.g. 257
+ that is searched in a byte. But this requires homogenization of the return
+ codes of all Field*::store() methods.
*/
void JOIN::remove_subq_pushed_predicates(Item **where)
@@ -710,17 +714,13 @@ void JOIN::remove_subq_pushed_predicates(Item **where)
if (conds->type() == Item::FUNC_ITEM &&
((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
((Item_func *)conds)->arguments()[0]->type() == Item::REF_ITEM &&
- ((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM)
+ ((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM &&
+ test_if_ref ((Item_field *)((Item_func *)conds)->arguments()[1],
+ ((Item_func *)conds)->arguments()[0]))
{
*where= 0;
return;
}
- if (conds->type() == Item::COND_ITEM &&
- ((class Item_func *)this->conds)->functype() ==
- Item_func::COND_AND_FUNC)
- {
- *where= remove_additional_cond(conds);
- }
}
@@ -915,7 +915,6 @@ JOIN::optimize()
}
if (res > 1)
{
- thd->fatal_error();
error= res;
DBUG_PRINT("error",("Error from opt_sum_query"));
DBUG_RETURN(1);
@@ -1283,7 +1282,7 @@ JOIN::optimize()
{
if (!having)
{
- Item *where= 0;
+ Item *where= conds;
if (join_tab[0].type == JT_EQ_REF &&
join_tab[0].ref.items[0]->name == in_left_expr_name)
{
@@ -2410,6 +2409,11 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
{
int error;
DBUG_ENTER("get_quick_record_count");
+#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
+ uchar buff[STACK_BUFF_ALLOC];
+#endif
+ if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
+ DBUG_RETURN(0); // Fatal error flag is set
if (select)
{
select->head=table;
@@ -3791,7 +3795,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
found_eq_constant=0;
for (i=0 ; i < keyuse->elements-1 ; i++,use++)
{
- if (!use->used_tables)
+ if (!use->used_tables && use->optimize != KEY_OPTIMIZE_REF_OR_NULL)
use->table->const_key_parts[use->key]|= use->keypart_map;
if (use->keypart != FT_KEYPART)
{
@@ -10675,7 +10679,8 @@ Next_select_func setup_end_select_func(JOIN *join)
/* Set up select_end */
if (table)
{
- if (table->group && tmp_tbl->sum_func_count)
+ if (table->group && tmp_tbl->sum_func_count &&
+ !tmp_tbl->precomputed_group_by)
{
if (table->s->keys)
{
@@ -12331,8 +12336,12 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
Item *ref_item=part_of_refkey(field->table,field);
if (ref_item && ref_item->eq(right_item,1))
{
+ right_item= right_item->real_item();
if (right_item->type() == Item::FIELD_ITEM)
return (field->eq_def(((Item_field *) right_item)->field));
+ /* remove equalities injected by IN->EXISTS transformation */
+ else if (right_item->type() == Item::CACHE_ITEM)
+ return ((Item_cache *)right_item)->eq_def (field);
if (right_item->const_item() && !(right_item->is_null()))
{
/*
@@ -14589,6 +14598,7 @@ calc_group_buffer(JOIN *join,ORDER *group)
default:
/* This case should never be choosen */
DBUG_ASSERT(0);
+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
join->thd->fatal_error();
}
}
@@ -16052,7 +16062,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
{
if (tab->use_quick == 2)
{
- char buf[MAX_KEY/8+1];
+ /* 4 bits per 1 hex digit + terminating '\0' */
+ char buf[MAX_KEY / 4 + 1];
extra.append(STRING_WITH_LEN("; Range checked for each "
"record (index map: 0x"));
extra.append(tab->keys.print(buf));
diff --git a/sql/sql_select.h b/sql/sql_select.h
index fa036dd8a63..dbeace2ffa4 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -599,14 +599,17 @@ public:
enum store_key_result copy()
{
enum store_key_result result;
- enum_check_fields saved_count_cuted_fields=
- to_field->table->in_use->count_cuted_fields;
+ THD *thd= to_field->table->in_use;
+ enum_check_fields saved_count_cuted_fields= thd->count_cuted_fields;
+ ulong sql_mode= thd->variables.sql_mode;
+ thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
- to_field->table->in_use->count_cuted_fields= CHECK_FIELD_IGNORE;
+ thd->count_cuted_fields= CHECK_FIELD_IGNORE;
result= copy_inner();
- to_field->table->in_use->count_cuted_fields= saved_count_cuted_fields;
+ thd->count_cuted_fields= saved_count_cuted_fields;
+ thd->variables.sql_mode= sql_mode;
return result;
}
diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc
index 602c289a605..8203ca92eed 100644
--- a/sql/sql_servers.cc
+++ b/sql/sql_servers.cc
@@ -239,7 +239,7 @@ bool servers_reload(THD *thd)
if (simple_open_n_lock_tables(thd, tables))
{
sql_print_error("Can't open and lock privilege tables: %s",
- thd->net.last_error);
+ thd->main_da.message());
goto end;
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index df754d82d58..177e84ab0a7 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -578,7 +578,8 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
/* Only one table for now, but VIEW can involve several tables */
if (open_normal_and_derived_tables(thd, table_list, 0))
{
- if (!table_list->view || thd->net.last_errno != ER_VIEW_INVALID)
+ if (!table_list->view ||
+ thd->is_error() && thd->main_da.sql_errno() != ER_VIEW_INVALID)
DBUG_RETURN(TRUE);
/*
@@ -786,10 +787,9 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
}
restore_record(table, s->default_values); // Get empty record
table->use_all_columns();
- if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS |
- Protocol::SEND_EOF))
+ if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS))
DBUG_VOID_RETURN;
- thd->protocol->flush();
+ send_eof(thd);
DBUG_VOID_RETURN;
}
@@ -2919,7 +2919,7 @@ static int fill_schema_table_names(THD *thd, TABLE *table,
default:
DBUG_ASSERT(0);
}
- if (thd->net.last_errno == ER_NO_SUCH_TABLE)
+ if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
{
thd->clear_error();
return 0;
@@ -3267,8 +3267,16 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
res= open_normal_and_derived_tables(thd, show_table_list,
MYSQL_LOCK_IGNORE_FLUSH);
lex->sql_command= save_sql_command;
-
- if (thd->net.last_errno == ER_NO_SUCH_TABLE)
+ /*
+ XXX: show_table_list has a flag i_is_requested,
+ and when it's set, open_normal_and_derived_tables()
+ can return an error without setting an error message
+ in THD, which is a hack. This is why we have to
+ check for res, then for thd->is_error() only then
+ for thd->main_da.sql_errno().
+ */
+ if (res && thd->is_error() &&
+ thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
{
/*
Hide error for not existing table.
@@ -3422,7 +3430,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
/*
there was errors during opening tables
*/
- const char *error= thd->net.last_error;
+ const char *error= thd->main_da.message();
if (tables->view)
table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
else if (tables->schema_table)
@@ -3624,7 +3632,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
rather than in SHOW COLUMNS
*/
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- thd->net.last_errno, thd->net.last_error);
+ thd->main_da.sql_errno(), thd->main_da.message());
thd->clear_error();
res= 0;
}
@@ -4098,9 +4106,9 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables,
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
rather than in SHOW KEYS
*/
- if (thd->net.last_errno)
+ if (thd->is_error())
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- thd->net.last_errno, thd->net.last_error);
+ thd->main_da.sql_errno(), thd->main_da.message());
thd->clear_error();
res= 0;
}
@@ -4290,9 +4298,9 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables,
if (schema_table_store_record(thd, table))
DBUG_RETURN(1);
- if (res && thd->net.last_errno)
+ if (res && thd->is_error())
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- thd->net.last_errno, thd->net.last_error);
+ thd->main_da.sql_errno(), thd->main_da.message());
}
if (res)
thd->clear_error();
@@ -4323,9 +4331,9 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
DBUG_ENTER("get_schema_constraints_record");
if (res)
{
- if (thd->net.last_errno)
+ if (thd->is_error())
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- thd->net.last_errno, thd->net.last_error);
+ thd->main_da.sql_errno(), thd->main_da.message());
thd->clear_error();
DBUG_RETURN(0);
}
@@ -4428,9 +4436,9 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables,
*/
if (res)
{
- if (thd->net.last_errno)
+ if (thd->is_error())
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- thd->net.last_errno, thd->net.last_error);
+ thd->main_da.sql_errno(), thd->main_da.message());
thd->clear_error();
DBUG_RETURN(0);
}
@@ -4511,9 +4519,9 @@ static int get_schema_key_column_usage_record(THD *thd,
DBUG_ENTER("get_schema_key_column_usage_record");
if (res)
{
- if (thd->net.last_errno)
+ if (thd->is_error())
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- thd->net.last_errno, thd->net.last_error);
+ thd->main_da.sql_errno(), thd->main_da.message());
thd->clear_error();
DBUG_RETURN(0);
}
@@ -4706,9 +4714,9 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
if (res)
{
- if (thd->net.last_errno)
+ if (thd->is_error())
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- thd->net.last_errno, thd->net.last_error);
+ thd->main_da.sql_errno(), thd->main_da.message());
thd->clear_error();
DBUG_RETURN(0);
}
@@ -4751,6 +4759,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
break;
default:
DBUG_ASSERT(0);
+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
current_thd->fatal_error();
DBUG_RETURN(1);
}
@@ -5243,9 +5252,9 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
if (res)
{
- if (thd->net.last_errno)
+ if (thd->is_error())
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- thd->net.last_errno, thd->net.last_error);
+ thd->main_da.sql_errno(), thd->main_da.message());
thd->clear_error();
DBUG_RETURN(0);
}
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index a8eb7360339..2e076af45eb 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -846,7 +846,7 @@ outp:
with optional left padding (for binary -> UCS2 conversion)
SYNOPSIS
- well_formed_copy_nhars()
+ well_formed_copy_nchars()
to Store result here
to_length Maxinum length of "to" string
to_cs Character set of "to" string
@@ -983,7 +983,10 @@ outp:
goto outp;
}
else
+ {
+ from= from_prev;
break;
+ }
}
*from_end_pos= from;
res= to - to_start;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 24cd63b8d4b..0f6678a01e8 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -279,7 +279,7 @@ uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
*/
-typedef struct st_global_ddl_log
+struct st_global_ddl_log
{
/*
We need to adjust buffer size to be able to handle downgrades/upgrades
@@ -297,10 +297,12 @@ typedef struct st_global_ddl_log
uint name_len;
uint io_size;
bool inited;
+ bool do_release;
bool recovery_phase;
-} GLOBAL_DDL_LOG;
+ st_global_ddl_log() : inited(false), do_release(false) {}
+};
-GLOBAL_DDL_LOG global_ddl_log;
+st_global_ddl_log global_ddl_log;
pthread_mutex_t LOCK_gdl;
@@ -460,6 +462,7 @@ static uint read_ddl_log_header()
global_ddl_log.first_used= NULL;
global_ddl_log.num_entries= 0;
VOID(pthread_mutex_init(&LOCK_gdl, MY_MUTEX_INIT_FAST));
+ global_ddl_log.do_release= true;
DBUG_RETURN(entry_no);
}
@@ -1150,6 +1153,9 @@ void release_ddl_log()
DDL_LOG_MEMORY_ENTRY *used_list= global_ddl_log.first_used;
DBUG_ENTER("release_ddl_log");
+ if (!global_ddl_log.do_release)
+ DBUG_VOID_RETURN;
+
pthread_mutex_lock(&LOCK_gdl);
while (used_list)
{
@@ -1167,6 +1173,7 @@ void release_ddl_log()
global_ddl_log.inited= 0;
pthread_mutex_unlock(&LOCK_gdl);
VOID(pthread_mutex_destroy(&LOCK_gdl));
+ global_ddl_log.do_release= false;
DBUG_VOID_RETURN;
}
@@ -1241,6 +1248,10 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
char shadow_path[FN_REFLEN+1];
char shadow_frm_name[FN_REFLEN+1];
char frm_name[FN_REFLEN+1];
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ char *part_syntax_buf;
+ uint syntax_len;
+#endif
DBUG_ENTER("mysql_write_frm");
/*
@@ -1264,12 +1275,8 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
#ifdef WITH_PARTITION_STORAGE_ENGINE
{
partition_info *part_info= lpt->table->part_info;
- char *part_syntax_buf;
- uint syntax_len;
-
if (part_info)
{
- TABLE_SHARE *share= lpt->table->s;
if (!(part_syntax_buf= generate_partition_syntax(part_info,
&syntax_len,
TRUE, TRUE)))
@@ -1277,16 +1284,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
DBUG_RETURN(TRUE);
}
part_info->part_info_string= part_syntax_buf;
- share->partition_info_len= part_info->part_info_len= syntax_len;
- if (share->partition_info_buffer_size < syntax_len + 1)
- {
- share->partition_info_buffer_size= syntax_len+1;
- if (!(share->partition_info=
- (char*) alloc_root(&share->mem_root, syntax_len+1)))
- DBUG_RETURN(TRUE);
-
- }
- memcpy((char*) share->partition_info, part_syntax_buf, syntax_len + 1);
+ part_info->part_info_len= syntax_len;
}
}
#endif
@@ -1364,7 +1362,40 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
#endif
{
error= 1;
+ goto err;
+ }
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (part_info)
+ {
+ TABLE_SHARE *share= lpt->table->s;
+ char *tmp_part_syntax_str;
+ if (!(part_syntax_buf= generate_partition_syntax(part_info,
+ &syntax_len,
+ TRUE, TRUE)))
+ {
+ error= 1;
+ goto err;
+ }
+ if (share->partition_info_buffer_size < syntax_len + 1)
+ {
+ share->partition_info_buffer_size= syntax_len+1;
+ if (!(tmp_part_syntax_str= (char*) strmake_root(&share->mem_root,
+ part_syntax_buf,
+ syntax_len)))
+ {
+ error= 1;
+ goto err;
+ }
+ share->partition_info= tmp_part_syntax_str;
+ }
+ else
+ memcpy((char*) share->partition_info, part_syntax_buf, syntax_len + 1);
+ share->partition_info_len= part_info->part_info_len= syntax_len;
+ part_info->part_info_string= part_syntax_buf;
}
+#endif
+
+err:
VOID(pthread_mutex_unlock(&LOCK_open));
#ifdef WITH_PARTITION_STORAGE_ENGINE
deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos);
@@ -1630,8 +1661,9 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
}
alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
/* remove .frm file and engine files */
- path_length= build_table_filename(path, sizeof(path),
- db, alias, reg_ext, 0);
+ path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
+ table->internal_tmp_table ?
+ FN_IS_TMP : 0);
}
if (drop_temporary ||
(table_type == NULL &&
@@ -1662,7 +1694,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
!dont_log_query);
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
(if_exists || table_type == NULL))
+ {
error= 0;
+ thd->clear_error();
+ }
if (error == HA_ERR_ROW_IS_REFERENCED)
{
/* the table is referenced by a foreign key constraint */
@@ -4201,18 +4236,22 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
(table->table->file->ha_check_for_upgrade(check_opt) ==
HA_ADMIN_NEEDS_ALTER))
{
- my_bool save_no_send_ok= thd->net.no_send_ok;
DBUG_PRINT("admin", ("recreating table"));
ha_autocommit_or_rollback(thd, 1);
close_thread_tables(thd);
tmp_disable_binlog(thd); // binlogging is done by caller if wanted
- thd->net.no_send_ok= TRUE;
result_code= mysql_recreate_table(thd, table);
- thd->net.no_send_ok= save_no_send_ok;
reenable_binlog(thd);
+ /*
+ mysql_recreate_table() can push OK or ERROR.
+ Clear 'OK' status. If there is an error, keep it:
+ we will store the error message in a result set row
+ and then clear.
+ */
+ if (thd->main_da.is_ok())
+ thd->main_da.reset_diagnostics_area();
goto send_result;
}
-
}
DBUG_PRINT("admin", ("calling operator_func '%s'", operator_name));
@@ -4306,7 +4345,6 @@ send_result_message:
case HA_ADMIN_TRY_ALTER:
{
- my_bool save_no_send_ok= thd->net.no_send_ok;
/*
This is currently used only by InnoDB. ha_innobase::optimize() answers
"try with alter", so here we close the table, do an ALTER TABLE,
@@ -4318,10 +4356,16 @@ send_result_message:
*save_next_global= table->next_global;
table->next_local= table->next_global= 0;
tmp_disable_binlog(thd); // binlogging is done by caller if wanted
- thd->net.no_send_ok= TRUE;
result_code= mysql_recreate_table(thd, table);
- thd->net.no_send_ok= save_no_send_ok;
reenable_binlog(thd);
+ /*
+ mysql_recreate_table() can push OK or ERROR.
+ Clear 'OK' status. If there is an error, keep it:
+ we will store the error message in a result set row
+ and then clear.
+ */
+ if (thd->main_da.is_ok())
+ thd->main_da.reset_diagnostics_area();
ha_autocommit_or_rollback(thd, 0);
close_thread_tables(thd);
if (!result_code) // recreation went ok
@@ -4332,9 +4376,10 @@ send_result_message:
}
if (result_code) // either mysql_recreate_table or analyze failed
{
- const char *err_msg;
- if ((err_msg= thd->net.last_error))
+ DBUG_ASSERT(thd->is_error());
+ if (thd->is_error())
{
+ const char *err_msg= thd->main_da.message();
if (!thd->vio_ok())
{
sql_print_error(err_msg);
@@ -4350,6 +4395,7 @@ send_result_message:
protocol->store(table_name, system_charset_info);
protocol->store(operator_name, system_charset_info);
}
+ thd->clear_error();
}
}
result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
@@ -4574,6 +4620,55 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* tables)
}
+
+/**
+ @brief Create frm file based on I_S table
+
+ @param[in] thd thread handler
+ @param[in] schema_table I_S table
+ @param[in] dst_path path where frm should be created
+ @param[in] create_info Create info
+
+ @return Operation status
+ @retval 0 success
+ @retval 1 error
+*/
+
+
+bool mysql_create_like_schema_frm(THD* thd, TABLE_LIST* schema_table,
+ char *dst_path, HA_CREATE_INFO *create_info)
+{
+ HA_CREATE_INFO local_create_info;
+ Alter_info alter_info;
+ bool tmp_table= (create_info->options & HA_LEX_CREATE_TMP_TABLE);
+ uint keys= schema_table->table->s->keys;
+ uint db_options= 0;
+ DBUG_ENTER("mysql_create_like_schema_frm");
+
+ bzero((char*) &local_create_info, sizeof(local_create_info));
+ local_create_info.db_type= schema_table->table->s->db_type();
+ local_create_info.row_type= schema_table->table->s->row_type;
+ local_create_info.default_table_charset=default_charset_info;
+ alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
+ schema_table->table->use_all_columns();
+ if (mysql_prepare_alter_table(thd, schema_table->table,
+ &local_create_info, &alter_info))
+ DBUG_RETURN(1);
+ if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
+ tmp_table, &db_options,
+ schema_table->table->file,
+ &schema_table->table->s->key_info, &keys, 0))
+ DBUG_RETURN(1);
+ local_create_info.max_rows= 0;
+ if (mysql_create_frm(thd, dst_path, NullS, NullS,
+ &local_create_info, alter_info.create_list,
+ keys, schema_table->table->s->key_info,
+ schema_table->table->file))
+ DBUG_RETURN(1);
+ DBUG_RETURN(0);
+}
+
+
/*
Create a table identical to the specified table
@@ -4677,7 +4772,15 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
during the call to ha_create_table(). See bug #28614 for more info.
*/
VOID(pthread_mutex_lock(&LOCK_open));
- if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)))
+ if (src_table->schema_table)
+ {
+ if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
+ {
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ goto err;
+ }
+ }
+ else if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)))
{
if (my_errno == ENOENT)
my_error(ER_BAD_DB_ERROR,MYF(0),db);
@@ -5979,7 +6082,8 @@ view_err:
goto err;
new_db_type= create_info->db_type;
- if (new_db_type != old_db_type &&
+ if ((new_db_type != old_db_type ||
+ alter_info->flags & ALTER_PARTITION) &&
!table->file->can_switch_engines())
{
my_error(ER_ROW_IS_REFERENCED, MYF(0));
@@ -6675,7 +6779,7 @@ view_err:
if (thd->locked_tables && new_name == table_name && new_db == db)
{
thd->in_lock_tables= 1;
- error= reopen_tables(thd, 1, 0);
+ error= reopen_tables(thd, 1, 1);
thd->in_lock_tables= 0;
if (error)
goto err_with_placeholders;
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 6f178b6fcc1..78dea6b7cdb 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1696,7 +1696,11 @@ void multi_update::send_error(uint errcode,const char *err)
{
/* First send error what ever it is ... */
my_error(errcode, MYF(0), err);
+}
+
+void multi_update::abort()
+{
/* the error was handled or nothing deleted and no side effects return */
if (error_handled ||
!thd->transaction.stmt.modified_non_trans_table && !updated)
@@ -1725,7 +1729,7 @@ void multi_update::send_error(uint errcode,const char *err)
todo/fixme: do_update() is never called with the arg 1.
should it change the signature to become argless?
*/
- VOID(do_updates(0));
+ VOID(do_updates());
}
}
if (thd->transaction.stmt.modified_non_trans_table)
@@ -1756,7 +1760,7 @@ void multi_update::send_error(uint errcode,const char *err)
}
-int multi_update::do_updates(bool from_send_error)
+int multi_update::do_updates()
{
TABLE_LIST *cur_table;
int local_error= 0;
@@ -1903,7 +1907,6 @@ int multi_update::do_updates(bool from_send_error)
DBUG_RETURN(0);
err:
- if (!from_send_error)
{
thd->fatal_error();
prepare_record_for_error_message(local_error, table);
@@ -1945,7 +1948,7 @@ bool multi_update::send_eof()
Does updates for the last n - 1 tables, returns 0 if ok;
error takes into account killed status gained in do_updates()
*/
- int local_error = (table_count) ? do_updates(0) : 0;
+ int local_error = (table_count) ? do_updates() : 0;
/*
if local_error is not set ON until after do_updates() then
later carried out killing should not affect binlogging.
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index f5ad9205d6f..9fa4f8585f5 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1239,7 +1239,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <variable> internal_variable_name
-%type <select_lex> subselect subselect_init
+%type <select_lex> subselect take_first_select
get_select_lex
%type <boolfunc2creator> comp_op
@@ -11737,37 +11737,22 @@ union_option:
| ALL { $$=0; }
;
-subselect:
- SELECT_SYM subselect_start subselect_init subselect_end
- {
- $$= $3;
- }
- | '(' subselect_start subselect ')'
- {
- THD *thd= YYTHD;
- /*
- note that a local variable can't be used for
- $3 as it's used in local variable construction
- and some compilers can't guarnatee the order
- in which the local variables are initialized.
- */
- List_iterator<Item> it($3->item_list);
- Item *item;
- /*
- we must fill the items list for the "derived table".
- */
- while ((item= it++))
- add_item_to_list(thd, item);
- }
- union_clause subselect_end { $$= $3; }
- ;
+take_first_select: /* empty */
+ {
+ $$= Lex->current_select->master_unit()->first_select();
+ };
-subselect_init:
- select_init2
- {
- $$= Lex->current_select->master_unit()->first_select();
- }
- ;
+subselect:
+ SELECT_SYM subselect_start select_init2 take_first_select
+ subselect_end
+ {
+ $$= $4;
+ }
+ | '(' subselect_start select_paren take_first_select
+ subselect_end ')'
+ {
+ $$= $4;
+ };
subselect_start:
{
diff --git a/sql/table.cc b/sql/table.cc
index 2143faaff5c..cacb3a94582 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1793,13 +1793,18 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
outparam, is_create_table,
share->default_part_db_type,
&work_part_info_used);
- if (!tmp)
- outparam->part_info->is_auto_partitioned= share->auto_partitioned;
+ if (tmp)
+ {
+ thd->stmt_arena= backup_stmt_arena_ptr;
+ thd->restore_active_arena(&part_func_arena, &backup_arena);
+ goto partititon_err;
+ }
+ outparam->part_info->is_auto_partitioned= share->auto_partitioned;
DBUG_PRINT("info", ("autopartitioned: %u", share->auto_partitioned));
/* we should perform the fix_partition_func in either local or
caller's arena depending on work_part_info_used value
*/
- if (!tmp && !work_part_info_used)
+ if (!work_part_info_used)
tmp= fix_partition_func(thd, outparam, is_create_table);
thd->stmt_arena= backup_stmt_arena_ptr;
thd->restore_active_arena(&part_func_arena, &backup_arena);
@@ -1809,6 +1814,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
tmp= fix_partition_func(thd, outparam, is_create_table);
outparam->part_info->item_free_list= part_func_arena.free_list;
}
+partititon_err:
if (tmp)
{
if (is_create_table)
@@ -3275,31 +3281,32 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
}
-/*
+/**
Hide errors which show view underlying table information
- SYNOPSIS
- TABLE_LIST::hide_view_error()
- thd thread handler
+ @param[in,out] thd thread handler
+ @pre This method can be called only if there is an error.
*/
void TABLE_LIST::hide_view_error(THD *thd)
{
/* Hide "Unknown column" or "Unknown function" error */
- if (thd->net.last_errno == ER_BAD_FIELD_ERROR ||
- thd->net.last_errno == ER_SP_DOES_NOT_EXIST ||
- thd->net.last_errno == ER_PROCACCESS_DENIED_ERROR ||
- thd->net.last_errno == ER_COLUMNACCESS_DENIED_ERROR ||
- thd->net.last_errno == ER_TABLEACCESS_DENIED_ERROR ||
- thd->net.last_errno == ER_TABLE_NOT_LOCKED ||
- thd->net.last_errno == ER_NO_SUCH_TABLE)
+ DBUG_ASSERT(thd->is_error());
+
+ if (thd->main_da.sql_errno() == ER_BAD_FIELD_ERROR ||
+ thd->main_da.sql_errno() == ER_SP_DOES_NOT_EXIST ||
+ thd->main_da.sql_errno() == ER_PROCACCESS_DENIED_ERROR ||
+ thd->main_da.sql_errno() == ER_COLUMNACCESS_DENIED_ERROR ||
+ thd->main_da.sql_errno() == ER_TABLEACCESS_DENIED_ERROR ||
+ thd->main_da.sql_errno() == ER_TABLE_NOT_LOCKED ||
+ thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
{
TABLE_LIST *top= top_table();
- thd->clear_error();
+ thd->clear_error();
my_error(ER_VIEW_INVALID, MYF(0), top->view_db.str, top->view_name.str);
}
- else if (thd->net.last_errno == ER_NO_DEFAULT_FOR_FIELD)
+ else if (thd->main_da.sql_errno() == ER_NO_DEFAULT_FOR_FIELD)
{
TABLE_LIST *top= top_table();
thd->clear_error();
diff --git a/sql/table.h b/sql/table.h
index 43070257c69..284885658e0 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1098,6 +1098,7 @@ struct TABLE_LIST
... SELECT implementation).
*/
bool create;
+ bool internal_tmp_table;
/* View creation context. */
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 920f8e87d13..f080c61e243 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -1642,7 +1642,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
if (open_system_tables_for_read(thd, tz_tables, &open_tables_state_backup))
{
sql_print_warning("Can't open and lock time zone table: %s "
- "trying to live without them", thd->net.last_error);
+ "trying to live without them", thd->main_da.message());
/* We will try emulate that everything is ok */
return_val= time_zone_tables_exist= 0;
goto end_with_setting_default_tz;
diff --git a/sql/udf_example.c b/sql/udf_example.c
index 6f2093cc92f..a3d149f0971 100644
--- a/sql/udf_example.c
+++ b/sql/udf_example.c
@@ -648,13 +648,11 @@ my_bool sequence_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
return 1;
}
bzero(initid->ptr,sizeof(longlong));
- /*
- Fool MySQL to think that this function is a constant
- This will ensure that MySQL only evalutes the function
- when the rows are sent to the client and not before any ORDER BY
- clauses
+ /*
+ sequence() is a non-deterministic function : it has different value
+ even if called with the same arguments.
*/
- initid->const_item=1;
+ initid->const_item=0;
return 0;
}
diff --git a/storage/archive/azio.c b/storage/archive/azio.c
index 2cf0fe114d3..cada6c57918 100644
--- a/storage/archive/azio.c
+++ b/storage/archive/azio.c
@@ -262,7 +262,7 @@ void check_header(azio_stream *s)
if (len) s->inbuf[0] = s->stream.next_in[0];
errno = 0;
len = (uInt)my_read(s->file, (uchar *)s->inbuf + len, AZ_BUFSIZE_READ >> len, MYF(0));
- if (len == 0) s->z_err = Z_ERRNO;
+ if (len == (uInt)-1) s->z_err = Z_ERRNO;
s->stream.avail_in += len;
s->stream.next_in = s->inbuf;
if (s->stream.avail_in < 2) {
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 84298e785d1..967e315d4a4 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -357,7 +357,7 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, int *rc)
{
DBUG_RETURN(NULL);
}
- stats.auto_increment_value= archive_tmp.auto_increment;
+ stats.auto_increment_value= archive_tmp.auto_increment + 1;
share->rows_recorded= (ha_rows)archive_tmp.rows;
share->crashed= archive_tmp.dirty;
azclose(&archive_tmp);
@@ -586,9 +586,7 @@ int ha_archive::create(const char *name, TABLE *table_arg,
DBUG_ENTER("ha_archive::create");
- stats.auto_increment_value= (create_info->auto_increment_value ?
- create_info->auto_increment_value -1 :
- (ulonglong) 0);
+ stats.auto_increment_value= create_info->auto_increment_value;
for (uint key= 0; key < table_arg->s->keys; key++)
{
@@ -673,7 +671,8 @@ int ha_archive::create(const char *name, TABLE *table_arg,
Yes you need to do this, because the starting value
for the autoincrement may not be zero.
*/
- create_stream.auto_increment= stats.auto_increment_value;
+ create_stream.auto_increment= stats.auto_increment_value ?
+ stats.auto_increment_value - 1 : 0;
if (azclose(&create_stream))
{
error= errno;
@@ -871,8 +870,8 @@ int ha_archive::write_row(uchar *buf)
else
{
if (temp_auto > share->archive_write.auto_increment)
- stats.auto_increment_value= share->archive_write.auto_increment=
- temp_auto;
+ stats.auto_increment_value=
+ (share->archive_write.auto_increment= temp_auto) + 1;
}
}
@@ -896,7 +895,7 @@ void ha_archive::get_auto_increment(ulonglong offset, ulonglong increment,
ulonglong *first_value,
ulonglong *nb_reserved_values)
{
- *nb_reserved_values= 1;
+ *nb_reserved_values= ULONGLONG_MAX;
*first_value= share->archive_write.auto_increment + 1;
}
@@ -1315,7 +1314,8 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
if (!rc)
{
share->rows_recorded= 0;
- stats.auto_increment_value= share->archive_write.auto_increment= 0;
+ stats.auto_increment_value= 1;
+ share->archive_write.auto_increment= 0;
my_bitmap_map *org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
while (!(rc= get_row(&archive, table->record[0])))
@@ -1332,8 +1332,8 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
(ulonglong) field->val_int(table->record[0] +
field->offset(table->record[0]));
if (share->archive_write.auto_increment < auto_value)
- stats.auto_increment_value= share->archive_write.auto_increment=
- auto_value;
+ stats.auto_increment_value=
+ (share->archive_write.auto_increment= auto_value) + 1;
}
}
@@ -1418,18 +1418,9 @@ void ha_archive::update_create_info(HA_CREATE_INFO *create_info)
DBUG_ENTER("ha_archive::update_create_info");
ha_archive::info(HA_STATUS_AUTO);
- if (create_info->used_fields & HA_CREATE_USED_AUTO)
+ if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
{
- /*
- Internally Archive keeps track of last used, not next used.
- To make the output look like MyISAM we add 1 here.
-
- This is not completely compatible with MYISAM though, since
- MyISAM will record on "SHOW CREATE TABLE" the last position,
- where we will report the original position the table was
- created with.
- */
- create_info->auto_increment_value= stats.auto_increment_value + 1;
+ create_info->auto_increment_value= stats.auto_increment_value;
}
if (!(my_readlink(share->real_path, share->data_file_name, MYF(0))))
@@ -1494,7 +1485,7 @@ int ha_archive::info(uint flag)
pthread_mutex_lock(&share->mutex);
azflush(&archive, Z_SYNC_FLUSH);
pthread_mutex_unlock(&share->mutex);
- stats.auto_increment_value= archive.auto_increment;
+ stats.auto_increment_value= archive.auto_increment + 1;
}
DBUG_RETURN(0);
diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc
index 0d9c019a19d..c9fab79a4c5 100644
--- a/storage/csv/ha_tina.cc
+++ b/storage/csv/ha_tina.cc
@@ -472,14 +472,6 @@ int ha_tina::encode_quote(uchar *buf)
const char *ptr;
const char *end_ptr;
const bool was_null= (*field)->is_null();
-
- /*
- CSV does not support nulls. ::create() prevents creation of a table
- with nullable columns so if we encounter them here, there is a bug.
- This may only occur if the frm was created by an older version of
- mysqld which permitted table creation with nullable columns.
- */
- DBUG_ASSERT(!(*field)->maybe_null());
/*
assistance for backwards compatibility in production builds.
@@ -1494,7 +1486,10 @@ int ha_tina::create(const char *name, TABLE *table_arg,
for (Field **field= table_arg->s->field; *field; field++)
{
if ((*field)->real_maybe_null())
- DBUG_RETURN(-1);
+ {
+ my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "nullable columns");
+ DBUG_RETURN(HA_ERR_UNSUPPORTED);
+ }
}
diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc
index 8673847fcac..091a26f6f36 100644
--- a/storage/federated/ha_federated.cc
+++ b/storage/federated/ha_federated.cc
@@ -2408,6 +2408,24 @@ error:
}
+/*
+ This method is used exlusevely by filesort() to check if we
+ can create sorting buffers of necessary size.
+ If the handler returns more records that it declares
+ here server can just crash on filesort().
+ We cannot guarantee that's not going to happen with
+ the FEDERATED engine, as we have records==0 always if the
+ client is a VIEW, and for the table the number of
+ records can inpredictably change during execution.
+ So we return maximum possible value here.
+*/
+
+ha_rows ha_federated::estimate_rows_upper_bound()
+{
+ return HA_POS_ERROR;
+}
+
+
/* Initialized at each key walk (called multiple times unlike rnd_init()) */
int ha_federated::index_init(uint keynr, bool sorted)
diff --git a/storage/federated/ha_federated.h b/storage/federated/ha_federated.h
index 40bcf9cc402..1974f9936fc 100644
--- a/storage/federated/ha_federated.h
+++ b/storage/federated/ha_federated.h
@@ -210,6 +210,7 @@ public:
int update_row(const uchar *old_data, uchar *new_data);
int delete_row(const uchar *buf);
int index_init(uint keynr, bool sorted);
+ ha_rows estimate_rows_upper_bound();
int index_read(uchar *buf, const uchar *key,
uint key_len, enum ha_rkey_function find_flag);
int index_read_idx(uchar *buf, uint idx, const uchar *key,
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 2703f15373b..e74464a1834 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -1407,10 +1407,8 @@ int ha_myisam::enable_indexes(uint mode)
might have been set by the first repair. They can still be seen
with SHOW WARNINGS then.
*/
-#ifndef EMBEDDED_LIBRARY
if (! error)
thd->clear_error();
-#endif /* EMBEDDED_LIBRARY */
}
info(HA_STATUS_CONST);
thd_proc_info(thd, save_proc_info);
@@ -1653,9 +1651,13 @@ int ha_myisam::index_next_same(uchar *buf,
const uchar *key __attribute__((unused)),
uint length __attribute__((unused)))
{
+ int error;
DBUG_ASSERT(inited==INDEX);
ha_statistic_increment(&SSV::ha_read_next_count);
- int error=mi_rnext_same(file,buf);
+ do
+ {
+ error= mi_rnext_same(file,buf);
+ } while (error == HA_ERR_RECORD_DELETED);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index d9b7033455c..3cc82b832c9 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -455,7 +455,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
if ((!(param->testflag & T_SILENT)))
printf ("- check data record references index: %d\n",key+1);
- if (keyinfo->flag & HA_FULLTEXT)
+ if (keyinfo->flag & (HA_FULLTEXT | HA_SPATIAL))
full_text_keys++;
if (share->state.key_root[key] == HA_OFFSET_ERROR &&
(info->state->records == 0 || keyinfo->flag & HA_FULLTEXT))
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index d7bbfc6a3dd..a4f6e1291db 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -919,7 +919,7 @@ uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
key_blocks=state->header.max_block_size_index;
state->open_count = mi_uint2korr(ptr); ptr +=2;
- state->changed= (bool) *ptr++;
+ state->changed= *ptr++;
state->sortkey = (uint) *ptr++;
state->state.records= mi_rowkorr(ptr); ptr +=8;
state->state.del = mi_rowkorr(ptr); ptr +=8;
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index f91b0dc7a92..3fccb91e9b5 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -730,9 +730,13 @@ int ha_myisammrg::index_next_same(uchar * buf,
const uchar *key __attribute__((unused)),
uint length __attribute__((unused)))
{
+ int error;
DBUG_ASSERT(this->file->children_attached);
ha_statistic_increment(&SSV::ha_read_next_count);
- int error=myrg_rnext_same(file,buf);
+ do
+ {
+ error= myrg_rnext_same(file,buf);
+ } while (error == HA_ERR_RECORD_DELETED);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
@@ -901,7 +905,14 @@ int ha_myisammrg::external_lock(THD *thd, int lock_type)
uint ha_myisammrg::lock_count(void) const
{
- DBUG_ASSERT(this->file->children_attached);
+ /*
+ Return the real lock count even if the children are not attached.
+ This method is used for allocating memory. If we would return 0
+ to another thread (e.g. doing FLUSH TABLE), and attach the children
+ before the other thread calls store_lock(), then we would return
+ more locks in store_lock() than we claimed by lock_count(). The
+ other tread would overrun its memory.
+ */
return file->tables;
}
@@ -911,7 +922,24 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd,
enum thr_lock_type lock_type)
{
MYRG_TABLE *open_table;
- DBUG_ASSERT(this->file->children_attached);
+
+ /*
+ This method can be called while another thread is attaching the
+ children. If the processor reorders instructions or write to memory,
+ 'children_attached' could be set before 'open_tables' has all the
+ pointers to the children. Use of a mutex here and in
+ myrg_attach_children() forces consistent data.
+ */
+ pthread_mutex_lock(&this->file->mutex);
+
+ /*
+ When MERGE table is open, but not yet attached, other threads
+ could flush it, which means call mysql_lock_abort_for_thread()
+ on this threads TABLE. 'children_attached' is FALSE in this
+ situaton. Since the table is not locked, return no lock data.
+ */
+ if (!this->file->children_attached)
+ goto end; /* purecov: tested */
for (open_table=file->open_tables ;
open_table != file->end_table ;
@@ -921,6 +949,9 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd,
if (lock_type != TL_IGNORE && open_table->table->lock.type == TL_UNLOCK)
open_table->table->lock.type=lock_type;
}
+
+ end:
+ pthread_mutex_unlock(&this->file->mutex);
return to;
}
diff --git a/storage/myisammrg/myrg_close.c b/storage/myisammrg/myrg_close.c
index b402a35a253..97216ed47fe 100644
--- a/storage/myisammrg/myrg_close.c
+++ b/storage/myisammrg/myrg_close.c
@@ -58,6 +58,7 @@ int myrg_close(MYRG_INFO *info)
pthread_mutex_lock(&THR_LOCK_open);
myrg_open_list=list_delete(myrg_open_list,&info->open_list);
pthread_mutex_unlock(&THR_LOCK_open);
+ VOID(pthread_mutex_destroy(&info->mutex));
my_free((uchar*) info,MYF(0));
if (error)
{
diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c
index 6fb1888f84d..b5002116164 100644
--- a/storage/myisammrg/myrg_open.c
+++ b/storage/myisammrg/myrg_open.c
@@ -33,7 +33,7 @@
myrg_attach_children(). Please duplicate changes in these
functions or make common sub-functions.
*/
-/* purecov: begin unused */
+/* purecov: begin deadcode */ /* not used in MySQL server */
MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
{
@@ -171,6 +171,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
VOID(my_close(fd,MYF(0)));
end_io_cache(&file);
+ VOID(pthread_mutex_init(&m_info->mutex, MY_MUTEX_INIT_FAST));
m_info->open_list.data=(void*) m_info;
pthread_mutex_lock(&THR_LOCK_open);
myrg_open_list=list_add(myrg_open_list,&m_info->open_list);
@@ -328,6 +329,7 @@ MYRG_INFO *myrg_parent_open(const char *parent_name,
end_io_cache(&file_cache);
VOID(my_close(fd, MYF(0)));
+ VOID(pthread_mutex_init(&m_info->mutex, MY_MUTEX_INIT_FAST));
m_info->open_list.data= (void*) m_info;
pthread_mutex_lock(&THR_LOCK_open);
@@ -393,6 +395,14 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking,
DBUG_ENTER("myrg_attach_children");
DBUG_PRINT("myrg", ("handle_locking: %d", handle_locking));
+ /*
+ This function can be called while another thread is trying to abort
+ locks of this MERGE table. If the processor reorders instructions or
+ write to memory, 'children_attached' could be set before
+ 'open_tables' has all the pointers to the children. Use of a mutex
+ here and in ha_myisammrg::store_lock() forces consistent data.
+ */
+ pthread_mutex_lock(&m_info->mutex);
rc= 1;
errpos= 0;
file_offset= 0;
@@ -464,6 +474,7 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking,
m_info->keys= min_keys;
m_info->last_used_table= m_info->open_tables;
m_info->children_attached= TRUE;
+ pthread_mutex_unlock(&m_info->mutex);
DBUG_RETURN(0);
err:
@@ -473,6 +484,7 @@ err:
my_free((char*) m_info->rec_per_key_part, MYF(0));
m_info->rec_per_key_part= NULL;
}
+ pthread_mutex_unlock(&m_info->mutex);
my_errno= save_errno;
DBUG_RETURN(1);
}
@@ -494,6 +506,8 @@ err:
int myrg_detach_children(MYRG_INFO *m_info)
{
DBUG_ENTER("myrg_detach_children");
+ /* For symmetry with myrg_attach_children() we use the mutex here. */
+ pthread_mutex_lock(&m_info->mutex);
if (m_info->tables)
{
/* Do not attach/detach an empty child list. */
@@ -504,6 +518,7 @@ int myrg_detach_children(MYRG_INFO *m_info)
m_info->del= 0;
m_info->data_file_length= 0;
m_info->options= 0;
+ pthread_mutex_unlock(&m_info->mutex);
DBUG_RETURN(0);
}
diff --git a/storage/ndb/include/kernel/signaldata/TcKeyRef.hpp b/storage/ndb/include/kernel/signaldata/TcKeyRef.hpp
index 2846ce3854f..56f6cdae29d 100644
--- a/storage/ndb/include/kernel/signaldata/TcKeyRef.hpp
+++ b/storage/ndb/include/kernel/signaldata/TcKeyRef.hpp
@@ -40,12 +40,13 @@ class TcKeyRef {
friend bool printTCKEYREF(FILE *, const Uint32 *, Uint32, Uint16);
public:
- STATIC_CONST( SignalLength = 4 );
+ STATIC_CONST( SignalLength = 5 );
private:
Uint32 connectPtr;
Uint32 transId[2];
Uint32 errorCode;
+ Uint32 errorData;
};
#endif
diff --git a/storage/ndb/include/kernel/signaldata/TcRollbackRep.hpp b/storage/ndb/include/kernel/signaldata/TcRollbackRep.hpp
index 3b5e2f3d3cb..609756605d5 100644
--- a/storage/ndb/include/kernel/signaldata/TcRollbackRep.hpp
+++ b/storage/ndb/include/kernel/signaldata/TcRollbackRep.hpp
@@ -38,12 +38,13 @@ class TcRollbackRep {
friend bool printTCROLBACKREP(FILE *, const Uint32 *, Uint32, Uint16);
public:
- STATIC_CONST( SignalLength = 4 );
+ STATIC_CONST( SignalLength = 5 );
private:
Uint32 connectPtr;
Uint32 transId[2];
Uint32 returnCode;
+ Uint32 errorData;
};
#endif
diff --git a/storage/ndb/include/ndbapi/NdbDictionary.hpp b/storage/ndb/include/ndbapi/NdbDictionary.hpp
index 58882e139fd..0e782ba9214 100644
--- a/storage/ndb/include/ndbapi/NdbDictionary.hpp
+++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp
@@ -1020,7 +1020,7 @@ public:
* Get the name of the table being indexed
*/
const char * getTable() const;
-
+
/**
* Get the number of columns in the index
*/
diff --git a/storage/ndb/src/common/transporter/Transporter.cpp b/storage/ndb/src/common/transporter/Transporter.cpp
index cec018575e0..269a5fba4e9 100644
--- a/storage/ndb/src/common/transporter/Transporter.cpp
+++ b/storage/ndb/src/common/transporter/Transporter.cpp
@@ -70,7 +70,7 @@ Transporter::Transporter(TransporterRegistry &t_reg,
signalIdUsed = _signalId;
m_connected = false;
- m_timeOutMillis = 1000;
+ m_timeOutMillis = 30000;
m_connect_address.s_addr= 0;
if(s_port<0)
@@ -101,7 +101,7 @@ Transporter::connect_server(NDB_SOCKET_TYPE sockfd) {
if(m_connected)
{
- DBUG_RETURN(true); // TODO assert(0);
+ DBUG_RETURN(false); // TODO assert(0);
}
{
diff --git a/storage/ndb/src/common/transporter/TransporterRegistry.cpp b/storage/ndb/src/common/transporter/TransporterRegistry.cpp
index 5f5f3c17b2d..848738b2983 100644
--- a/storage/ndb/src/common/transporter/TransporterRegistry.cpp
+++ b/storage/ndb/src/common/transporter/TransporterRegistry.cpp
@@ -758,7 +758,8 @@ TransporterRegistry::poll_TCP(Uint32 timeOutMillis)
TCP_Transporter * t = theTCPTransporters[i];
// If the transporter is connected
- if (t->isConnected()) {
+ NodeId nodeId = t->getRemoteNodeId();
+ if (is_connected(nodeId) && t->isConnected()) {
const NDB_SOCKET_TYPE socket = t->getSocket();
// Find the highest socket value. It will be used by select
diff --git a/storage/ndb/src/kernel/blocks/ERROR_codes.txt b/storage/ndb/src/kernel/blocks/ERROR_codes.txt
index 4d4d4fcafc4..72791cb0ebc 100644
--- a/storage/ndb/src/kernel/blocks/ERROR_codes.txt
+++ b/storage/ndb/src/kernel/blocks/ERROR_codes.txt
@@ -5,7 +5,7 @@ Next DBACC 3002
Next DBTUP 4029
Next DBLQH 5047
Next DBDICT 6008
-Next DBDIH 7193
+Next DBDIH 7195
Next DBTC 8054
Next CMVMI 9000
Next BACKUP 10038
@@ -81,6 +81,11 @@ Delay GCP_SAVEREQ by 10 secs
7185: Dont reply to COPY_GCI_REQ where reason == GCP
+7193: Dont send LCP_FRAG_ORD to self, and crash when sending first
+ LCP_FRAG_ORD(last)
+
+7194: Force removeNodeFromStored to complete in the middle of MASTER_LCPCONF
+
ERROR CODES FOR TESTING NODE FAILURE, LOCAL CHECKPOINT HANDLING:
-----------------------------------------------------------------
diff --git a/storage/ndb/src/kernel/blocks/backup/Backup.cpp b/storage/ndb/src/kernel/blocks/backup/Backup.cpp
index 64e2c41aa69..45501bf50d5 100644
--- a/storage/ndb/src/kernel/blocks/backup/Backup.cpp
+++ b/storage/ndb/src/kernel/blocks/backup/Backup.cpp
@@ -1026,8 +1026,9 @@ Backup::execINCL_NODEREQ(Signal* signal)
break;
}//if
}//for
- signal->theData[0] = reference();
- sendSignal(senderRef, GSN_INCL_NODECONF, signal, 1, JBB);
+ signal->theData[0] = inclNode;
+ signal->theData[1] = reference();
+ sendSignal(senderRef, GSN_INCL_NODECONF, signal, 2, JBB);
}
/*****************************************************************************
diff --git a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
index 3406176d7a8..6c869435bfa 100644
--- a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
+++ b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
@@ -421,9 +421,10 @@ void Cmvmi::execCLOSE_COMREQ(Signal* signal)
// Uint32 noOfNodes = closeCom->noOfNodes;
jamEntry();
- for (unsigned i = 0; i < MAX_NODES; i++){
- if(NodeBitmask::get(closeCom->theNodes, i)){
-
+ for (unsigned i = 0; i < MAX_NODES; i++)
+ {
+ if(NodeBitmask::get(closeCom->theNodes, i))
+ {
jam();
//-----------------------------------------------------
@@ -437,7 +438,9 @@ void Cmvmi::execCLOSE_COMREQ(Signal* signal)
globalTransporterRegistry.do_disconnect(i);
}
}
- if (failNo != 0) {
+
+ if (failNo != 0)
+ {
jam();
signal->theData[0] = userRef;
signal->theData[1] = failNo;
@@ -456,13 +459,21 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal)
jamEntry();
const Uint32 len = signal->getLength();
- if(len == 2){
-
+ if(len == 2)
+ {
#ifdef ERROR_INSERT
if (! ((ERROR_INSERTED(9000) || ERROR_INSERTED(9002))
&& c_error_9000_nodes_mask.get(tStartingNode)))
#endif
{
+ if (globalData.theStartLevel != NodeState::SL_STARTED &&
+ (getNodeInfo(tStartingNode).m_type != NodeInfo::DB &&
+ getNodeInfo(tStartingNode).m_type != NodeInfo::MGM))
+ {
+ jam();
+ goto done;
+ }
+
globalTransporterRegistry.do_connect(tStartingNode);
globalTransporterRegistry.setIOState(tStartingNode, HaltIO);
@@ -475,9 +486,11 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal)
//-----------------------------------------------------
}
} else {
- for(unsigned int i = 1; i < MAX_NODES; i++ ) {
+ for(unsigned int i = 1; i < MAX_NODES; i++ )
+ {
jam();
- if (i != getOwnNodeId() && getNodeInfo(i).m_type == tData2){
+ if (i != getOwnNodeId() && getNodeInfo(i).m_type == tData2)
+ {
jam();
#ifdef ERROR_INSERT
@@ -496,6 +509,7 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal)
}
}
+done:
if (userRef != 0) {
jam();
signal->theData[0] = tStartingNode;
@@ -536,24 +550,10 @@ void Cmvmi::execDISCONNECT_REP(Signal *signal)
setNodeInfo(hostId).m_connectCount++;
const NodeInfo::NodeType type = getNodeInfo(hostId).getType();
ndbrequire(type != NodeInfo::INVALID);
-
- if(type == NodeInfo::DB || globalData.theStartLevel == NodeState::SL_STARTED){
- jam();
- DisconnectRep * const rep = (DisconnectRep *)&signal->theData[0];
- rep->nodeId = hostId;
- rep->err = errNo;
- sendSignal(QMGR_REF, GSN_DISCONNECT_REP, signal,
- DisconnectRep::SignalLength, JBA);
- } else if((globalData.theStartLevel == NodeState::SL_CMVMI ||
- globalData.theStartLevel == NodeState::SL_STARTING)
- && type == NodeInfo::MGM) {
- /**
- * Someone disconnected during cmvmi period
- */
- jam();
- globalTransporterRegistry.do_connect(hostId);
- }
+ sendSignal(QMGR_REF, GSN_DISCONNECT_REP, signal,
+ DisconnectRep::SignalLength, JBA);
+
cancelSubscription(hostId);
signal->theData[0] = NDB_LE_Disconnected;
@@ -587,6 +587,8 @@ void Cmvmi::execCONNECT_REP(Signal *signal){
*/
if(type == NodeInfo::MGM){
jam();
+ signal->theData[0] = hostId;
+ sendSignal(QMGR_REF, GSN_CONNECT_REP, signal, 1, JBA);
} else {
/**
* Dont allow api nodes to connect
@@ -802,6 +804,8 @@ Cmvmi::execSTART_ORD(Signal* signal) {
}
}
}
+
+ EXECUTE_DIRECT(QMGR, GSN_START_ORD, signal, 1);
return ;
}
@@ -829,9 +833,6 @@ Cmvmi::execSTART_ORD(Signal* signal) {
*
* Do Restart
*/
-
- globalScheduler.clear();
- globalTimeQueue.clear();
// Disconnect all nodes as part of the system restart.
// We need to ensure that we are starting up
diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
index 569958a6aa9..7ced078144a 100644
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
@@ -3825,8 +3825,9 @@ void Dbdict::execINCL_NODEREQ(Signal* signal)
c_nodes.getPtr(nodePtr);
ndbrequire(nodePtr.p->nodeState == NodeRecord::NDB_NODE_DEAD);
nodePtr.p->nodeState = NodeRecord::NDB_NODE_ALIVE;
- signal->theData[0] = reference();
- sendSignal(retRef, GSN_INCL_NODECONF, signal, 1, JBB);
+ signal->theData[0] = nodePtr.i;
+ signal->theData[1] = reference();
+ sendSignal(retRef, GSN_INCL_NODECONF, signal, 2, JBB);
c_aliveNodes.set(nodePtr.i);
}//execINCL_NODEREQ()
diff --git a/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp b/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
index 21826df28f9..b0bbdefff55 100644
--- a/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
+++ b/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
@@ -1310,7 +1310,17 @@ private:
LcpStatus lcpStatus;
Uint32 lcpStatusUpdatedPlace;
+ struct Save {
+ LcpStatus m_status;
+ Uint32 m_place;
+ } m_saveState[10];
+
void setLcpStatus(LcpStatus status, Uint32 line){
+ for (Uint32 i = 9; i > 0; i--)
+ m_saveState[i] = m_saveState[i-1];
+ m_saveState[0].m_status = lcpStatus;
+ m_saveState[0].m_place = lcpStatusUpdatedPlace;
+
lcpStatus = status;
lcpStatusUpdatedPlace = line;
}
diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
index 5403ac5cc38..bbacb300089 100644
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
@@ -2135,12 +2135,9 @@ void Dbdih::gcpBlockedLab(Signal* signal)
/*---------------------------------------------------------------------------*/
void Dbdih::execINCL_NODECONF(Signal* signal)
{
- Uint32 TsendNodeId;
- Uint32 TstartNode_or_blockref;
-
jamEntry();
- TstartNode_or_blockref = signal->theData[0];
- TsendNodeId = signal->theData[1];
+ Uint32 TstartNode = signal->theData[0];
+ Uint32 TsendNodeId_or_blockref = signal->theData[1];
Uint32 blocklist[6];
blocklist[0] = clocallqhblockref;
@@ -2152,9 +2149,21 @@ void Dbdih::execINCL_NODECONF(Signal* signal)
for (Uint32 i = 0; blocklist[i] != 0; i++)
{
- if (TstartNode_or_blockref == blocklist[i])
+ if (TsendNodeId_or_blockref == blocklist[i])
{
jam();
+
+ if (TstartNode != c_nodeStartSlave.nodeId)
+ {
+ jam();
+ warningEvent("Recevied INCL_NODECONF for %u from %s"
+ " while %u is starting",
+ TstartNode,
+ getBlockName(refToBlock(TsendNodeId_or_blockref)),
+ c_nodeStartSlave.nodeId);
+ return;
+ }
+
if (getNodeStatus(c_nodeStartSlave.nodeId) == NodeRecord::ALIVE &&
blocklist[i+1] != 0)
{
@@ -2182,10 +2191,21 @@ void Dbdih::execINCL_NODECONF(Signal* signal)
}
}
}
+
+ if (c_nodeStartMaster.startNode != TstartNode)
+ {
+ jam();
+ warningEvent("Recevied INCL_NODECONF for %u from %u"
+ " while %u is starting",
+ TstartNode,
+ TsendNodeId_or_blockref,
+ c_nodeStartMaster.startNode);
+ return;
+ }
ndbrequire(cmasterdihref = reference());
- receiveLoopMacro(INCL_NODEREQ, TsendNodeId);
-
+ receiveLoopMacro(INCL_NODEREQ, TsendNodeId_or_blockref);
+
CRASH_INSERTION(7128);
/*-------------------------------------------------------------------------*/
// Now that we have included the starting node in the node lists in the
@@ -5181,11 +5201,19 @@ void Dbdih::startRemoveFailedNode(Signal* signal, NodeRecordPtr failedNodePtr)
}
jam();
- signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
- signal->theData[1] = failedNodePtr.i;
- signal->theData[2] = 0; // Tab id
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
-
+
+ if (!ERROR_INSERTED(7194))
+ {
+ signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
+ signal->theData[1] = failedNodePtr.i;
+ signal->theData[2] = 0; // Tab id
+ sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
+ }
+ else
+ {
+ ndbout_c("7194 Not starting ZREMOVE_NODE_FROM_TABLE");
+ }
+
setLocalNodefailHandling(signal, failedNodePtr.i, NF_REMOVE_NODE_FROM_TABLE);
}//Dbdih::startRemoveFailedNode()
@@ -6114,12 +6142,22 @@ Dbdih::checkEmptyLcpComplete(Signal *signal){
signal->theData[0] = 7012;
execDUMP_STATE_ORD(signal);
+
+ if (ERROR_INSERTED(7194))
+ {
+ ndbout_c("7194 starting ZREMOVE_NODE_FROM_TABLE");
+ signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
+ signal->theData[1] = c_lcpMasterTakeOverState.failedNodeId;
+ signal->theData[2] = 0; // Tab id
+ sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
+ }
c_lcpMasterTakeOverState.set(LMTOS_INITIAL, __LINE__);
MasterLCPReq * const req = (MasterLCPReq *)&signal->theData[0];
req->masterRef = reference();
req->failedNodeId = c_lcpMasterTakeOverState.failedNodeId;
sendLoopMacro(MASTER_LCPREQ, sendMASTER_LCPREQ);
+
} else {
sendMASTER_LCPCONF(signal);
}
@@ -6141,7 +6179,7 @@ void Dbdih::execMASTER_LCPREQ(Signal* signal)
jam();
ndbout_c("resending GSN_MASTER_LCPREQ");
sendSignalWithDelay(reference(), GSN_MASTER_LCPREQ, signal,
- signal->getLength(), 50);
+ 50, signal->getLength());
return;
}
Uint32 failedNodeId = req->failedNodeId;
@@ -6432,6 +6470,15 @@ void Dbdih::execMASTER_LCPCONF(Signal* signal)
{
const MasterLCPConf * const conf = (MasterLCPConf *)&signal->theData[0];
jamEntry();
+
+ if (ERROR_INSERTED(7194))
+ {
+ ndbout_c("delaying MASTER_LCPCONF due to error 7194");
+ sendSignalWithDelay(reference(), GSN_MASTER_LCPCONF, signal,
+ 300, signal->getLength());
+ return;
+ }
+
Uint32 senderNodeId = conf->senderNodeId;
MasterLCPConf::State lcpState = (MasterLCPConf::State)conf->lcpState;
const Uint32 failedNodeId = conf->failedNodeId;
@@ -6566,7 +6613,6 @@ void Dbdih::MASTER_LCPhandling(Signal* signal, Uint32 failedNodeId)
#endif
c_lcpState.keepGci = SYSFILE->keepGCI;
- c_lcpState.setLcpStatus(LCP_START_LCP_ROUND, __LINE__);
startLcpRoundLoopLab(signal, 0, 0);
break;
}
@@ -10538,6 +10584,8 @@ void Dbdih::sendLastLCP_FRAG_ORD(Signal* signal)
if(ERROR_INSERTED(7075)){
continue;
}
+
+ CRASH_INSERTION(7193);
BlockReference ref = calcLqhBlockRef(nodePtr.i);
sendSignal(ref, GSN_LCP_FRAG_ORD, signal,LcpFragOrd::SignalLength, JBB);
}
@@ -10650,6 +10698,12 @@ void Dbdih::execLCP_FRAG_REP(Signal* signal)
Uint32 started = lcpReport->maxGciStarted;
Uint32 completed = lcpReport->maxGciCompleted;
+ if (started > c_lcpState.lcpStopGcp)
+ {
+ jam();
+ c_lcpState.lcpStopGcp = started;
+ }
+
if(tableDone){
jam();
@@ -10765,6 +10819,13 @@ Dbdih::checkLcpAllTablesDoneInLqh(){
CRASH_INSERTION2(7017, !isMaster());
c_lcpState.setLcpStatus(LCP_TAB_COMPLETED, __LINE__);
+
+ if (ERROR_INSERTED(7194))
+ {
+ ndbout_c("CLEARING 7194");
+ CLEAR_ERROR_INSERT_VALUE;
+ }
+
return true;
}
@@ -10954,6 +11015,11 @@ Dbdih::sendLCP_FRAG_ORD(Signal* signal,
BlockReference ref = calcLqhBlockRef(replicaPtr.p->procNode);
+ if (ERROR_INSERTED(7193) && replicaPtr.p->procNode == getOwnNodeId())
+ {
+ return;
+ }
+
LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0];
lcpFragOrd->tableId = info.tableId;
lcpFragOrd->fragmentId = info.fragId;
@@ -11178,7 +11244,12 @@ void Dbdih::allNodesLcpCompletedLab(Signal* signal)
signal->theData[0] = NDB_LE_LocalCheckpointCompleted; //Event type
signal->theData[1] = SYSFILE->latestLCP_ID;
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
- c_lcpState.lcpStopGcp = c_newest_restorable_gci;
+
+ if (c_newest_restorable_gci > c_lcpState.lcpStopGcp)
+ {
+ jam();
+ c_lcpState.lcpStopGcp = c_newest_restorable_gci;
+ }
/**
* Start checking for next LCP
@@ -12048,13 +12119,12 @@ void Dbdih::findMinGci(ReplicaRecordPtr fmgReplicaPtr,
lcpNo = fmgReplicaPtr.p->nextLcp;
do {
ndbrequire(lcpNo < MAX_LCP_STORED);
- if (fmgReplicaPtr.p->lcpStatus[lcpNo] == ZVALID &&
- fmgReplicaPtr.p->maxGciStarted[lcpNo] < c_newest_restorable_gci)
+ if (fmgReplicaPtr.p->lcpStatus[lcpNo] == ZVALID)
{
jam();
keepGci = fmgReplicaPtr.p->maxGciCompleted[lcpNo];
oldestRestorableGci = fmgReplicaPtr.p->maxGciStarted[lcpNo];
- ndbrequire(((int)oldestRestorableGci) >= 0);
+ ndbassert(fmgReplicaPtr.p->maxGciStarted[lcpNo] <c_newest_restorable_gci);
return;
} else {
jam();
@@ -12956,6 +13026,7 @@ void Dbdih::newCrashedReplica(Uint32 nodeId, ReplicaRecordPtr ncrReplicaPtr)
void Dbdih::nodeResetStart()
{
jam();
+ c_nodeStartSlave.nodeId = 0;
c_nodeStartMaster.startNode = RNIL;
c_nodeStartMaster.failNr = cfailurenr;
c_nodeStartMaster.activeState = false;
@@ -14500,6 +14571,14 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal)
("immediateLcpStart = %d masterLcpNodeId = %d",
c_lcpState.immediateLcpStart,
refToNode(c_lcpState.m_masterLcpDihRef));
+
+ for (Uint32 i = 0; i<10; i++)
+ {
+ infoEvent("%u : status: %u place: %u", i,
+ c_lcpState.m_saveState[i].m_status,
+ c_lcpState.m_saveState[i].m_place);
+ }
+
infoEvent("-- Node %d LCP STATE --", getOwnNodeId());
}
diff --git a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
index 95cad98b81c..62add0cf503 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
@@ -585,7 +585,6 @@ public:
enum ExecSrStatus {
IDLE = 0,
- ACTIVE_REMOVE_AFTER = 1,
ACTIVE = 2
};
/**
@@ -869,11 +868,6 @@ public:
* heard of.
*/
Uint8 fragDistributionKey;
- /**
- * The identity of the next local checkpoint this fragment
- * should perform.
- */
- Uint8 nextLcp;
/**
* How many local checkpoints does the fragment contain
*/
@@ -2097,10 +2091,6 @@ private:
void execEXEC_SRCONF(Signal* signal);
void execREAD_PSEUDO_REQ(Signal* signal);
- void build_acc(Signal*, Uint32 fragPtrI);
- void execBUILDINDXREF(Signal*signal);
- void execBUILDINDXCONF(Signal*signal);
-
void execDUMP_STATE_ORD(Signal* signal);
void execACC_ABORTCONF(Signal* signal);
void execNODE_FAILREP(Signal* signal);
@@ -2780,7 +2770,13 @@ private:
/*THIS VARIABLE KEEPS TRACK OF HOW MANY FRAGMENTS THAT PARTICIPATE IN */
/*EXECUTING THE LOG. IF ZERO WE DON'T NEED TO EXECUTE THE LOG AT ALL. */
/* ------------------------------------------------------------------------- */
- UintR cnoFragmentsExecSr;
+ Uint32 cnoFragmentsExecSr;
+
+ /**
+ * This is no of sent GSN_EXEC_FRAGREQ during this log phase
+ */
+ Uint32 cnoOutstandingExecFragReq;
+
/* ------------------------------------------------------------------------- */
/*THIS VARIABLE KEEPS TRACK OF WHICH OF THE FIRST TWO RESTART PHASES THAT */
/*HAVE COMPLETED. */
@@ -2801,7 +2797,6 @@ private:
DLFifoList<Fragrecord> c_lcp_waiting_fragments; // StartFragReq'ed
DLFifoList<Fragrecord> c_lcp_restoring_fragments; // Restoring as we speek
DLFifoList<Fragrecord> c_lcp_complete_fragments; // Restored
- DLFifoList<Fragrecord> c_redo_complete_fragments; // Redo'ed
/* ------------------------------------------------------------------------- */
/*USED DURING SYSTEM RESTART, INDICATES THE OLDEST GCI THAT CAN BE RESTARTED */
diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
index db6d201575f..b3a3d512da7 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
@@ -168,7 +168,6 @@ Dblqh::Dblqh(Block_context& ctx):
c_lcp_waiting_fragments(c_fragment_pool),
c_lcp_restoring_fragments(c_fragment_pool),
c_lcp_complete_fragments(c_fragment_pool),
- c_redo_complete_fragments(c_fragment_pool),
m_commitAckMarkerHash(m_commitAckMarkerPool),
c_scanTakeOverHash(c_scanRecordPool)
{
@@ -295,9 +294,6 @@ Dblqh::Dblqh(Block_context& ctx):
addRecSignal(GSN_READ_PSEUDO_REQ, &Dblqh::execREAD_PSEUDO_REQ);
- addRecSignal(GSN_BUILDINDXREF, &Dblqh::execBUILDINDXREF);
- addRecSignal(GSN_BUILDINDXCONF, &Dblqh::execBUILDINDXCONF);
-
addRecSignal(GSN_DEFINE_BACKUP_REF, &Dblqh::execDEFINE_BACKUP_REF);
addRecSignal(GSN_DEFINE_BACKUP_CONF, &Dblqh::execDEFINE_BACKUP_CONF);
diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index e0449e08ddd..83d38595c1f 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -356,7 +356,6 @@ void Dblqh::execCONTINUEB(Signal* signal)
break;
case ZSR_PHASE3_START:
jam();
- signal->theData[0] = data0;
srPhase3Start(signal);
return;
break;
@@ -428,25 +427,25 @@ void Dblqh::execCONTINUEB(Signal* signal)
if (fragptr.i != RNIL)
{
jam();
- c_redo_complete_fragments.getPtr(fragptr);
+ c_lcp_complete_fragments.getPtr(fragptr);
signal->theData[0] = fragptr.p->tabRef;
signal->theData[1] = fragptr.p->fragId;
sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB);
Ptr<Fragrecord> save = fragptr;
- c_redo_complete_fragments.next(fragptr);
+ c_lcp_complete_fragments.next(fragptr);
signal->theData[0] = ZENABLE_EXPAND_CHECK;
signal->theData[1] = fragptr.i;
sendSignal(DBLQH_REF, GSN_CONTINUEB, signal, 2, JBB);
- c_redo_complete_fragments.remove(save);
+ c_lcp_complete_fragments.remove(save);
return;
}
else
{
jam();
cstartRecReq = 2;
- ndbrequire(c_redo_complete_fragments.isEmpty());
+ ndbrequire(c_lcp_complete_fragments.isEmpty());
StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
conf->startingNodeId = getOwnNodeId();
sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal,
@@ -495,8 +494,9 @@ void Dblqh::execINCL_NODEREQ(Signal* signal)
cnodeStatus[i] = ZNODE_UP;
}//if
}//for
- signal->theData[0] = cownref;
- sendSignal(retRef, GSN_INCL_NODECONF, signal, 1, JBB);
+ signal->theData[0] = nodeId;
+ signal->theData[1] = cownref;
+ sendSignal(retRef, GSN_INCL_NODECONF, signal, 2, JBB);
return;
}//Dblqh::execINCL_NODEREQ()
@@ -1121,7 +1121,6 @@ void Dblqh::execLQHFRAGREQ(Signal* signal)
Uint32 minRowsHigh = req->minRowsHigh;
Uint32 tschemaVersion = req->schemaVersion;
Uint32 ttupKeyLength = req->keyLength;
- Uint32 nextLcp = req->nextLCP;
Uint32 noOfKeyAttr = req->noOfKeyAttr;
Uint32 noOfCharsets = req->noOfCharsets;
Uint32 checksumIndicator = req->checksumIndicator;
@@ -1214,7 +1213,6 @@ void Dblqh::execLQHFRAGREQ(Signal* signal)
fragptr.p->lcpFlag = Fragrecord::LCP_STATE_FALSE;
}//if
- fragptr.p->nextLcp = nextLcp;
//----------------------------------------------
// For node restarts it is not necessarily zero
//----------------------------------------------
@@ -8939,6 +8937,9 @@ void Dblqh::storedProcConfScanLab(Signal* signal)
case Fragrecord::REMOVING:
jam();
default:
+ jamLine(fragptr.p->fragStatus);
+ ndbout_c("fragptr.p->fragStatus: %u",
+ fragptr.p->fragStatus);
ndbrequire(false);
break;
}//switch
@@ -14141,15 +14142,12 @@ void Dblqh::execSTART_FRAGREQ(Signal* signal)
if (lcpNo == (MAX_LCP_STORED - 1)) {
jam();
fragptr.p->lcpId[lcpNo] = lcpId;
- fragptr.p->nextLcp = 0;
} else if (lcpNo < (MAX_LCP_STORED - 1)) {
jam();
fragptr.p->lcpId[lcpNo] = lcpId;
- fragptr.p->nextLcp = lcpNo + 1;
} else {
ndbrequire(lcpNo == ZNIL);
jam();
- fragptr.p->nextLcp = 0;
}//if
fragptr.p->srNoLognodes = noOfLogNodes;
fragptr.p->logFlag = Fragrecord::STATE_FALSE;
@@ -14181,19 +14179,9 @@ void Dblqh::execSTART_FRAGREQ(Signal* signal)
*/
c_lcp_complete_fragments.add(fragptr);
- if(lcpNo == ZNIL)
- {
- signal->theData[0] = tabptr.i;
- signal->theData[1] = fragId;
- sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB);
- }
-
- if (getNodeState().getNodeRestartInProgress())
- {
- jam();
- fragptr.p->fragStatus = Fragrecord::ACTIVE_CREATION;
- }
-
+ signal->theData[0] = tabptr.i;
+ signal->theData[1] = fragId;
+ sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB);
c_tup->disk_restart_lcp_id(tabptr.i, fragId, RNIL);
jamEntry();
return;
@@ -14395,65 +14383,9 @@ void Dblqh::execSTART_RECCONF(Signal* signal)
return;
}
- c_lcp_complete_fragments.first(fragptr);
- build_acc(signal, fragptr.i);
- return;
-}//Dblqh::execSTART_RECCONF()
-
-void
-Dblqh::build_acc(Signal* signal, Uint32 fragPtrI)
-{
- fragptr.i = fragPtrI;
- while(fragptr.i != RNIL)
- {
- c_lcp_complete_fragments.getPtr(fragptr);
- tabptr.i = fragptr.p->tabRef;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
-
- if(true || fragptr.i != tabptr.p->fragrec[0])
- {
- // Only need to send 1 build per table, TUP will rebuild all
- fragptr.i = fragptr.p->nextList;
- continue;
- }
-
- BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(fragptr.i);
- req->setRequestType(BuildIndxReq::RT_SYSTEMRESTART);
- req->setBuildId(0); // not used
- req->setBuildKey(0); // not used
- req->setIndexType(RNIL);
- req->setIndexId(RNIL);
- req->setTableId(tabptr.i);
- req->setParallelism(0);
-
- sendSignal(DBTUP_REF, GSN_BUILDINDXREQ, signal,
- BuildIndxReq::SignalLength, JBB);
- return;
- }
-
startExecSr(signal);
}
-void
-Dblqh::execBUILDINDXREF(Signal* signal)
-{
- ndbrequire(false);
-}
-
-void
-Dblqh::execBUILDINDXCONF(Signal* signal)
-{
- BuildIndxConf* conf = (BuildIndxConf*)signal->getDataPtrSend();
- Uint32 fragPtrI = conf->getConnectionPtr();
-
- fragptr.i = fragPtrI;
- c_fragment_pool.getPtr(fragptr);
- infoEvent("LQH: primary key index %u rebuild done", fragptr.p->tabRef);
- build_acc(signal, fragptr.p->nextList);
-}
-
/* ***************> */
/* START_RECREF > */
/* ***************> */
@@ -14472,9 +14404,9 @@ void Dblqh::execSTART_EXEC_SR(Signal* signal)
fragptr.i = signal->theData[0];
Uint32 next = RNIL;
- if (fragptr.i == RNIL) {
+ if (fragptr.i == RNIL)
+ {
jam();
- ndbrequire(cnoOfNodes < MAX_NDB_NODES);
/* ----------------------------------------------------------------------
* NO MORE FRAGMENTS TO START EXECUTING THE LOG ON.
* SEND EXEC_SRREQ TO ALL LQH TO INDICATE THAT THIS NODE WILL
@@ -14490,10 +14422,15 @@ void Dblqh::execSTART_EXEC_SR(Signal* signal)
} else {
jam();
c_lcp_complete_fragments.getPtr(fragptr);
- if (fragptr.p->srNoLognodes > csrPhasesCompleted) {
+ next = fragptr.p->nextList;
+
+ if (fragptr.p->srNoLognodes > csrPhasesCompleted)
+ {
jam();
+ cnoOutstandingExecFragReq++;
+
Uint32 index = csrPhasesCompleted;
- arrGuard(index, 4);
+ arrGuard(index, MAX_LOG_EXEC);
BlockReference ref = calcLqhBlockRef(fragptr.p->srLqhLognode[index]);
fragptr.p->srStatus = Fragrecord::SS_STARTED;
@@ -14512,34 +14449,7 @@ void Dblqh::execSTART_EXEC_SR(Signal* signal)
sendSignal(ref, GSN_EXEC_FRAGREQ, signal,
ExecFragReq::SignalLength, JBB);
- next = fragptr.p->nextList;
- } else {
- jam();
- /* --------------------------------------------------------------------
- * THIS FRAGMENT IS NOW FINISHED WITH THE SYSTEM RESTART. IT DOES
- * NOT NEED TO PARTICIPATE IN ANY MORE PHASES. REMOVE IT FROM THE
- * LIST OF COMPLETED FRAGMENTS TO EXECUTE THE LOG ON.
- * ALSO SEND START_FRAGCONF TO DIH AND SET THE STATE TO ACTIVE ON THE
- * FRAGMENT.
- * ------------------------------------------------------------------- */
- next = fragptr.p->nextList;
- c_lcp_complete_fragments.remove(fragptr);
- c_redo_complete_fragments.add(fragptr);
-
- if (!getNodeState().getNodeRestartInProgress())
- {
- fragptr.p->logFlag = Fragrecord::STATE_TRUE;
- fragptr.p->fragStatus = Fragrecord::FSACTIVE;
- }
- else
- {
- fragptr.p->fragStatus = Fragrecord::ACTIVE_CREATION;
- }
- signal->theData[0] = fragptr.p->srUserptr;
- signal->theData[1] = cownNodeid;
- sendSignal(fragptr.p->srBlockref, GSN_START_FRAGCONF, signal, 2, JBB);
-
- } //if
+ }
signal->theData[0] = next;
sendSignal(cownref, GSN_START_EXEC_SR, signal, 1, JBB);
}//if
@@ -14560,24 +14470,8 @@ void Dblqh::execEXEC_FRAGREQ(Signal* signal)
tabptr.i = execFragReq->tableId;
Uint32 fragId = execFragReq->fragId;
ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- if (!getFragmentrec(signal, fragId)) {
- jam();
- if (!insertFragrec(signal, fragId)) {
- jam();
- sendExecFragRefLab(signal);
- return;
- }//if
- initFragrec(signal, tabptr.i, fragId, ZLOG_NODE);
- fragptr.p->execSrStatus = Fragrecord::ACTIVE_REMOVE_AFTER;
- } else {
- jam();
- if (fragptr.p->execSrStatus == Fragrecord::ACTIVE_REMOVE_AFTER) {
- jam();
- fragptr.p->execSrStatus = Fragrecord::ACTIVE_REMOVE_AFTER;
- } else {
- jam();
- }//if
- }//if
+ ndbrequire(getFragmentrec(signal, fragId));
+
ndbrequire(fragptr.p->execSrNoReplicas < 4);
fragptr.p->execSrBlockref[fragptr.p->execSrNoReplicas] = execFragReq->userRef;
fragptr.p->execSrUserptr[fragptr.p->execSrNoReplicas] = execFragReq->userPtr;
@@ -14610,6 +14504,21 @@ void Dblqh::execEXEC_FRAGCONF(Signal* signal)
fragptr.i = signal->theData[0];
c_fragment_pool.getPtr(fragptr);
fragptr.p->srStatus = Fragrecord::SS_COMPLETED;
+
+ ndbrequire(cnoOutstandingExecFragReq);
+ cnoOutstandingExecFragReq--;
+ if (fragptr.p->srNoLognodes == csrPhasesCompleted + 1)
+ {
+ jam();
+
+ fragptr.p->logFlag = Fragrecord::STATE_TRUE;
+ fragptr.p->fragStatus = Fragrecord::FSACTIVE;
+
+ signal->theData[0] = fragptr.p->srUserptr;
+ signal->theData[1] = cownNodeid;
+ sendSignal(fragptr.p->srBlockref, GSN_START_FRAGCONF, signal, 2, JBB);
+ }
+
return;
}//Dblqh::execEXEC_FRAGCONF()
@@ -14633,6 +14542,7 @@ void Dblqh::execEXEC_SRCONF(Signal* signal)
Uint32 nodeId = signal->theData[0];
arrGuard(nodeId, MAX_NDB_NODES);
m_sr_exec_sr_conf.set(nodeId);
+
if (!m_sr_nodes.equal(m_sr_exec_sr_conf))
{
jam();
@@ -14653,16 +14563,8 @@ void Dblqh::execEXEC_SRCONF(Signal* signal)
* NOW CHECK IF ALL FRAGMENTS IN THIS PHASE HAVE COMPLETED. IF SO START THE
* NEXT PHASE.
* ----------------------------------------------------------------------- */
- c_lcp_complete_fragments.first(fragptr);
- while (fragptr.i != RNIL)
- {
- jam();
- if(fragptr.p->srStatus != Fragrecord::SS_COMPLETED)
- {
- return;
- }
- c_lcp_complete_fragments.next(fragptr);
- }
+ ndbrequire(cnoOutstandingExecFragReq == 0);
+
execSrCompletedLab(signal);
return;
}//Dblqh::execEXEC_SRCONF()
@@ -14718,6 +14620,7 @@ void Dblqh::execSrCompletedLab(Signal* signal)
* THERE ARE YET MORE PHASES TO RESTART.
* WE MUST INITIALISE DATA FOR NEXT PHASE AND SEND START SIGNAL.
* --------------------------------------------------------------------- */
+ csrPhaseStarted = ZSR_PHASE1_COMPLETED; // Set correct state first...
startExecSr(signal);
}//if
return;
@@ -14791,7 +14694,8 @@ void Dblqh::srPhase3Start(Signal* signal)
UintR tsrPhaseStarted;
jamEntry();
- tsrPhaseStarted = signal->theData[0];
+
+ tsrPhaseStarted = signal->theData[1];
if (csrPhaseStarted == ZSR_NO_PHASE_STARTED) {
jam();
csrPhaseStarted = tsrPhaseStarted;
@@ -15968,18 +15872,6 @@ void Dblqh::sendExecConf(Signal* signal)
sendSignal(fragptr.p->execSrBlockref[i], GSN_EXEC_FRAGCONF,
signal, 1, JBB);
}//for
- if (fragptr.p->execSrStatus == Fragrecord::ACTIVE) {
- jam();
- fragptr.p->execSrStatus = Fragrecord::IDLE;
- } else {
- ndbrequire(fragptr.p->execSrStatus == Fragrecord::ACTIVE_REMOVE_AFTER);
- jam();
- Uint32 fragId = fragptr.p->fragId;
- tabptr.i = fragptr.p->tabRef;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- c_lcp_complete_fragments.remove(fragptr);
- deleteFragrec(fragId);
- }//if
fragptr.p->execSrNoReplicas = 0;
}//if
loopCount++;
@@ -16007,17 +15899,10 @@ void Dblqh::sendExecConf(Signal* signal)
void Dblqh::srPhase3Comp(Signal* signal)
{
jamEntry();
- ndbrequire(cnoOfNodes < MAX_NDB_NODES);
- for (Uint32 i = 0; i < cnoOfNodes; i++) {
- jam();
- if (cnodeStatus[i] == ZNODE_UP) {
- jam();
- ndbrequire(cnodeData[i] < MAX_NDB_NODES);
- BlockReference ref = calcLqhBlockRef(cnodeData[i]);
- signal->theData[0] = cownNodeid;
- sendSignal(ref, GSN_EXEC_SRCONF, signal, 1, JBB);
- }//if
- }//for
+
+ signal->theData[0] = cownNodeid;
+ NodeReceiverGroup rg(DBLQH, m_sr_nodes);
+ sendSignal(rg, GSN_EXEC_SRCONF, signal, 1, JBB);
return;
}//Dblqh::srPhase3Comp()
@@ -16259,7 +16144,7 @@ void Dblqh::srFourthComp(Signal* signal)
if(cstartType == NodeState::ST_SYSTEM_RESTART)
{
jam();
- if (c_redo_complete_fragments.first(fragptr))
+ if (c_lcp_complete_fragments.first(fragptr))
{
jam();
signal->theData[0] = ZENABLE_EXPAND_CHECK;
@@ -17367,7 +17252,6 @@ void Dblqh::initFragrec(Signal* signal,
fragptr.p->maxGciInLcp = 0;
fragptr.p->copyFragState = ZIDLE;
fragptr.p->newestGci = cnewestGci;
- fragptr.p->nextLcp = 0;
fragptr.p->tabRef = tableId;
fragptr.p->fragId = fragId;
fragptr.p->srStatus = Fragrecord::SS_IDLE;
@@ -18456,6 +18340,7 @@ void Dblqh::sendLqhTransconf(Signal* signal, LqhTransConf::OperationStatus stat)
void Dblqh::startExecSr(Signal* signal)
{
cnoFragmentsExecSr = 0;
+ cnoOutstandingExecFragReq = 0;
c_lcp_complete_fragments.first(fragptr);
signal->theData[0] = fragptr.i;
sendSignal(cownref, GSN_START_EXEC_SR, signal, 1, JBB);
diff --git a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
index 3d5e52a525d..db9f1454548 100644
--- a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
+++ b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
@@ -734,6 +734,7 @@ public:
// Index op return context
UintR indexOp;
UintR clientData;
+ Uint32 errorData;
UintR attrInfoLen;
UintR accumulatingIndexOp;
@@ -1671,6 +1672,7 @@ private:
UintR cfailure_nr;
UintR coperationsize;
UintR ctcTimer;
+ UintR cDbHbInterval;
ApiConnectRecordPtr tmpApiConnectptr;
UintR tcheckGcpId;
diff --git a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
index ce20059e663..e584883e3b6 100644
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
@@ -310,9 +310,11 @@ void Dbtc::execINCL_NODEREQ(Signal* signal)
hostptr.i = signal->theData[1];
ptrCheckGuard(hostptr, chostFilesize, hostRecord);
hostptr.p->hostStatus = HS_ALIVE;
- signal->theData[0] = cownref;
c_alive_nodes.set(hostptr.i);
+ signal->theData[0] = hostptr.i;
+ signal->theData[1] = cownref;
+
if (ERROR_INSERTED(8039))
{
CLEAR_ERROR_INSERT_VALUE;
@@ -321,11 +323,11 @@ void Dbtc::execINCL_NODEREQ(Signal* signal)
sendSignal(numberToRef(CMVMI, hostptr.i),
GSN_NDB_TAMPER, signal, 1, JBB);
signal->theData[0] = save;
- sendSignalWithDelay(tblockref, GSN_INCL_NODECONF, signal, 5000, 1);
+ sendSignalWithDelay(tblockref, GSN_INCL_NODECONF, signal, 5000, 2);
return;
}
- sendSignal(tblockref, GSN_INCL_NODECONF, signal, 1, JBB);
+ sendSignal(tblockref, GSN_INCL_NODECONF, signal, 2, JBB);
}
void Dbtc::execREAD_NODESREF(Signal* signal)
@@ -659,6 +661,10 @@ void Dbtc::execREAD_CONFIG_REQ(Signal* signal)
ndb_mgm_get_int_parameter(p, CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT, &val);
set_timeout_value(val);
+ val = 1500;
+ ndb_mgm_get_int_parameter(p, CFG_DB_HEARTBEAT_INTERVAL, &val);
+ cDbHbInterval = (val < 10) ? 10 : val;
+
val = 3000;
ndb_mgm_get_int_parameter(p, CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, &val);
set_appl_timeout_value(val);
@@ -5117,6 +5123,7 @@ void Dbtc::releaseDirtyWrite(Signal* signal)
void Dbtc::execLQHKEYREF(Signal* signal)
{
const LqhKeyRef * const lqhKeyRef = (LqhKeyRef *)signal->getDataPtr();
+ Uint32 indexId = 0;
jamEntry();
UintR compare_transid1, compare_transid2;
@@ -5168,6 +5175,9 @@ void Dbtc::execLQHKEYREF(Signal* signal)
ptrCheckGuard(opPtr, ctcConnectFilesize, localTcConnectRecord);
// The operation executed an index trigger
+ TcIndexData* indexData = c_theIndexes.getPtr(currentIndexId);
+ indexId = indexData->indexId;
+ regApiPtr->errorData = indexId;
const Uint32 opType = regTcPtr->operation;
if (errCode == ZALREADYEXIST)
errCode = terrorCode = ZNOTUNIQUE;
@@ -5180,7 +5190,6 @@ void Dbtc::execLQHKEYREF(Signal* signal)
} else {
jam();
/** ZDELETE && NOT_FOUND */
- TcIndexData* indexData = c_theIndexes.getPtr(currentIndexId);
if(indexData->indexState == IS_BUILDING && state != CS_ABORTING){
jam();
/**
@@ -5265,12 +5274,14 @@ void Dbtc::execLQHKEYREF(Signal* signal)
jam();
regApiPtr->lqhkeyreqrec--; // Compensate for extra during read
tcKeyRef->connectPtr = indexOp;
+ tcKeyRef->errorData = indexId;
EXECUTE_DIRECT(DBTC, GSN_TCKEYREF, signal, TcKeyRef::SignalLength);
apiConnectptr.i = save;
apiConnectptr.p = regApiPtr;
} else {
jam();
tcKeyRef->connectPtr = clientData;
+ tcKeyRef->errorData = indexId;
sendSignal(regApiPtr->ndbapiBlockref,
GSN_TCKEYREF, signal, TcKeyRef::SignalLength, JBB);
}//if
@@ -6400,6 +6411,7 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr, Uint32 errCode)
// conditions should get us here. We ignore it.
/*------------------------------------------------------------------*/
case CS_PREPARE_TO_COMMIT:
+ {
jam();
/*------------------------------------------------------------------*/
/* WE ARE WAITING FOR DIH TO COMMIT THE TRANSACTION. WE SIMPLY*/
@@ -6408,12 +6420,16 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr, Uint32 errCode)
// To ensure against strange bugs we crash the system if we have passed
// time-out period by a factor of 10 and it is also at least 5 seconds.
/*------------------------------------------------------------------*/
- if (((ctcTimer - getApiConTimer(apiConnectptr.i)) > (10 * ctimeOutValue)) &&
- ((ctcTimer - getApiConTimer(apiConnectptr.i)) > 500)) {
- jam();
- systemErrorLab(signal, __LINE__);
+ Uint32 time_passed = ctcTimer - getApiConTimer(apiConnectptr.i);
+ if (time_passed > 500 &&
+ time_passed > (5 * cDbHbInterval) &&
+ time_passed > (10 * ctimeOutValue))
+ {
+ jam();
+ systemErrorLab(signal, __LINE__);
}//if
break;
+ }
case CS_COMMIT_SENT:
jam();
/*------------------------------------------------------------------*/
@@ -10571,6 +10587,7 @@ void Dbtc::releaseAbortResources(Signal* signal)
tcRollbackRep->transId[0] = apiConnectptr.p->transid[0];
tcRollbackRep->transId[1] = apiConnectptr.p->transid[1];
tcRollbackRep->returnCode = apiConnectptr.p->returncode;
+ tcRollbackRep->errorData = apiConnectptr.p->errorData;
sendSignal(blockRef, GSN_TCROLLBACKREP, signal,
TcRollbackRep::SignalLength, JBB);
}
@@ -11995,6 +12012,7 @@ void Dbtc::execTCKEYCONF(Signal* signal)
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4349;
+ tcIndxRef->errorData = 0;
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
return;
@@ -12014,6 +12032,7 @@ void Dbtc::execTCKEYCONF(Signal* signal)
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4349;
+ tcIndxRef->errorData = 0;
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
return;
@@ -12097,6 +12116,7 @@ void Dbtc::execTCKEYREF(Signal* signal)
tcIndxRef->transId[0] = tcKeyRef->transId[0];
tcIndxRef->transId[1] = tcKeyRef->transId[1];
tcIndxRef->errorCode = tcKeyRef->errorCode;
+ tcIndxRef->errorData = 0;
releaseIndexOperation(regApiPtr, indexOp);
@@ -12174,6 +12194,7 @@ void Dbtc::execTRANSID_AI(Signal* signal)
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4000;
+ tcIndxRef->errorData = 0;
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
return;
@@ -12189,6 +12210,7 @@ void Dbtc::execTRANSID_AI(Signal* signal)
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4349;
+ tcIndxRef->errorData = 0;
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
return;
@@ -12217,6 +12239,7 @@ void Dbtc::execTRANSID_AI(Signal* signal)
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4349;
+ tcIndxRef->errorData = 0;
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
*/
@@ -12242,6 +12265,7 @@ void Dbtc::execTRANSID_AI(Signal* signal)
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4349;
+ tcIndxRef->errorData = regApiPtr->errorData;
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
return;
@@ -12295,6 +12319,7 @@ void Dbtc::readIndexTable(Signal* signal,
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4000;
+ // tcIndxRef->errorData = ??; Where to find indexId
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
return;
@@ -12441,6 +12466,7 @@ void Dbtc::executeIndexOperation(Signal* signal,
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4349;
+ tcIndxRef->errorData = 0;
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
return;
diff --git a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
index 8d51b24ec6a..6a76ce5217a 100644
--- a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
+++ b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
@@ -265,6 +265,8 @@ private:
void execALLOC_NODEID_CONF(Signal *);
void execALLOC_NODEID_REF(Signal *);
void completeAllocNodeIdReq(Signal *);
+
+ void execSTART_ORD(Signal*);
// Arbitration signals
void execARBIT_CFG(Signal* signal);
@@ -281,6 +283,7 @@ private:
void check_readnodes_reply(Signal* signal, Uint32 nodeId, Uint32 gsn);
Uint32 check_startup(Signal* signal);
+ void api_failed(Signal* signal, Uint32 aFailedNode);
void node_failed(Signal* signal, Uint16 aFailedNode);
void checkStartInterface(Signal* signal);
void failReport(Signal* signal,
diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp
index f9950072ab4..2f03bd56694 100644
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp
@@ -31,10 +31,6 @@ void Qmgr::initData()
cnoCommitFailedNodes = 0;
c_maxDynamicId = 0;
c_clusterNodes.clear();
-
- Uint32 hbDBAPI = 500;
- setHbApiDelay(hbDBAPI);
- c_connectedNodes.set(getOwnNodeId());
c_stopReq.senderRef = 0;
/**
@@ -43,6 +39,27 @@ void Qmgr::initData()
ndbrequire((Uint32)NodeInfo::DB == 0);
ndbrequire((Uint32)NodeInfo::API == 1);
ndbrequire((Uint32)NodeInfo::MGM == 2);
+
+ NodeRecPtr nodePtr;
+ nodePtr.i = getOwnNodeId();
+ ptrAss(nodePtr, nodeRec);
+ nodePtr.p->blockRef = reference();
+
+ c_connectedNodes.set(getOwnNodeId());
+ setNodeInfo(getOwnNodeId()).m_version = NDB_VERSION;
+
+
+ /**
+ * Timeouts
+ */
+ const ndb_mgm_configuration_iterator * p =
+ m_ctx.m_config.getOwnConfigIterator();
+ ndbrequire(p != 0);
+
+ Uint32 hbDBAPI = 1500;
+ ndb_mgm_get_int_parameter(p, CFG_DB_API_HEARTBEAT_INTERVAL, &hbDBAPI);
+
+ setHbApiDelay(hbDBAPI);
}//Qmgr::initData()
void Qmgr::initRecords()
@@ -113,6 +130,7 @@ Qmgr::Qmgr(Block_context& ctx)
addRecSignal(GSN_DIH_RESTARTREF, &Qmgr::execDIH_RESTARTREF);
addRecSignal(GSN_DIH_RESTARTCONF, &Qmgr::execDIH_RESTARTCONF);
addRecSignal(GSN_NODE_VERSION_REP, &Qmgr::execNODE_VERSION_REP);
+ addRecSignal(GSN_START_ORD, &Qmgr::execSTART_ORD);
initData();
}//Qmgr::Qmgr()
diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
index 1fba4d62e17..23e7829481e 100644
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
@@ -238,6 +238,38 @@ Qmgr::execREAD_CONFIG_REQ(Signal* signal)
ReadConfigConf::SignalLength, JBB);
}
+void
+Qmgr::execSTART_ORD(Signal* signal)
+{
+ /**
+ * Start timer handling
+ */
+ signal->theData[0] = ZTIMER_HANDLING;
+ sendSignal(QMGR_REF, GSN_CONTINUEB, signal, 1, JBB);
+
+ NodeRecPtr nodePtr;
+ for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++)
+ {
+ ptrAss(nodePtr, nodeRec);
+ nodePtr.p->ndynamicId = 0;
+ if(getNodeInfo(nodePtr.i).m_type == NodeInfo::DB)
+ {
+ nodePtr.p->phase = ZINIT;
+ c_definedNodes.set(nodePtr.i);
+ } else {
+ nodePtr.p->phase = ZAPI_INACTIVE;
+ }
+
+ setNodeInfo(nodePtr.i).m_heartbeat_cnt= 0;
+ nodePtr.p->sendPrepFailReqStatus = Q_NOT_ACTIVE;
+ nodePtr.p->sendCommitFailReqStatus = Q_NOT_ACTIVE;
+ nodePtr.p->sendPresToStatus = Q_NOT_ACTIVE;
+ nodePtr.p->failState = NORMAL;
+ nodePtr.p->rcv[0] = 0;
+ nodePtr.p->rcv[1] = 0;
+ }//for
+}
+
/*
4.2 ADD NODE MODULE*/
/*##########################################################################*/
@@ -298,8 +330,6 @@ void Qmgr::startphase1(Signal* signal)
nodePtr.i = getOwnNodeId();
ptrAss(nodePtr, nodeRec);
nodePtr.p->phase = ZSTARTING;
- nodePtr.p->blockRef = reference();
- c_connectedNodes.set(nodePtr.i);
signal->theData[0] = reference();
sendSignal(DBDIH_REF, GSN_DIH_RESTARTREQ, signal, 1, JBB);
@@ -371,11 +401,14 @@ void Qmgr::execCONNECT_REP(Signal* signal)
case ZFAIL_CLOSING:
jam();
return;
- case ZINIT:
- ndbrequire(false);
case ZAPI_ACTIVE:
case ZAPI_INACTIVE:
return;
+ case ZINIT:
+ ndbrequire(getNodeInfo(nodeId).m_type == NodeInfo::MGM);
+ break;
+ default:
+ ndbrequire(false);
}
if (getNodeInfo(nodeId).getType() != NodeInfo::DB)
@@ -1212,12 +1245,6 @@ void Qmgr::execCM_REGREF(Signal* signal)
{
jam();
electionWon(signal);
-
- /**
- * Start timer handling
- */
- signal->theData[0] = ZTIMER_HANDLING;
- sendSignal(QMGR_REF, GSN_CONTINUEB, signal, 10, JBB);
}
return;
@@ -1855,12 +1882,6 @@ Qmgr::joinedCluster(Signal* signal, NodeRecPtr nodePtr){
sendSttorryLab(signal);
- /**
- * Start timer handling
- */
- signal->theData[0] = ZTIMER_HANDLING;
- sendSignal(QMGR_REF, GSN_CONTINUEB, signal, 10, JBB);
-
sendCmAckAdd(signal, getOwnNodeId(), CmAdd::CommitNew);
}
@@ -2094,25 +2115,6 @@ void Qmgr::findNeighbours(Signal* signal)
/*---------------------------------------------------------------------------*/
void Qmgr::initData(Signal* signal)
{
- NodeRecPtr nodePtr;
- for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++) {
- ptrAss(nodePtr, nodeRec);
- nodePtr.p->ndynamicId = 0;
- if(getNodeInfo(nodePtr.i).m_type == NodeInfo::DB){
- nodePtr.p->phase = ZINIT;
- c_definedNodes.set(nodePtr.i);
- } else {
- nodePtr.p->phase = ZAPI_INACTIVE;
- }
-
- setNodeInfo(nodePtr.i).m_heartbeat_cnt= 0;
- nodePtr.p->sendPrepFailReqStatus = Q_NOT_ACTIVE;
- nodePtr.p->sendCommitFailReqStatus = Q_NOT_ACTIVE;
- nodePtr.p->sendPresToStatus = Q_NOT_ACTIVE;
- nodePtr.p->failState = NORMAL;
- nodePtr.p->rcv[0] = 0;
- nodePtr.p->rcv[1] = 0;
- }//for
cfailureNr = 1;
ccommitFailureNr = 1;
cprepareFailureNr = 1;
@@ -2146,13 +2148,11 @@ void Qmgr::initData(Signal* signal)
ndbrequire(p != 0);
Uint32 hbDBDB = 1500;
- Uint32 hbDBAPI = 1500;
Uint32 arbitTimeout = 1000;
c_restartPartialTimeout = 30000;
c_restartPartionedTimeout = 60000;
c_restartFailureTimeout = ~0;
ndb_mgm_get_int_parameter(p, CFG_DB_HEARTBEAT_INTERVAL, &hbDBDB);
- ndb_mgm_get_int_parameter(p, CFG_DB_API_HEARTBEAT_INTERVAL, &hbDBAPI);
ndb_mgm_get_int_parameter(p, CFG_DB_ARBIT_TIMEOUT, &arbitTimeout);
ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTIAL_TIMEOUT,
&c_restartPartialTimeout);
@@ -2177,7 +2177,6 @@ void Qmgr::initData(Signal* signal)
}
setHbDelay(hbDBDB);
- setHbApiDelay(hbDBAPI);
setArbitTimeout(arbitTimeout);
arbitRec.state = ARBIT_NULL; // start state for all nodes
@@ -2204,7 +2203,6 @@ void Qmgr::initData(Signal* signal)
execARBIT_CFG(signal);
}
- setNodeInfo(getOwnNodeId()).m_version = NDB_VERSION;
}//Qmgr::initData()
@@ -2237,20 +2235,22 @@ void Qmgr::timerHandlingLab(Signal* signal)
hb_check_timer.reset();
}
}
-
+
if (interface_check_timer.check(TcurrentTime)) {
jam();
interface_check_timer.reset();
checkStartInterface(signal);
}
+ if (hb_api_timer.check(TcurrentTime))
+ {
+ jam();
+ hb_api_timer.reset();
+ apiHbHandlingLab(signal);
+ }
+
if (cactivateApiCheck != 0) {
jam();
- if (hb_api_timer.check(TcurrentTime)) {
- jam();
- hb_api_timer.reset();
- apiHbHandlingLab(signal);
- }//if
if (clatestTransactionCheck == 0) {
//-------------------------------------------------------------
// Initialise the Transaction check timer.
@@ -2367,18 +2367,21 @@ void Qmgr::apiHbHandlingLab(Signal* signal)
if(type == NodeInfo::INVALID)
continue;
- if (TnodePtr.p->phase == ZAPI_ACTIVE){
+ if (c_connectedNodes.get(nodeId))
+ {
jam();
setNodeInfo(TnodePtr.i).m_heartbeat_cnt++;
- if(getNodeInfo(TnodePtr.i).m_heartbeat_cnt > 2){
+ if(getNodeInfo(TnodePtr.i).m_heartbeat_cnt > 2)
+ {
signal->theData[0] = NDB_LE_MissedHeartbeat;
signal->theData[1] = nodeId;
signal->theData[2] = getNodeInfo(TnodePtr.i).m_heartbeat_cnt - 1;
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
}
- if (getNodeInfo(TnodePtr.i).m_heartbeat_cnt > 4) {
+ if (getNodeInfo(TnodePtr.i).m_heartbeat_cnt > 4)
+ {
jam();
/*------------------------------------------------------------------*/
/* THE API NODE HAS NOT SENT ANY HEARTBEAT FOR THREE SECONDS.
@@ -2390,8 +2393,8 @@ void Qmgr::apiHbHandlingLab(Signal* signal)
signal->theData[0] = NDB_LE_DeadDueToHeartbeat;
signal->theData[1] = nodeId;
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
- node_failed(signal, nodeId);
+
+ api_failed(signal, nodeId);
}//if
}//if
}//for
@@ -2480,26 +2483,6 @@ void Qmgr::sendApiFailReq(Signal* signal, Uint16 failedNodeNo)
sendSignal(DBTC_REF, GSN_API_FAILREQ, signal, 2, JBA);
sendSignal(DBDICT_REF, GSN_API_FAILREQ, signal, 2, JBA);
sendSignal(SUMA_REF, GSN_API_FAILREQ, signal, 2, JBA);
-
- /**-------------------------------------------------------------------------
- * THE OTHER NODE WAS AN API NODE. THE COMMUNICATION LINK IS ALREADY
- * BROKEN AND THUS NO ACTION IS NEEDED TO BREAK THE CONNECTION.
- * WE ONLY NEED TO SET PARAMETERS TO ENABLE A NEW CONNECTION IN A FEW
- * SECONDS.
- *-------------------------------------------------------------------------*/
- setNodeInfo(failedNodePtr.i).m_heartbeat_cnt= 0;
- setNodeInfo(failedNodePtr.i).m_version = 0;
- recompute_version_info(getNodeInfo(failedNodePtr.i).m_type);
-
- CloseComReqConf * const closeCom = (CloseComReqConf *)&signal->theData[0];
-
- closeCom->xxxBlockRef = reference();
- closeCom->failNo = 0;
- closeCom->noOfNodes = 1;
- NodeBitmask::clear(closeCom->theNodes);
- NodeBitmask::set(closeCom->theNodes, failedNodePtr.i);
- sendSignal(CMVMI_REF, GSN_CLOSE_COMREQ, signal,
- CloseComReqConf::SignalLength, JBA);
}//Qmgr::sendApiFailReq()
void Qmgr::execAPI_FAILREQ(Signal* signal)
@@ -2512,20 +2495,7 @@ void Qmgr::execAPI_FAILREQ(Signal* signal)
ndbrequire(getNodeInfo(failedNodePtr.i).getType() != NodeInfo::DB);
- // ignore if api not active
- if (failedNodePtr.p->phase != ZAPI_ACTIVE)
- {
- jam();
- // But send to SUMA anyway...
- sendSignal(SUMA_REF, GSN_API_FAILREQ, signal, 2, JBA);
- return;
- }
-
- signal->theData[0] = NDB_LE_Disconnected;
- signal->theData[1] = failedNodePtr.i;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
- node_failed(signal, failedNodePtr.i);
+ api_failed(signal, signal->theData[0]);
}
void Qmgr::execAPI_FAILCONF(Signal* signal)
@@ -2649,6 +2619,13 @@ void Qmgr::execDISCONNECT_REP(Signal* signal)
ndbrequire(false);
}
+ if (getNodeInfo(nodeId).getType() != NodeInfo::DB)
+ {
+ jam();
+ api_failed(signal, nodeId);
+ return;
+ }
+
switch(nodePtr.p->phase){
case ZRUNNING:
jam();
@@ -2685,66 +2662,109 @@ void Qmgr::node_failed(Signal* signal, Uint16 aFailedNode)
failedNodePtr.i = aFailedNode;
ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec);
- if (getNodeInfo(failedNodePtr.i).getType() == NodeInfo::DB){
+ ndbrequire(getNodeInfo(failedNodePtr.i).getType() == NodeInfo::DB);
+
+ /**---------------------------------------------------------------------
+ * THE OTHER NODE IS AN NDB NODE, WE HANDLE IT AS IF A HEARTBEAT
+ * FAILURE WAS DISCOVERED.
+ *---------------------------------------------------------------------*/
+ switch(failedNodePtr.p->phase){
+ case ZRUNNING:
jam();
- /**---------------------------------------------------------------------
- * THE OTHER NODE IS AN NDB NODE, WE HANDLE IT AS IF A HEARTBEAT
- * FAILURE WAS DISCOVERED.
- *---------------------------------------------------------------------*/
- switch(failedNodePtr.p->phase){
- case ZRUNNING:
- jam();
- failReportLab(signal, aFailedNode, FailRep::ZLINK_FAILURE);
- return;
- case ZFAIL_CLOSING:
- jam();
- return;
- case ZSTARTING:
- c_start.reset();
- // Fall-through
- default:
- jam();
- /*---------------------------------------------------------------------*/
- // The other node is still not in the cluster but disconnected.
- // We must restart communication in three seconds.
- /*---------------------------------------------------------------------*/
- failedNodePtr.p->failState = NORMAL;
- failedNodePtr.p->phase = ZFAIL_CLOSING;
- setNodeInfo(failedNodePtr.i).m_heartbeat_cnt= 0;
-
- CloseComReqConf * const closeCom =
- (CloseComReqConf *)&signal->theData[0];
-
- closeCom->xxxBlockRef = reference();
- closeCom->failNo = 0;
- closeCom->noOfNodes = 1;
- NodeBitmask::clear(closeCom->theNodes);
- NodeBitmask::set(closeCom->theNodes, failedNodePtr.i);
- sendSignal(CMVMI_REF, GSN_CLOSE_COMREQ, signal,
- CloseComReqConf::SignalLength, JBA);
- }//if
+ failReportLab(signal, aFailedNode, FailRep::ZLINK_FAILURE);
return;
- }
-
- /**
- * API code
- */
- jam();
- if (failedNodePtr.p->phase != ZFAIL_CLOSING){
+ case ZFAIL_CLOSING:
+ jam();
+ return;
+ case ZSTARTING:
+ c_start.reset();
+ // Fall-through
+ default:
jam();
- //-------------------------------------------------------------------------
- // The API was active and has now failed. We need to initiate API failure
- // handling. If the API had already failed then we can ignore this
- // discovery.
- //-------------------------------------------------------------------------
+ /*---------------------------------------------------------------------*/
+ // The other node is still not in the cluster but disconnected.
+ // We must restart communication in three seconds.
+ /*---------------------------------------------------------------------*/
+ failedNodePtr.p->failState = NORMAL;
failedNodePtr.p->phase = ZFAIL_CLOSING;
-
- sendApiFailReq(signal, aFailedNode);
- arbitRec.code = ArbitCode::ApiFail;
- handleArbitApiFail(signal, aFailedNode);
+ setNodeInfo(failedNodePtr.i).m_heartbeat_cnt= 0;
+
+ CloseComReqConf * const closeCom =
+ (CloseComReqConf *)&signal->theData[0];
+
+ closeCom->xxxBlockRef = reference();
+ closeCom->failNo = 0;
+ closeCom->noOfNodes = 1;
+ NodeBitmask::clear(closeCom->theNodes);
+ NodeBitmask::set(closeCom->theNodes, failedNodePtr.i);
+ sendSignal(CMVMI_REF, GSN_CLOSE_COMREQ, signal,
+ CloseComReqConf::SignalLength, JBA);
}//if
return;
-}//Qmgr::node_failed()
+}
+
+void
+Qmgr::api_failed(Signal* signal, Uint32 nodeId)
+{
+ NodeRecPtr failedNodePtr;
+ /**------------------------------------------------------------------------
+ * A COMMUNICATION LINK HAS BEEN DISCONNECTED. WE MUST TAKE SOME ACTION
+ * DUE TO THIS.
+ *-----------------------------------------------------------------------*/
+ failedNodePtr.i = nodeId;
+ ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec);
+
+ if (failedNodePtr.p->phase == ZFAIL_CLOSING)
+ {
+ /**
+ * Failure handling already in progress
+ */
+ jam();
+ return;
+ }
+
+ if (failedNodePtr.p->phase == ZAPI_ACTIVE)
+ {
+ jam();
+ sendApiFailReq(signal, nodeId);
+ arbitRec.code = ArbitCode::ApiFail;
+ handleArbitApiFail(signal, nodeId);
+ }
+ else
+ {
+ /**
+ * Always inform SUMA
+ */
+ jam();
+ signal->theData[0] = nodeId;
+ signal->theData[1] = QMGR_REF;
+ sendSignal(SUMA_REF, GSN_API_FAILREQ, signal, 2, JBA);
+ failedNodePtr.p->failState = NORMAL;
+ }
+
+ failedNodePtr.p->phase = ZFAIL_CLOSING;
+ setNodeInfo(failedNodePtr.i).m_heartbeat_cnt= 0;
+ setNodeInfo(failedNodePtr.i).m_version = 0;
+ recompute_version_info(getNodeInfo(failedNodePtr.i).m_type);
+
+ CloseComReqConf * const closeCom = (CloseComReqConf *)&signal->theData[0];
+ closeCom->xxxBlockRef = reference();
+ closeCom->failNo = 0;
+ closeCom->noOfNodes = 1;
+ NodeBitmask::clear(closeCom->theNodes);
+ NodeBitmask::set(closeCom->theNodes, failedNodePtr.i);
+ sendSignal(CMVMI_REF, GSN_CLOSE_COMREQ, signal,
+ CloseComReqConf::SignalLength, JBA);
+
+ if (getNodeInfo(failedNodePtr.i).getType() == NodeInfo::MGM)
+ {
+ /**
+ * Allow MGM do reconnect "directly"
+ */
+ jam();
+ setNodeInfo(failedNodePtr.i).m_heartbeat_cnt = 3;
+ }
+}
/**--------------------------------------------------------------------------
* AN API NODE IS REGISTERING. IF FOR THE FIRST TIME WE WILL ENABLE
@@ -4963,43 +4983,39 @@ Qmgr::execDUMP_STATE_ORD(Signal* signal)
c_start.m_president_candidate_gci);
infoEvent("ctoStatus = %d\n", ctoStatus);
for(Uint32 i = 1; i<MAX_NDB_NODES; i++){
- if(getNodeInfo(i).getType() == NodeInfo::DB){
- NodeRecPtr nodePtr;
- nodePtr.i = i;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- char buf[100];
- switch(nodePtr.p->phase){
- case ZINIT:
- sprintf(buf, "Node %d: ZINIT(%d)", i, nodePtr.p->phase);
- break;
- case ZSTARTING:
- sprintf(buf, "Node %d: ZSTARTING(%d)", i, nodePtr.p->phase);
- break;
- case ZRUNNING:
- sprintf(buf, "Node %d: ZRUNNING(%d)", i, nodePtr.p->phase);
- break;
- case ZPREPARE_FAIL:
- sprintf(buf, "Node %d: ZPREPARE_FAIL(%d)", i, nodePtr.p->phase);
- break;
- case ZFAIL_CLOSING:
- sprintf(buf, "Node %d: ZFAIL_CLOSING(%d)", i, nodePtr.p->phase);
- break;
- case ZAPI_INACTIVE:
- sprintf(buf, "Node %d: ZAPI_INACTIVE(%d)", i, nodePtr.p->phase);
- break;
- case ZAPI_ACTIVE:
- sprintf(buf, "Node %d: ZAPI_ACTIVE(%d)", i, nodePtr.p->phase);
- break;
- default:
- sprintf(buf, "Node %d: <UNKNOWN>(%d)", i, nodePtr.p->phase);
- break;
- }
- infoEvent(buf);
+ NodeRecPtr nodePtr;
+ nodePtr.i = i;
+ ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
+ char buf[100];
+ switch(nodePtr.p->phase){
+ case ZINIT:
+ sprintf(buf, "Node %d: ZINIT(%d)", i, nodePtr.p->phase);
+ break;
+ case ZSTARTING:
+ sprintf(buf, "Node %d: ZSTARTING(%d)", i, nodePtr.p->phase);
+ break;
+ case ZRUNNING:
+ sprintf(buf, "Node %d: ZRUNNING(%d)", i, nodePtr.p->phase);
+ break;
+ case ZPREPARE_FAIL:
+ sprintf(buf, "Node %d: ZPREPARE_FAIL(%d)", i, nodePtr.p->phase);
+ break;
+ case ZFAIL_CLOSING:
+ sprintf(buf, "Node %d: ZFAIL_CLOSING(%d)", i, nodePtr.p->phase);
+ break;
+ case ZAPI_INACTIVE:
+ sprintf(buf, "Node %d: ZAPI_INACTIVE(%d)", i, nodePtr.p->phase);
+ break;
+ case ZAPI_ACTIVE:
+ sprintf(buf, "Node %d: ZAPI_ACTIVE(%d)", i, nodePtr.p->phase);
+ break;
+ default:
+ sprintf(buf, "Node %d: <UNKNOWN>(%d)", i, nodePtr.p->phase);
+ break;
}
+ infoEvent(buf);
}
- default:
- ;
- }//switch
+ }
#ifdef ERROR_INSERT
if (signal->theData[0] == 935 && signal->getLength() == 2)
diff --git a/storage/ndb/src/kernel/blocks/suma/Suma.cpp b/storage/ndb/src/kernel/blocks/suma/Suma.cpp
index 7845b83693c..113b63a19d3 100644
--- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp
+++ b/storage/ndb/src/kernel/blocks/suma/Suma.cpp
@@ -821,8 +821,9 @@ Suma::execINCL_NODEREQ(Signal* signal){
ndbrequire(!c_alive_nodes.get(nodeId));
c_alive_nodes.set(nodeId);
- signal->theData[0] = reference();
- sendSignal(senderRef, GSN_INCL_NODECONF, signal, 1, JBB);
+ signal->theData[0] = nodeId;
+ signal->theData[1] = reference();
+ sendSignal(senderRef, GSN_INCL_NODECONF, signal, 2, JBB);
}
void
@@ -974,6 +975,54 @@ Suma::execDUMP_STATE_ORD(Signal* signal){
}
return;
}
+
+ if (tCase == 8011)
+ {
+ jam();
+ Uint32 bucket = signal->theData[1];
+ KeyTable<Table>::Iterator it;
+ if (signal->getLength() == 1)
+ {
+ jam();
+ bucket = 0;
+ infoEvent("-- Starting dump of subscribers --");
+ }
+
+ c_tables.next(bucket, it);
+ const Uint32 RT_BREAK = 16;
+ for(Uint32 i = 0; i<RT_BREAK || it.bucket == bucket; i++)
+ {
+ jam();
+ if(it.curr.i == RNIL)
+ {
+ jam();
+ infoEvent("-- Ending dump of subscribers --");
+ return;
+ }
+
+ infoEvent("Table: %u ver: %u #n: %u (ref,data,subscritopn)",
+ it.curr.p->m_tableId,
+ it.curr.p->m_schemaVersion,
+ it.curr.p->n_subscribers);
+
+ Ptr<Subscriber> ptr;
+ LocalDLList<Subscriber> list(c_subscriberPool, it.curr.p->c_subscribers);
+ for (list.first(ptr); !ptr.isNull(); list.next(ptr), i++)
+ {
+ jam();
+ infoEvent(" [ %x %u %u ]",
+ ptr.p->m_senderRef,
+ ptr.p->m_senderData,
+ ptr.p->m_subPtrI);
+ }
+ c_tables.next(it);
+ }
+
+ signal->theData[0] = tCase;
+ signal->theData[1] = it.bucket;
+ sendSignalWithDelay(reference(), GSN_DUMP_STATE_ORD, signal, 100, 2);
+ return;
+ }
}
/*************************************************************
@@ -2402,6 +2451,7 @@ Suma::execSUB_START_REQ(Signal* signal){
{
jam();
+ c_subscriberPool.release(subbPtr);
sendSubStartRef(signal, SubStartRef::PartiallyConnected);
return;
}
diff --git a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp
index bc16b9f364e..2963b8a02ad 100644
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp
+++ b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp
@@ -1056,6 +1056,7 @@ SimulatedBlock::assembleFragments(Signal * signal){
/**
* Don't release allocated segments
*/
+ signal->header.m_fragmentInfo = 0;
signal->header.m_noOfSections = 0;
return false;
}
@@ -1083,6 +1084,7 @@ SimulatedBlock::assembleFragments(Signal * signal){
* fragInfo = 2
*/
if(fragInfo == 2){
+ signal->header.m_fragmentInfo = 0;
signal->header.m_noOfSections = 0;
return false;
}
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
index ee5bb5103d8..184d51bad78 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -119,7 +119,11 @@ operator<<(NdbOut& out, const LogLevel & ll)
void
MgmtSrvr::logLevelThreadRun()
{
- while (!_isStopThread) {
+ while (!_isStopThread)
+ {
+ Vector<NodeId> failed_started_nodes;
+ Vector<EventSubscribeReq> failed_log_level_requests;
+
/**
* Handle started nodes
*/
@@ -144,14 +148,15 @@ MgmtSrvr::logLevelThreadRun()
m_started_nodes.unlock();
if (setEventReportingLevelImpl(node, req))
- {
- ndbout_c("setEventReportingLevelImpl(%d): failed", node);
- }
-
- SetLogLevelOrd ord;
- ord = m_nodeLogLevel[node];
- setNodeLogLevelImpl(node, ord);
-
+ {
+ failed_started_nodes.push_back(node);
+ }
+ else
+ {
+ SetLogLevelOrd ord;
+ ord = m_nodeLogLevel[node];
+ setNodeLogLevelImpl(node, ord);
+ }
m_started_nodes.lock();
}
}
@@ -166,17 +171,20 @@ MgmtSrvr::logLevelThreadRun()
if(req.blockRef == 0)
{
- req.blockRef = _ownReference;
- if (setEventReportingLevelImpl(0, req))
- {
- ndbout_c("setEventReportingLevelImpl: failed 2!");
- }
+ req.blockRef = _ownReference;
+ if (setEventReportingLevelImpl(0, req))
+ {
+ failed_log_level_requests.push_back(req);
+ }
}
else
{
SetLogLevelOrd ord;
ord = req;
- setNodeLogLevelImpl(req.blockRef, ord);
+ if (setNodeLogLevelImpl(req.blockRef, ord))
+ {
+ failed_log_level_requests.push_back(req);
+ }
}
m_log_level_requests.lock();
}
@@ -185,7 +193,28 @@ MgmtSrvr::logLevelThreadRun()
if(!ERROR_INSERTED(10000))
m_event_listner.check_listeners();
- NdbSleep_MilliSleep(_logLevelThreadSleep);
+ Uint32 sleeptime = _logLevelThreadSleep;
+ if (failed_started_nodes.size())
+ {
+ m_started_nodes.lock();
+ for (Uint32 i = 0; i<failed_started_nodes.size(); i++)
+ m_started_nodes.push_back(failed_started_nodes[i], false);
+ m_started_nodes.unlock();
+ failed_started_nodes.clear();
+ sleeptime = 100;
+ }
+
+ if (failed_log_level_requests.size())
+ {
+ m_log_level_requests.lock();
+ for (Uint32 i = 0; i<failed_log_level_requests.size(); i++)
+ m_log_level_requests.push_back(failed_log_level_requests[i], false);
+ m_log_level_requests.unlock();
+ failed_log_level_requests.clear();
+ sleeptime = 100;
+ }
+
+ NdbSleep_MilliSleep(sleeptime);
}
}
@@ -1535,7 +1564,6 @@ MgmtSrvr::setEventReportingLevelImpl(int nodeId_arg,
{
SignalSender ss(theFacade);
NdbNodeBitmask nodes;
- int retries = 30;
nodes.clear();
while (1)
{
@@ -1572,18 +1600,8 @@ MgmtSrvr::setEventReportingLevelImpl(int nodeId_arg,
continue;
}
// api_reg_conf not recevied yet, need to retry
- break;
- }
- }
- if (nodeId <= max)
- {
- if (--retries)
- {
- ss.unlock();
- NdbSleep_MilliSleep(100);
- continue;
+ return SEND_OR_RECEIVE_FAILED;
}
- return SEND_OR_RECEIVE_FAILED;
}
if (nodeId_arg == 0)
@@ -1607,6 +1625,10 @@ MgmtSrvr::setEventReportingLevelImpl(int nodeId_arg,
continue; // node is not connected, skip
if (ss.sendSignal(nodeId, &ssig) == SEND_OK)
nodes.set(nodeId);
+ else if (max == nodeId)
+ {
+ return SEND_OR_RECEIVE_FAILED;
+ }
}
break;
}
@@ -2988,8 +3010,7 @@ int MgmtSrvr::connect_to_self(void)
return 0;
}
-
-
template class MutexVector<unsigned short>;
template class MutexVector<Ndb_mgmd_event_service::Event_listener>;
+template class Vector<EventSubscribeReq>;
template class MutexVector<EventSubscribeReq>;
diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
index a82983fca8c..dff953923fe 100644
--- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
+++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
@@ -792,6 +792,18 @@ NdbEventOperationImpl::receive_event()
p = p->next();
}
}
+ // change the blobHandle's to refer to the new table object.
+ NdbBlob *p = theBlobList;
+ while (p)
+ {
+ int no = p->getColumn()->getColumnNo();
+ NdbColumnImpl *tAttrInfo = at->getColumn(no);
+ DBUG_PRINT("info", ("blob_handle: 0x%lx "
+ "switching column impl 0x%lx -> 0x%lx",
+ (long) p, (long) p->theColumn, (long) tAttrInfo));
+ p->theColumn = tAttrInfo;
+ p = p->next();
+ }
if (tmp_table_impl)
delete tmp_table_impl;
}
diff --git a/storage/ndb/src/ndbapi/NdbOperationExec.cpp b/storage/ndb/src/ndbapi/NdbOperationExec.cpp
index 27672e0458c..cd1ac44d82c 100644
--- a/storage/ndb/src/ndbapi/NdbOperationExec.cpp
+++ b/storage/ndb/src/ndbapi/NdbOperationExec.cpp
@@ -24,6 +24,7 @@
#include "Interpreter.hpp"
#include <AttributeHeader.hpp>
#include <signaldata/TcKeyReq.hpp>
+#include <signaldata/TcKeyRef.hpp>
#include <signaldata/KeyInfo.hpp>
#include <signaldata/AttrInfo.hpp>
#include <signaldata/ScanTab.hpp>
@@ -545,6 +546,12 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal)
}//if
setErrorCode(aSignal->readData(4));
+ if (aSignal->getLength() == TcKeyRef::SignalLength)
+ {
+ // Signal may contain additional error data
+ theError.details = (char *) aSignal->readData(5);
+ }
+
theStatus = Finished;
theReceiver.m_received_result_length = ~0;
diff --git a/storage/ndb/src/ndbapi/NdbTransaction.cpp b/storage/ndb/src/ndbapi/NdbTransaction.cpp
index bc59df722aa..17c7188bff2 100644
--- a/storage/ndb/src/ndbapi/NdbTransaction.cpp
+++ b/storage/ndb/src/ndbapi/NdbTransaction.cpp
@@ -30,6 +30,7 @@
#include <signaldata/TcCommit.hpp>
#include <signaldata/TcKeyFailConf.hpp>
#include <signaldata/TcHbRep.hpp>
+#include <signaldata/TcRollbackRep.hpp>
/*****************************************************************************
NdbTransaction( Ndb* aNdb );
@@ -1729,6 +1730,8 @@ Remark: Handles the reception of the ROLLBACKREP signal.
int
NdbTransaction::receiveTCROLLBACKREP( NdbApiSignal* aSignal)
{
+ DBUG_ENTER("NdbTransaction::receiveTCROLLBACKREP");
+
/****************************************************************************
Check that we are expecting signals from this transaction and that it doesn't
belong to a transaction already completed. Simply ignore messages from other
@@ -1736,6 +1739,11 @@ transactions.
****************************************************************************/
if(checkState_TransId(aSignal->getDataPtr() + 1)){
theError.code = aSignal->readData(4);// Override any previous errors
+ if (aSignal->getLength() == TcRollbackRep::SignalLength)
+ {
+ // Signal may contain additional error data
+ theError.details = (char *) aSignal->readData(5);
+ }
/**********************************************************************/
/* A serious error has occured. This could be due to deadlock or */
@@ -1747,14 +1755,14 @@ transactions.
theCompletionStatus = CompletedFailure;
theCommitStatus = Aborted;
theReturnStatus = ReturnFailure;
- return 0;
+ DBUG_RETURN(0);
} else {
#ifdef NDB_NO_DROPPED_SIGNAL
abort();
#endif
}
- return -1;
+ DBUG_RETURN(-1);
}//NdbTransaction::receiveTCROLLBACKREP()
/*******************************************************************************
diff --git a/storage/ndb/src/ndbapi/TransporterFacade.cpp b/storage/ndb/src/ndbapi/TransporterFacade.cpp
index eabfc6bc371..22eee859ef3 100644
--- a/storage/ndb/src/ndbapi/TransporterFacade.cpp
+++ b/storage/ndb/src/ndbapi/TransporterFacade.cpp
@@ -1501,9 +1501,9 @@ void PollGuard::unlock_and_signal()
if (t_signal_cond_waiter)
t_signal_cond_waiter->set_poll_owner(true);
}
- m_tp->unlock_mutex();
if (t_signal_cond_waiter)
t_signal_cond_waiter->cond_signal();
+ m_tp->unlock_mutex();
m_locked=false;
}
diff --git a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c
index 0ad2faff76a..e7f946118f2 100644
--- a/storage/ndb/src/ndbapi/ndberror.c
+++ b/storage/ndb/src/ndbapi/ndberror.c
@@ -169,7 +169,7 @@ ErrorBundle ErrorCodes[] = {
{ 219, DMEC, TR, "219" },
{ 233, DMEC, TR,
"Out of operation records in transaction coordinator (increase MaxNoOfConcurrentOperations)" },
- { 275, DMEC, TR, "275" },
+ { 275, DMEC, TR, "Out of transaction records for complete phase (increase MaxNoOfConcurrentTransactions)" },
{ 279, DMEC, TR, "Out of transaction markers in transaction coordinator" },
{ 414, DMEC, TR, "414" },
{ 418, DMEC, TR, "Out of transaction buffers in LQH" },
@@ -766,8 +766,6 @@ ndberror_update(ndberror_struct * error){
if(!found){
error->status = ST_U;
}
-
- error->details = 0;
}
#if CHECK_ERRORCODES
diff --git a/storage/ndb/test/ndbapi/testDict.cpp b/storage/ndb/test/ndbapi/testDict.cpp
index 16b6e129605..e1b8f2b3c7f 100644
--- a/storage/ndb/test/ndbapi/testDict.cpp
+++ b/storage/ndb/test/ndbapi/testDict.cpp
@@ -2776,9 +2776,13 @@ runDropDDObjects(NDBT_Context* ctx, NDBT_Step* step){
case NdbDictionary::Object::UserTable:
tableFound = list.elements[i].name;
if(tableFound != 0){
- if(pDict->dropTable(tableFound) != 0){
- g_err << "Failed to drop table: " << pDict->getNdbError() << endl;
- return NDBT_FAILED;
+ if(strcmp(tableFound, "ndb_apply_status") != 0 &&
+ strcmp(tableFound, "NDB$BLOB_2_3") != 0 &&
+ strcmp(tableFound, "ndb_schema") != 0){
+ if(pDict->dropTable(tableFound) != 0){
+ g_err << "Failed to drop table: " << tableFound << pDict->getNdbError() << endl;
+ return NDBT_FAILED;
+ }
}
}
tableFound = 0;
diff --git a/storage/ndb/test/ndbapi/testNodeRestart.cpp b/storage/ndb/test/ndbapi/testNodeRestart.cpp
index 419196e00eb..751134c43c5 100644
--- a/storage/ndb/test/ndbapi/testNodeRestart.cpp
+++ b/storage/ndb/test/ndbapi/testNodeRestart.cpp
@@ -1590,6 +1590,8 @@ runBug27466(NDBT_Context* ctx, NDBT_Step* step)
node2 = res.getDbNodeId(rand() % res.getNumDbNodes());
}
+ ndbout_c("nodes %u %u", node1, node2);
+
if (res.restartOneDbNode(node1, false, true, true))
return NDBT_FAILED;
@@ -1832,6 +1834,51 @@ runBug31525(NDBT_Context* ctx, NDBT_Step* step)
if (res.waitClusterStarted())
return NDBT_FAILED;
+
+ return NDBT_OK;
+}
+
+int
+runBug32160(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() < 2)
+ {
+ return NDBT_OK;
+ }
+
+ int master = res.getMasterNodeId();
+ int next = res.getNextMasterNodeId(master);
+
+ if (res.insertErrorInNode(next, 7194))
+ {
+ return NDBT_FAILED;
+ }
+
+ int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
+ if (res.dumpStateOneNode(master, val2, 2))
+ return NDBT_FAILED;
+
+ if (res.insertErrorInNode(master, 7193))
+ return NDBT_FAILED;
+
+ int val3[] = { 7099 };
+ if (res.dumpStateOneNode(master, val3, 1))
+ return NDBT_FAILED;
+
+ if (res.waitNodesNoStart(&master, 1))
+ return NDBT_FAILED;
+
+ if (res.startNodes(&master, 1))
+ return NDBT_FAILED;
+
+ if (res.waitClusterStarted())
+ return NDBT_FAILED;
return NDBT_OK;
}
@@ -2205,6 +2252,9 @@ TESTCASE("Bug28717", ""){
TESTCASE("Bug29364", ""){
INITIALIZER(runBug29364);
}
+TESTCASE("Bug32160", ""){
+ INITIALIZER(runBug32160);
+}
NDBT_TESTSUITE_END(testNodeRestart);
int main(int argc, const char** argv){
diff --git a/storage/ndb/test/ndbapi/testSystemRestart.cpp b/storage/ndb/test/ndbapi/testSystemRestart.cpp
index 89580c0cef8..0f9100f67fa 100644
--- a/storage/ndb/test/ndbapi/testSystemRestart.cpp
+++ b/storage/ndb/test/ndbapi/testSystemRestart.cpp
@@ -1501,6 +1501,38 @@ int runSR_DD_2(NDBT_Context* ctx, NDBT_Step* step)
return result;
}
+int runBug22696(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* pNdb = GETNDB(step);
+ int result = NDBT_OK;
+ Uint32 loops = ctx->getNumLoops();
+ Uint32 rows = ctx->getNumRecords();
+ NdbRestarter restarter;
+ HugoTransactions hugoTrans(*ctx->getTab());
+
+ Uint32 i = 0;
+ while(i<=loops && result != NDBT_FAILED)
+ {
+ for (Uint32 j = 0; j<10 && result != NDBT_FAILED; j++)
+ CHECK(hugoTrans.scanUpdateRecords(pNdb, rows) == 0);
+
+ CHECK(restarter.restartAll(false, true, i > 0 ? true : false) == 0);
+ CHECK(restarter.waitClusterNoStart() == 0);
+ CHECK(restarter.insertErrorInAllNodes(7072) == 0);
+ CHECK(restarter.startAll() == 0);
+ CHECK(restarter.waitClusterStarted() == 0);
+
+ i++;
+ if (i < loops)
+ {
+ NdbSleep_SecSleep(5); // Wait for a few gcp
+ }
+ }
+
+ ctx->stopTest();
+ return result;
+}
+
int
runBug27434(NDBT_Context* ctx, NDBT_Step* step)
{
@@ -1813,8 +1845,13 @@ TESTCASE("Bug28770",
STEP(runBug28770);
FINALIZER(runClearTable);
}
-
-
+TESTCASE("Bug22696", "")
+{
+ INITIALIZER(runWaitStarted);
+ INITIALIZER(runLoadTable);
+ INITIALIZER(runBug22696);
+ FINALIZER(runClearTable);
+}
NDBT_TESTSUITE_END(testSystemRestart);
int main(int argc, const char** argv){
diff --git a/storage/ndb/test/run-test/daily-basic-tests.txt b/storage/ndb/test/run-test/daily-basic-tests.txt
index 103675d8e35..37db5e01dd6 100644
--- a/storage/ndb/test/run-test/daily-basic-tests.txt
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt
@@ -581,6 +581,10 @@ max-time: 1000
cmd: testNodeRestart
args: -n Bug29364 T1
+max-time: 300
+cmd: testNodeRestart
+args: -n Bug32160 T1
+
#
# DICT TESTS
max-time: 500
@@ -1038,4 +1042,7 @@ max-time: 300
cmd: test_event
args: -n Bug31701 T1
+max-time: 300
+cmd: testSystemRestart
+args: -n Bug22696 T1
diff --git a/storage/ndb/test/tools/Makefile.am b/storage/ndb/test/tools/Makefile.am
index 1683d4d84ae..da715caa1cb 100644
--- a/storage/ndb/test/tools/Makefile.am
+++ b/storage/ndb/test/tools/Makefile.am
@@ -13,7 +13,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-ndbtest_PROGRAMS = hugoLoad hugoFill hugoLockRecords hugoPkDelete hugoPkRead hugoPkReadRecord hugoPkUpdate hugoScanRead hugoScanUpdate restart verify_index copy_tab create_index ndb_cpcc listen_event eventlog rep_latency
+ndbtest_PROGRAMS = hugoLoad hugoFill hugoLockRecords hugoPkDelete hugoPkRead hugoPkReadRecord hugoPkUpdate hugoScanRead hugoScanUpdate restart verify_index copy_tab create_index ndb_cpcc listen_event eventlog rep_latency ndb_connect
# transproxy
@@ -35,6 +35,7 @@ ndb_cpcc_SOURCES = cpcc.cpp
listen_event_SOURCES = listen.cpp
eventlog_SOURCES = log_listner.cpp
rep_latency_SOURCES = rep_latency.cpp
+ndb_connect_SOURCES = connect.cpp
include $(top_srcdir)/storage/ndb/config/common.mk.am
include $(top_srcdir)/storage/ndb/config/type_ndbapitest.mk.am
diff --git a/storage/ndb/test/tools/connect.cpp b/storage/ndb/test/tools/connect.cpp
new file mode 100644
index 00000000000..2d3ac34d3e8
--- /dev/null
+++ b/storage/ndb/test/tools/connect.cpp
@@ -0,0 +1,152 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <ndb_global.h>
+#include <ndb_opts.h>
+#include <NDBT.hpp>
+#include <NdbApi.hpp>
+#include <NdbSleep.h>
+
+NDB_STD_OPTS_VARS;
+
+static int _loop = 25;
+static int _sleep = 25;
+static int _drop = 1;
+
+typedef uchar* gptr;
+
+static struct my_option my_long_options[] =
+{
+ NDB_STD_OPTS("ndb_desc"),
+ { "loop", 'l', "loops",
+ (gptr*) &_loop, (gptr*) &_loop, 0,
+ GET_INT, REQUIRED_ARG, _loop, 0, 0, 0, 0, 0 },
+ { "sleep", 's', "Sleep (ms) between connection attempt",
+ (gptr*) &_sleep, (gptr*) &_sleep, 0,
+ GET_INT, REQUIRED_ARG, _sleep, 0, 0, 0, 0, 0 },
+ { "drop", 'd',
+ "Drop event operations before disconnect (0 = no, 1 = yes, else rand",
+ (gptr*) &_drop, (gptr*) &_drop, 0,
+ GET_INT, REQUIRED_ARG, _drop, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+static void usage()
+{
+ char desc[] = "This program connects to ndbd, and then disconnects\n";
+ ndb_std_print_version();
+ my_print_help(my_long_options);
+ my_print_variables(my_long_options);
+}
+
+int main(int argc, char** argv){
+ NDB_INIT(argv[0]);
+
+ const char *load_default_groups[]= { "mysql_cluster",0 };
+ load_defaults("my",load_default_groups,&argc,&argv);
+ int ho_error;
+#ifndef DBUG_OFF
+ opt_debug= "d:t:O,/tmp/ndb_desc.trace";
+#endif
+ if ((ho_error=handle_options(&argc, &argv, my_long_options,
+ ndb_std_get_one_option)))
+ return NDBT_ProgramExit(NDBT_WRONGARGS);
+
+ for (int i = 0; i<_loop; i++)
+ {
+ Ndb_cluster_connection con(opt_connect_str);
+ if(con.connect(12, 5, 1) != 0)
+ {
+ ndbout << "Unable to connect to management server." << endl;
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ if (con.wait_until_ready(30,30) != 0)
+ {
+ ndbout << "Cluster nodes not ready in 30 seconds." << endl;
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
+ Ndb MyNdb(&con, "TEST_DB");
+ if(MyNdb.init() != 0){
+ ERR(MyNdb.getNdbError());
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
+ Vector<NdbEventOperation*> ops;
+ const NdbDictionary::Dictionary * dict= MyNdb.getDictionary();
+ for (int j = 0; j < argc; j++)
+ {
+ const NdbDictionary::Table * pTab = dict->getTable(argv[j]);
+ if (pTab == 0)
+ {
+ ndbout_c("Failed to retreive table: \"%s\"", argv[j]);
+ }
+
+ BaseString tmp;
+ tmp.appfmt("EV-%s", argv[j]);
+ NdbEventOperation* pOp = MyNdb.createEventOperation(tmp.c_str());
+ if ( pOp == NULL )
+ {
+ ndbout << "Event operation creation failed: " <<
+ MyNdb.getNdbError() << endl;
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
+ for (int a = 0; a < pTab->getNoOfColumns(); a++)
+ {
+ pOp->getValue(pTab->getColumn(a)->getName());
+ pOp->getPreValue(pTab->getColumn(a)->getName());
+ }
+
+ if (pOp->execute())
+ {
+ ndbout << "operation execution failed: " << pOp->getNdbError()
+ << endl;
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ ops.push_back(pOp);
+ }
+
+ if (_sleep)
+ {
+ NdbSleep_MilliSleep(10 + rand() % _sleep);
+ }
+
+ for (Uint32 i = 0; i<ops.size(); i++)
+ {
+ switch(_drop){
+ case 0:
+ break;
+ do_drop:
+ case 1:
+ if (MyNdb.dropEventOperation(ops[i]))
+ {
+ ndbout << "drop event operation failed "
+ << MyNdb.getNdbError() << endl;
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ break;
+ default:
+ if ((rand() % 100) > 50)
+ goto do_drop;
+ }
+ }
+ }
+
+ return NDBT_ProgramExit(NDBT_OK);
+}
+
+template class Vector<NdbEventOperation*>;
diff --git a/storage/ndb/tools/restore/Restore.cpp b/storage/ndb/tools/restore/Restore.cpp
index a7d8a9d10d9..f599bb21978 100644
--- a/storage/ndb/tools/restore/Restore.cpp
+++ b/storage/ndb/tools/restore/Restore.cpp
@@ -534,6 +534,88 @@ TupleS::prepareRecord(TableS & tab){
return true;
}
+int
+RestoreDataIterator::readTupleData(Uint32 *buf_ptr, Uint32 *ptr,
+ Uint32 dataLength)
+{
+ while (ptr + 2 < buf_ptr + dataLength)
+ {
+ typedef BackupFormat::DataFile::VariableData VarData;
+ VarData * data = (VarData *)ptr;
+ Uint32 sz = ntohl(data->Sz);
+ Uint32 attrId = ntohl(data->Id); // column_no
+
+ AttributeData * attr_data = m_tuple.getData(attrId);
+ const AttributeDesc * attr_desc = m_tuple.getDesc(attrId);
+
+ // just a reminder - remove when backwards compat implemented
+ if (m_currentTable->backupVersion < MAKE_VERSION(5,1,3) &&
+ attr_desc->m_column->getNullable())
+ {
+ const Uint32 ind = attr_desc->m_nullBitIndex;
+ if(BitmaskImpl::get(m_currentTable->m_nullBitmaskSize,
+ buf_ptr,ind))
+ {
+ attr_data->null = true;
+ attr_data->void_value = NULL;
+ continue;
+ }
+ }
+
+ if (m_currentTable->backupVersion < MAKE_VERSION(5,1,3))
+ {
+ sz *= 4;
+ }
+
+ attr_data->null = false;
+ attr_data->void_value = &data->Data[0];
+ attr_data->size = sz;
+
+ //if (m_currentTable->getTableId() >= 2) { ndbout << "var off=" << ptr-buf_ptr << " attrId=" << attrId << endl; }
+
+ /**
+ * Compute array size
+ */
+ const Uint32 arraySize = sz / (attr_desc->size / 8);
+ assert(arraySize <= attr_desc->arraySize);
+
+ //convert the length of blob(v1) and text(v1)
+ if(!m_hostByteOrder
+ && (attr_desc->m_column->getType() == NdbDictionary::Column::Blob
+ || attr_desc->m_column->getType() == NdbDictionary::Column::Text)
+ && attr_desc->m_column->getArrayType() == NdbDictionary::Column::ArrayTypeFixed)
+ {
+ char* p = (char*)&attr_data->u_int64_value[0];
+ Uint64 x;
+ memcpy(&x, p, sizeof(Uint64));
+ x = Twiddle64(x);
+ memcpy(p, &x, sizeof(Uint64));
+ }
+
+ //convert datetime type
+ if(!m_hostByteOrder
+ && attr_desc->m_column->getType() == NdbDictionary::Column::Datetime)
+ {
+ char* p = (char*)&attr_data->u_int64_value[0];
+ Uint64 x;
+ memcpy(&x, p, sizeof(Uint64));
+ x = Twiddle64(x);
+ memcpy(p, &x, sizeof(Uint64));
+ }
+
+ if(!Twiddle(attr_desc, attr_data, attr_desc->arraySize))
+ {
+ return -1;
+ }
+
+ ptr += ((sz + 3) >> 2) + 2;
+ }
+
+ assert(ptr == buf_ptr + dataLength);
+
+ return 0;
+}
+
const TupleS *
RestoreDataIterator::getNextTuple(int & res)
{
@@ -630,78 +712,8 @@ RestoreDataIterator::getNextTuple(int & res)
attr_data->void_value = NULL;
}
- while (ptr + 2 < buf_ptr + dataLength) {
- typedef BackupFormat::DataFile::VariableData VarData;
- VarData * data = (VarData *)ptr;
- Uint32 sz = ntohl(data->Sz);
- Uint32 attrId = ntohl(data->Id); // column_no
-
- AttributeData * attr_data = m_tuple.getData(attrId);
- const AttributeDesc * attr_desc = m_tuple.getDesc(attrId);
-
- // just a reminder - remove when backwards compat implemented
- if(m_currentTable->backupVersion < MAKE_VERSION(5,1,3) &&
- attr_desc->m_column->getNullable()){
- const Uint32 ind = attr_desc->m_nullBitIndex;
- if(BitmaskImpl::get(m_currentTable->m_nullBitmaskSize,
- buf_ptr,ind)){
- attr_data->null = true;
- attr_data->void_value = NULL;
- continue;
- }
- }
-
- if (m_currentTable->backupVersion < MAKE_VERSION(5,1,3))
- {
- sz *= 4;
- }
-
- attr_data->null = false;
- attr_data->void_value = &data->Data[0];
- attr_data->size = sz;
-
- //if (m_currentTable->getTableId() >= 2) { ndbout << "var off=" << ptr-buf_ptr << " attrId=" << attrId << endl; }
-
- /**
- * Compute array size
- */
- const Uint32 arraySize = sz / (attr_desc->size / 8);
- assert(arraySize <= attr_desc->arraySize);
-
- //convert the length of blob(v1) and text(v1)
- if(!m_hostByteOrder
- && (attr_desc->m_column->getType() == NdbDictionary::Column::Blob
- || attr_desc->m_column->getType() == NdbDictionary::Column::Text)
- && attr_desc->m_column->getArrayType() == NdbDictionary::Column::ArrayTypeFixed)
- {
- char* p = (char*)&attr_data->u_int64_value[0];
- Uint64 x;
- memcpy(&x, p, sizeof(Uint64));
- x = Twiddle64(x);
- memcpy(p, &x, sizeof(Uint64));
- }
-
- //convert datetime type
- if(!m_hostByteOrder
- && attr_desc->m_column->getType() == NdbDictionary::Column::Datetime)
- {
- char* p = (char*)&attr_data->u_int64_value[0];
- Uint64 x;
- memcpy(&x, p, sizeof(Uint64));
- x = Twiddle64(x);
- memcpy(p, &x, sizeof(Uint64));
- }
-
- if(!Twiddle(attr_desc, attr_data, attr_desc->arraySize))
- {
- res = -1;
- return NULL;
- }
-
- ptr += ((sz + 3) >> 2) + 2;
- }
-
- assert(ptr == buf_ptr + dataLength);
+ if ((res = readTupleData(buf_ptr, ptr, dataLength)))
+ return NULL;
m_count ++;
res = 0;
diff --git a/storage/ndb/tools/restore/Restore.hpp b/storage/ndb/tools/restore/Restore.hpp
index 5455fa17aa0..f6de9245509 100644
--- a/storage/ndb/tools/restore/Restore.hpp
+++ b/storage/ndb/tools/restore/Restore.hpp
@@ -355,6 +355,10 @@ public:
bool validateFragmentFooter();
const TupleS *getNextTuple(int & res);
+
+private:
+
+ int readTupleData(Uint32 *buf_ptr, Uint32 *ptr, Uint32 dataLength);
};
class LogEntry {
diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c
index a0ff0314246..c1aba0b35c6 100644
--- a/strings/ctype-cp932.c
+++ b/strings/ctype-cp932.c
@@ -5360,12 +5360,12 @@ my_wc_mb_cp932(CHARSET_INFO *cs __attribute__((unused)),
static int
my_mb_wc_cp932(CHARSET_INFO *cs __attribute__((unused)),
my_wc_t *pwc, const uchar *s, const uchar *e){
- int hi=s[0];
+ int hi;
if (s >= e)
return MY_CS_TOOSMALL;
- if (hi < 0x80)
+ if ((hi= s[0]) < 0x80)
{
pwc[0]=hi;
return 1;
diff --git a/strings/llstr.c b/strings/llstr.c
index 12aea63e014..643cf36a311 100644
--- a/strings/llstr.c
+++ b/strings/llstr.c
@@ -32,3 +32,9 @@ char *llstr(longlong value,char *buff)
longlong10_to_str(value,buff,-10);
return buff;
}
+
+char *ullstr(longlong value,char *buff)
+{
+ longlong10_to_str(value,buff,10);
+ return buff;
+}
diff --git a/support-files/MacOSX/ReadMe.txt b/support-files/MacOSX/ReadMe.txt
index 485dbaeaa37..b3dcba21705 100644
--- a/support-files/MacOSX/ReadMe.txt
+++ b/support-files/MacOSX/ReadMe.txt
@@ -1,7 +1,7 @@
You can find information about how to install on Mac OS X at
- http://dev.mysql.com/doc/refman/5.0/en/mac-os-x-installation.html
+ http://dev.mysql.com/doc/refman/5.1/en/mac-os-x-installation.html
The MySQL Reference Manual is also available in various formats on
http://dev.mysql.com/doc; if you're interested in the DocBook XML
diff --git a/tests/bug25714.c b/tests/bug25714.c
index 4782178e2f2..03d28f59aa4 100644
--- a/tests/bug25714.c
+++ b/tests/bug25714.c
@@ -29,8 +29,12 @@ int main (int argc, char **argv)
MY_INIT(argv[0]);
- if (argc != 2)
+ if (argc != 2 || !strcmp(argv[1], "--help"))
+ {
+ fprintf(stderr, "This program is a part of the MySQL test suite. "
+ "It is not intended to be executed directly by a user.\n");
return -1;
+ }
mysql_init(&conn);
if (!mysql_real_connect(
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 8bfe315fb59..9284b2182b1 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -129,7 +129,7 @@ static void die(const char *file, int line, const char *expr)
fflush(stdout);
fprintf(stderr, "%s:%d: check failed: '%s'\n", file, line, expr);
fflush(stderr);
- abort();
+ exit(1);
}
@@ -5914,6 +5914,20 @@ DROP TABLE IF EXISTS test_multi_tab";
(void) my_process_result_set(result);
mysql_free_result(result);
+ /*
+ Check if errors in one of the queries handled properly.
+ */
+ rc= mysql_query(mysql_local, "select 1; select * from not_existing_table");
+ myquery(rc);
+ result= mysql_store_result(mysql_local);
+ mysql_free_result(result);
+
+ rc= mysql_next_result(mysql_local);
+ DIE_UNLESS(rc > 0);
+
+ rc= mysql_next_result(mysql_local);
+ DIE_UNLESS(rc < 0);
+
mysql_close(mysql_local);
}
@@ -9552,7 +9566,7 @@ static void test_subqueries_ref()
{
MYSQL_STMT *stmt;
int rc, i;
- const char *query= "SELECT a as ccc from t1 where a+1=(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1)";
+ const char *query= "SELECT a as ccc from t1 outr where a+1=(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1)";
myheader("test_subqueries_ref");
@@ -11930,7 +11944,7 @@ static void test_bug5194()
MAX_PARAM_COUNT * CHARS_PER_PARAM + 1);
param_str= (char*) malloc(COLUMN_COUNT * CHARS_PER_PARAM);
- if (bind == 0 || query == 0 || param_str == 0)
+ if (my_bind == 0 || query == 0 || param_str == 0)
{
fprintf(stderr, "Can't allocate enough memory for query structs\n");
if (my_bind)
@@ -15869,6 +15883,8 @@ static void test_status()
Test that client gets updated value of insert_id on UPDATE that uses
LAST_INSERT_ID(expr).
+ select_query added to test for bug
+ #26921 Problem in mysql_insert_id() Embedded C API function
*/
static void test_bug21726()
{
@@ -15881,6 +15897,8 @@ static void test_bug21726()
const char *update_query= "UPDATE t1 SET i= LAST_INSERT_ID(i + 1)";
int rc;
my_ulonglong insert_id;
+ const char *select_query= "SELECT * FROM t1";
+ MYSQL_RES *result;
DBUG_ENTER("test_bug21726");
myheader("test_bug21726");
@@ -15897,6 +15915,13 @@ static void test_bug21726()
insert_id= mysql_insert_id(mysql);
DIE_UNLESS(insert_id == 3);
+ rc= mysql_query(mysql, select_query);
+ myquery(rc);
+ insert_id= mysql_insert_id(mysql);
+ DIE_UNLESS(insert_id == 3);
+ result= mysql_store_result(mysql);
+ mysql_free_result(result);
+
DBUG_VOID_RETURN;
}
@@ -16878,7 +16903,9 @@ static void test_bug20023()
int sql_big_selects_4;
int sql_big_selects_5;
+#if NOT_USED
char query_buffer[MAX_TEST_QUERY_LENGTH];
+#endif
/* Create a new connection. */
@@ -16976,6 +17003,12 @@ static void test_bug20023()
Check that SQL_BIG_SELECTS will be the original one.
***********************************************************************/
+#if NOT_USED
+ /*
+ max_join_size is a ulong or better.
+ my_snprintf() only goes up to ul.
+ */
+
/* Restore MAX_JOIN_SIZE. */
my_snprintf(query_buffer,
@@ -16984,6 +17017,11 @@ static void test_bug20023()
(int) max_join_size_orig);
DIE_IF(mysql_query(&con, query_buffer));
+
+#else
+ DIE_IF(mysql_query(&con, "SET @@global.max_join_size = -1"));
+#endif
+
DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
/* Issue COM_CHANGE_USER. */