summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormskold/marty@linux.site <>2006-11-10 11:38:54 +0100
committermskold/marty@linux.site <>2006-11-10 11:38:54 +0100
commit6ad1b4f92c9d6a12625a8aa65f1c9d382a870e72 (patch)
treeb96d3600e3e38a8e8d192f5382405b8b455773b3
parentb7cc16c7cc19393768ec5082a4d20cddf4ca7502 (diff)
parent5d96bcedea8c1dc6a1c1f991619f3711735fe3ac (diff)
downloadmariadb-git-6ad1b4f92c9d6a12625a8aa65f1c9d382a870e72.tar.gz
Merge mysql.com:/windows/Linux_space/MySQL/mysql-5.1
into mysql.com:/windows/Linux_space/MySQL/mysql-5.1-new-ndb
-rw-r--r--.bzrignore3
-rwxr-xr-xBUILD/SETUP.sh2
-rw-r--r--BitKeeper/etc/collapsed10
-rwxr-xr-xBitKeeper/triggers/pre-outgoing.crash-protect.pl4
-rwxr-xr-xBitKeeper/triggers/pre-resolve.crash-protect.pl4
-rw-r--r--Docs/MySQLEULA.txt252
-rw-r--r--README14
-rw-r--r--client/Makefile.am3
-rw-r--r--client/mysql.cc23
-rw-r--r--client/mysqldump.c142
-rw-r--r--client/mysqltest.c5858
-rw-r--r--configure.in23
-rw-r--r--extra/yassl/include/yassl_int.hpp7
-rw-r--r--extra/yassl/taocrypt/include/hmac.hpp10
-rw-r--r--extra/yassl/testsuite/test.hpp5
-rw-r--r--include/Makefile.am27
-rw-r--r--include/abi_check0
-rw-r--r--include/hash.h2
-rw-r--r--include/my_dbug.h3
-rw-r--r--include/my_time.h64
-rw-r--r--include/mysql.h11
-rw-r--r--include/mysql/plugin.h2
-rw-r--r--include/mysql_h.ic961
-rw-r--r--mysql-test/extra/rpl_tests/rpl_flsh_tbls.test2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_truncate_helper.test1
-rw-r--r--mysql-test/include/analyze_failure_sync_with_master.test15
-rw-r--r--mysql-test/include/ctype_like_escape.inc4
-rw-r--r--mysql-test/include/mix1.inc86
-rw-r--r--mysql-test/include/mysqltest_while.inc137
-rwxr-xr-xmysql-test/include/parser_bug21114.inc59
-rw-r--r--mysql-test/include/sourced.inc1
-rw-r--r--mysql-test/include/sourced1.inc1
-rw-r--r--mysql-test/include/sp-vars.inc9
-rw-r--r--mysql-test/include/wait_for_query_to_suceed.inc25
-rw-r--r--mysql-test/lib/mtr_cases.pl290
-rw-r--r--mysql-test/lib/mtr_gcov.pl18
-rw-r--r--mysql-test/lib/mtr_io.pl26
-rw-r--r--mysql-test/lib/mtr_misc.pl40
-rw-r--r--mysql-test/lib/mtr_process.pl116
-rw-r--r--mysql-test/lib/mtr_report.pl52
-rw-r--r--mysql-test/lib/mtr_stress.pl7
-rw-r--r--mysql-test/lib/mtr_timer.pl29
-rw-r--r--mysql-test/mysql-test-run-shell.sh7
-rwxr-xr-xmysql-test/mysql-test-run.pl1844
-rw-r--r--mysql-test/r/binlog_row_mix_innodb_myisam.result2
-rw-r--r--mysql-test/r/binlog_stm_mix_innodb_myisam.result2
-rw-r--r--mysql-test/r/check.result2
-rw-r--r--mysql-test/r/csv.result3
-rw-r--r--mysql-test/r/drop.result4
-rw-r--r--mysql-test/r/events_bugs.result50
-rw-r--r--mysql-test/r/events_grant.result22
-rw-r--r--mysql-test/r/flush.result8
-rw-r--r--mysql-test/r/flush_block_commit.result8
-rw-r--r--mysql-test/r/flush_read_lock_kill.result2
-rw-r--r--mysql-test/r/flush_table.result6
-rw-r--r--mysql-test/r/func_compress.result10
-rw-r--r--mysql-test/r/func_date_add.result14
-rw-r--r--mysql-test/r/func_math.result12
-rw-r--r--mysql-test/r/func_misc.result2
-rw-r--r--mysql-test/r/func_sapdb.result15
-rw-r--r--mysql-test/r/func_test.result75
-rw-r--r--mysql-test/r/func_time.result147
-rw-r--r--mysql-test/r/grant2.result8
-rw-r--r--mysql-test/r/handler_innodb.result4
-rw-r--r--mysql-test/r/handler_myisam.result4
-rw-r--r--mysql-test/r/im_daemon_life_cycle.result2
-rw-r--r--mysql-test/r/im_life_cycle.result4
-rw-r--r--mysql-test/r/information_schema.result14
-rw-r--r--mysql-test/r/innodb_mysql.result48
-rw-r--r--mysql-test/r/innodb_notembedded.result2
-rw-r--r--mysql-test/r/kill.result6
-rw-r--r--mysql-test/r/lock_multi.result26
-rw-r--r--mysql-test/r/log_tables.result72
-rw-r--r--mysql-test/r/multi_update.result4
-rw-r--r--mysql-test/r/mysql.result29
-rw-r--r--mysql-test/r/mysqldump-max.result19
-rw-r--r--mysql-test/r/mysqldump.result22
-rw-r--r--mysql-test/r/mysqltest.result71
-rw-r--r--mysql-test/r/not_partition.require2
-rw-r--r--mysql-test/r/not_partition.result48
-rw-r--r--mysql-test/r/openssl_1.result4
-rw-r--r--mysql-test/r/parser.result388
-rw-r--r--mysql-test/r/parser_bug21114_innodb.result867
-rw-r--r--mysql-test/r/partition.result36
-rw-r--r--mysql-test/r/ps.result153
-rw-r--r--mysql-test/r/ps_11bugs.result33
-rw-r--r--mysql-test/r/query_cache.result3
-rw-r--r--mysql-test/r/query_cache_notembedded.result2
-rw-r--r--mysql-test/r/range.result10
-rw-r--r--mysql-test/r/rename.result4
-rw-r--r--mysql-test/r/rpl_err_ignoredtable.result2
-rw-r--r--mysql-test/r/rpl_master_pos_wait.result2
-rw-r--r--mysql-test/r/rpl_ndb_sp003.result2
-rw-r--r--mysql-test/r/rpl_row_sp003.result2
-rw-r--r--mysql-test/r/rpl_stm_000001.result2
-rw-r--r--mysql-test/r/rpl_trigger.result2
-rw-r--r--mysql-test/r/show_check.result35
-rw-r--r--mysql-test/r/sp-error.result32
-rw-r--r--mysql-test/r/sp-threads.result4
-rw-r--r--mysql-test/r/sp-vars.result23
-rw-r--r--mysql-test/r/sp.result156
-rw-r--r--mysql-test/r/sp_notembedded.result3
-rw-r--r--mysql-test/r/ssl_des.result2159
-rw-r--r--mysql-test/r/subselect.result3
-rw-r--r--mysql-test/r/synchronization.result40
-rw-r--r--mysql-test/r/timezone.result8
-rw-r--r--mysql-test/r/timezone2.result24
-rw-r--r--mysql-test/r/timezone4.result6
-rw-r--r--mysql-test/r/trigger.result64
-rw-r--r--mysql-test/r/type_newdecimal.result2
-rw-r--r--mysql-test/r/user_var.result9
-rw-r--r--mysql-test/r/view.result70
-rw-r--r--mysql-test/std_data/server-cert-des.pem16
-rw-r--r--mysql-test/std_data/server-key-des.pem18
-rw-r--r--mysql-test/t/connect.test1
-rw-r--r--mysql-test/t/crash_commit_before.test3
-rw-r--r--mysql-test/t/csv.test2
-rw-r--r--mysql-test/t/ctype_utf8.test4
-rw-r--r--mysql-test/t/disabled.def15
-rw-r--r--mysql-test/t/events_bugs.test51
-rw-r--r--mysql-test/t/events_grant.test12
-rw-r--r--mysql-test/t/func_compress.test14
-rw-r--r--mysql-test/t/func_date_add.test15
-rw-r--r--mysql-test/t/func_gconcat.test2
-rw-r--r--mysql-test/t/func_math.test5
-rw-r--r--mysql-test/t/func_test.test34
-rw-r--r--mysql-test/t/func_time.test114
-rw-r--r--mysql-test/t/im_daemon_life_cycle.imtest14
-rw-r--r--mysql-test/t/information_schema.test39
-rw-r--r--mysql-test/t/init_file.test2
-rw-r--r--mysql-test/t/kill.test2
-rw-r--r--mysql-test/t/lock_multi.test3
-rw-r--r--mysql-test/t/log_tables.test83
-rw-r--r--mysql-test/t/mysql.test70
-rw-r--r--mysql-test/t/mysqldump-max.test11
-rw-r--r--mysql-test/t/mysqldump.test15
-rw-r--r--mysql-test/t/mysqltest.test428
-rw-r--r--mysql-test/t/ndb_index_unique.test15
-rw-r--r--mysql-test/t/not_embedded_server-master.opt2
-rw-r--r--mysql-test/t/not_partition.test62
-rw-r--r--mysql-test/t/parser.test510
-rw-r--r--mysql-test/t/parser_bug21114_innodb.test422
-rw-r--r--mysql-test/t/partition.test53
-rw-r--r--mysql-test/t/ps-master.opt1
-rw-r--r--mysql-test/t/ps.test116
-rw-r--r--mysql-test/t/ps_11bugs.test34
-rw-r--r--mysql-test/t/ps_1general.test2
-rw-r--r--mysql-test/t/ps_grant.test2
-rw-r--r--mysql-test/t/query_cache.test2
-rw-r--r--mysql-test/t/range.test12
-rw-r--r--mysql-test/t/rename.test19
-rw-r--r--mysql-test/t/rpl_dual_pos_advance-master.opt2
-rw-r--r--mysql-test/t/rpl_empty_master_crash-master.opt1
-rw-r--r--mysql-test/t/rpl_ndb_auto_inc.test1
-rw-r--r--mysql-test/t/rpl_slave_status.test2
-rw-r--r--mysql-test/t/rpl_stm_log-master.opt2
-rw-r--r--mysql-test/t/rpl_trigger.test2
-rw-r--r--mysql-test/t/rpl_truncate_7ndb.test1
-rw-r--r--mysql-test/t/show_check-master.opt1
-rw-r--r--mysql-test/t/show_check.test14
-rw-r--r--mysql-test/t/sp-error.test61
-rw-r--r--mysql-test/t/sp-vars.test10
-rw-r--r--mysql-test/t/sp.test174
-rw-r--r--mysql-test/t/sp_notembedded.test12
-rw-r--r--mysql-test/t/ssl_des-master.opt1
-rw-r--r--mysql-test/t/ssl_des.test19
-rw-r--r--mysql-test/t/subselect.test2
-rw-r--r--mysql-test/t/system_mysql_db_fix.test6
-rw-r--r--mysql-test/t/timezone.test7
-rw-r--r--mysql-test/t/timezone2.test10
-rw-r--r--mysql-test/t/timezone4-master.opt1
-rw-r--r--mysql-test/t/timezone4.test13
-rw-r--r--mysql-test/t/trigger.test63
-rw-r--r--mysql-test/t/type_newdecimal.test4
-rw-r--r--mysql-test/t/user_var.test10
-rw-r--r--mysql-test/t/view.test105
-rwxr-xr-xmysql-test/t/wait_for_socket.sh62
-rw-r--r--mysql-test/t/wait_timeout.test2
-rw-r--r--mysys/CMakeLists.txt2
-rw-r--r--mysys/Makefile.am2
-rw-r--r--mysys/charset.c15
-rwxr-xr-xmysys/make-ccc2
-rw-r--r--mysys/mf_iocache.c108
-rw-r--r--mysys/my_chsize.c6
-rw-r--r--mysys/my_lock.c39
-rw-r--r--mysys/my_lread.c53
-rw-r--r--mysys/my_lwrite.c46
-rw-r--r--mysys/my_pread.c12
-rw-r--r--mysys/my_quick.c26
-rw-r--r--mysys/my_read.c9
-rw-r--r--mysys/my_seek.c35
-rw-r--r--mysys/my_write.c20
-rwxr-xr-xnetware/BUILD/compile-netware-END11
-rwxr-xr-x[-rw-r--r--]netware/BUILD/compile-netware-max2
-rwxr-xr-x[-rw-r--r--]netware/BUILD/compile-netware-max-debug2
-rwxr-xr-x[-rw-r--r--]netware/BUILD/compile-netware-src0
-rwxr-xr-xnetware/BUILD/mwenv31
-rwxr-xr-xnetware/BUILD/mwldnlm7
-rw-r--r--scripts/make_binary_distribution.sh7
-rw-r--r--server-tools/instance-manager/commands.cc2
-rw-r--r--server-tools/instance-manager/guardian.cc80
-rw-r--r--server-tools/instance-manager/guardian.h4
-rw-r--r--server-tools/instance-manager/instance.cc68
-rw-r--r--server-tools/instance-manager/instance.h4
-rw-r--r--server-tools/instance-manager/instance_map.cc14
-rw-r--r--server-tools/instance-manager/instance_map.h6
-rw-r--r--server-tools/instance-manager/instance_options.cc2
-rw-r--r--server-tools/instance-manager/listener.cc26
-rw-r--r--server-tools/instance-manager/log.cc18
-rw-r--r--server-tools/instance-manager/manager.cc45
-rw-r--r--server-tools/instance-manager/messages.cc2
-rw-r--r--server-tools/instance-manager/mysql_connection.cc34
-rw-r--r--server-tools/instance-manager/options.cc6
-rw-r--r--server-tools/instance-manager/options.h2
-rw-r--r--server-tools/instance-manager/parse.cc2
-rw-r--r--server-tools/instance-manager/thread_registry.cc117
-rw-r--r--server-tools/instance-manager/thread_registry.h12
-rw-r--r--server-tools/instance-manager/user_map.cc9
-rw-r--r--sql-common/client.c2
-rw-r--r--sql-common/my_time.c215
-rw-r--r--sql/Makefile.am10
-rw-r--r--sql/event_data_objects.cc27
-rw-r--r--sql/event_db_repository.cc10
-rw-r--r--sql/field.cc35
-rw-r--r--sql/ha_ndbcluster.cc20
-rw-r--r--sql/ha_ndbcluster_binlog.cc5
-rw-r--r--sql/handler.cc51
-rw-r--r--sql/handler.h7
-rw-r--r--sql/item_cmpfunc.cc3
-rw-r--r--sql/item_create.cc4828
-rw-r--r--sql/item_create.h296
-rw-r--r--sql/item_func.cc9
-rw-r--r--sql/item_func.h1
-rw-r--r--sql/item_geofunc.h4
-rw-r--r--sql/item_strfunc.cc1
-rw-r--r--sql/item_sum.cc1
-rw-r--r--sql/item_sum.h49
-rw-r--r--sql/item_timefunc.cc255
-rw-r--r--sql/lex.h222
-rw-r--r--sql/lex_symbol.h1
-rw-r--r--sql/lock.cc3
-rw-r--r--sql/log.cc240
-rw-r--r--sql/log.h49
-rw-r--r--sql/mysql_priv.h18
-rw-r--r--sql/mysqld.cc71
-rw-r--r--sql/opt_range.cc11
-rw-r--r--sql/opt_range.h2
-rw-r--r--sql/parse_file.h16
-rw-r--r--sql/partition_info.cc6
-rw-r--r--sql/protocol.cc4
-rw-r--r--sql/set_var.cc5
-rw-r--r--sql/share/errmsg.txt6
-rw-r--r--sql/slave.cc29
-rw-r--r--sql/sp.cc27
-rw-r--r--sql/sp_head.cc15
-rw-r--r--sql/sql_acl.cc67
-rw-r--r--sql/sql_base.cc13
-rw-r--r--sql/sql_class.cc8
-rw-r--r--sql/sql_class.h14
-rw-r--r--sql/sql_db.cc5
-rw-r--r--sql/sql_delete.cc31
-rw-r--r--sql/sql_insert.cc12
-rw-r--r--sql/sql_lex.cc35
-rw-r--r--sql/sql_lex.h29
-rw-r--r--sql/sql_parse.cc189
-rw-r--r--sql/sql_plugin.cc4
-rw-r--r--sql/sql_prepare.cc46
-rw-r--r--sql/sql_rename.cc102
-rw-r--r--sql/sql_select.cc15
-rw-r--r--sql/sql_show.cc6
-rw-r--r--sql/sql_table.cc151
-rw-r--r--sql/sql_trigger.cc21
-rw-r--r--sql/sql_union.cc15
-rw-r--r--sql/sql_view.cc112
-rw-r--r--sql/sql_view.h2
-rw-r--r--sql/sql_yacc.yy1635
-rw-r--r--sql/stacktrace.c2
-rw-r--r--sql/strfunc.cc30
-rw-r--r--sql/table.cc23
-rw-r--r--sql/time.cc28
-rw-r--r--sql/tztime.cc77
-rw-r--r--storage/csv/ha_tina.cc4
-rw-r--r--storage/innobase/btr/btr0btr.c3
-rw-r--r--storage/innobase/dict/dict0dict.c34
-rw-r--r--storage/innobase/handler/ha_innodb.cc13
-rw-r--r--storage/innobase/include/dict0dict.h4
-rw-r--r--storage/innobase/include/mem0dbg.h13
-rw-r--r--storage/innobase/include/mtr0mtr.h2
-rw-r--r--storage/innobase/include/mtr0mtr.ic2
-rw-r--r--storage/innobase/include/sync0rw.h5
-rw-r--r--storage/innobase/include/sync0sync.h6
-rw-r--r--storage/innobase/include/univ.i50
-rw-r--r--storage/innobase/include/ut0ut.h10
-rw-r--r--storage/innobase/mem/mem0dbg.c14
-rw-r--r--storage/innobase/mem/mem0pool.c17
-rw-r--r--storage/innobase/mtr/mtr0mtr.c2
-rw-r--r--storage/innobase/row/row0purge.c2
-rw-r--r--storage/innobase/sync/sync0rw.c15
-rw-r--r--storage/innobase/sync/sync0sync.c19
-rw-r--r--storage/innobase/ut/ut0ut.c12
-rw-r--r--storage/myisam/ha_myisam.cc8
-rw-r--r--storage/myisam/sort.c260
-rw-r--r--storage/ndb/tools/ndb_size.pl171
-rw-r--r--storage/ndb/tools/ndb_size.tmpl20
-rw-r--r--tests/mysql_client_test.c47
-rw-r--r--vio/viossl.c9
-rw-r--r--vio/viosslfactories.c13
307 files changed, 21671 insertions, 7129 deletions
diff --git a/.bzrignore b/.bzrignore
index 6abf5d3eb8b..9c9121c5dc5 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -567,8 +567,10 @@ heap/hp_test2
help
help.c
help.h
+include/check_abi
include/my_config.h
include/my_global.h
+include/mysql_h.ic
include/mysql_version.h
include/mysqld_ername.h
include/mysqld_error.h
@@ -1260,6 +1262,7 @@ mysql-test/r/bdb-deadlock.err
mysql-test/r/bdb.err
mysql-test/r/bdb.log
mysql-test/r/bdb_cache.err
+mysql-test/r/blackhole.log
mysql-test/r/client_test.err
mysql-test/r/csv.err
mysql-test/r/ctype_ucs.err
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index bca7e7b2e1f..87aec7417f1 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -106,7 +106,7 @@ else
cxx_warnings="$warnings -std=c++98"
# NOTE: warning mode should not influence optimize/debug mode.
# Please feel free to add a separate option if you don't feel it's an overkill.
- debug_extra_flags="-O0"
+ debug_extra_cflags="-O0"
# Reset CPU flags (-mtune), they don't work in -pedantic mode
check_cpu_cflags=""
fi
diff --git a/BitKeeper/etc/collapsed b/BitKeeper/etc/collapsed
index 79836bb030e..226f0f1a2e2 100644
--- a/BitKeeper/etc/collapsed
+++ b/BitKeeper/etc/collapsed
@@ -5,5 +5,15 @@
45001f7c3b2hhCXDKfUvzkX9TNe6VA
45002051rHJfMEXAIMiAZV0clxvKSA
4513d8e4Af4dQWuk13sArwofRgFDQw
+45143312u0Tz4r0wPXCbUKwdHa2jWA
+45143b90ewOQuTW8-jrB3ZSAQvMRJw
+45184588w9U72A6KX1hUFeAC4shSHA
+45185df8mZbxfp85FbA0VxUXkmDewA
4519a6c5BVUxEHTf5iJnjZkixMBs8g
451ab499rgdjXyOnUDqHu-wBDoS-OQ
+451b110a3ZV6MITl93ehXk2wxrbW7g
+45214442pBGT9KuZEGixBH71jTzbOA
+45214a07hVsIGwvwa-WrO-jpeaSwVw
+452a92d0-31-8wSzSfZi165fcGcXPA
+454a7ef8gdvE_ddMlJyghvOAkKPNOQ
+454f8960jsVT_kMKJtZ9OCgXoba0xQ
diff --git a/BitKeeper/triggers/pre-outgoing.crash-protect.pl b/BitKeeper/triggers/pre-outgoing.crash-protect.pl
index bbaa092e335..80567012c0f 100755
--- a/BitKeeper/triggers/pre-outgoing.crash-protect.pl
+++ b/BitKeeper/triggers/pre-outgoing.crash-protect.pl
@@ -9,8 +9,6 @@ unless($event eq 'outgoing pull' || $event eq 'outgoing push' ||
exit 0;
}
-print "Checking for bad changesets from old crashed 5.1 tree...\n";
-
my @bad_csets=
( 'monty@mysql.com|ChangeSet|20060418090255|16983',
'monty@mysql.com|ChangeSet|20060418090458|02628',
@@ -80,6 +78,4 @@ END
}
}
-print "No bad changesets found, proceeding.\n";
-
exit 0;
diff --git a/BitKeeper/triggers/pre-resolve.crash-protect.pl b/BitKeeper/triggers/pre-resolve.crash-protect.pl
index bbaa092e335..80567012c0f 100755
--- a/BitKeeper/triggers/pre-resolve.crash-protect.pl
+++ b/BitKeeper/triggers/pre-resolve.crash-protect.pl
@@ -9,8 +9,6 @@ unless($event eq 'outgoing pull' || $event eq 'outgoing push' ||
exit 0;
}
-print "Checking for bad changesets from old crashed 5.1 tree...\n";
-
my @bad_csets=
( 'monty@mysql.com|ChangeSet|20060418090255|16983',
'monty@mysql.com|ChangeSet|20060418090458|02628',
@@ -80,6 +78,4 @@ END
}
}
-print "No bad changesets found, proceeding.\n";
-
exit 0;
diff --git a/Docs/MySQLEULA.txt b/Docs/MySQLEULA.txt
deleted file mode 100644
index f50c50298b1..00000000000
--- a/Docs/MySQLEULA.txt
+++ /dev/null
@@ -1,252 +0,0 @@
- License Agreement for Commercial Use of MySQL[tm] Software
-
-This Agreement ("License") is between MySQL AB, a Swedish company
-("Licensor"), and the customer ("Licensee") identified on the electronic order
-form submitted on behalf of Licensee (the "Order Form"). In consideration of
-the mutual promises, covenants and conditions contained herein, the
-sufficiency of which is hereby acknowledged, the parties agree as follows.
-
-1. License Grant.
-"Licensed Software" means a complete and unchanged copy of the object code
-version of the MySQL relational database management software identified in the
-Order Form and posted on a special download page of the MySQL AB web site (the
-"Download Page") made available to Licensee immediately after payment as
-provided in Section 4. Subject to payment and the other terms and conditions
-hereof, Licensor grants to Licensee a limited, non-exclusive and
-non-transferable right to: (a) make one copy of the Licensed Software for each
-license purchased (each, a "Licensed Copy"); (b) compile and/or link each
-Licensed Copy to one copy of the Licensee software identified in the Order
-Form (the "Licensee Application") without modifying the Licensed Software
-(each, an "Integrated Product"); and (c) load and use the Licensed Copy
-portion of an Integrated Product on one machine or instrument in the operating
-system environment(s), and on the hardware platform(s) specified in the Order
-Form, and solely for running and extracting data from, the Licensee
-Application. "Use" means operation by one person for internal business
-purposes in accordance with the terms and conditions hereof. Licensed Copies
-shall be deemed accepted by Licensee immediately upon download. Licensee may
-make one additional copy of each Licensed Copy for backup and archival
-purposes only.
-
-2. Transfer.
-Only after Licensee has linked or compiled a Licensed Copy as permitted in
-Section 1, Licensee may transfer to a third party (the "Transferee") the right
-to use such copy as described in Section 1. As a condition to any such
-transfer: (a) Licensee must deliver the Licensed Copy and any backup copy to
-the Transferee along with a copy of this License (including the Sales Order);
-and (b) the Transferee must accept the terms and conditions of this License.
-Any and all of Licensee's rights to a Licensed Copy shall terminate upon
-transfer of the right to use such copy. A Transferee's rights are limited to
-the use rights described in Section 1(c), and do not include the linking,
-compilation or copying rights (except for backup and archival copies)
-described in Section 1. If you did not purchase this License directly from
-MySQL AB, then you are a Transferee. Licensee and any Transferee must comply
-with all applicable export laws and regulations.
-
-3. Restrictions.
-Licensee may use the Licensed Software only as expressly provided in Section
-1. Without limiting the foregoing, Licensee shall not: (a) lease, license,
-use, make available, distribute or modify all or any part of the Licensed
-Software to any third party, except as otherwise expressly permitted herein;
-(b) use the Licensed Software to operate in or as a time-sharing, outsourcing,
-service bureau, application service provider or managed service provider
-environment; (c) lease, license, use, make available or distribute the
-Licensed Software as a general SQL server, as a stand alone application or
-with applications other than the Licensee Application under this License; (d)
-copy the Licensed Software onto any public or distributed network; (e)
-distribute Integrated Products pursuant to a public or open source license;
-(f) port the Licensed Software to any operating system other than as described
-in the Order Form; or (g) change any proprietary rights notices which appear
-in the Licensed Software. Except as otherwise provided in Section 2, the
-rights granted to Licensee herein are rights that may be exercised solely by
-Licensee.
-
-4. Price and payment.
-No later than thirty (30) days after submission of the Order Form, Licensee
-shall remit one non-refundable license fee per Licensed Copy as posted on
-http://shop.mysql.com on the date Licensee submitted the Order Form (the
-"License Fee"). All payments shall be made in Euros or U.S. dollars. Licensee
-shall be responsible for paying all local, state, federal and international
-sales, value added, excise and other taxes and duties payable in connection
-with this License, other than taxes based upon Licensor's net income. Licensee
-shall not be permitted to access the Download Page until Licensor has received
-payment in full.
-
-5. Termination.
-Licensor may terminate this License immediately if the Licensee shall breach
-any of the provisions of this License and such breach remains uncured 30 days
-after receipt of notice. In the event that Licensee becomes liquidated,
-dissolved, bankrupt or insolvent, whether voluntarily or involuntarily, or
-shall take any action to be so declared, Licensor shall have the right to
-terminate this License immediately. Upon expiration, cancellation or other
-termination of this License, Licensee shall immediately: (a) discontinue
-distribution of Integrated Products that include Licensed Software; and (b)
-destroy all copies of the Licensed Software, including (without limitation) as
-linked or compiled in any Integrated Product. Sections 4 through 10 shall
-survive the termination of this License for any reason.
-
-6. Proprietary Rights.
-Licensee agrees that the copyright, patent, trade secrets and all other
-intellectual proprietary rights of whatever nature in the Licensed Software
-and related documentation, including derivative works, are and shall remain
-the exclusive property of Licensor and any third party suppliers. Nothing in
-this License should be construed as transferring any aspects of such rights to
-Licensee or any third party. Licensor reserves any and all rights not
-expressly granted herein. MySQL is a trademark of MySQL AB, and shall not be
-used by Licensee without Licensor's express written authorization. Licensee
-shall include in the Integrated Products a conspicuous notice that the
-Integrated Products include software whose copyright is owned by MySQL AB.
-
-7. Disclaimer of Warranties.
-THE LICENSED SOFTWARE IS LICENSED "AS IS," WITHOUT ANY WARRANTIES WHATSOEVER.
-LICENSOR EXPRESSLY DISCLAIMS, AND LICENSEE EXPRESSLY WAIVES, ALL WARRANTIES,
-WHETHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OF MERCHANTIBILITY, FITNESS
-FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, SYSTEM INTEGRATION,
-NON-INTERFERENCE AND ACCURACY OF INFORMATIONAL CONTENT. LICENSOR DOES NOT
-WARRANT THAT THE LICENSED SOFTWARE WILL MEET LICENSEE'S REQUIREMENTS OR THAT
-THE OPERATION OF THE LICENSED SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR
-THAT ERRORS WILL BE CORRECTED. THE ENTIRE RISK OF THE LICENSED SOFTWARE'S
-QUALITY AND PERFORMANCE IS WITH LICENSEE. Without limiting the generality of
-the foregoing disclaimer, Licensee acknowledges that the Licensed Software is
-not specifically designed, manufactured or intended for use in the planning,
-construction, maintenance, control or direct operation of nuclear facilities,
-aircraft navigation, control or communication systems, weapons systems or
-direct life support systems.
-
-8. Indemnification.
-Licensee hereby indemnifies and agrees to defend Licensor against any and all
-damages, judgments and costs (including reasonable attorneys' fees) related to
-any claim based upon: (a) an allegation that the Licensee Application
-infringes the intellectual property of a third party; (b) use of the Licensed
-Software in a manner prohibited under this License or in a manner for which
-the Licensed Software was not designed; (c) integration or use of the Licensed
-Software with the Licensee Application (where use of the Licensed Software
-alone would not infringe); (d) changes made by Licensee to the Licensed
-Software (where use of unmodified Licensed Software would not infringe); (e)
-changes made, or actions taken, by Licensor upon Licensee's direct
-instructions; or (f) bodily injury, property damage or any other damage or
-injury due to the use or inability to use an Integrated Product.
-
-9. Limitation of Liability.
-LICENSOR SHALL HAVE NO LIABILITY WITH RESPECT TO ITS OBLIGATIONS UNDER THIS
-AGREEMENT OR OTHERWISE FOR CONSEQUENTIAL, EXEMPLARY, SPECIAL, INDIRECT,
-INCIDENTAL OR PUNITIVE DAMAGES, INCLUDING (WITHOUT LIMITATION) ANY LOST
-PROFITS OR LOST SAVINGS (WHETHER RESULTING FROM IMPAIRED OR LOST DATA,
-SOFTWARE OR COMPUTER FAILURE OR ANY OTHER CAUSE), EVEN IF IT HAS BEEN ADVISED
-OF THE POSSIBILITY OF SUCH DAMAGES. NOTWITHSTANDING ANY OTHER PROVISION IN
-THIS AGREEMENT, THE LIABILITY OF LICENSOR FOR ANY REASON AND UPON ANY CAUSE OF
-ACTION SHALL BE LIMITED TO THE AMOUNT PAID TO LICENSOR BY LICENSEE UNDER THIS
-AGREEMENT. THIS LIMITATION APPLIES TO ALL CAUSES OF ACTION IN THE AGGREGATE,
-INCLUDING (WITHOUT LIMITATION) BREACH OF CONTRACT, BREACH OF WARRANTY,
-NEGLIGENCE, MISREPRESENTATIONS AND OTHER TORTS. THE PARTIES AGREE THAT THE
-REMEDIES AND LIMITATIONS HEREIN ALLOCATE THE RISKS BETWEEN THE PARTIES AS
-AUTHORIZED BY APPLICABLE LAWS. THE LICENSE FEES ARE SET IN RELIANCE UPON THIS
-ALLOCATION OF RISK AND THE EXCLUSION OF CERTAIN DAMAGES AS SET FORTH IN THIS
-AGREEMENT.
-
-10. Miscellaneous.
-
-10.1 Interpretation.
-Failure by Licensor to exercise any right or remedy does not signify
-acceptance of the event giving rise to such right or remedy. No action arising
-out of this License may be brought by Licensee more than one year after the
-cause of action has accrued. If any part of this License is held by a court of
-competent jurisdiction to be illegal or unenforceable, the validity or
-enforceability of the remainder of this License shall not be affected and such
-provision shall be deemed modified to the minimum extent necessary to make
-such provision consistent with applicable law and, in its modified form, such
-provision shall be enforceable and enforced. Licensor reserves the right not
-to accept any Order Form. Any invoice issued by Licensor in connection with
-this License shall be deemed a part of this Agreement. To the extent of any
-inconsistency between an Order Form and an invoice issued by Licensor, the
-terms and conditions of the invoice shall prevail; Licensee shall be deemed to
-have accepted an invoice upon payment of such invoice. In the event that
-Licensee placed an order by telephone or through an authorized sales
-representative, the invoice issued by Licensor shall constitute the Order
-Form. The terms and conditions of this Agreement shall replace and serve as a
-novation of the terms and conditions of any commercial (i.e., non-GPL) license
-purchased online by Licensee prior to August 2002.
-
-10.2 Binding.
-This Agreement will be binding upon and inure to the benefit of the parties,
-their respective successors and permitted assigns. Except as otherwise
-provided in Section 2, without the prior written consent of Licensor, Licensee
-may not assign this License or its rights or obligations under this License to
-any person or party, whether by operation of law or otherwise; any attempt by
-Licensee to assign this License without Licensor's prior written consent shall
-be null and void. There are no intended third party beneficiaries of this
-License. The parties are, and shall remain, independent contractors; nothing
-in this License is designed to create, nor shall create between them, a
-partnership, joint venture, agency, or employment relationship.
-
-10.3 Governing Law; Dispute Forum.
-If Licensee's residence, principal place of business or place of organization
-is in the United States of America ("USA"), then this License shall be deemed
-to have been executed in the USA and shall be governed by the laws of the
-State of Delaware, without regard to the conflict of laws provisions thereof.
-If Licensee's residence, principal place of business or place of organization
-is in any country other than the USA, then this License shall be deemed to
-have been executed in Sweden and shall be governed by the laws of Sweden,
-without regard to the conflict of laws provisions thereof. In no event shall
-the United Nations Convention on Contracts for the International Sale of Goods
-apply to, or govern, this License. The parties consent to the exclusive
-jurisdiction of the courts of Sweden and the USA, as provided in this Section.
-In the event that Licensor initiates an action in connection with this License
-or any other dispute between the parties, the exclusive jurisdiction of such
-action shall be in: (a) Newark, Delaware, if Licensee's residence, principal
-place of business or place of organization is in the USA; or (b) Uppsala,
-Sweden, if Licensee's residence, principal place of business or place of
-organization is in any country other than the USA. In the event that Licensee
-initiates an action in connection with this License or any other dispute
-between the parties, the exclusive jurisdiction of such action shall be in
-Stockholm, Sweden. Notwithstanding the foregoing, either party may bring a
-counterclaim in an action in the same jurisdiction in which the originating
-claim was filed, and either party may enforce any judgment rendered by such
-court in any court of competent jurisdiction. Licensee shall comply at its own
-expense with all relevant and applicable laws related to use and distribution
-of the Licensed Software as permitted in this License. Notwithstanding the
-foregoing, Licensor may seek injunctive or other equitable relief in any
-jurisdiction in order to protect its intellectual property rights. The parties
-have agreed to execute this License in the English language, and the English
-language version of the Agreement will control for all purposes. Any action
-brought under this License shall be conducted in the English language.
-Licensee shall be responsible for Licensor's attorneys fees and other expenses
-associated with the enforcement of this License or the collection of any
-amounts due under this License.
-
-10.4 Notice.
-Unless otherwise agreed, any notice under this License shall be delivered and
-addressed to Licensee at the address set forth on the Order Form, and to
-Licensor at Bangardsgatan 8, 753 20, Uppsala, Sweden. Notice shall be deemed
-received by any party: (a) on the day given, if personally delivered or if
-sent by confirmed facsimile transmission, receipt verified; (b) on the third
-day after deposit, if mailed by certified, first class, postage prepaid,
-return receipt requested mail, or by reputable, expedited overnight courier;
-or (c) on the fifth day after deposit, if sent by reputable, expedited
-international courier. Either party may change its address for notice
-purposes upon notice in accordance with this Section. Licensor may identify
-Licensee as a commercial licensee, including on the MySQL web site.
-
-10.5 GPL.
-The GPL License shall continue to apply to any and all uses and distributions
-of the Licensed Software undertaken by Licensee either prior to the Effective
-Date, after termination, or otherwise outside the scope of this License. This
-Agreement shall not be deemed to replace or otherwise amend any Licensee
-rights or obligations pursuant to the GPL License with respect to any uses of
-the Licensed Software described in the preceding sentence.
-
-10.6 Entire Agreement.
-This Agreement (including the Order Form and the invoice) comprises the entire
-agreement, and supercedes and merges all prior proposals, understandings and
-agreements, oral and written, between the parties relating to the subject
-matter of this License. This Agreement may be amended or modified only in a
-writing executed by both parties. To the extent of any conflict or
-inconsistency between this License and any invoice or other document submitted
-by Licensee to Licensor, this License will control. Licensor's acceptance of
-any document shall not be construed as an acceptance of provisions which are
-in any way in conflict or inconsistent with, or in addition to, this License,
-unless such terms are separately and specifically accepted in writing by an
-authorized officer of Licensor.
-
-10.7 Print this License.
-For record keeping purposes, we encourage Licensee to print this License and
-the Order Form on the date that the Order Form is submitted.
diff --git a/README b/README
index d37b37cd918..56bd912d3d6 100644
--- a/README
+++ b/README
@@ -2,8 +2,9 @@ This is a release of MySQL, a dual-license SQL database server.
MySQL is brought to you by the MySQL team at MySQL AB.
License information can be found in these files:
-- For GPL (free) distributions, see the COPYING file.
-- For commercial distributions, see the MySQLEULA.txt file.
+- For GPL (free) distributions, see the COPYING file and
+ the EXCEPTIONS-CLIENT file.
+- For commercial distributions, see the LICENSE.mysql file.
For further information about MySQL or additional documentation, see:
@@ -15,11 +16,10 @@ Some manual sections of special interest:
- If you are migrating from an older version of MySQL, please read the
"Upgrading from..." section first!
- To see what MySQL can do, take a look at the features section.
-- For installation instructions, see the Installation chapter.
-- For future plans, see the TODO appendix.
-- For the new features/bugfix history, see the News appendix.
-- For the currently known bugs/misfeatures (known errors) see the problems
- appendix.
+- For installation instructions, see the Installing and Upgrading chapter.
+- For the new features/bugfix history, see the Change History appendix.
+- For the currently known bugs/misfeatures (known errors) see the Problems
+ and Common Errors appendix.
- For a list of developers and other contributors, see the Credits
appendix.
diff --git a/client/Makefile.am b/client/Makefile.am
index d3e96dd126f..7d48e34b37b 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -46,7 +46,8 @@ mysqladmin_SOURCES = mysqladmin.cc
mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS)
mysqltest_SOURCES= mysqltest.c $(top_srcdir)/mysys/my_getsystime.c \
$(yassl_dummy_link_fix)
-mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD)
+mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) \
+ $(top_builddir)/mysys/libmysys.a
mysqlbinlog_SOURCES = mysqlbinlog.cc $(top_srcdir)/mysys/mf_tempdir.c \
$(top_srcdir)/mysys/my_new.cc \
$(top_srcdir)/mysys/my_bit.c \
diff --git a/client/mysql.cc b/client/mysql.cc
index 1dbdeb8be97..486e5bc113c 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -386,6 +386,21 @@ int main(int argc,char *argv[])
else
status.add_to_history=1;
status.exit_status=1;
+
+ {
+ /*
+ The file descriptor-layer may be out-of-sync with the file-number layer,
+ so we make sure that "stdout" is really open. If its file is closed then
+ explicitly close the FD layer.
+ */
+ int stdout_fileno_copy;
+ stdout_fileno_copy= dup(fileno(stdout)); /* Okay if fileno fails. */
+ if (stdout_fileno_copy == -1)
+ fclose(stdout);
+ else
+ close(stdout_fileno_copy); /* Clean up dup(). */
+ }
+
load_defaults("my",load_default_groups,&argc,&argv);
defaults_argv=argv;
if (get_options(argc, (char **) argv))
@@ -2091,6 +2106,8 @@ com_go(String *buffer,char *line __attribute__((unused)))
(long) mysql_num_rows(result),
(long) mysql_num_rows(result) == 1 ? "row" : "rows");
end_pager();
+ if (mysql_errno(&mysql))
+ error= put_error(&mysql);
}
}
else if (mysql_affected_rows(&mysql) == ~(ulonglong) 0)
@@ -2905,7 +2922,11 @@ com_connect(String *buffer, char *line)
bzero(buff, sizeof(buff));
if (buffer)
{
- strmake(buff, line, sizeof(buff) - 1);
+ /*
+ Two null bytes are needed in the end of buff to allow
+ get_arg to find end of string the second time it's called.
+ */
+ strmake(buff, line, sizeof(buff)-2);
tmp= get_arg(buff, 0);
if (tmp && *tmp)
{
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 543b61c2843..05c28e46eb5 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -45,6 +45,7 @@
#include <m_string.h>
#include <m_ctype.h>
#include <hash.h>
+#include <stdarg.h>
#include "client_priv.h"
#include "mysql.h"
@@ -544,6 +545,8 @@ static void write_header(FILE *sql_file, char *db_name)
if (opt_xml)
{
fputs("<?xml version=\"1.0\"?>\n", sql_file);
+ /* Schema reference. Allows use of xsi:nil for NULL values and
+ xsi:type to define an element's data type. */
fputs("<mysqldump ", sql_file);
fputs("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"",
sql_file);
@@ -1144,7 +1147,7 @@ static char *quote_for_like(const char *name, char *buff)
SYNOPSIS
print_quoted_xml()
- output - output file
+ xml_file - output file
str - string to print
len - its length
@@ -1181,34 +1184,63 @@ static void print_quoted_xml(FILE *xml_file, const char *str, ulong len)
/*
- Print xml tag with one attribute.
+ Print xml tag. Optionally add attribute(s).
SYNOPSIS
- print_xml_tag1()
- xml_file - output file
- sbeg - line beginning
- stag_atr - tag and attribute
- sval - value of attribute
- send - line ending
+ print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
+ ..., attribute_name_n, attribute_value_n, NullS)
+ xml_file - output file
+ sbeg - line beginning
+ send - line ending
+ tag_name - XML tag name.
+ first_attribute_name - tag and first attribute
+ first_attribute_value - (Implied) value of first attribute
+ attribute_name_n - attribute n
+ attribute_value_n - value of attribute n
DESCRIPTION
- Print tag with one attribute to the xml_file. Format is:
- sbeg<stag_atr="sval">send
+ Print XML tag with any number of attribute="value" pairs to the xml_file.
+
+ Format is:
+ sbeg<tag_name first_attribute_name="first_attribute_value" ...
+ attribute_name_n="attribute_value_n">send
NOTE
- sval MUST be a NULL terminated string.
- sval string will be qouted before output.
+ Additional arguments must be present in attribute/value pairs.
+ The last argument should be the null character pointer.
+ All attribute_value arguments MUST be NULL terminated strings.
+ All attribute_value arguments will be quoted before output.
*/
-static void print_xml_tag1(FILE * xml_file, const char* sbeg,
- const char* stag_atr, const char* sval,
- const char* send)
+static void print_xml_tag(FILE * xml_file, const char* sbeg, const char* send,
+ const char* tag_name,
+ const char* first_attribute_name, ...)
{
+ va_list arg_list;
+ const char *attribute_name, *attribute_value;
+
fputs(sbeg, xml_file);
- fputs("<", xml_file);
- fputs(stag_atr, xml_file);
- fputs("\"", xml_file);
- print_quoted_xml(xml_file, sval, strlen(sval));
- fputs("\">", xml_file);
+ fputc('<', xml_file);
+ fputs(tag_name, xml_file);
+
+ va_start(arg_list, first_attribute_name);
+ attribute_name= first_attribute_name;
+ while (attribute_name != NullS)
+ {
+ attribute_value= va_arg(arg_list, char *);
+ DBUG_ASSERT(attribute_value != NullS);
+
+ fputc(' ', xml_file);
+ fputs(attribute_name, xml_file);
+ fputc('\"', xml_file);
+
+ print_quoted_xml(xml_file, attribute_value, strlen(attribute_value));
+ fputc('\"', xml_file);
+
+ attribute_name= va_arg(arg_list, char *);
+ }
+ va_end(arg_list);
+
+ fputc('>', xml_file);
fputs(send, xml_file);
check_io(xml_file);
}
@@ -1419,6 +1451,28 @@ static uint dump_events_for_db(char *db)
/*
+ Print hex value for blob data.
+
+ SYNOPSIS
+ print_blob_as_hex()
+ output_file - output file
+ str - string to print
+ len - its length
+
+ DESCRIPTION
+ Print hex value for blob data.
+*/
+
+static void print_blob_as_hex(FILE *output_file, const char *str, ulong len)
+{
+ /* sakaik got the idea to to provide blob's in hex notation. */
+ const char *ptr= str, *end= ptr + len;
+ for (; ptr < end ; ptr++)
+ fprintf(output_file, "%02X", *((uchar *)ptr));
+ check_io(output_file);
+}
+
+/*
dump_routines_for_db
-- retrieves list of routines for a given db, and prints out
the CREATE PROCEDURE definition into the output (the dump).
@@ -1865,7 +1919,8 @@ static uint get_table_structure(char *table, char *db, char *table_type,
if (!opt_xml)
fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
else
- print_xml_tag1(sql_file, "\t", "table_structure name=", table, "\n");
+ print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table,
+ NullS);
check_io(sql_file);
}
@@ -2437,8 +2492,8 @@ static void dump_table(char *table, char *db)
rownr=0;
init_length=(uint) insert_pat.length+4;
if (opt_xml)
- print_xml_tag1(md_result_file, "\t", "table_data name=", table, "\n");
-
+ print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table,
+ NullS);
if (opt_autocommit)
{
fprintf(md_result_file, "set autocommit=0;\n");
@@ -2492,7 +2547,7 @@ static void dump_table(char *table, char *db)
field->type == MYSQL_TYPE_LONG_BLOB ||
field->type == MYSQL_TYPE_MEDIUM_BLOB ||
field->type == MYSQL_TYPE_TINY_BLOB)) ? 1 : 0;
- if (extended_insert)
+ if (extended_insert && !opt_xml)
{
if (i == 0)
dynstr_set(&extended_row,"(");
@@ -2581,18 +2636,25 @@ static void dump_table(char *table, char *db)
{
if (opt_xml)
{
- print_xml_tag1(md_result_file, "\t\t", "field name=",
- field->name, "");
- print_quoted_xml(md_result_file, row[i], length);
+ if (opt_hex_blob && is_blob && length)
+ {
+ /* Define xsi:type="xs:hexBinary" for hex encoded data */
+ print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
+ field->name, "xsi:type=", "xs:hexBinary", NullS);
+ print_blob_as_hex(md_result_file, row[i], length);
+ }
+ else
+ {
+ print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
+ field->name, NullS);
+ print_quoted_xml(md_result_file, row[i], length);
+ }
fputs("</field>\n", md_result_file);
}
else if (opt_hex_blob && is_blob && length)
{
- /* sakaik got the idea to to provide blob's in hex notation. */
- char *ptr= row[i], *end= ptr + length;
fputs("0x", md_result_file);
- for (; ptr < end ; ptr++)
- fprintf(md_result_file, "%02X", *((uchar *)ptr));
+ print_blob_as_hex(md_result_file, row[i], length);
}
else
unescape(md_result_file, row[i], length);
@@ -2603,8 +2665,8 @@ static void dump_table(char *table, char *db)
char *ptr= row[i];
if (opt_xml)
{
- print_xml_tag1(md_result_file, "\t\t", "field name=",
- field->name, "");
+ print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
+ field->name, NullS);
fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
md_result_file);
fputs("</field>\n", md_result_file);
@@ -3187,7 +3249,7 @@ static int dump_all_tables_in_db(char *database)
if (init_dumping(database, init_dumping_tables))
return 1;
if (opt_xml)
- print_xml_tag1(md_result_file, "", "database name=", database, "\n");
+ print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS);
if (lock_tables)
{
DYNAMIC_STRING query;
@@ -3270,7 +3332,7 @@ static my_bool dump_all_views_in_db(char *database)
if (init_dumping(database, init_dumping_views))
return 1;
if (opt_xml)
- print_xml_tag1(md_result_file, "", "database name=", database, "\n");
+ print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS);
if (lock_tables)
{
DYNAMIC_STRING query;
@@ -3409,7 +3471,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
/* We shall countinue here, if --force was given */
}
if (opt_xml)
- print_xml_tag1(md_result_file, "", "database name=", db, "\n");
+ print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NullS);
/* Dump each selected table */
for (pos= dump_tables; pos < end; pos++)
@@ -3522,7 +3584,7 @@ static int do_reset_master(MYSQL *mysql_con)
}
-static int start_transaction(MYSQL *mysql_con, my_bool consistent_read_now)
+static int start_transaction(MYSQL *mysql_con)
{
/*
We use BEGIN for old servers. --single-transaction --master-data will fail
@@ -3537,10 +3599,8 @@ static int start_transaction(MYSQL *mysql_con, my_bool consistent_read_now)
"SET SESSION TRANSACTION ISOLATION "
"LEVEL REPEATABLE READ") ||
mysql_query_with_error_report(mysql_con, 0,
- consistent_read_now ?
"START TRANSACTION "
- "WITH CONSISTENT SNAPSHOT" :
- "BEGIN"));
+ "/*!40100 WITH CONSISTENT SNAPSHOT */"));
}
@@ -4030,7 +4090,7 @@ int main(int argc, char **argv)
if ((opt_lock_all_tables || opt_master_data) &&
do_flush_tables_read_lock(mysql))
goto err;
- if (opt_single_transaction && start_transaction(mysql, test(opt_master_data)))
+ if (opt_single_transaction && start_transaction(mysql))
goto err;
if (opt_delete_master_logs && do_reset_master(mysql))
goto err;
diff --git a/client/mysqltest.c b/client/mysqltest.c
index f9c4ae617fd..aeb86575333 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -14,35 +14,24 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* mysqltest test tool
- * See the manual for more information
- * TODO: document better how mysqltest works
- *
- * Written by:
- * Sasha Pachev <sasha@mysql.com>
- * Matt Wagner <matt@mysql.com>
- * Monty
- * Jani
- **/
-
-/**********************************************************************
- TODO:
+/*
+ mysqltest
-- Do comparison line by line, instead of doing a full comparison of
- the text file. This will save space as we don't need to keep many
- results in memory. It will also make it possible to do simple
- 'comparison' fixes like accepting the result even if a float differed
- in the last decimals.
+ Tool used for executing a .test file
-- Don't buffer lines from the test that you don't expect to need
- again.
+ See the "MySQL Test framework manual" for more information
+ http://dev.mysql.com/doc/mysqltest/en/index.html
-- Change 'read_line' to be faster by using the readline.cc code;
- We can do better than calling feof() for each character!
+ Please keep the test framework tools identical in all versions!
-**********************************************************************/
+ Written by:
+ Sasha Pachev <sasha@mysql.com>
+ Matt Wagner <matt@mysql.com>
+ Monty
+ Jani
+*/
-#define MTEST_VERSION "2.6"
+#define MTEST_VERSION "3.0"
#include <my_global.h>
#include <mysql_embed.h>
@@ -51,18 +40,18 @@
#include <mysql.h>
#include <mysql_version.h>
#include <mysqld_error.h>
+#include <errmsg.h>
#include <m_ctype.h>
#include <my_dir.h>
-#include <errmsg.h> /* Error codes */
#include <hash.h>
#include <my_getopt.h>
#include <stdarg.h>
-#include <sys/stat.h>
#include <violite.h>
-#include "my_regex.h" /* Our own version of lib */
+#include "my_regex.h" /* Our own version of regex */
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
+
#ifndef WEXITSTATUS
# ifdef __WIN__
# define WEXITSTATUS(stat_val) (stat_val)
@@ -70,169 +59,116 @@
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
# endif
#endif
-/* MAX_QUERY is 256K -- there is a test in sp-big that is >128K */
-#define MAX_QUERY (256*1024)
-#define MAX_VAR_NAME 256
-#define MAX_COLUMNS 256
-#define MAX_CONS 128
-#define MAX_INCLUDE_DEPTH 16
-#define INIT_Q_LINES 1024
-#define MIN_VAR_ALLOC 32
-#define BLOCK_STACK_DEPTH 32
-#define MAX_EXPECTED_ERRORS 10
-#define QUERY_SEND 1
-#define QUERY_REAP 2
-#define MAX_SERVER_ARGS 64
-
-
-#define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */
-#define DEFAULT_DELIMITER ";"
-#define MAX_DELIMITER 16
-
-#define RESULT_OK 0
-#define RESULT_CONTENT_MISMATCH 1
-#define RESULT_LENGTH_MISMATCH 2
-
-enum {OPT_SKIP_SAFEMALLOC=256, OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT,
- OPT_SSL_CA, OPT_SSL_CAPATH, OPT_SSL_CIPHER, OPT_PS_PROTOCOL,
- OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
- OPT_SSL_VERIFY_SERVER_CERT, OPT_MAX_CONNECT_RETRIES,
- OPT_MARK_PROGRESS};
-
-/* ************************************************************************ */
-/*
- The list of error codes to --error are stored in an internal array of
- structs. This struct can hold numeric SQL error codes or SQLSTATE codes
- as strings. The element next to the last active element in the list is
- set to type ERR_EMPTY. When an SQL statement returns an error, we use
- this list to check if this is an expected error.
-*/
-
-enum match_err_type
-{
- ERR_EMPTY= 0,
- ERR_ERRNO,
- ERR_SQLSTATE
-};
-
-typedef struct
-{
- enum match_err_type type;
- union
- {
- uint errnum;
- char sqlstate[SQLSTATE_LENGTH+1]; /* \0 terminated string */
- } code;
-} match_err;
-
-typedef struct
-{
- const char *name;
- long code;
-} st_error;
-static st_error global_error[] =
-{
-#include <mysqld_ername.h>
- { 0, 0 }
+#define MAX_VAR_NAME_LENGTH 256
+#define MAX_COLUMNS 256
+#define MAX_EMBEDDED_SERVER_ARGS 64
+#define MAX_DELIMITER_LENGTH 16
+
+/* Flags controlling send and reap */
+#define QUERY_SEND_FLAG 1
+#define QUERY_REAP_FLAG 2
+
+ enum {
+ RESULT_OK= 0,
+ RESULT_CONTENT_MISMATCH= 1,
+ RESULT_LENGTH_MISMATCH= 2
+ };
+
+enum {
+ OPT_SKIP_SAFEMALLOC=256, OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT,
+ OPT_SSL_CA, OPT_SSL_CAPATH, OPT_SSL_CIPHER, OPT_PS_PROTOCOL,
+ OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
+ OPT_SSL_VERIFY_SERVER_CERT, OPT_MAX_CONNECT_RETRIES,
+ OPT_MARK_PROGRESS
};
-static match_err global_expected_errno[MAX_EXPECTED_ERRORS];
-static uint global_expected_errors;
-
-/* ************************************************************************ */
-
static int record= 0, opt_sleep= -1;
-static char *db = 0, *pass=0;
-const char *user = 0, *host = 0, *unix_sock = 0, *opt_basedir="./";
+static char *db= 0, *pass= 0;
+const char *user= 0, *host= 0, *unix_sock= 0, *opt_basedir= "./";
const char *opt_include= 0;
-static int port = 0;
+static int port= 0;
static int opt_max_connect_retries;
-static my_bool opt_big_test= 0, opt_compress= 0, silent= 0, verbose = 0;
+static my_bool opt_compress= 0, silent= 0, verbose= 0;
static my_bool tty_password= 0;
static my_bool opt_mark_progress= 0;
static my_bool ps_protocol= 0, ps_protocol_enabled= 0;
static my_bool sp_protocol= 0, sp_protocol_enabled= 0;
static my_bool view_protocol= 0, view_protocol_enabled= 0;
static my_bool cursor_protocol= 0, cursor_protocol_enabled= 0;
-static my_bool opt_valgrind_test= 0;
-static int parsing_disabled= 0;
+static my_bool parsing_disabled= 0;
+static my_bool display_result_vertically= FALSE, display_metadata= FALSE;
+static my_bool disable_query_log= 0, disable_result_log= 0;
+static my_bool disable_warnings= 0, disable_ps_warnings= 0;
+static my_bool disable_info= 1;
+static my_bool abort_on_error= 1;
static char **default_argv;
-static const char *load_default_groups[]= { "mysqltest","client",0 };
-static char line_buffer[MAX_DELIMITER], *line_buffer_pos= line_buffer;
+static const char *load_default_groups[]= { "mysqltest", "client", 0 };
+static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer;
-typedef struct
-{
- FILE* file;
- const char *file_name;
- uint lineno; /* Current line in file */
-} test_file;
+static uint start_lineno= 0; /* Start line of current command */
+
+static char delimiter[MAX_DELIMITER_LENGTH]= ";";
+static uint delimiter_length= 1;
-static test_file file_stack[MAX_INCLUDE_DEPTH];
-static test_file* cur_file;
-static test_file* file_stack_end;
-uint start_lineno= 0; /* Start line of query */
+static char TMPDIR[FN_REFLEN];
-/* Stores regex substitutions */
+/* Block stack */
+enum block_cmd {
+ cmd_none,
+ cmd_if,
+ cmd_while
+};
-struct st_regex
+struct st_block
{
- char* pattern; /* Pattern to be replaced */
- char* replace; /* String or expression to replace the pattern with */
- int icase; /* true if the match is case insensitive */
+ int line; /* Start line of block */
+ my_bool ok; /* Should block be executed */
+ enum block_cmd cmd; /* Command owning the block */
};
-struct st_replace_regex
+static struct st_block block_stack[32];
+static struct st_block *cur_block, *block_stack_end;
+
+/* Open file stack */
+struct st_test_file
{
- DYNAMIC_ARRAY regex_arr; /* stores a list of st_regex subsitutions */
-
- /*
- Temporary storage areas for substitutions. To reduce unnessary copying
- and memory freeing/allocation, we pre-allocate two buffers, and alternate
- their use, one for input/one for output, the roles changing on the next
- st_regex substition. At the end of substitutions buf points to the
- one containing the final result.
- */
- char* buf;
- char* even_buf;
- char* odd_buf;
- int even_buf_len;
- int odd_buf_len;
+ FILE* file;
+ const char *file_name;
+ uint lineno; /* Current line in file */
};
-struct st_replace_regex *glob_replace_regex= 0;
-
-static char TMPDIR[FN_REFLEN];
-static char delimiter[MAX_DELIMITER]= DEFAULT_DELIMITER;
-static uint delimiter_length= 1;
+static struct st_test_file file_stack[16];
+static struct st_test_file* cur_file;
+static struct st_test_file* file_stack_end;
-/* Block stack */
-enum block_cmd { cmd_none, cmd_if, cmd_while };
-typedef struct
-{
- int line; /* Start line of block */
- my_bool ok; /* Should block be executed */
- enum block_cmd cmd; /* Command owning the block */
-} BLOCK;
-static BLOCK block_stack[BLOCK_STACK_DEPTH];
-static BLOCK *cur_block, *block_stack_end;
static CHARSET_INFO *charset_info= &my_charset_latin1; /* Default charset */
static const char *charset_name= "latin1"; /* Default character set name */
-static int embedded_server_arg_count=0;
-static char *embedded_server_args[MAX_SERVER_ARGS];
+static const char *embedded_server_groups[]=
+{
+ "server",
+ "embedded",
+ "mysqltest_SERVER",
+ NullS
+};
-static my_bool display_result_vertically= FALSE, display_metadata= FALSE;
+static int embedded_server_arg_count=0;
+static char *embedded_server_args[MAX_EMBEDDED_SERVER_ARGS];
-/* See the timer_output() definition for details */
+/*
+ Timer related variables
+ See the timer_output() definition for details
+*/
static char *timer_file = NULL;
-static ulonglong timer_start, progress_start= 0;
-static int got_end_timer= FALSE;
+static ulonglong timer_start;
static void timer_output(void);
static ulonglong timer_now(void);
+static ulonglong progress_start= 0;
+
/* Precompiled re's */
static my_regex_t ps_re; /* the query can be run using PS protocol */
static my_regex_t sp_re; /* the query can be run as a SP */
@@ -242,47 +178,25 @@ static void init_re(void);
static int match_re(my_regex_t *, char *);
static void free_re(void);
-static int reg_replace(char** buf_p, int* buf_len_p, char *pattern, char *replace,
- char *string, int icase);
-
-static const char *embedded_server_groups[]=
-{
- "server",
- "embedded",
- "mysqltest_SERVER",
- NullS
-};
-
DYNAMIC_ARRAY q_lines;
#include "sslopt-vars.h"
-typedef struct
-{
- char file[FN_REFLEN];
- ulong pos;
-} MASTER_POS ;
-
-struct connection
+struct
{
- MYSQL mysql;
- /* Used when creating views and sp, to avoid implicit commit */
- MYSQL* util_mysql;
- char *name;
- MYSQL_STMT* stmt;
-};
+ int read_lines,current_line;
+} parser;
-typedef struct
+struct
{
- int read_lines,current_line;
-} PARSER;
+ char file[FN_REFLEN];
+ ulong pos;
+} master_pos;
-PARSER parser;
-MASTER_POS master_pos;
/* if set, all results are concated and compared against this file */
-const char *result_file = 0;
+const char *result_file_name= 0;
-typedef struct
+typedef struct st_var
{
char *name;
int name_len;
@@ -295,70 +209,68 @@ typedef struct
char *env_s;
} VAR;
-VAR var_reg[10];
/*Perl/shell-like variable registers */
-HASH var_hash;
-my_bool disable_query_log=0, disable_result_log=0, disable_warnings=0;
-my_bool disable_ps_warnings= 0;
-my_bool disable_info= 1; /* By default off */
-my_bool abort_on_error= 1;
+VAR var_reg[10];
-struct connection cons[MAX_CONS];
-struct connection* cur_con, *next_con, *cons_end;
+HASH var_hash;
- /* Add new commands before Q_UNKNOWN !*/
+struct st_connection
+{
+ MYSQL mysql;
+ /* Used when creating views and sp, to avoid implicit commit */
+ MYSQL* util_mysql;
+ char *name;
+ MYSQL_STMT* stmt;
+};
+struct st_connection connections[128];
+struct st_connection* cur_con, *next_con, *connections_end;
+/*
+ List of commands in mysqltest
+ Must match the "command_names" array
+ Add new commands before Q_UNKNOWN!
+*/
enum enum_commands {
-Q_CONNECTION=1, Q_QUERY,
-Q_CONNECT, Q_SLEEP, Q_REAL_SLEEP,
-Q_INC, Q_DEC,
-Q_SOURCE, Q_DISCONNECT,
-Q_LET, Q_ECHO,
-Q_WHILE, Q_END_BLOCK,
-Q_SYSTEM, Q_RESULT,
-Q_REQUIRE, Q_SAVE_MASTER_POS,
-Q_SYNC_WITH_MASTER,
-Q_SYNC_SLAVE_WITH_MASTER,
-Q_ERROR,
-Q_SEND, Q_REAP,
-Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN,
-Q_PING, Q_EVAL,
-Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
-Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
-Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
-Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
-Q_WAIT_FOR_SLAVE_TO_STOP,
-Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS,
-Q_ENABLE_PS_WARNINGS, Q_DISABLE_PS_WARNINGS,
-Q_ENABLE_INFO, Q_DISABLE_INFO,
-Q_ENABLE_METADATA, Q_DISABLE_METADATA,
-Q_EXEC, Q_DELIMITER,
-Q_DISABLE_ABORT_ON_ERROR, Q_ENABLE_ABORT_ON_ERROR,
-Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS,
-Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL,
-Q_START_TIMER, Q_END_TIMER,
-Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL,
-Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT,
-Q_IF,
-Q_DISABLE_PARSING, Q_ENABLE_PARSING,
-Q_REPLACE_REGEX, Q_DIE,
-
-Q_UNKNOWN, /* Unknown command. */
-Q_COMMENT, /* Comments, ignored. */
-Q_COMMENT_WITH_COMMAND
+ Q_CONNECTION=1, Q_QUERY,
+ Q_CONNECT, Q_SLEEP, Q_REAL_SLEEP,
+ Q_INC, Q_DEC,
+ Q_SOURCE, Q_DISCONNECT,
+ Q_LET, Q_ECHO,
+ Q_WHILE, Q_END_BLOCK,
+ Q_SYSTEM, Q_RESULT,
+ Q_REQUIRE, Q_SAVE_MASTER_POS,
+ Q_SYNC_WITH_MASTER,
+ Q_SYNC_SLAVE_WITH_MASTER,
+ Q_ERROR,
+ Q_SEND, Q_REAP,
+ Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN,
+ Q_PING, Q_EVAL,
+ Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
+ Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
+ Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
+ Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
+ Q_WAIT_FOR_SLAVE_TO_STOP,
+ Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS,
+ Q_ENABLE_PS_WARNINGS, Q_DISABLE_PS_WARNINGS,
+ Q_ENABLE_INFO, Q_DISABLE_INFO,
+ Q_ENABLE_METADATA, Q_DISABLE_METADATA,
+ Q_EXEC, Q_DELIMITER,
+ Q_DISABLE_ABORT_ON_ERROR, Q_ENABLE_ABORT_ON_ERROR,
+ Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS,
+ Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL,
+ Q_START_TIMER, Q_END_TIMER,
+ Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL,
+ Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT,
+ Q_IF,
+ Q_DISABLE_PARSING, Q_ENABLE_PARSING,
+ Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST,
+ Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT,
+
+ Q_UNKNOWN, /* Unknown command. */
+ Q_COMMENT, /* Comments, ignored. */
+ Q_COMMENT_WITH_COMMAND
};
-/* this should really be called command */
-struct st_query
-{
- char *query, *query_buf,*first_argument,*last_argument,*end;
- int first_word_len;
- my_bool abort_on_error, require_file;
- match_err expected_errno[MAX_EXPECTED_ERRORS];
- uint expected_errors;
- char record_file[FN_REFLEN];
- enum enum_commands type;
-};
const char *command_names[]=
{
@@ -427,69 +339,118 @@ const char *command_names[]=
"disable_parsing",
"enable_parsing",
"replace_regex",
+ "remove_file",
+ "file_exists",
+ "write_file",
+ "copy_file",
+ "perl",
"die",
+ /* Don't execute any more commands, compare result */
+ "exit",
0
};
-TYPELIB command_typelib= {array_elements(command_names),"",
- command_names, 0};
-
-DYNAMIC_STRING ds_res, ds_progress;
-static void die(const char *fmt, ...);
-static void init_var_hash();
-static VAR* var_from_env(const char *, const char *);
-static byte* get_var_key(const byte* rec, uint* len, my_bool t);
-static VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
- int val_len);
-static void var_free(void* v);
+/*
+ The list of error codes to --error are stored in an internal array of
+ structs. This struct can hold numeric SQL error codes, error names or
+ SQLSTATE codes as strings. The element next to the last active element
+ in the list is set to type ERR_EMPTY. When an SQL statement returns an
+ error, we use this list to check if this is an expected error.
+*/
+enum match_err_type
+{
+ ERR_EMPTY= 0,
+ ERR_ERRNO,
+ ERR_SQLSTATE
+};
-void dump_result_to_reject_file(const char *record_file, char *buf, int size);
-void dump_result_to_log_file(const char *record_file, char *buf, int size);
+struct st_match_err
+{
+ enum match_err_type type;
+ union
+ {
+ uint errnum;
+ char sqlstate[SQLSTATE_LENGTH+1]; /* \0 terminated string */
+ } code;
+};
-int close_connection(struct st_query*);
-static void set_charset(struct st_query*);
-VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw,
- my_bool ignore_not_existing);
-int eval_expr(VAR* v, const char *p, const char** p_end);
-static int read_server_arguments(const char *name);
+struct st_expected_errors
+{
+ struct st_match_err err[10];
+ uint count;
+};
+static struct st_expected_errors saved_expected_errors;
-/* Definitions for replace result */
+struct st_command
+{
+ char *query, *query_buf,*first_argument,*last_argument,*end;
+ int first_word_len, query_len;
+ my_bool abort_on_error;
+ struct st_expected_errors expected_errors;
+ char require_file[FN_REFLEN];
+ enum enum_commands type;
+};
-typedef struct st_pointer_array { /* when using array-strings */
- TYPELIB typelib; /* Pointer to strings */
- byte *str; /* Strings is here */
- int7 *flag; /* Flag about each var. */
- uint array_allocs,max_count,length,max_length;
-} POINTER_ARRAY;
+TYPELIB command_typelib= {array_elements(command_names),"",
+ command_names, 0};
-struct st_replace;
-struct st_replace *init_replace(my_string *from, my_string *to, uint count,
- my_string word_end_chars);
-void free_replace();
-static void free_replace_regex();
-static int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name);
-static void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds,
- const char *from, int len);
-void free_pointer_array(POINTER_ARRAY *pa);
-static void do_eval(DYNAMIC_STRING *query_eval, const char *query,
- my_bool pass_through_escape_chars);
-static void str_to_file(const char *fname, char *str, int size);
+DYNAMIC_STRING ds_res, ds_progress, ds_warning_messages;
+
+void die(const char *fmt, ...)
+ ATTRIBUTE_FORMAT(printf, 1, 2);
+void abort_not_supported_test(const char *fmt, ...)
+ ATTRIBUTE_FORMAT(printf, 1, 2);
+void verbose_msg(const char *fmt, ...)
+ ATTRIBUTE_FORMAT(printf, 1, 2);
+void warning_msg(const char *fmt, ...)
+ ATTRIBUTE_FORMAT(printf, 1, 2);
+
+VAR* var_from_env(const char *, const char *);
+VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
+ int val_len);
+void var_free(void* v);
+VAR* var_get(const char *var_name, const char** var_name_end,
+ my_bool raw, my_bool ignore_not_existing);
+void eval_expr(VAR* v, const char *p, const char** p_end);
+my_bool match_delimiter(int c, const char *delim, uint length);
+void dump_result_to_reject_file(char *buf, int size);
+void dump_result_to_log_file(char *buf, int size);
+void dump_warning_messages();
+void dump_progress();
+
+void do_eval(DYNAMIC_STRING *query_eval, const char *query,
+ const char *query_end, my_bool pass_through_escape_chars);
+void str_to_file(const char *fname, char *str, int size);
#ifdef __WIN__
-static void free_tmp_sh_file();
-static void free_win_path_patterns();
+void free_tmp_sh_file();
+void free_win_path_patterns();
#endif
-struct st_replace *glob_replace;
static int eval_result = 0;
-/* For column replace */
-char *replace_column[MAX_COLUMNS];
-uint max_replace_column= 0;
+/* For replace_column */
+static char *replace_column[MAX_COLUMNS];
+static uint max_replace_column= 0;
+void do_get_replace_column(struct st_command*);
+void free_replace_column();
+
+/* For replace */
+void do_get_replace(struct st_command *command);
+void free_replace();
+
+/* For replace_regex */
+void do_get_replace_regex(struct st_command *command);
+void free_replace_regex();
+
+
+void free_all_replace(){
+ free_replace();
+ free_replace_regex();
+ free_replace_column();
+}
-static void get_replace_column(struct st_query *q);
-static void free_replace_column();
/* Disable functions that only exist in MySQL 4.0 */
#if MYSQL_VERSION_ID < 40000
@@ -498,35 +459,40 @@ void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; }
my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
#endif
-static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
- int len);
-static void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
-static void handle_error(const char *query, struct st_query *q,
- unsigned int err_errno, const char *err_error,
- const char *err_sqlstate, DYNAMIC_STRING *ds);
-static void handle_no_error(struct st_query *q);
-static void do_eval(DYNAMIC_STRING* query_eval, const char *query,
- my_bool pass_through_escape_chars)
+void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
+ int len);
+void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
+void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val);
+
+void handle_error(struct st_command*,
+ unsigned int err_errno, const char *err_error,
+ const char *err_sqlstate, DYNAMIC_STRING *ds);
+void handle_no_error(struct st_command*);
+
+
+
+void do_eval(DYNAMIC_STRING *query_eval, const char *query,
+ const char *query_end, my_bool pass_through_escape_chars)
{
const char *p;
register char c, next_c;
register int escaped = 0;
- VAR* v;
+ VAR *v;
DBUG_ENTER("do_eval");
- for (p= query; (c = *p); ++p)
+ for (p= query; (c= *p) && p < query_end; ++p)
{
switch(c) {
case '$':
if (escaped)
{
- escaped = 0;
+ escaped= 0;
dynstr_append_mem(query_eval, p, 1);
}
else
{
- if (!(v = var_get(p, &p, 0, 0)))
+ if (!(v= var_get(p, &p, 0, 0)))
die("Bad variable in eval");
dynstr_append_mem(query_eval, v->str_val, v->str_val_len);
}
@@ -535,13 +501,13 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char *query,
next_c= *(p+1);
if (escaped)
{
- escaped = 0;
+ escaped= 0;
dynstr_append_mem(query_eval, p, 1);
}
- else if (next_c == '\\' || next_c == '$')
+ else if (next_c == '\\' || next_c == '$' || next_c == '"')
{
- /* Set escaped only if next char is \ or $ */
- escaped = 1;
+ /* Set escaped only if next char is \, " or $ */
+ escaped= 1;
if (pass_through_escape_chars)
{
@@ -561,10 +527,131 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char *query,
}
-static void close_cons()
+enum arg_type
+{
+ ARG_STRING,
+ ARG_REST
+};
+
+struct command_arg {
+ const char *argname; /* Name of argument */
+ enum arg_type type; /* Type of argument */
+ my_bool required; /* Argument required */
+ DYNAMIC_STRING *ds; /* Storage for argument */
+ const char *description; /* Description of the argument */
+};
+
+
+void check_command_args(struct st_command *command,
+ const char *arguments,
+ const struct command_arg *args,
+ int num_args, const char delimiter_arg)
+{
+ int i;
+ const char *ptr= arguments;
+ const char *start;
+
+ DBUG_ENTER("check_command_args");
+ DBUG_PRINT("enter", ("num_args: %d", num_args));
+ for (i= 0; i < num_args; i++)
+ {
+ const struct command_arg *arg= &args[i];
+
+ switch (arg->type)
+ {
+ /* A string */
+ case ARG_STRING:
+ /* Skip leading spaces */
+ while (*ptr && *ptr == ' ')
+ ptr++;
+ start= ptr;
+ /* Find end of arg, terminated by "delimiter_arg" */
+ while (*ptr && *ptr != delimiter_arg)
+ ptr++;
+ if (ptr > start)
+ {
+ init_dynamic_string(arg->ds, 0, ptr-start, 32);
+ do_eval(arg->ds, start, ptr, FALSE);
+ }
+ else
+ {
+ /* Empty string */
+ init_dynamic_string(arg->ds, "", 0, 0);
+ }
+ command->last_argument= (char*)ptr;
+
+ /* Step past the delimiter */
+ if (*ptr && *ptr == delimiter_arg)
+ ptr++;
+ DBUG_PRINT("info", ("val: %s", arg->ds->str));
+ break;
+
+ /* Rest of line */
+ case ARG_REST:
+ start= ptr;
+ init_dynamic_string(arg->ds, 0, command->query_len, 256);
+ do_eval(arg->ds, start, command->end, FALSE);
+ command->last_argument= command->end;
+ DBUG_PRINT("info", ("val: %s", arg->ds->str));
+ break;
+
+ default:
+ DBUG_ASSERT("Unknown argument type");
+ break;
+ }
+
+ /* Check required arg */
+ if (arg->ds->length == 0 && arg->required)
+ die("Missing required argument '%s' to command '%.*s'", arg->argname,
+ command->first_word_len, command->query);
+
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+void handle_command_error(struct st_command *command, uint error)
+{
+ DBUG_ENTER("handle_command_error");
+ DBUG_PRINT("enter", ("error: %d", error));
+ if (error != 0)
+ {
+ uint i;
+
+ if (command->abort_on_error)
+ die("command \"%.*s\" failed with error %d",
+ command->first_word_len, command->query, error);
+ for (i= 0; i < command->expected_errors.count; i++)
+ {
+ DBUG_PRINT("info", ("expected error: %d",
+ command->expected_errors.err[i].code.errnum));
+ if ((command->expected_errors.err[i].type == ERR_ERRNO) &&
+ (command->expected_errors.err[i].code.errnum == error))
+ {
+ DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %d",
+ command->first_word_len, command->query, error));
+ DBUG_VOID_RETURN;
+ }
+ }
+ die("command \"%.*s\" failed with wrong error: %d",
+ command->first_word_len, command->query, error);
+ }
+ else if (command->expected_errors.err[0].type == ERR_ERRNO &&
+ command->expected_errors.err[0].code.errnum != 0)
+ {
+ /* Error code we wanted was != 0, i.e. not an expected success */
+ die("command \"%.*s\" succeeded - should have failed with errno %d...",
+ command->first_word_len, command->query,
+ command->expected_errors.err[0].code.errnum);
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+void close_connections()
{
- DBUG_ENTER("close_cons");
- for (--next_con; next_con >= cons; --next_con)
+ DBUG_ENTER("close_connections");
+ for (--next_con; next_con >= connections; --next_con)
{
if (next_con->stmt)
mysql_stmt_close(next_con->stmt);
@@ -578,14 +665,16 @@ static void close_cons()
}
-static void close_files()
+void close_files()
{
DBUG_ENTER("close_files");
for (; cur_file >= file_stack; cur_file--)
{
- DBUG_PRINT("info", ("file_name: %s", cur_file->file_name));
if (cur_file->file && cur_file->file != stdin)
+ {
+ DBUG_PRINT("info", ("closing file: %s", cur_file->file_name));
my_fclose(cur_file->file, MYF(0));
+ }
my_free((gptr)cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR));
cur_file->file_name= 0;
}
@@ -593,22 +682,22 @@ static void close_files()
}
-static void free_used_memory()
+void free_used_memory()
{
uint i;
DBUG_ENTER("free_used_memory");
- close_cons();
+ close_connections();
close_files();
hash_free(&var_hash);
- for (i=0 ; i < q_lines.elements ; i++)
+ for (i= 0 ; i < q_lines.elements ; i++)
{
- struct st_query **q= dynamic_element(&q_lines, i, struct st_query**);
+ struct st_command **q= dynamic_element(&q_lines, i, struct st_command**);
my_free((gptr) (*q)->query_buf,MYF(MY_ALLOW_ZERO_PTR));
my_free((gptr) (*q),MYF(0));
}
- for (i=0; i < 10; i++)
+ for (i= 0; i < 10; i++)
{
if (var_reg[i].alloced_len)
my_free(var_reg[i].str_val, MYF(MY_WME));
@@ -618,8 +707,8 @@ static void free_used_memory()
delete_dynamic(&q_lines);
dynstr_free(&ds_res);
dynstr_free(&ds_progress);
- free_replace();
- free_replace_column();
+ dynstr_free(&ds_warning_messages);
+ free_all_replace();
my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
free_defaults(default_argv);
mysql_server_end();
@@ -631,10 +720,12 @@ static void free_used_memory()
DBUG_VOID_RETURN;
}
-static void die(const char *fmt, ...)
+
+void die(const char *fmt, ...)
{
va_list args;
DBUG_ENTER("die");
+ DBUG_PRINT("enter", ("start_lineno: %d", start_lineno));
/* Print the error message */
va_start(args, fmt);
@@ -653,8 +744,12 @@ static void die(const char *fmt, ...)
va_end(args);
/* Dump the result that has been accumulated so far to .log file */
- if (result_file && ds_res.length)
- dump_result_to_log_file(result_file, ds_res.str, ds_res.length);
+ if (result_file_name && ds_res.length)
+ dump_result_to_log_file(ds_res.str, ds_res.length);
+
+ /* Dump warning messages */
+ if (result_file_name && ds_warning_messages.length)
+ dump_warning_messages();
/* Clean up and exit */
free_used_memory();
@@ -667,10 +762,10 @@ static void die(const char *fmt, ...)
}
-static void abort_not_supported_test(const char *fmt, ...)
+void abort_not_supported_test(const char *fmt, ...)
{
va_list args;
- test_file* err_file= cur_file;
+ struct st_test_file* err_file= cur_file;
DBUG_ENTER("abort_not_supported_test");
/* Print include filestack */
@@ -706,7 +801,14 @@ static void abort_not_supported_test(const char *fmt, ...)
exit(62);
}
-static void verbose_msg(const char *fmt, ...)
+
+void abort_not_in_this_version()
+{
+ die("Not available in this version of mysqltest");
+}
+
+
+void verbose_msg(const char *fmt, ...)
{
va_list args;
DBUG_ENTER("verbose_msg");
@@ -715,6 +817,9 @@ static void verbose_msg(const char *fmt, ...)
va_start(args, fmt);
fprintf(stderr, "mysqltest: ");
+ if (cur_file && cur_file != file_stack)
+ fprintf(stderr, "In included file \"%s\": ",
+ cur_file->file_name);
if (start_lineno != 0)
fprintf(stderr, "At line %u: ", start_lineno);
vfprintf(stderr, fmt, args);
@@ -725,14 +830,46 @@ static void verbose_msg(const char *fmt, ...)
}
-void init_parser()
+void warning_msg(const char *fmt, ...)
{
- parser.current_line= parser.read_lines= 0;
- memset(&var_reg, 0, sizeof(var_reg));
+ va_list args;
+ char buff[512];
+ size_t len;
+ DBUG_ENTER("warning_msg");
+
+ va_start(args, fmt);
+ dynstr_append(&ds_warning_messages, "mysqltest: ");
+ if (start_lineno != 0)
+ {
+ dynstr_append(&ds_warning_messages, "Warning detected ");
+ if (cur_file && cur_file != file_stack)
+ {
+ len= my_snprintf(buff, sizeof(buff), "in included file %s ",
+ cur_file->file_name);
+ dynstr_append_mem(&ds_warning_messages,
+ buff, len);
+ }
+ len= my_snprintf(buff, sizeof(buff), "at line %d: ",
+ start_lineno);
+ dynstr_append_mem(&ds_warning_messages,
+ buff, len);
+ }
+#ifndef __WIN__
+ len= vsnprintf(buff, sizeof(buff), fmt, args);
+ dynstr_append_mem(&ds_warning_messages, buff, len);
+#endif
+ dynstr_append(&ds_warning_messages, "\n");
+ va_end(args);
+
+ DBUG_VOID_RETURN;
}
-static int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
+/*
+ Compare content of the string ds to content of file fname
+*/
+
+int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
{
MY_STAT stat_info;
char *tmp, *res_ptr;
@@ -755,25 +892,26 @@ static int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
die(NullS);
if (!eval_result && (uint) stat_info.st_size != ds->length)
{
- DBUG_PRINT("info",("Size differs: result size: %u file size: %u",
+ DBUG_PRINT("info",("Size differs: result size: %u file size: %llu",
ds->length, stat_info.st_size));
DBUG_PRINT("info",("result: '%s'", ds->str));
DBUG_RETURN(RESULT_LENGTH_MISMATCH);
}
if (!(tmp = (char*) my_malloc(stat_info.st_size + 1, MYF(MY_WME))))
- die(NullS);
+ die("Out of memory");
if ((fd = my_open(eval_file, O_RDONLY, MYF(MY_WME))) < 0)
- die(NullS);
+ die("Failed to open file %s", eval_file);
if (my_read(fd, (byte*)tmp, stat_info.st_size, MYF(MY_WME|MY_NABP)))
- die(NullS);
+ die("Failed to read from file %s, errno: %d", eval_file, errno);
tmp[stat_info.st_size] = 0;
- init_dynamic_string(&res_ds, "", 0, 65536);
+ init_dynamic_string(&res_ds, "", stat_info.st_size+256, 256);
if (eval_result)
{
- do_eval(&res_ds, tmp, FALSE);
- res_ptr = res_ds.str;
- if ((res_len = res_ds.length) != ds->length)
+ do_eval(&res_ds, tmp, tmp + stat_info.st_size, FALSE);
+ res_ptr= res_ds.str;
+ res_len= res_ds.length;
+ if (res_len != ds->length)
{
res= RESULT_LENGTH_MISMATCH;
goto err;
@@ -794,48 +932,41 @@ err:
MY_REPLACE_EXT),
res_ptr, res_len);
+ dynstr_free(&res_ds);
my_free((gptr) tmp, MYF(0));
my_close(fd, MYF(MY_WME));
- dynstr_free(&res_ds);
DBUG_RETURN(res);
}
+
/*
- Check the content of ds against content of file fname
+ Check the content of ds against result file
SYNOPSIS
check_result
ds - content to be checked
- fname - name of file to check against
- require_option - if set and check fails, the test will be aborted
- with the special exit code "not supported test"
RETURN VALUES
- error - the function will not return
+ error - the function will not return
*/
-static void check_result(DYNAMIC_STRING* ds, const char *fname,
- my_bool require_option)
+
+void check_result(DYNAMIC_STRING* ds)
{
- int res= dyn_string_cmp(ds, fname);
DBUG_ENTER("check_result");
+ DBUG_ASSERT(result_file_name);
- if (res && require_option)
+ switch (dyn_string_cmp(ds, result_file_name))
{
- char reason[FN_REFLEN];
- fn_format(reason, fname, "", "", MY_REPLACE_EXT | MY_REPLACE_DIR);
- abort_not_supported_test("Test requires: '%s'", reason);
- }
- switch (res) {
case RESULT_OK:
break; /* ok */
case RESULT_LENGTH_MISMATCH:
- dump_result_to_reject_file(fname, ds->str, ds->length);
+ dump_result_to_reject_file(ds->str, ds->length);
die("Result length mismatch");
break;
case RESULT_CONTENT_MISMATCH:
- dump_result_to_reject_file(fname, ds->str, ds->length);
+ dump_result_to_reject_file(ds->str, ds->length);
die("Result content mismatch");
break;
default: /* impossible */
@@ -846,13 +977,109 @@ static void check_result(DYNAMIC_STRING* ds, const char *fname,
}
-VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw,
+/*
+ Check the content of ds against a require file
+ If match fails, abort the test with special error code
+ indicating that test is not supported
+
+ SYNOPSIS
+ check_result
+ ds - content to be checked
+ fname - name of file to check against
+
+ RETURN VALUES
+ error - the function will not return
+
+*/
+
+void check_require(DYNAMIC_STRING* ds, const char *fname)
+{
+ DBUG_ENTER("check_require");
+
+ if (dyn_string_cmp(ds, fname))
+ {
+ char reason[FN_REFLEN];
+ fn_format(reason, fname, "", "", MY_REPLACE_EXT | MY_REPLACE_DIR);
+ abort_not_supported_test("Test requires: '%s'", reason);
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+static byte *get_var_key(const byte* var, uint* len,
+ my_bool __attribute__((unused)) t)
+{
+ register char* key;
+ key = ((VAR*)var)->name;
+ *len = ((VAR*)var)->name_len;
+ return (byte*)key;
+}
+
+
+VAR *var_init(VAR *v, const char *name, int name_len, const char *val,
+ int val_len)
+{
+ int val_alloc_len;
+ VAR *tmp_var;
+ if (!name_len && name)
+ name_len = strlen(name);
+ if (!val_len && val)
+ val_len = strlen(val) ;
+ val_alloc_len = val_len + 16; /* room to grow */
+ if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var)
+ + name_len+1, MYF(MY_WME))))
+ die("Out of memory");
+
+ tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0;
+ tmp_var->alloced = (v == 0);
+
+ if (!(tmp_var->str_val = my_malloc(val_alloc_len+1, MYF(MY_WME))))
+ die("Out of memory");
+
+ memcpy(tmp_var->name, name, name_len);
+ if (val)
+ {
+ memcpy(tmp_var->str_val, val, val_len);
+ tmp_var->str_val[val_len]= 0;
+ }
+ tmp_var->name_len = name_len;
+ tmp_var->str_val_len = val_len;
+ tmp_var->alloced_len = val_alloc_len;
+ tmp_var->int_val = (val) ? atoi(val) : 0;
+ tmp_var->int_dirty = 0;
+ tmp_var->env_s = 0;
+ return tmp_var;
+}
+
+
+void var_free(void *v)
+{
+ my_free(((VAR*) v)->str_val, MYF(MY_WME));
+ if (((VAR*)v)->alloced)
+ my_free((char*) v, MYF(MY_WME));
+}
+
+
+VAR* var_from_env(const char *name, const char *def_val)
+{
+ const char *tmp;
+ VAR *v;
+ if (!(tmp = getenv(name)))
+ tmp = def_val;
+
+ v = var_init(0, name, strlen(name), tmp, strlen(tmp));
+ my_hash_insert(&var_hash, (byte*)v);
+ return v;
+}
+
+
+VAR* var_get(const char *var_name, const char **var_name_end, my_bool raw,
my_bool ignore_not_existing)
{
int digit;
- VAR* v;
+ VAR *v;
DBUG_ENTER("var_get");
- DBUG_PRINT("enter",("var_name: %s",var_name));
+ DBUG_PRINT("enter", ("var_name: %s",var_name));
if (*var_name != '$')
goto err;
@@ -871,16 +1098,16 @@ VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw,
die("Empty variable");
}
length= (uint) (var_name - save_var_name);
- if (length >= MAX_VAR_NAME)
+ if (length >= MAX_VAR_NAME_LENGTH)
die("Too long variable name: %s", save_var_name);
if (!(v = (VAR*) hash_search(&var_hash, save_var_name, length)))
{
- char buff[MAX_VAR_NAME+1];
+ char buff[MAX_VAR_NAME_LENGTH+1];
strmake(buff, save_var_name, length);
v= var_from_env(buff, "");
}
- var_name--; /* Point at last character */
+ var_name--; /* Point at last character */
}
else
v = var_reg + digit;
@@ -901,7 +1128,8 @@ err:
DBUG_RETURN(0);
}
-static VAR *var_obtain(const char *name, int len)
+
+VAR *var_obtain(const char *name, int len)
{
VAR* v;
if ((v = (VAR*)hash_search(&var_hash, name, len)))
@@ -911,16 +1139,18 @@ static VAR *var_obtain(const char *name, int len)
return v;
}
+
/*
- if variable starts with a $ it is regarded as a local test varable
- if not it is treated as a environment variable, and the corresponding
environment variable will be updated
*/
-int var_set(const char *var_name, const char *var_name_end,
- const char *var_val, const char *var_val_end)
+
+void var_set(const char *var_name, const char *var_name_end,
+ const char *var_val, const char *var_val_end)
{
- int digit, result, env_var= 0;
- VAR* v;
+ int digit, env_var= 0;
+ VAR *v;
DBUG_ENTER("var_set");
DBUG_PRINT("enter", ("var_name: '%.*s' = '%.*s' (length: %d)",
(int) (var_name_end - var_name), var_name,
@@ -932,15 +1162,15 @@ int var_set(const char *var_name, const char *var_name_end,
else
var_name++;
- digit = *var_name - '0';
+ digit= *var_name - '0';
if (!(digit < 10 && digit >= 0))
{
- v = var_obtain(var_name, (uint) (var_name_end - var_name));
+ v= var_obtain(var_name, (uint) (var_name_end - var_name));
}
else
- v = var_reg + digit;
+ v= var_reg + digit;
- result= eval_expr(v, var_val, (const char**) &var_val_end);
+ eval_expr(v, var_val, (const char**) &var_val_end);
if (env_var)
{
@@ -957,7 +1187,183 @@ int var_set(const char *var_name, const char *var_name_end,
putenv(v->env_s);
my_free((gptr)old_env_s, MYF(MY_ALLOW_ZERO_PTR));
}
- DBUG_RETURN(result);
+ DBUG_VOID_RETURN;
+}
+
+/*
+ Store an integer (typically the returncode of the last SQL)
+ statement in the mysqltest builtin variable $mysql_errno, by
+ simulating of a user statement "let $mysql_errno= <integer>"
+*/
+
+void var_set_errno(int sql_errno)
+{
+ /* TODO MASV make easier */
+ const char *var_name= "$mysql_errno";
+ char var_val[21];
+ uint length= my_sprintf(var_val, (var_val, "%d", sql_errno));
+ var_set(var_name, var_name + 12, var_val, var_val + length);
+ return;
+}
+
+
+/*
+ Set variable from the result of a query
+
+ SYNOPSIS
+ var_query_set()
+ var variable to set from query
+ query start of query string to execute
+ query_end end of the query string to execute
+
+
+ DESCRIPTION
+ let @<var_name> = `<query>`
+
+ Execute the query and assign the first row of result to var as
+ a tab separated strings
+
+ Also assign each column of the result set to
+ variable "$<var_name>_<column_name>"
+ Thus the tab separated output can be read from $<var_name> and
+ and each individual column can be read as $<var_name>_<col_name>
+
+*/
+
+void var_query_set(VAR *var, const char *query, const char** query_end)
+{
+ char* end = (char*)((query_end && *query_end) ?
+ *query_end : query + strlen(query));
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ MYSQL* mysql = &cur_con->mysql;
+ DBUG_ENTER("var_query_set");
+ LINT_INIT(res);
+
+ while (end > query && *end != '`')
+ --end;
+ if (query == end)
+ die("Syntax error in query, missing '`'");
+ ++query;
+
+ if (mysql_real_query(mysql, query, (int)(end - query)) ||
+ !(res = mysql_store_result(mysql)))
+ {
+ *end = 0;
+ die("Error running query '%s': %d %s", query,
+ mysql_errno(mysql), mysql_error(mysql));
+ }
+
+ if ((row = mysql_fetch_row(res)) && row[0])
+ {
+ /*
+ Concatenate all row results with tab in between to allow us to work
+ with results from many columns (for example from SHOW VARIABLES)
+ */
+ DYNAMIC_STRING result;
+ uint i;
+ ulong *lengths;
+ char *end;
+#ifdef NOT_YET
+ MYSQL_FIELD *fields= mysql_fetch_fields(res);
+#endif
+
+ init_dynamic_string(&result, "", 2048, 2048);
+ lengths= mysql_fetch_lengths(res);
+ for (i=0; i < mysql_num_fields(res); i++)
+ {
+ if (row[0])
+ {
+#ifdef NOT_YET
+ /* Add to <var_name>_<col_name> */
+ uint j;
+ char var_col_name[MAX_VAR_NAME_LENGTH];
+ uint length= snprintf(var_col_name, MAX_VAR_NAME_LENGTH,
+ "$%s_%s", var->name, fields[i].name);
+ /* Convert characters not allowed in variable names to '_' */
+ for (j= 1; j < length; j++)
+ {
+ if (!my_isvar(charset_info,var_col_name[j]))
+ var_col_name[j]= '_';
+ }
+ var_set(var_col_name, var_col_name + length,
+ row[i], row[i] + lengths[i]);
+#endif
+ /* Add column to tab separated string */
+ dynstr_append_mem(&result, row[i], lengths[i]);
+ }
+ dynstr_append_mem(&result, "\t", 1);
+ }
+ end= result.str + result.length-1;
+ eval_expr(var, result.str, (const char**) &end);
+ dynstr_free(&result);
+ }
+ else
+ eval_expr(var, "", 0);
+
+ mysql_free_result(res);
+ DBUG_VOID_RETURN;
+}
+
+
+void var_copy(VAR *dest, VAR *src)
+{
+ dest->int_val= src->int_val;
+ dest->int_dirty= src->int_dirty;
+
+ /* Alloc/realloc data for str_val in dest */
+ if (dest->alloced_len < src->alloced_len &&
+ !(dest->str_val= dest->str_val
+ ? my_realloc(dest->str_val, src->alloced_len, MYF(MY_WME))
+ : my_malloc(src->alloced_len, MYF(MY_WME))))
+ die("Out of memory");
+ else
+ dest->alloced_len= src->alloced_len;
+
+ /* Copy str_val data to dest */
+ dest->str_val_len= src->str_val_len;
+ if (src->str_val_len)
+ memcpy(dest->str_val, src->str_val, src->str_val_len);
+}
+
+
+void eval_expr(VAR *v, const char *p, const char **p_end)
+{
+ static int MIN_VAR_ALLOC= 32; /* MASV why 32? */
+ VAR *vp;
+ if (*p == '$')
+ {
+ if ((vp= var_get(p, p_end, 0, 0)))
+ {
+ var_copy(v, vp);
+ return;
+ }
+ }
+ else if (*p == '`')
+ {
+ var_query_set(v, p, p_end);
+ }
+ else
+ {
+ int new_val_len = (p_end && *p_end) ?
+ (int) (*p_end - p) : (int) strlen(p);
+ if (new_val_len + 1 >= v->alloced_len)
+ {
+ v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ?
+ MIN_VAR_ALLOC : new_val_len + 1;
+ if (!(v->str_val =
+ v->str_val ? my_realloc(v->str_val, v->alloced_len+1,
+ MYF(MY_WME)) :
+ my_malloc(v->alloced_len+1, MYF(MY_WME))))
+ die("Out of memory");
+ }
+ v->str_val_len = new_val_len;
+ memcpy(v->str_val, p, new_val_len);
+ v->str_val[new_val_len] = 0;
+ v->int_val=atoi(p);
+ v->int_dirty=0;
+ }
+ return;
}
@@ -988,103 +1394,53 @@ int open_file(const char *name)
/*
- Check for unexpected "junk" after the end of query
- This is normally caused by missing delimiters
-*/
-
-int check_eol_junk(const char *eol)
-{
- const char *p= eol;
- DBUG_ENTER("check_eol_junk");
- DBUG_PRINT("enter", ("eol: %s", eol));
- /* Remove all spacing chars except new line */
- while (*p && my_isspace(charset_info, *p) && (*p != '\n'))
- p++;
-
- /* Check for extra delimiter */
- if (*p && !strncmp(p, delimiter, delimiter_length))
- die("Extra delimiter \"%s\" found", delimiter);
-
- /* Allow trailing # comment */
- if (*p && *p != '#')
- {
- if (*p == '\n')
- die("Missing delimiter");
- die("End of line junk detected: \"%s\"", p);
- }
- DBUG_RETURN(0);
-}
-
-
-/* ugly long name, but we are following the convention */
-int do_wait_for_slave_to_stop(struct st_query *q __attribute__((unused)))
-{
- MYSQL* mysql = &cur_con->mysql;
- for (;;)
- {
- MYSQL_RES *res;
- MYSQL_ROW row;
- int done;
- LINT_INIT(res);
-
- if (mysql_query(mysql,"show status like 'Slave_running'") ||
- !(res=mysql_store_result(mysql)))
- die("Query failed while probing slave for stop: %s",
- mysql_error(mysql));
- if (!(row=mysql_fetch_row(res)) || !row[1])
- {
- mysql_free_result(res);
- die("Strange result from query while probing slave for stop");
- }
- done = !strcmp(row[1],"OFF");
- mysql_free_result(res);
- if (done)
- break;
- my_sleep(SLAVE_POLL_INTERVAL);
- }
- return 0;
-}
-
-
-/*
Source and execute the given file
SYNOPSIS
- do_source()
- query called command
+ do_source()
+ query called command
DESCRIPTION
- source <file_name>
+ source <file_name>
- Open the file <file_name> and execute it
+ Open the file <file_name> and execute it
*/
-int do_source(struct st_query *query)
+void do_source(struct st_command *command)
{
- char *p= query->first_argument, *name;
- if (!*p)
- die("Missing file name in source");
- name= p;
- while (*p && !my_isspace(charset_info,*p))
- p++;
- if (*p)
- *p++= 0;
- query->last_argument= p;
+ static DYNAMIC_STRING ds_filename;
+ const struct command_arg source_args[] = {
+ "filename", ARG_STRING, TRUE, &ds_filename, "File to source"
+ };
+ DBUG_ENTER("do_source");
+
+ check_command_args(command, command->first_argument, source_args,
+ sizeof(source_args)/sizeof(struct command_arg),
+ ' ');
+
/*
- If this file has already been sourced, don't source it again.
- It's already available in the q_lines cache.
+ If this file has already been sourced, don't source it again.
+ It's already available in the q_lines cache.
*/
if (parser.current_line < (parser.read_lines - 1))
- return 0;
- return open_file(name);
+ ; /* Do nothing */
+ else
+ {
+ DBUG_PRINT("info", ("sourcing file: %s", ds_filename.str));
+ open_file(ds_filename.str);
+ }
+
+ dynstr_free(&ds_filename);
+ return;
}
+
#ifdef __WIN__
-/* Variables used for temuprary sh files used for emulating Unix on Windows */
+/* Variables used for temporary sh files used for emulating Unix on Windows */
char tmp_sh_name[64], tmp_sh_cmd[70];
-static void init_tmp_sh_file()
+void init_tmp_sh_file()
{
/* Format a name for the tmp sh file that is unique for this process */
my_snprintf(tmp_sh_name, sizeof(tmp_sh_name), "tmp_%d.sh", getpid());
@@ -1092,13 +1448,15 @@ static void init_tmp_sh_file()
my_snprintf(tmp_sh_cmd, sizeof(tmp_sh_cmd), "sh %s", tmp_sh_name);
}
-static void free_tmp_sh_file()
+
+void free_tmp_sh_file()
{
my_delete(tmp_sh_name, MYF(0));
}
#endif
-FILE* my_popen(DYNAMIC_STRING* ds_cmd, const char* mode)
+
+FILE* my_popen(DYNAMIC_STRING *ds_cmd, const char *mode)
{
#ifdef __WIN__
/* Dump the command into a sh script file and execute with popen */
@@ -1114,49 +1472,49 @@ FILE* my_popen(DYNAMIC_STRING* ds_cmd, const char* mode)
Execute given command.
SYNOPSIS
- do_exec()
- query called command
+ do_exec()
+ query called command
DESCRIPTION
- exec <command>
+ exec <command>
- Execute the text between exec and end of line in a subprocess.
- The error code returned from the subprocess is checked against the
- expected error array, previously set with the --error command.
- It can thus be used to execute a command that shall fail.
+ Execute the text between exec and end of line in a subprocess.
+ The error code returned from the subprocess is checked against the
+ expected error array, previously set with the --error command.
+ It can thus be used to execute a command that shall fail.
NOTE
- Although mysqltest is executed from cygwin shell, the command will be
- executed in "cmd.exe". Thus commands like "rm" etc can NOT be used, use
- system for those commands.
+ Although mysqltest is executed from cygwin shell, the command will be
+ executed in "cmd.exe". Thus commands like "rm" etc can NOT be used, use
+ system for those commands.
*/
-static void do_exec(struct st_query *query)
+void do_exec(struct st_command *command)
{
int error;
char buf[1024];
FILE *res_file;
- char *cmd= query->first_argument;
+ char *cmd= command->first_argument;
DYNAMIC_STRING ds_cmd;
DBUG_ENTER("do_exec");
DBUG_PRINT("enter", ("cmd: '%s'", cmd));
+ /* Skip leading space */
while (*cmd && my_isspace(charset_info, *cmd))
cmd++;
if (!*cmd)
die("Missing argument in exec");
- query->last_argument= query->end;
+ command->last_argument= command->end;
- init_dynamic_string(&ds_cmd, 0, strlen(cmd)+256, 256);
+ init_dynamic_string(&ds_cmd, 0, command->query_len+256, 256);
/* Eval the command, thus replacing all environment variables */
- do_eval(&ds_cmd, cmd, TRUE);
- cmd= ds_cmd.str;
+ do_eval(&ds_cmd, cmd, command->end, TRUE);
DBUG_PRINT("info", ("Executing '%s' as '%s'",
- query->first_argument, cmd));
+ command->first_argument, ds_cmd.str));
- if (!(res_file= my_popen(&ds_cmd, "r")) && query->abort_on_error)
- die("popen(\"%s\", \"r\") failed", query->first_argument);
+ if (!(res_file= my_popen(&ds_cmd, "r")) && command->abort_on_error)
+ die("popen(\"%s\", \"r\") failed", command->first_argument);
while (fgets(buf, sizeof(buf), res_file))
{
@@ -1176,229 +1534,70 @@ static void do_exec(struct st_query *query)
uint status= WEXITSTATUS(error), i;
my_bool ok= 0;
- if (query->abort_on_error)
- die("command \"%s\" failed", query->first_argument);
+ if (command->abort_on_error)
+ die("command \"%s\" failed", command->first_argument);
DBUG_PRINT("info",
("error: %d, status: %d", error, status));
- for (i= 0; i < query->expected_errors; i++)
+ for (i= 0; i < command->expected_errors.count; i++)
{
DBUG_PRINT("info", ("expected error: %d",
- query->expected_errno[i].code.errnum));
- if ((query->expected_errno[i].type == ERR_ERRNO) &&
- (query->expected_errno[i].code.errnum == status))
+ command->expected_errors.err[i].code.errnum));
+ if ((command->expected_errors.err[i].type == ERR_ERRNO) &&
+ (command->expected_errors.err[i].code.errnum == status))
{
ok= 1;
DBUG_PRINT("info", ("command \"%s\" failed with expected error: %d",
- query->first_argument, status));
+ command->first_argument, status));
}
}
if (!ok)
die("command \"%s\" failed with wrong error: %d",
- query->first_argument, status);
+ command->first_argument, status);
}
- else if (query->expected_errno[0].type == ERR_ERRNO &&
- query->expected_errno[0].code.errnum != 0)
+ else if (command->expected_errors.err[0].type == ERR_ERRNO &&
+ command->expected_errors.err[0].code.errnum != 0)
{
/* Error code we wanted was != 0, i.e. not an expected success */
die("command \"%s\" succeeded - should have failed with errno %d...",
- query->first_argument, query->expected_errno[0].code.errnum);
+ command->first_argument, command->expected_errors.err[0].code.errnum);
}
- free_replace();
+ dynstr_free(&ds_cmd);
DBUG_VOID_RETURN;
}
-/*
- Set variable from the result of a query
-
- SYNOPSIS
- var_query_set()
- var variable to set from query
- query start of query string to execute
- query_end end of the query string to execute
-
-
- DESCRIPTION
- let @<var_name> = `<query>`
-
- Execute the query and assign the first row of result to var as
- a tab separated strings
-
- Also assign each column of the result set to
- variable "$<var_name>_<column_name>"
- Thus the tab separated output can be read from $<var_name> and
- and each individual column can be read as $<var_name>_<col_name>
-
-*/
-
-int var_query_set(VAR* var, const char *query, const char** query_end)
-{
- char* end = (char*)((query_end && *query_end) ?
- *query_end : query + strlen(query));
- MYSQL_RES *res;
- MYSQL_ROW row;
- MYSQL* mysql = &cur_con->mysql;
- DBUG_ENTER("var_query_set");
- LINT_INIT(res);
-
- while (end > query && *end != '`')
- --end;
- if (query == end)
- die("Syntax error in query, missing '`'");
- ++query;
-
- if (mysql_real_query(mysql, query, (int)(end - query)) ||
- !(res = mysql_store_result(mysql)))
- {
- *end = 0;
- die("Error running query '%s': %d: %s", query,
- mysql_errno(mysql) ,mysql_error(mysql));
- }
-
- if ((row = mysql_fetch_row(res)) && row[0])
- {
- /*
- Concatenate all row results with tab in between to allow us to work
- with results from many columns (for example from SHOW VARIABLES)
- */
- DYNAMIC_STRING result;
- uint i;
- ulong *lengths;
- char *end;
-#ifdef NOT_YET
- MYSQL_FIELD *fields= mysql_fetch_fields(res);
-#endif
-
- init_dynamic_string(&result, "", 16384, 65536);
- lengths= mysql_fetch_lengths(res);
- for (i=0; i < mysql_num_fields(res); i++)
- {
- if (row[0])
- {
-#ifdef NOT_YET
- /* Add to <var_name>_<col_name> */
- uint j;
- char var_col_name[MAX_VAR_NAME];
- uint length= snprintf(var_col_name, MAX_VAR_NAME,
- "$%s_%s", var->name, fields[i].name);
- /* Convert characters not allowed in variable names to '_' */
- for (j= 1; j < length; j++)
- {
- if (!my_isvar(charset_info,var_col_name[j]))
- var_col_name[j]= '_';
- }
- var_set(var_col_name, var_col_name + length,
- row[i], row[i] + lengths[i]);
-#endif
- /* Add column to tab separated string */
- dynstr_append_mem(&result, row[i], lengths[i]);
- }
- dynstr_append_mem(&result, "\t", 1);
- }
- end= result.str + result.length-1;
- eval_expr(var, result.str, (const char**) &end);
- dynstr_free(&result);
- }
- else
- eval_expr(var, "", 0);
-
- mysql_free_result(res);
- DBUG_RETURN(0);
-}
-
-void var_copy(VAR *dest, VAR *src)
-{
- dest->int_val= src->int_val;
- dest->int_dirty= src->int_dirty;
-
- /* Alloc/realloc data for str_val in dest */
- if (dest->alloced_len < src->alloced_len &&
- !(dest->str_val= dest->str_val
- ? my_realloc(dest->str_val, src->alloced_len, MYF(MY_WME))
- : my_malloc(src->alloced_len, MYF(MY_WME))))
- die("Out of memory");
- else
- dest->alloced_len= src->alloced_len;
-
- /* Copy str_val data to dest */
- dest->str_val_len= src->str_val_len;
- if (src->str_val_len)
- memcpy(dest->str_val, src->str_val, src->str_val_len);
-}
-
-int eval_expr(VAR* v, const char *p, const char** p_end)
-{
- VAR* vp;
- if (*p == '$')
- {
- if ((vp = var_get(p,p_end,0,0)))
- {
- var_copy(v, vp);
- return 0;
- }
- }
- else if (*p == '`')
- {
- return var_query_set(v, p, p_end);
- }
- else
- {
- int new_val_len = (p_end && *p_end) ?
- (int) (*p_end - p) : (int) strlen(p);
- if (new_val_len + 1 >= v->alloced_len)
- {
- v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ?
- MIN_VAR_ALLOC : new_val_len + 1;
- if (!(v->str_val =
- v->str_val ? my_realloc(v->str_val, v->alloced_len+1,
- MYF(MY_WME)) :
- my_malloc(v->alloced_len+1, MYF(MY_WME))))
- die("Out of memory");
- }
- v->str_val_len = new_val_len;
- memcpy(v->str_val, p, new_val_len);
- v->str_val[new_val_len] = 0;
- v->int_val=atoi(p);
- v->int_dirty=0;
- return 0;
- }
-
- die("Invalid expr: %s", p);
- return 1;
-}
-
-
enum enum_operator
{
DO_DEC,
DO_INC
};
+
/*
Decrease or increase the value of a variable
SYNOPSIS
- do_modify_var()
- query called command
- operator operation to perform on the var
+ do_modify_var()
+ query called command
+ operator operation to perform on the var
DESCRIPTION
- dec $var_name
- inc $var_name
+ dec $var_name
+ inc $var_name
*/
-int do_modify_var(struct st_query *query,
+int do_modify_var(struct st_command *command,
enum enum_operator operator)
{
- const char *p= query->first_argument;
+ const char *p= command->first_argument;
VAR* v;
if (!*p)
- die("Missing argument to %.*s", query->first_word_len, query->query);
+ die("Missing argument to %.*s", command->first_word_len, command->query);
if (*p != '$')
die("The argument to %.*s must be a variable (start with $)",
- query->first_word_len, query->query);
+ command->first_word_len, command->query);
v= var_get(p, &p, 1, 0);
switch (operator) {
case DO_DEC:
@@ -1412,7 +1611,7 @@ int do_modify_var(struct st_query *query,
break;
}
v->int_dirty= 1;
- query->last_argument= (char*)++p;
+ command->last_argument= (char*)++p;
return 0;
}
@@ -1421,10 +1620,10 @@ int do_modify_var(struct st_query *query,
Wrapper for 'system' function
NOTE
- If mysqltest is executed from cygwin shell, the command will be
- executed in the "windows command interpreter" cmd.exe and we prepend "sh"
- to make it be executed by cygwins "bash". Thus commands like "rm",
- "mkdir" as well as shellscripts can executed by "system" in Windows.
+ If mysqltest is executed from cygwin shell, the command will be
+ executed in the "windows command interpreter" cmd.exe and we prepend "sh"
+ to make it be executed by cygwins "bash". Thus commands like "rm",
+ "mkdir" as well as shellscripts can executed by "system" in Windows.
*/
@@ -1441,20 +1640,19 @@ int my_system(DYNAMIC_STRING* ds_cmd)
/*
-
SYNOPSIS
do_system
- command called command
+ command called command
DESCRIPTION
- system <command>
+ system <command>
- Eval the query to expand any $variables in the command.
- Execute the command with the "system" command.
+ Eval the query to expand any $variables in the command.
+ Execute the command with the "system" command.
*/
-void do_system(struct st_query *command)
+void do_system(struct st_command *command)
{
DYNAMIC_STRING ds_cmd;
DBUG_ENTER("do_system");
@@ -1462,10 +1660,10 @@ void do_system(struct st_query *command)
if (strlen(command->first_argument) == 0)
die("Missing arguments to system, nothing to do!");
- init_dynamic_string(&ds_cmd, 0, strlen(command->first_argument) + 64, 256);
+ init_dynamic_string(&ds_cmd, 0, command->query_len + 64, 256);
/* Eval the system command, thus replacing all environment variables */
- do_eval(&ds_cmd, command->first_argument, TRUE);
+ do_eval(&ds_cmd, command->first_argument, command->end, TRUE);
DBUG_PRINT("info", ("running system command '%s' as '%s'",
command->first_argument, ds_cmd.str));
@@ -1487,50 +1685,375 @@ void do_system(struct st_query *command)
/*
+ SYNOPSIS
+ do_remove_file
+ command called command
+
+ DESCRIPTION
+ remove_file <file_name>
+ Remove the file <file_name>
+*/
+
+void do_remove_file(struct st_command *command)
+{
+ int error;
+ static DYNAMIC_STRING ds_filename;
+ const struct command_arg rm_args[] = {
+ "filename", ARG_STRING, TRUE, &ds_filename, "File to delete"
+ };
+ DBUG_ENTER("do_remove_file");
+
+ check_command_args(command, command->first_argument,
+ rm_args, sizeof(rm_args)/sizeof(struct command_arg),
+ ' ');
+
+ DBUG_PRINT("info", ("removing file: %s", ds_filename.str));
+ error= my_delete(ds_filename.str, MYF(0)) != 0;
+ handle_command_error(command, error);
+ dynstr_free(&ds_filename);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ SYNOPSIS
+ do_copy_file
+ command command handle
+
+ DESCRIPTION
+ copy_file <from_file> <to_file>
+ Copy <from_file> to <to_file>
+
+ NOTE! Will fail if <to_file> exists
+*/
+
+void do_copy_file(struct st_command *command)
+{
+ int error;
+ static DYNAMIC_STRING ds_from_file;
+ static DYNAMIC_STRING ds_to_file;
+ const struct command_arg copy_file_args[] = {
+ "from_file", ARG_STRING, TRUE, &ds_from_file, "Filename to copy from",
+ "to_file", ARG_STRING, TRUE, &ds_to_file, "Filename to copy to"
+ };
+ DBUG_ENTER("do_copy_file");
+
+ check_command_args(command, command->first_argument,
+ copy_file_args,
+ sizeof(copy_file_args)/sizeof(struct command_arg),
+ ' ');
+
+ DBUG_PRINT("info", ("Copy %s to %s", ds_from_file.str, ds_to_file.str));
+ error= (my_copy(ds_from_file.str, ds_to_file.str,
+ MYF(MY_DONT_OVERWRITE_FILE)) != 0);
+ handle_command_error(command, error);
+ dynstr_free(&ds_from_file);
+ dynstr_free(&ds_to_file);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ SYNOPSIS
+ do_file_exists
+ command called command
+
+ DESCRIPTION
+ fiile_exist <file_name>
+ Check if file <file_name> exists
+*/
+
+void do_file_exist(struct st_command *command)
+{
+ int error;
+ static DYNAMIC_STRING ds_filename;
+ const struct command_arg file_exist_args[] = {
+ "filename", ARG_STRING, TRUE, &ds_filename, "File to check if it exist"
+ };
+ DBUG_ENTER("do_file_exist");
+
+ check_command_args(command, command->first_argument,
+ file_exist_args,
+ sizeof(file_exist_args)/sizeof(struct command_arg),
+ ' ');
+
+ DBUG_PRINT("info", ("Checking for existence of file: %s", ds_filename.str));
+ error= (access(ds_filename.str, F_OK) != 0);
+ handle_command_error(command, error);
+ dynstr_free(&ds_filename);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Read characters from line buffer or file. This is needed to allow
+ my_ungetc() to buffer MAX_DELIMITER_LENGTH characters for a file
+
+ NOTE:
+ This works as long as one doesn't change files (with 'source file_name')
+ when there is things pushed into the buffer. This should however not
+ happen for any tests in the test suite.
+*/
+
+int my_getc(FILE *file)
+{
+ if (line_buffer_pos == line_buffer)
+ return fgetc(file);
+ return *--line_buffer_pos;
+}
+
+
+void my_ungetc(int c)
+{
+ *line_buffer_pos++= (char) c;
+}
+
+
+void read_until_delimiter(DYNAMIC_STRING *ds,
+ DYNAMIC_STRING *ds_delimiter)
+{
+ char c;
+ DBUG_ENTER("read_until_delimiter");
+ DBUG_PRINT("enter", ("delimiter: %s, length: %d",
+ ds_delimiter->str, ds_delimiter->length));
+
+ if (ds_delimiter->length > MAX_DELIMITER_LENGTH)
+ die("Max delimiter length(%d) exceeded", MAX_DELIMITER_LENGTH);
+
+ /* Read from file until delimiter is found */
+ while (1)
+ {
+ c= my_getc(cur_file->file);
+
+ if (c == '\n')
+ cur_file->lineno++;
+
+ if (feof(cur_file->file))
+ die("End of file encountered before '%s' delimiter was found",
+ ds_delimiter->str);
+
+ if (match_delimiter(c, ds_delimiter->str, ds_delimiter->length))
+ {
+ DBUG_PRINT("exit", ("Found delimiter '%s'", ds_delimiter->str));
+ break;
+ }
+ dynstr_append_mem(ds, (const char*)&c, 1);
+ }
+ DBUG_PRINT("exit", ("ds: %s", ds->str));
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ SYNOPSIS
+ do_write_file
+ command called command
+
+ DESCRIPTION
+ write_file <file_name> [<delimiter>];
+ <what to write line 1>
+ <...>
+ < what to write line n>
+ EOF
+
+ --write_file <file_name>;
+ <what to write line 1>
+ <...>
+ < what to write line n>
+ EOF
+
+ Write everything between the "write_file" command and 'delimiter'
+ to "file_name"
+
+ NOTE! Overwrites existing file
+
+ Default <delimiter> is EOF
+
+*/
+
+void do_write_file(struct st_command *command)
+{
+ static DYNAMIC_STRING ds_content;
+ static DYNAMIC_STRING ds_filename;
+ static DYNAMIC_STRING ds_delimiter;
+ const struct command_arg write_file_args[] = {
+ "filename", ARG_STRING, TRUE, &ds_filename, "File to write to",
+ "delimiter", ARG_STRING, FALSE, &ds_delimiter, "Delimiter to read until"
+ };
+ DBUG_ENTER("do_write_file");
+
+ check_command_args(command,
+ command->first_argument,
+ write_file_args,
+ sizeof(write_file_args)/sizeof(struct command_arg),
+ ' ');
+
+ /* If no delimiter was provided, use EOF */
+ if (ds_delimiter.length == 0)
+ dynstr_set(&ds_delimiter, "EOF");
+
+ init_dynamic_string(&ds_content, "", 1024, 1024);
+ read_until_delimiter(&ds_content, &ds_delimiter);
+ DBUG_PRINT("info", ("Writing to file: %s", ds_filename.str));
+ str_to_file(ds_filename.str, ds_content.str, ds_content.length);
+ dynstr_free(&ds_content);
+ dynstr_free(&ds_filename);
+ dynstr_free(&ds_delimiter);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ SYNOPSIS
+ do_perl
+ command command handle
+
+ DESCRIPTION
+ perl [<delimiter>];
+ <perlscript line 1>
+ <...>
+ <perlscript line n>
+ EOF
+
+ Execute everything after "perl" until <delimiter> as perl.
+ Useful for doing more advanced things
+ but still being able to execute it on all platforms.
+
+ Default <delimiter> is EOF
+*/
+
+void do_perl(struct st_command *command)
+{
+ int error;
+ char buf[FN_REFLEN];
+ FILE *res_file;
+ static DYNAMIC_STRING ds_script;
+ static DYNAMIC_STRING ds_delimiter;
+ const struct command_arg perl_args[] = {
+ "delimiter", ARG_STRING, FALSE, &ds_delimiter, "Delimiter to read until"
+ };
+ DBUG_ENTER("do_perl");
+
+ check_command_args(command,
+ command->first_argument,
+ perl_args,
+ sizeof(perl_args)/sizeof(struct command_arg),
+ ' ');
+
+ /* If no delimiter was provided, use EOF */
+ if (ds_delimiter.length == 0)
+ dynstr_set(&ds_delimiter, "EOF");
+
+ init_dynamic_string(&ds_script, "", 1024, 1024);
+ read_until_delimiter(&ds_script, &ds_delimiter);
+
+ DBUG_PRINT("info", ("Executing perl: %s", ds_script.str));
+
+ /* Format a name for a tmp .pl file that is unique for this process */
+ my_snprintf(buf, sizeof(buf), "%s/tmp/tmp_%d.pl",
+ getenv("MYSQLTEST_VARDIR"), getpid());
+ str_to_file(buf, ds_script.str, ds_script.length);
+
+ /* Format the perl <filename> command */
+ my_snprintf(buf, sizeof(buf), "perl %s/tmp/tmp_%d.pl",
+ getenv("MYSQLTEST_VARDIR"), getpid());
+
+ if (!(res_file= popen(buf, "r")) && command->abort_on_error)
+ die("popen(\"%s\", \"r\") failed", buf);
+
+ while (fgets(buf, sizeof(buf), res_file))
+ {
+ if (disable_result_log)
+ {
+ buf[strlen(buf)-1]=0;
+ DBUG_PRINT("exec_result",("%s", buf));
+ }
+ else
+ {
+ replace_dynstr_append(&ds_res, buf);
+ }
+ }
+ error= pclose(res_file);
+ handle_command_error(command, WEXITSTATUS(error));
+ dynstr_free(&ds_script);
+ dynstr_free(&ds_delimiter);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
Print the content between echo and <delimiter> to result file.
Evaluate all variables in the string before printing, allow
for variable names to be escaped using \
SYNOPSIS
- do_echo()
- q called command
+ do_echo()
+ command called command
DESCRIPTION
- echo text
- Print the text after echo until end of command to result file
+ echo text
+ Print the text after echo until end of command to result file
- echo $<var_name>
- Print the content of the variable <var_name> to result file
+ echo $<var_name>
+ Print the content of the variable <var_name> to result file
- echo Some text $<var_name>
- Print "Some text" plus the content of the variable <var_name> to
- result file
+ echo Some text $<var_name>
+ Print "Some text" plus the content of the variable <var_name> to
+ result file
- echo Some text \$<var_name>
- Print "Some text" plus $<var_name> to result file
+ echo Some text \$<var_name>
+ Print "Some text" plus $<var_name> to result file
*/
-int do_echo(struct st_query *command)
+int do_echo(struct st_command *command)
{
- DYNAMIC_STRING *ds, ds_echo;
+ DYNAMIC_STRING ds_echo;
- ds= &ds_res;
-
- init_dynamic_string(&ds_echo, "", 256, 256);
- do_eval(&ds_echo, command->first_argument, FALSE);
- dynstr_append_mem(ds, ds_echo.str, ds_echo.length);
- dynstr_append_mem(ds, "\n", 1);
+ init_dynamic_string(&ds_echo, "", command->query_len, 256);
+ do_eval(&ds_echo, command->first_argument, command->end, FALSE);
+ dynstr_append_mem(&ds_res, ds_echo.str, ds_echo.length);
+ dynstr_append_mem(&ds_res, "\n", 1);
dynstr_free(&ds_echo);
command->last_argument= command->end;
return(0);
}
-int do_sync_with_master2(long offset)
+void do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused)))
{
- MYSQL_RES* res;
+ static int SLAVE_POLL_INTERVAL= 300000;
+ MYSQL* mysql = &cur_con->mysql;
+ for (;;)
+ {
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ int done;
+ LINT_INIT(res);
+
+ if (mysql_query(mysql,"show status like 'Slave_running'") ||
+ !(res=mysql_store_result(mysql)))
+ die("Query failed while probing slave for stop: %s",
+ mysql_error(mysql));
+ if (!(row=mysql_fetch_row(res)) || !row[1])
+ {
+ mysql_free_result(res);
+ die("Strange result from query while probing slave for stop");
+ }
+ done = !strcmp(row[1],"OFF");
+ mysql_free_result(res);
+ if (done)
+ break;
+ my_sleep(SLAVE_POLL_INTERVAL);
+ }
+ return;
+}
+
+
+void do_sync_with_master2(long offset)
+{
+ MYSQL_RES *res;
MYSQL_ROW row;
- MYSQL* mysql= &cur_con->mysql;
+ MYSQL *mysql= &cur_con->mysql;
char query_buf[FN_REFLEN+128];
int tries= 0;
int rpl_parse;
@@ -1546,7 +2069,7 @@ int do_sync_with_master2(long offset)
wait_for_position:
if (mysql_query(mysql, query_buf))
- die("failed in %s: %d: %s", query_buf, mysql_errno(mysql),
+ die("failed in '%s': %d: %s", query_buf, mysql_errno(mysql),
mysql_error(mysql));
if (!(res= mysql_store_result(mysql)))
@@ -1569,13 +2092,14 @@ wait_for_position:
if (rpl_parse)
mysql_enable_rpl_parse(mysql);
- return 0;
+ return;
}
-int do_sync_with_master(struct st_query *query)
+
+void do_sync_with_master(struct st_command *command)
{
long offset= 0;
- char *p= query->first_argument;
+ char *p= command->first_argument;
const char *offset_start= p;
if (*offset_start)
{
@@ -1584,20 +2108,22 @@ int do_sync_with_master(struct st_query *query)
if(*p && !my_isspace(charset_info, *p))
die("Invalid integer argument \"%s\"", offset_start);
- query->last_argument= p;
+ command->last_argument= p;
}
- return do_sync_with_master2(offset);
+ do_sync_with_master2(offset);
+ return;
}
+
/*
when ndb binlog is on, this call will wait until last updated epoch
(locally in the mysqld) has been received into the binlog
*/
int do_save_master_pos()
{
- MYSQL_RES* res;
+ MYSQL_RES *res;
MYSQL_ROW row;
- MYSQL* mysql = &cur_con->mysql;
+ MYSQL *mysql = &cur_con->mysql;
const char *query;
int rpl_parse;
@@ -1606,19 +2132,18 @@ int do_save_master_pos()
#ifdef HAVE_NDB_BINLOG
/*
- Wait for ndb binlog to be up-to-date with all changes
- done on the local mysql server
+ Wait for ndb binlog to be up-to-date with all changes
+ done on the local mysql server
*/
{
ulong have_ndbcluster;
if (mysql_query(mysql, query= "show variables like 'have_ndbcluster'"))
- die("At line %u: failed in %s: %d: %s", start_lineno, query,
+ die("'%s' failed: %d %s", query,
mysql_errno(mysql), mysql_error(mysql));
if (!(res= mysql_store_result(mysql)))
- die("line %u: mysql_store_result() retuned NULL for '%s'", start_lineno,
- query);
+ die("mysql_store_result() returned NULL for '%s'", query);
if (!(row= mysql_fetch_row(res)))
- die("line %u: empty result in %s", start_lineno, query);
+ die("Query '%s' returned empty result", query);
have_ndbcluster= strcmp("YES", row[1]) == 0;
mysql_free_result(res);
@@ -1626,7 +2151,7 @@ int do_save_master_pos()
if (have_ndbcluster)
{
ulonglong start_epoch= 0, applied_epoch= 0,
- latest_epoch=0, latest_trans_epoch=0,
+ latest_epoch=0, latest_trans_epoch=0,
latest_handled_binlog_epoch= 0, latest_received_binlog_epoch= 0,
latest_applied_binlog_epoch= 0;
int count= 0;
@@ -1647,11 +2172,10 @@ int do_save_master_pos()
if (count)
sleep(1);
if (mysql_query(mysql, query= "show engine ndb status"))
- die("At line %u: failed in '%s': %d: %s", start_lineno, query,
+ die("failed in '%s': %d %s", query,
mysql_errno(mysql), mysql_error(mysql));
if (!(res= mysql_store_result(mysql)))
- die("line %u: mysql_store_result() retuned NULL for '%s'",
- start_lineno, query);
+ die("mysql_store_result() returned NULL for '%s'", query);
while ((row= mysql_fetch_row(res)))
{
if (strcmp(row[1], binlog) == 0)
@@ -1668,8 +2192,8 @@ int do_save_master_pos()
latest_epoch= strtoull(status, (char**) 0, 10);
}
else
- die("line %u: result does not contain '%s' in '%s'",
- start_lineno, latest_epoch_str, query);
+ die("result does not contain '%s' in '%s'",
+ latest_epoch_str, query);
/* latest_trans_epoch */
while (*status && strncmp(status, latest_trans_epoch_str,
sizeof(latest_trans_epoch_str)-1))
@@ -1680,10 +2204,10 @@ int do_save_master_pos()
latest_trans_epoch= strtoull(status, (char**) 0, 10);
}
else
- die("line %u: result does not contain '%s' in '%s'",
- start_lineno, latest_trans_epoch_str, query);
+ die("result does not contain '%s' in '%s'",
+ latest_trans_epoch_str, query);
/* latest_received_binlog_epoch */
- while (*status &&
+ while (*status &&
strncmp(status, latest_received_binlog_epoch_str,
sizeof(latest_received_binlog_epoch_str)-1))
status++;
@@ -1693,10 +2217,10 @@ int do_save_master_pos()
latest_received_binlog_epoch= strtoull(status, (char**) 0, 10);
}
else
- die("line %u: result does not contain '%s' in '%s'",
- start_lineno, latest_received_binlog_epoch_str, query);
+ die("result does not contain '%s' in '%s'",
+ latest_received_binlog_epoch_str, query);
/* latest_handled_binlog */
- while (*status &&
+ while (*status &&
strncmp(status, latest_handled_binlog_epoch_str,
sizeof(latest_handled_binlog_epoch_str)-1))
status++;
@@ -1706,10 +2230,10 @@ int do_save_master_pos()
latest_handled_binlog_epoch= strtoull(status, (char**) 0, 10);
}
else
- die("line %u: result does not contain '%s' in '%s'",
- start_lineno, latest_handled_binlog_epoch_str, query);
+ die("result does not contain '%s' in '%s'",
+ latest_handled_binlog_epoch_str, query);
/* latest_applied_binlog_epoch */
- while (*status &&
+ while (*status &&
strncmp(status, latest_applied_binlog_epoch_str,
sizeof(latest_applied_binlog_epoch_str)-1))
status++;
@@ -1719,16 +2243,16 @@ int do_save_master_pos()
latest_applied_binlog_epoch= strtoull(status, (char**) 0, 10);
}
else
- die("line %u: result does not contain '%s' in '%s'",
- start_lineno, latest_applied_binlog_epoch_str, query);
+ die("result does not contain '%s' in '%s'",
+ latest_applied_binlog_epoch_str, query);
if (count == 0)
start_epoch= latest_trans_epoch;
break;
}
}
if (!row)
- die("line %u: result does not contain '%s' in '%s'",
- start_lineno, binlog, query);
+ die("result does not contain '%s' in '%s'",
+ binlog, query);
if (latest_applied_binlog_epoch > applied_epoch)
count= 0;
applied_epoch= latest_applied_binlog_epoch;
@@ -1745,7 +2269,7 @@ int do_save_master_pos()
}
#endif
if (mysql_query(mysql, query= "show master status"))
- die("failed in show master status: %d: %s",
+ die("failed in 'show master status': %d %s",
mysql_errno(mysql), mysql_error(mysql));
if (!(res = mysql_store_result(mysql)))
@@ -1767,28 +2291,29 @@ int do_save_master_pos()
Assign the variable <var_name> with <var_val>
SYNOPSIS
- do_let()
- query called command
+ do_let()
+ query called command
DESCRIPTION
- let $<var_name>=<var_val><delimiter>
+ let $<var_name>=<var_val><delimiter>
- <var_name> - is the string string found between the $ and =
- <var_val> - is the content between the = and <delimiter>, it may span
- multiple line and contain any characters except <delimiter>
- <delimiter> - is a string containing of one or more chars, default is ;
+ <var_name> - is the string string found between the $ and =
+ <var_val> - is the content between the = and <delimiter>, it may span
+ multiple line and contain any characters except <delimiter>
+ <delimiter> - is a string containing of one or more chars, default is ;
RETURN VALUES
- Program will die if error detected
+ Program will die if error detected
*/
-int do_let(struct st_query *query)
+void do_let(struct st_command *command)
{
- int ret;
- char *p= query->first_argument;
+ char *p= command->first_argument;
char *var_name, *var_name_end;
DYNAMIC_STRING let_rhs_expr;
+ DBUG_ENTER("do_let");
+
init_dynamic_string(&let_rhs_expr, "", 512, 2048);
/* Find <var_name> */
@@ -1810,34 +2335,18 @@ int do_let(struct st_query *query)
while (*p && my_isspace(charset_info,*p))
p++;
- do_eval(&let_rhs_expr, p, FALSE);
+ do_eval(&let_rhs_expr, p, command->end, FALSE);
- query->last_argument= query->end;
+ command->last_argument= command->end;
/* Assign var_val to var_name */
- ret= var_set(var_name, var_name_end, let_rhs_expr.str,
- (let_rhs_expr.str + let_rhs_expr.length));
+ var_set(var_name, var_name_end, let_rhs_expr.str,
+ (let_rhs_expr.str + let_rhs_expr.length));
dynstr_free(&let_rhs_expr);
-
- return(ret);
-}
-
-
-/*
- Store an integer (typically the returncode of the last SQL)
- statement in the mysqltest builtin variable $mysql_errno, by
- simulating of a user statement "let $mysql_errno= <integer>"
-*/
-
-int var_set_errno(int sql_errno)
-{
- const char *var_name= "$mysql_errno";
- char var_val[21];
- uint length= my_sprintf(var_val, (var_val, "%d", sql_errno));
- return var_set(var_name, var_name + 12, var_val, var_val + length);
+ DBUG_VOID_RETURN;
}
-int do_rpl_probe(struct st_query *query __attribute__((unused)))
+int do_rpl_probe(struct st_command *command __attribute__((unused)))
{
DBUG_ENTER("do_rpl_probe");
if (mysql_rpl_probe(&cur_con->mysql))
@@ -1846,14 +2355,14 @@ int do_rpl_probe(struct st_query *query __attribute__((unused)))
}
-int do_enable_rpl_parse(struct st_query *query __attribute__((unused)))
+int do_enable_rpl_parse(struct st_command *command __attribute__((unused)))
{
mysql_enable_rpl_parse(&cur_con->mysql);
return 0;
}
-int do_disable_rpl_parse(struct st_query *query __attribute__((unused)))
+int do_disable_rpl_parse(struct st_command *command __attribute__((unused)))
{
mysql_disable_rpl_parse(&cur_con->mysql);
return 0;
@@ -1861,17 +2370,17 @@ int do_disable_rpl_parse(struct st_query *query __attribute__((unused)))
/*
- Sleep the number of specifed seconds
+ Sleep the number of specified seconds
SYNOPSIS
- do_sleep()
- q called command
- real_sleep use the value from opt_sleep as number of seconds to sleep
- if real_sleep is false
+ do_sleep()
+ q called command
+ real_sleep use the value from opt_sleep as number of seconds to sleep
+ if real_sleep is false
DESCRIPTION
- sleep <seconds>
- real_sleep <seconds>
+ sleep <seconds>
+ real_sleep <seconds>
The difference between the sleep and real_sleep commands is that sleep
uses the delay from the --sleep command-line option if there is one.
@@ -1882,26 +2391,26 @@ int do_disable_rpl_parse(struct st_query *query __attribute__((unused)))
used for cpu-independent delays.
*/
-int do_sleep(struct st_query *query, my_bool real_sleep)
+int do_sleep(struct st_command *command, my_bool real_sleep)
{
int error= 0;
- char *p= query->first_argument;
- char *sleep_start, *sleep_end= query->end;
+ char *p= command->first_argument;
+ char *sleep_start, *sleep_end= command->end;
double sleep_val;
while (my_isspace(charset_info, *p))
p++;
if (!*p)
- die("Missing argument to %.*s", query->first_word_len, query->query);
+ die("Missing argument to %.*s", command->first_word_len, command->query);
sleep_start= p;
/* Check that arg starts with a digit, not handled by my_strtod */
if (!my_isdigit(charset_info, *sleep_start))
- die("Invalid argument to %.*s \"%s\"", query->first_word_len, query->query,
- query->first_argument);
+ die("Invalid argument to %.*s \"%s\"", command->first_word_len,
+ command->query,command->first_argument);
sleep_val= my_strtod(sleep_start, &sleep_end, &error);
if (error)
- die("Invalid argument to %.*s \"%s\"", query->first_word_len, query->query,
- query->first_argument);
+ die("Invalid argument to %.*s \"%s\"", command->first_word_len,
+ command->query, command->first_argument);
/* Fixed sleep time selected by --sleep option */
if (opt_sleep >= 0 && !real_sleep)
@@ -1910,13 +2419,15 @@ int do_sleep(struct st_query *query, my_bool real_sleep)
DBUG_PRINT("info", ("sleep_val: %f", sleep_val));
if (sleep_val)
my_sleep((ulong) (sleep_val * 1000000L));
- query->last_argument= sleep_end;
+ command->last_argument= sleep_end;
return 0;
}
-static void get_file_name(char *filename, struct st_query *q)
+
+void do_get_file_name(struct st_command *command,
+ char* dest, uint dest_max_len)
{
- char *p= q->first_argument, *name;
+ char *p= command->first_argument, *name;
if (!*p)
die("Missing file name argument");
name= p;
@@ -1924,13 +2435,14 @@ static void get_file_name(char *filename, struct st_query *q)
p++;
if (*p)
*p++= 0;
- q->last_argument= p;
- strmake(filename, name, FN_REFLEN);
+ command->last_argument= p;
+ strmake(dest, name, dest_max_len);
}
-static void set_charset(struct st_query *q)
+
+void do_set_charset(struct st_command *command)
{
- char *charset_name= q->first_argument;
+ char *charset_name= command->first_argument;
char *p;
if (!charset_name || !*charset_name)
@@ -1941,78 +2453,182 @@ static void set_charset(struct st_query *q)
p++;
if(*p)
*p++= 0;
- q->last_argument= p;
+ command->last_argument= p;
charset_info= get_charset_by_csname(charset_name,MY_CS_PRIMARY,MYF(MY_WME));
if (!charset_info)
abort_not_supported_test("Test requires charset '%s'", charset_name);
}
-static uint get_errcodes(match_err *to,struct st_query *q)
+
+#if MYSQL_VERSION_ID >= 50000
+/* List of error names to error codes, available from 5.0 */
+typedef struct
+{
+ const char *name;
+ uint code;
+} st_error;
+
+static st_error global_error_names[] =
+{
+#include <mysqld_ername.h>
+ { 0, 0 }
+};
+
+uint get_errcode_from_name(char *error_name, char *error_end)
{
- char *p= q->first_argument;
+ /* SQL error as string */
+ st_error *e= global_error_names;
+
+ DBUG_ENTER("get_errcode_from_name");
+ DBUG_PRINT("enter", ("error_name: %s", error_name));
+
+ /* Loop through the array of known error names */
+ for (; e->name; e++)
+ {
+ /*
+ If we get a match, we need to check the length of the name we
+ matched against in case it was longer than what we are checking
+ (as in ER_WRONG_VALUE vs. ER_WRONG_VALUE_COUNT).
+ */
+ if (!strncmp(error_name, e->name, (int) (error_end - error_name)) &&
+ (uint) strlen(e->name) == (uint) (error_end - error_name))
+ {
+ DBUG_RETURN(e->code);
+ }
+ }
+ if (!e->name)
+ die("Unknown SQL error name '%s'", error_name);
+ DBUG_RETURN(0);
+}
+#else
+uint get_errcode_from_name(char *error_name __attribute__((unused)),
+ char *error_end __attribute__((unused)))
+{
+ abort_not_in_this_version();
+ return 0; /* Never reached */
+}
+#endif
+
+
+
+void do_get_errcodes(struct st_command *command)
+{
+ struct st_match_err *to= saved_expected_errors.err;
+ char *p= command->first_argument;
uint count= 0;
- DBUG_ENTER("get_errcodes");
+ DBUG_ENTER("do_get_errcodes");
if (!*p)
- die("Missing argument in %s", q->query);
+ die("Missing argument(s) to 'error'");
do
{
+ char *end;
+
+ /* Skip leading spaces */
+ while (*p && *p == ' ')
+ p++;
+
+ /* Find end */
+ end= p;
+ while (*end && *end != ',' && *end != ' ')
+ end++;
+
if (*p == 'S')
{
- /* SQLSTATE string */
- char *end= ++p + SQLSTATE_LENGTH;
- char *to_ptr= to[count].code.sqlstate;
+ char *to_ptr= to->code.sqlstate;
- for (; my_isalnum(charset_info, *p) && p != end; p++)
- *to_ptr++= *p;
- *to_ptr= 0;
+ /*
+ SQLSTATE string
+ - Must be SQLSTATE_LENGTH long
+ - May contain only digits[0-9] and _uppercase_ letters
+ */
+ p++; /* Step past the S */
+ if ((end - p) != SQLSTATE_LENGTH)
+ die("The sqlstate must be exactly %d chars long", SQLSTATE_LENGTH);
- to[count].type= ERR_SQLSTATE;
+ /* Check sqlstate string validity */
+ while (*p && p < end)
+ {
+ if (my_isdigit(charset_info, *p) || my_isupper(charset_info, *p))
+ *to_ptr++= *p++;
+ else
+ die("The sqlstate may only consist of digits[0-9] " \
+ "and _uppercase_ letters");
+ }
+
+ *to_ptr= 0;
+ to->type= ERR_SQLSTATE;
+ DBUG_PRINT("info", ("ERR_SQLSTATE: %s", to->code.sqlstate));
+ }
+ else if (*p == 's')
+ {
+ die("The sqlstate definition must start with an uppercase S");
}
else if (*p == 'E')
{
- /* SQL error as string */
- st_error *e= global_error;
- char *start= p++;
+ /* Error name string */
- for (; *p == '_' || my_isalnum(charset_info, *p); p++)
- ;
- for (; e->name; e++)
- {
- /*
- If we get a match, we need to check the length of the name we
- matched against in case it was longer than what we are checking
- (as in ER_WRONG_VALUE vs. ER_WRONG_VALUE_COUNT).
- */
- if (!strncmp(start, e->name, (int) (p - start)) &&
- (uint) strlen(e->name) == (uint) (p - start))
- {
- to[count].code.errnum= (uint) e->code;
- to[count].type= ERR_ERRNO;
- break;
- }
- }
- if (!e->name)
- die("Unknown SQL error '%s'", start);
+ DBUG_PRINT("info", ("Error name: %s", p));
+ to->code.errnum= get_errcode_from_name(p, end);
+ to->type= ERR_ERRNO;
+ DBUG_PRINT("info", ("ERR_ERRNO: %d", to->code.errnum));
+ }
+ else if (*p == 'e')
+ {
+ die("The error name definition must start with an uppercase E");
}
else
{
long val;
+ char *start= p;
+ /* Check that the string passed to str2int only contain digits */
+ while (*p && p != end)
+ {
+ if (!my_isdigit(charset_info, *p))
+ die("Invalid argument to error: '%s' - "\
+ "the errno may only consist of digits[0-9]",
+ command->first_argument);
+ p++;
+ }
+
+ /* Convert the sting to int */
+ if (!str2int(start, 10, (long) INT_MIN, (long) INT_MAX, &val))
+ die("Invalid argument to error: '%s'", command->first_argument);
- if (!(p= str2int(p,10,(long) INT_MIN, (long) INT_MAX, &val)))
- die("Invalid argument in %s", q->query);
- to[count].code.errnum= (uint) val;
- to[count].type= ERR_ERRNO;
+ to->code.errnum= (uint) val;
+ to->type= ERR_ERRNO;
+ DBUG_PRINT("info", ("ERR_ERRNO: %d", to->code.errnum));
}
+ to++;
count++;
- } while (*(p++) == ',');
- q->last_argument= (p - 1);
- to[count].type= ERR_EMPTY; /* End of data */
- DBUG_RETURN(count);
+
+ if (count >= (sizeof(saved_expected_errors.err) /
+ sizeof(struct st_match_err)))
+ die("Too many errorcodes specified");
+
+ /* Set pointer to the end of the last error code */
+ p= end;
+
+ /* Find next ',' */
+ while (*p && *p != ',')
+ p++;
+
+ if (*p)
+ p++; /* Step past ',' */
+
+ } while (*p);
+
+ command->last_argument= p;
+ to->type= ERR_EMPTY; /* End of data */
+
+ DBUG_PRINT("info", ("Expected errors: %d", count));
+ saved_expected_errors.count= count;
+ DBUG_VOID_RETURN;
}
+
/*
Get a string; Return ptr to end of string
Strings may be surrounded by " or '
@@ -2020,11 +2636,10 @@ static uint get_errcodes(match_err *to,struct st_query *q)
If string is a '$variable', return the value of the variable.
*/
-
-static char *get_string(char **to_ptr, char **from_ptr,
- struct st_query *q)
+char *get_string(char **to_ptr, char **from_ptr,
+ struct st_command *command)
{
- reg1 char c,sep;
+ char c, sep;
char *to= *to_ptr, *from= *from_ptr, *start=to;
DBUG_ENTER("get_string");
@@ -2070,7 +2685,7 @@ static char *get_string(char **to_ptr, char **from_ptr,
*to++=c;
}
if (*from != ' ' && *from)
- die("Wrong string argument in %s", q->query);
+ die("Wrong string argument in %s", command->query);
while (my_isspace(charset_info,*from)) /* Point to next string */
from++;
@@ -2093,282 +2708,25 @@ static char *get_string(char **to_ptr, char **from_ptr,
DBUG_RETURN(start);
}
-/*
- Finds the next (non-escaped) '/' in the expression.
- (If the character '/' is needed, it can be escaped using '\'.)
-*/
-
-#define PARSE_REGEX_ARG \
- while (p < expr_end) \
- {\
- char c= *p;\
- if (c == '/')\
- {\
- if (last_c == '\\')\
- {\
- buf_p[-1]= '/';\
- }\
- else\
- {\
- *buf_p++ = 0;\
- break;\
- } \
- } \
- else\
- *buf_p++ = c;\
- \
- last_c= c;\
- p++;\
- } \
-
-/*
- Initializes the regular substitution expression to be used in the
- result output of test.
-
- Returns: st_replace_regex struct with pairs of substitutions
-*/
-
-static struct st_replace_regex* init_replace_regex(char* expr)
-{
- struct st_replace_regex* res;
- char* buf,*expr_end;
- char* p;
- char* buf_p;
- uint expr_len= strlen(expr);
- char last_c = 0;
- struct st_regex reg;
-
- /* my_malloc() will die on fail with MY_FAE */
- res=(struct st_replace_regex*)my_malloc(
- sizeof(*res)+expr_len ,MYF(MY_FAE+MY_WME));
- my_init_dynamic_array(&res->regex_arr,sizeof(struct st_regex),128,128);
-
- buf= (char*)res + sizeof(*res);
- expr_end= expr + expr_len;
- p= expr;
- buf_p= buf;
-
- /* for each regexp substitution statement */
- while (p < expr_end)
- {
- bzero(&reg,sizeof(reg));
- /* find the start of the statement */
- while (p < expr_end)
- {
- if (*p == '/')
- break;
- p++;
- }
-
- if (p == expr_end || ++p == expr_end)
- {
- if (res->regex_arr.elements)
- break;
- else
- goto err;
- }
- /* we found the start */
- reg.pattern= buf_p;
-
- /* Find first argument -- pattern string to be removed */
- PARSE_REGEX_ARG
-
- if (p == expr_end || ++p == expr_end)
- goto err;
-
- /* buf_p now points to the replacement pattern terminated with \0 */
- reg.replace= buf_p;
-
- /* Find second argument -- replace string to replace pattern */
- PARSE_REGEX_ARG
-
- if (p == expr_end)
- goto err;
-
- /* skip the ending '/' in the statement */
- p++;
-
- /* Check if we should do matching case insensitive */
- if (p < expr_end && *p == 'i')
- reg.icase= 1;
-
- /* done parsing the statement, now place it in regex_arr */
- if (insert_dynamic(&res->regex_arr,(gptr) &reg))
- die("Out of memory");
- }
- res->odd_buf_len= res->even_buf_len= 8192;
- res->even_buf= (char*)my_malloc(res->even_buf_len,MYF(MY_WME+MY_FAE));
- res->odd_buf= (char*)my_malloc(res->odd_buf_len,MYF(MY_WME+MY_FAE));
- res->buf= res->even_buf;
-
- return res;
-
-err:
- my_free((gptr)res,0);
- die("Error parsing replace_regex \"%s\"", expr);
- return 0;
-}
-
-/*
- Execute all substitutions on val.
-
- Returns: true if substituition was made, false otherwise
- Side-effect: Sets r->buf to be the buffer with all substitutions done.
-
- IN:
- struct st_replace_regex* r
- char* val
- Out:
- struct st_replace_regex* r
- r->buf points at the resulting buffer
- r->even_buf and r->odd_buf might have been reallocated
- r->even_buf_len and r->odd_buf_len might have been changed
-
- TODO: at some point figure out if there is a way to do everything
- in one pass
-*/
-
-static int multi_reg_replace(struct st_replace_regex* r,char* val)
-{
- uint i;
- char* in_buf, *out_buf;
- int* buf_len_p;
-
- in_buf= val;
- out_buf= r->even_buf;
- buf_len_p= &r->even_buf_len;
- r->buf= 0;
-
- /* For each substitution, do the replace */
- for (i= 0; i < r->regex_arr.elements; i++)
- {
- struct st_regex re;
- char* save_out_buf= out_buf;
-
- get_dynamic(&r->regex_arr,(gptr)&re,i);
-
- if (!reg_replace(&out_buf, buf_len_p, re.pattern, re.replace,
- in_buf, re.icase))
- {
- /* if the buffer has been reallocated, make adjustements */
- if (save_out_buf != out_buf)
- {
- if (save_out_buf == r->even_buf)
- r->even_buf= out_buf;
- else
- r->odd_buf= out_buf;
- }
-
- r->buf= out_buf;
- if (in_buf == val)
- in_buf= r->odd_buf;
-
- swap_variables(char*,in_buf,out_buf);
-
- buf_len_p= (out_buf == r->even_buf) ? &r->even_buf_len :
- &r->odd_buf_len;
- }
- }
-
- return (r->buf == 0);
-}
-
-/*
- Parse the regular expression to be used in all result files
- from now on.
-
- The syntax is --replace_regex /from/to/i /from/to/i ...
- i means case-insensitive match. If omitted, the match is
- case-sensitive
-
-*/
-static void get_replace_regex(struct st_query *q)
-{
- char *expr= q->first_argument;
- free_replace_regex();
- if (!(glob_replace_regex=init_replace_regex(expr)))
- die("Could not init replace_regex");
- q->last_argument= q->end;
-}
-
-/*
- Get arguments for replace. The syntax is:
- replace from to [from to ...]
- Where each argument may be quoted with ' or "
- A argument may also be a variable, in which case the value of the
- variable is replaced.
-*/
-
-static void get_replace(struct st_query *q)
+void set_reconnect(MYSQL* mysql, int val)
{
- uint i;
- char *from= q->first_argument;
- char *buff,*start;
- char word_end_chars[256],*pos;
- POINTER_ARRAY to_array,from_array;
- DBUG_ENTER("get_replace");
-
- free_replace();
-
- bzero((char*) &to_array,sizeof(to_array));
- bzero((char*) &from_array,sizeof(from_array));
- if (!*from)
- die("Missing argument in %s", q->query);
- start=buff=my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
- while (*from)
- {
- char *to=buff;
- to=get_string(&buff, &from, q);
- if (!*from)
- die("Wrong number of arguments to replace_result in '%s'", q->query);
- insert_pointer_name(&from_array,to);
- to=get_string(&buff, &from, q);
- insert_pointer_name(&to_array,to);
- }
- for (i=1,pos=word_end_chars ; i < 256 ; i++)
- if (my_isspace(charset_info,i))
- *pos++= i;
- *pos=0; /* End pointer */
- if (!(glob_replace=init_replace((char**) from_array.typelib.type_names,
- (char**) to_array.typelib.type_names,
- (uint) from_array.typelib.count,
- word_end_chars)))
- die("Can't initialize replace from '%s'", q->query);
- free_pointer_array(&from_array);
- free_pointer_array(&to_array);
- my_free(start, MYF(0));
- q->last_argument= q->end;
+ my_bool reconnect= val;
+ DBUG_ENTER("set_reconnect");
+ DBUG_PRINT("info", ("val: %d", val));
+#if MYSQL_VERSION_ID < 50000
+ mysql->reconnect= reconnect;
+#else
+ mysql_options(mysql, MYSQL_OPT_RECONNECT, (char *)&reconnect);
+#endif
DBUG_VOID_RETURN;
}
-static void free_replace_regex()
-{
- if (glob_replace_regex)
- {
- my_free(glob_replace_regex->even_buf,MYF(MY_ALLOW_ZERO_PTR));
- my_free(glob_replace_regex->odd_buf,MYF(MY_ALLOW_ZERO_PTR));
- my_free((char*) glob_replace_regex,MYF(0));
- glob_replace_regex=0;
- }
-}
-
-
-void free_replace()
-{
- DBUG_ENTER("free_replace");
- if (glob_replace)
- {
- my_free((char*) glob_replace,MYF(0));
- glob_replace=0;
- }
- DBUG_VOID_RETURN;
-}
-struct connection * find_connection_by_name(const char *name)
+struct st_connection * find_connection_by_name(const char *name)
{
- struct connection *con;
- for (con= cons; con < next_con; con++)
+ struct st_connection *con;
+ for (con= connections; con < next_con; con++)
{
if (!strcmp(con->name, name))
{
@@ -2390,10 +2748,10 @@ int select_connection_name(const char *name)
}
-int select_connection(struct st_query *query)
+int select_connection(struct st_command *command)
{
char *name;
- char *p= query->first_argument;
+ char *p= command->first_argument;
DBUG_ENTER("select_connection");
if (!*p)
@@ -2403,15 +2761,16 @@ int select_connection(struct st_query *query)
p++;
if (*p)
*p++= 0;
- query->last_argument= p;
+ command->last_argument= p;
return select_connection_name(name);
}
-int close_connection(struct st_query *q)
+void do_close_connection(struct st_command *command)
{
- char *p= q->first_argument, *name;
- struct connection *con;
+ char *p= command->first_argument, *name;
+ struct st_connection *con;
+
DBUG_ENTER("close_connection");
DBUG_PRINT("enter",("name: '%s'",p));
@@ -2423,13 +2782,17 @@ int close_connection(struct st_query *q)
if (*p)
*p++= 0;
- q->last_argument= p;
- for (con= cons; con < next_con; con++)
+ command->last_argument= p;
+
+ /* Loop through connection pool for connection to close */
+ for (con= connections; con < next_con; con++)
{
+ DBUG_PRINT("info", ("con->name: %s", con->name));
if (!strcmp(con->name, name))
{
+ DBUG_PRINT("info", ("Closing connection %s", con->name));
#ifndef EMBEDDED_LIBRARY
- if (q->type == Q_DIRTY_CLOSE)
+ if (command->type == Q_DIRTY_CLOSE)
{
if (con->mysql.net.vio)
{
@@ -2443,59 +2806,19 @@ int close_connection(struct st_query *q)
mysql_close(con->util_mysql);
con->util_mysql= 0;
my_free(con->name, MYF(0));
+
/*
- When the connection is closed set name to "closed_connection"
- to make it possible to reuse the connection name.
- The connection slot will not be reused
- */
+ When the connection is closed set name to "closed_connection"
+ to make it possible to reuse the connection name.
+ The connection slot will not be reused
+ */
if (!(con->name = my_strdup("closed_connection", MYF(MY_WME))))
die("Out of memory");
- DBUG_RETURN(0);
+
+ DBUG_VOID_RETURN;
}
}
die("connection '%s' not found in connection pool", name);
- DBUG_RETURN(1); /* Never reached */
-}
-
-
-/*
- This one now is a hack - we may want to improve in in the
- future to handle quotes. For now we assume that anything that is not
- a comma, a space or ) belongs to the argument. space is a chopper, comma or
- ) are delimiters/terminators
-
- SYNOPSIS
- safe_get_param
- str - string to get param from
- arg - pointer to string where result will be stored
- msg - Message to display if param is not found
- if msg is 0 this param is not required and param may be empty
-
- RETURNS
- pointer to str after param
-
-*/
-
-char* safe_get_param(char *str, char** arg, const char *msg)
-{
- DBUG_ENTER("safe_get_param");
- if(!*str)
- {
- if (msg)
- die(msg);
- *arg= str;
- DBUG_RETURN(str);
- }
- while (*str && my_isspace(charset_info,*str))
- str++;
- *arg= str;
- while (*str && *str != ',' && *str != ')')
- str++;
- if (msg && !*arg)
- die(msg);
-
- *str++= 0;
- DBUG_RETURN(str);
}
@@ -2503,54 +2826,60 @@ char* safe_get_param(char *str, char** arg, const char *msg)
Connect to a server doing several retries if needed.
SYNOPSIS
- safe_connect()
- con - connection structure to be used
- host, user, pass, - connection parameters
- db, port, sock
+ safe_connect()
+ con - connection structure to be used
+ host, user, pass, - connection parameters
+ db, port, sock
NOTE
- Sometimes in a test the client starts before
- the server - to solve the problem, we try again
- after some sleep if connection fails the first
- time
+ Sometimes in a test the client starts before
+ the server - to solve the problem, we try again
+ after some sleep if connection fails the first
+ time
- This function will try to connect to the given server
- "opt_max_connect_retries" times and sleep "connection_retry_sleep"
- seconds between attempts before finally giving up.
- This helps in situation when the client starts
- before the server (which happens sometimes).
- It will ignore any errors during these retries. One should use
- connect_n_handle_errors() if he expects a connection error and wants
- handle as if it was an error from a usual statement.
+ This function will try to connect to the given server
+ "opt_max_connect_retries" times and sleep "connection_retry_sleep"
+ seconds between attempts before finally giving up.
+ This helps in situation when the client starts
+ before the server (which happens sometimes).
+ It will only ignore connection errors during these retries.
- RETURN VALUE
- 0 - success, non-0 - failure
*/
-int safe_connect(MYSQL* mysql, const char *host, const char *user,
- const char *pass, const char *db, int port, const char *sock)
+void safe_connect(MYSQL* mysql, const char *name, const char *host,
+ const char *user, const char *pass, const char *db,
+ int port, const char *sock)
{
- int con_error= 1;
- my_bool reconnect= 1;
+ int failed_attempts= 0;
static ulong connection_retry_sleep= 100000; /* Microseconds */
- int i;
- for (i= 0; i < opt_max_connect_retries; i++)
+
+ DBUG_ENTER("safe_connect");
+ while(!mysql_real_connect(mysql, host,user, pass, db, port, sock,
+ CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS))
{
- if (mysql_real_connect(mysql, host,user, pass, db, port, sock,
- CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS))
+ /*
+ Connect failed
+
+ Only allow retry if this was an error indicating the server
+ could not be contacted
+ */
+
+ if (mysql_errno(mysql) == CR_CONNECTION_ERROR &&
+ failed_attempts < opt_max_connect_retries)
+ my_sleep(connection_retry_sleep);
+ else
{
- con_error= 0;
- break;
+ if (failed_attempts > 0)
+ die("Could not open connection '%s' after %d attempts: %d %s", name,
+ failed_attempts, mysql_errno(mysql), mysql_error(mysql));
+ else
+ die("Could not open connection '%s': %d %s", name,
+ mysql_errno(mysql), mysql_error(mysql));
}
- my_sleep(connection_retry_sleep);
+ failed_attempts++;
}
- /*
- TODO: change this to 0 in future versions, but the 'kill' test relies on
- existing behavior
- */
- mysql_options(mysql, MYSQL_OPT_RECONNECT, (char *)&reconnect);
- return con_error;
+ DBUG_VOID_RETURN;
}
@@ -2558,45 +2887,41 @@ int safe_connect(MYSQL* mysql, const char *host, const char *user,
Connect to a server and handle connection errors in case they occur.
SYNOPSIS
- connect_n_handle_errors()
- q - context of connect "query" (command)
- con - connection structure to be used
- host, user, pass, - connection parameters
- db, port, sock
- create_conn - out parameter, set to zero if connection was
- not established and is not touched otherwise
+ connect_n_handle_errors()
+ q - context of connect "query" (command)
+ con - connection structure to be used
+ host, user, pass, - connection parameters
+ db, port, sock
DESCRIPTION
- This function will try to establish a connection to server and handle
- possible errors in the same manner as if "connect" was usual SQL-statement
- (If error is expected it will ignore it once it occurs and log the
- "statement" to the query log).
- Unlike safe_connect() it won't do several attempts.
+ This function will try to establish a connection to server and handle
+ possible errors in the same manner as if "connect" was usual SQL-statement
+ (If error is expected it will ignore it once it occurs and log the
+ "statement" to the query log).
+ Unlike safe_connect() it won't do several attempts.
+
+ RETURN VALUES
+ 1 - Connected
+ 0 - Not connected
- RETURN VALUE
- 0 - success, non-0 - failure
*/
-int connect_n_handle_errors(struct st_query *q, MYSQL* con, const char* host,
+int connect_n_handle_errors(struct st_command *command,
+ MYSQL* con, const char* host,
const char* user, const char* pass,
- const char* db, int port, const char* sock,
- int* create_conn)
+ const char* db, int port, const char* sock)
{
DYNAMIC_STRING *ds;
- my_bool reconnect= 1;
- int error= 0;
ds= &ds_res;
- if (!disable_query_log)
+ /* Only log if an error is expected */
+ if (!command->abort_on_error &&
+ !disable_query_log)
{
/*
- It is nice to have connect() statement logged in result file
- in this case.
- QQ: Should we do this only if we are expecting an error ?
+ Log the connect to result log
*/
- char port_buff[22]; /* This should be enough for any int */
- char *port_end;
dynstr_append_mem(ds, "connect(", 8);
replace_dynstr_append(ds, host);
dynstr_append_mem(ds, ",", 1);
@@ -2607,8 +2932,7 @@ int connect_n_handle_errors(struct st_query *q, MYSQL* con, const char* host,
if (db)
replace_dynstr_append(ds, db);
dynstr_append_mem(ds, ",", 1);
- port_end= int10_to_str(port, port_buff, 10);
- replace_dynstr_append_mem(ds, port_buff, port_end - port_buff);
+ replace_dynstr_append_uint(ds, port);
dynstr_append_mem(ds, ",", 1);
if (sock)
replace_dynstr_append(ds, sock);
@@ -2619,148 +2943,150 @@ int connect_n_handle_errors(struct st_query *q, MYSQL* con, const char* host,
if (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0,
CLIENT_MULTI_STATEMENTS))
{
- handle_error("connect", q, mysql_errno(con), mysql_error(con),
+ handle_error(command, mysql_errno(con), mysql_error(con),
mysql_sqlstate(con), ds);
- *create_conn= 0;
- goto err;
+ return 0; /* Not connected */
}
- handle_no_error(q);
-
- /*
- TODO: change this to 0 in future versions, but the 'kill' test relies on
- existing behavior
- */
- mysql_options(con, MYSQL_OPT_RECONNECT, (char *)&reconnect);
-
-err:
- free_replace();
- free_replace_regex();
- return error;
+ handle_no_error(command);
+ return 1; /* Connected */
}
/*
Open a new connection to MySQL Server with the parameters
- specified
+ specified. Make the new connection the current connection.
SYNOPSIS
- do_connect()
- q called command
+ do_connect()
+ q called command
DESCRIPTION
- connect(<name>,<host>,<user>,<pass>,<db>,[<port>,<sock>[<opts>]]);
-
- <name> - name of the new connection
- <host> - hostname of server
- <user> - user to connect as
- <pass> - password used when connecting
- <db> - initial db when connected
- <port> - server port
- <sock> - server socket
- <opts> - options to use for the connection
- SSL - use SSL if available
- COMPRESS - use compression if available
-
- */
-
-int do_connect(struct st_query *q)
-{
- char *con_name, *con_user,*con_pass, *con_host, *con_port_str,
- *con_db, *con_sock, *con_options;
- char *con_buf, *p;
- char buff[FN_REFLEN];
- int con_port;
- bool con_ssl= 0;
- bool con_compress= 0;
- int free_con_sock= 0;
- int error= 0;
- int create_conn= 1;
- VAR *var_port, *var_sock;
+ connect(<name>,<host>,<user>,[<pass>,[<db>,[<port>,<sock>[<opts>]]]]);
+ connect <name>,<host>,<user>,[<pass>,[<db>,[<port>,<sock>[<opts>]]]];
+
+ <name> - name of the new connection
+ <host> - hostname of server
+ <user> - user to connect as
+ <pass> - password used when connecting
+ <db> - initial db when connected
+ <port> - server port
+ <sock> - server socket
+ <opts> - options to use for the connection
+ * SSL - use SSL if available
+ * COMPRESS - use compression if available
+
+*/
+
+void do_connect(struct st_command *command)
+{
+ int con_port= port;
+ char *con_options;
+ bool con_ssl= 0, con_compress= 0;
+ char *ptr;
+
+ static DYNAMIC_STRING ds_connection_name;
+ static DYNAMIC_STRING ds_host;
+ static DYNAMIC_STRING ds_user;
+ static DYNAMIC_STRING ds_password;
+ static DYNAMIC_STRING ds_database;
+ static DYNAMIC_STRING ds_port;
+ static DYNAMIC_STRING ds_sock;
+ static DYNAMIC_STRING ds_options;
+ const struct command_arg connect_args[] = {
+ "connection name", ARG_STRING, TRUE, &ds_connection_name,
+ "Name of the connection",
+ "host", ARG_STRING, TRUE, &ds_host, "Host to connect to",
+ "user", ARG_STRING, FALSE, &ds_user, "User to connect as",
+ "passsword", ARG_STRING, FALSE, &ds_password,
+ "Password used when connecting",
+ "database", ARG_STRING, FALSE, &ds_database,
+ "Dtabase to select after connect",
+ "port", ARG_STRING, FALSE, &ds_port, "Port to connect to",
+ "socket", ARG_STRING, FALSE, &ds_sock, "Socket to connect with",
+ "options", ARG_STRING, FALSE, &ds_options,
+ "Options to use while connecting"
+ };
DBUG_ENTER("do_connect");
- DBUG_PRINT("enter",("connect: %s", q->first_argument));
-
- /* Make a copy of query before parsing, safe_get_param will modify */
- if (!(con_buf= my_strdup(q->first_argument, MYF(MY_WME))))
- die("Could not allocate con_buf");
- p= con_buf;
-
- if (*p != '(')
- die("Syntax error in connect - expected '(' found '%c'", *p);
- p++;
- p= safe_get_param(p, &con_name, "Missing connection name");
- p= safe_get_param(p, &con_host, "Missing connection host");
- p= safe_get_param(p, &con_user, "Missing connection user");
- p= safe_get_param(p, &con_pass, "Missing connection password");
- p= safe_get_param(p, &con_db, "Missing connection db");
+ DBUG_PRINT("enter",("connect: %s", command->first_argument));
- /* Port */
- p= safe_get_param(p, &con_port_str, 0);
- if (*con_port_str)
+ /* Remove parenteses around connect arguments */
+ if ((ptr= strstr(command->first_argument, "(")))
{
- if (*con_port_str == '$')
+ /* Replace it with a space */
+ *ptr= ' ';
+ if ((ptr= strstr(command->first_argument, ")")))
{
- if (!(var_port= var_get(con_port_str, 0, 0, 0)))
- die("Unknown variable '%s'", con_port_str+1);
- con_port= var_port->int_val;
+ /* Replace it with \0 */
+ *ptr= 0;
}
else
- {
- con_port= atoi(con_port_str);
- if (con_port == 0)
- die("Illegal argument for port: '%s'", con_port_str);
- }
+ die("connect - argument list started with '(' must be ended with ')'");
}
- else
+
+ check_command_args(command, command->first_argument, connect_args,
+ sizeof(connect_args)/sizeof(struct command_arg),
+ ',');
+
+ /* Port */
+ if (ds_port.length)
{
- con_port= port;
+ con_port= atoi(ds_port.str);
+ if (con_port == 0)
+ die("Illegal argument for port: '%s'", ds_port.str);
}
/* Sock */
- p= safe_get_param(p, &con_sock, 0);
- if (*con_sock)
+ if (ds_sock.length)
{
- if (*con_sock == '$')
+ /*
+ If the socket is specified just as a name without path
+ append tmpdir in front
+ */
+ if (*ds_sock.str != FN_LIBCHAR)
{
- if (!(var_sock= var_get(con_sock, 0, 0, 0)))
- die("Unknown variable '%s'", con_sock+1);
- if (!(con_sock= (char*)my_malloc(var_sock->str_val_len+1, MYF(0))))
- die("Out of memory");
- free_con_sock= 1;
- memcpy(con_sock, var_sock->str_val, var_sock->str_val_len);
- con_sock[var_sock->str_val_len]= 0;
+ char buff[FN_REFLEN];
+ fn_format(buff, ds_sock.str, TMPDIR, "", 0);
+ dynstr_set(&ds_sock, buff);
}
}
else
{
- con_sock= (char*) unix_sock;
+ /* No socket specified, use default */
+ dynstr_set(&ds_sock, unix_sock);
}
+ DBUG_PRINT("info", ("socket: %s", ds_sock.str));
+
/* Options */
- p= safe_get_param(p, &con_options, 0);
+ con_options= ds_options.str;
while (*con_options)
{
- char* str= con_options;
- while (*str && !my_isspace(charset_info, *str))
- str++;
- *str++= 0;
- if (!strcmp(con_options, "SSL"))
+ char* end;
+ /* Step past any spaces in beginning of option*/
+ while (*con_options && my_isspace(charset_info, *con_options))
+ con_options++;
+ /* Find end of this option */
+ end= con_options;
+ while (*end && !my_isspace(charset_info, *end))
+ end++;
+ if (!strncmp(con_options, "SSL", 3))
con_ssl= 1;
- else if (!strcmp(con_options, "COMPRESS"))
+ else if (!strncmp(con_options, "COMPRESS", 8))
con_compress= 1;
else
- die("Illegal option to connect: %s", con_options);
- con_options= str;
+ die("Illegal option to connect: %.*s", end - con_options, con_options);
+ /* Process next option */
+ con_options= end;
}
- /* Note: 'p' is pointing into the copy 'con_buf' */
- q->last_argument= q->first_argument + (p - con_buf);
- if (next_con == cons_end)
- die("Connection limit exhausted - increase MAX_CONS in mysqltest.c");
+ if (next_con == connections_end)
+ die("Connection limit exhausted, you can have max %d connections",
+ (sizeof(connections)/sizeof(struct st_connection)));
- if (find_connection_by_name(con_name))
- die("Connection %s already exists", con_name);
+ if (find_connection_by_name(ds_connection_name.str))
+ die("Connection %s already exists", ds_connection_name.str);
if (!mysql_init(&next_con->mysql))
die("Failed on mysql_init()");
@@ -2772,53 +3098,56 @@ int do_connect(struct st_query *q)
#ifdef HAVE_OPENSSL
if (opt_use_ssl || con_ssl)
{
- /* Turn on ssl_verify_server_cert only if host is "localhost" */
- opt_ssl_verify_server_cert= !strcmp(con_host, "localhost");
-
mysql_ssl_set(&next_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+#if MYSQL_VERSION_ID >= 50000
+ /* Turn on ssl_verify_server_cert only if host is "localhost" */
+ opt_ssl_verify_server_cert= !strcmp(ds_connection_name.str, "localhost");
mysql_options(&next_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
&opt_ssl_verify_server_cert);
+#endif
}
#endif
- if (con_sock && !free_con_sock && *con_sock && *con_sock != FN_LIBCHAR)
- con_sock=fn_format(buff, con_sock, TMPDIR, "", 0);
- if (!con_db[0])
- con_db= db;
+
+ /* Use default db name */
+ if (ds_database.length == 0)
+ dynstr_set(&ds_database, db);
+
/* Special database to allow one to connect without a database name */
- if (con_db && !strcmp(con_db,"*NO-ONE*"))
- con_db= 0;
- if (q->abort_on_error)
- {
- if (safe_connect(&next_con->mysql, con_host, con_user, con_pass,
- con_db, con_port, con_sock ? con_sock: 0))
- die("Could not open connection '%s': %d %s", con_name,
- mysql_errno(&next_con->mysql), mysql_error(&next_con->mysql));
- }
- else
- error= connect_n_handle_errors(q, &next_con->mysql, con_host, con_user,
- con_pass, con_db, con_port, con_sock,
- &create_conn);
+ if (ds_database.length && !strcmp(ds_database.str,"*NO-ONE*"))
+ dynstr_set(&ds_database, "");
- if (create_conn)
+
+ if (connect_n_handle_errors(command, &next_con->mysql,
+ ds_host.str,ds_user.str,
+ ds_password.str, ds_database.str,
+ con_port, ds_sock.str))
{
- if (!(next_con->name= my_strdup(con_name, MYF(MY_WME))))
- die(NullS);
+ DBUG_PRINT("info", ("Inserting connection %s in connection pool",
+ ds_connection_name.str));
+ if (!(next_con->name= my_strdup(ds_connection_name.str, MYF(MY_WME))))
+ die("Out of memory");
cur_con= next_con++;
}
- if (free_con_sock)
- my_free(con_sock, MYF(MY_WME));
- my_free(con_buf, MYF(MY_WME));
- DBUG_RETURN(error);
+
+ dynstr_free(&ds_connection_name);
+ dynstr_free(&ds_host);
+ dynstr_free(&ds_user);
+ dynstr_free(&ds_password);
+ dynstr_free(&ds_database);
+ dynstr_free(&ds_port);
+ dynstr_free(&ds_sock);
+ dynstr_free(&ds_options);
+ DBUG_VOID_RETURN;
}
-int do_done(struct st_query *q)
+int do_done(struct st_command *command)
{
/* Check if empty block stack */
if (cur_block == block_stack)
{
- if (*q->query != '}')
+ if (*command->query != '}')
die("Stray 'end' command - end of block before beginning");
die("Stray '}' - end of block before beginning");
}
@@ -2844,31 +3173,31 @@ int do_done(struct st_query *q)
Process start of a "if" or "while" statement
SYNOPSIS
- do_block()
- cmd Type of block
- q called command
+ do_block()
+ cmd Type of block
+ q called command
DESCRIPTION
- if ([!]<expr>)
- {
- <block statements>
- }
+ if ([!]<expr>)
+ {
+ <block statements>
+ }
- while ([!]<expr>)
- {
- <block statements>
- }
+ while ([!]<expr>)
+ {
+ <block statements>
+ }
- Evaluates the <expr> and if it evaluates to
- greater than zero executes the following code block.
- A '!' can be used before the <expr> to indicate it should
- be executed if it evaluates to zero.
+ Evaluates the <expr> and if it evaluates to
+ greater than zero executes the following code block.
+ A '!' can be used before the <expr> to indicate it should
+ be executed if it evaluates to zero.
- */
+*/
-void do_block(enum block_cmd cmd, struct st_query* q)
+void do_block(enum block_cmd cmd, struct st_command* command)
{
- char *p= q->first_argument;
+ char *p= command->first_argument;
const char *expr_start, *expr_end;
VAR v;
const char *cmd_name= (cmd == cmd_while ? "while" : "if");
@@ -2912,9 +3241,7 @@ void do_block(enum block_cmd cmd, struct st_query* q)
while (*p && my_isspace(charset_info, *p))
p++;
- if (*p == '{')
- die("Missing newline between %s and '{'", cmd_name);
- if (*p)
+ if (*p && *p != '{')
die("Missing '{' after %s. Found \"%s\"", cmd_name, p);
var_init(&v,0,0,0,0);
@@ -2935,43 +3262,41 @@ void do_block(enum block_cmd cmd, struct st_query* q)
}
-/*
- Read characters from line buffer or file. This is needed to allow
- my_ungetc() to buffer MAX_DELIMITER characters for a file
+void do_delimiter(struct st_command* command)
+{
+ char* p= command->first_argument;
+ DBUG_ENTER("do_delimiter");
+ DBUG_PRINT("enter", ("first_argument: %s", command->first_argument));
- NOTE:
- This works as long as one doesn't change files (with 'source file_name')
- when there is things pushed into the buffer. This should however not
- happen for any tests in the test suite.
-*/
+ while (*p && my_isspace(charset_info, *p))
+ p++;
-int my_getc(FILE *file)
-{
- if (line_buffer_pos == line_buffer)
- return fgetc(file);
- return *--line_buffer_pos;
-}
+ if (!(*p))
+ die("Can't set empty delimiter");
-void my_ungetc(int c)
-{
- *line_buffer_pos++= (char) c;
+ strmake(delimiter, p, sizeof(delimiter) - 1);
+ delimiter_length= strlen(delimiter);
+
+ DBUG_PRINT("exit", ("delimiter: %s", delimiter));
+ command->last_argument= p + delimiter_length;
+ DBUG_VOID_RETURN;
}
-my_bool end_of_query(int c)
+my_bool match_delimiter(int c, const char *delim, uint length)
{
uint i;
- char tmp[MAX_DELIMITER];
+ char tmp[MAX_DELIMITER_LENGTH];
- if (c != *delimiter)
+ if (c != *delim)
return 0;
- for (i= 1; i < delimiter_length &&
- (c= my_getc(cur_file->file)) == *(delimiter + i);
+ for (i= 1; i < length &&
+ (c= my_getc(cur_file->file)) == *(delim + i);
i++)
tmp[i]= c;
- if (i == delimiter_length)
+ if (i == length)
return 1; /* Found delimiter */
/* didn't find delimiter, push back things that we read */
@@ -2982,45 +3307,51 @@ my_bool end_of_query(int c)
}
+my_bool end_of_query(int c)
+{
+ return match_delimiter(c, delimiter, delimiter_length);
+}
+
+
/*
Read one "line" from the file
SYNOPSIS
- read_line
- buf buffer for the read line
- size size of the buffer i.e max size to read
+ read_line
+ buf buffer for the read line
+ size size of the buffer i.e max size to read
DESCRIPTION
- This function actually reads several lines and adds them to the
- buffer buf. It continues to read until it finds what it believes
- is a complete query.
+ This function actually reads several lines and adds them to the
+ buffer buf. It continues to read until it finds what it believes
+ is a complete query.
- Normally that means it will read lines until it reaches the
- "delimiter" that marks end of query. Default delimiter is ';'
- The function should be smart enough not to detect delimiter's
- found inside strings surrounded with '"' and '\'' escaped strings.
+ Normally that means it will read lines until it reaches the
+ "delimiter" that marks end of query. Default delimiter is ';'
+ The function should be smart enough not to detect delimiter's
+ found inside strings surrounded with '"' and '\'' escaped strings.
- If the first line in a query starts with '#' or '-' this line is treated
- as a comment. A comment is always terminated when end of line '\n' is
- reached.
+ If the first line in a query starts with '#' or '-' this line is treated
+ as a comment. A comment is always terminated when end of line '\n' is
+ reached.
*/
int read_line(char *buf, int size)
{
- int c;
- char quote;
+ char c, last_quote;
char *p= buf, *buf_end= buf + size - 1;
- int no_save= 0;
- enum {R_NORMAL, R_Q, R_Q_IN_Q, R_SLASH_IN_Q,
- R_COMMENT, R_LINE_START} state= R_LINE_START;
+ int skip_char= 0;
+ enum {R_NORMAL, R_Q, R_SLASH_IN_Q,
+ R_COMMENT, R_LINE_START} state= R_LINE_START;
DBUG_ENTER("read_line");
- LINT_INIT(quote);
+ LINT_INIT(last_quote);
start_lineno= cur_file->lineno;
+ DBUG_PRINT("info", ("Starting to read at lineno: %d", start_lineno));
for (; p < buf_end ;)
{
- no_save= 0;
+ skip_char= 0;
c= my_getc(cur_file->file);
if (feof(cur_file->file))
{
@@ -3036,12 +3367,13 @@ int read_line(char *buf, int size)
{
/* We're back at the first file, check if
all { have matching }
- */
+ */
if (cur_block != block_stack)
die("Missing end of block");
- DBUG_PRINT("info", ("end of file"));
- DBUG_RETURN(1);
+ *p= 0;
+ DBUG_PRINT("info", ("end of file at line %d", cur_file->lineno));
+ DBUG_RETURN(1);
}
cur_file--;
start_lineno= cur_file->lineno;
@@ -3055,61 +3387,86 @@ int read_line(char *buf, int size)
/* Convert cr/lf to lf */
if (p != buf && *(p-1) == '\r')
- *(p-1)= 0;
+ p--;
}
switch(state) {
case R_NORMAL:
- /* Only accept '{' in the beginning of a line */
if (end_of_query(c))
{
*p= 0;
+ DBUG_PRINT("exit", ("Found delimiter '%s' at line %d",
+ delimiter, cur_file->lineno));
DBUG_RETURN(0);
}
- else if (c == '\'' || c == '"' || c == '`')
+ else if ((c == '{' &&
+ (!my_strnncoll_simple(charset_info, "while", 5,
+ buf, min(5, p - buf), 0) ||
+ !my_strnncoll_simple(charset_info, "if", 2,
+ buf, min(2, p - buf), 0))))
{
- quote= c;
- state= R_Q;
+ /* Only if and while commands can be terminated by { */
+ *p++= c;
+ *p= 0;
+ DBUG_PRINT("exit", ("Found '{' indicating start of block at line %d",
+ cur_file->lineno));
+ DBUG_RETURN(0);
}
- else if (c == '\n')
+ else if (c == '\'' || c == '"' || c == '`')
{
- state = R_LINE_START;
+ last_quote= c;
+ state= R_Q;
}
break;
+
case R_COMMENT:
if (c == '\n')
{
+ /* Comments are terminated by newline */
*p= 0;
+ DBUG_PRINT("exit", ("Found newline in comment at line: %d",
+ cur_file->lineno));
DBUG_RETURN(0);
}
break;
+
case R_LINE_START:
- /* Only accept start of comment if this is the first line in query */
- if ((cur_file->lineno == start_lineno) &&
- (c == '#' || c == '-' || parsing_disabled))
+ if (c == '#' || c == '-')
{
+ /* A # or - in the first position of the line - this is a comment */
state = R_COMMENT;
}
else if (my_isspace(charset_info, c))
{
+ /* Skip all space at begining of line */
if (c == '\n')
- start_lineno= cur_file->lineno; /* Query hasn't started yet */
- no_save= 1;
+ {
+ /* Query hasn't started yet */
+ start_lineno= cur_file->lineno;
+ DBUG_PRINT("info", ("Query hasn't started yet, start_lineno: %d",
+ start_lineno));
+ }
+ skip_char= 1;
}
- else if (c == '}')
+ else if (end_of_query(c))
{
- *buf++= '}';
- *buf= 0;
+ *p= 0;
+ DBUG_PRINT("exit", ("Found delimiter '%s' at line: %d",
+ delimiter, cur_file->lineno));
DBUG_RETURN(0);
}
- else if (end_of_query(c) || c == '{')
+ else if (c == '}')
{
+ /* A "}" need to be by itself in the begining of a line to terminate */
+ *p++= c;
*p= 0;
+ DBUG_PRINT("exit", ("Found '}' in begining of a line at line: %d",
+ cur_file->lineno));
DBUG_RETURN(0);
}
else if (c == '\'' || c == '"' || c == '`')
{
- quote= c;
+ last_quote= c;
state= R_Q;
}
else
@@ -3117,29 +3474,19 @@ int read_line(char *buf, int size)
break;
case R_Q:
- if (c == quote)
- state= R_Q_IN_Q;
+ if (c == last_quote)
+ state= R_NORMAL;
else if (c == '\\')
state= R_SLASH_IN_Q;
break;
- case R_Q_IN_Q:
- if (end_of_query(c))
- {
- *p= 0;
- DBUG_RETURN(0);
- }
- if (c != quote)
- state= R_NORMAL;
- else
- state= R_Q;
- break;
+
case R_SLASH_IN_Q:
state= R_Q;
break;
}
- if (!no_save)
+ if (!skip_char)
{
/* Could be a multibyte character */
/* This code is based on the code in "sql_load.cc" */
@@ -3157,7 +3504,7 @@ int read_line(char *buf, int size)
for (i= 1; i < charlen; i++)
{
if (feof(cur_file->file))
- goto found_eof; /* FIXME: could we just break here?! */
+ goto found_eof;
c= my_getc(cur_file->file);
*p++ = c;
}
@@ -3174,99 +3521,253 @@ int read_line(char *buf, int size)
*p++= c;
}
}
- *p= 0; /* Always end with \0 */
- DBUG_RETURN(feof(cur_file->file));
+ die("The input buffer is too small for this query.x\n" \
+ "check your query or increase MAX_QUERY and recompile");
+ DBUG_RETURN(0);
}
+
/*
- Create a query from a set of lines
+ Convert the read query to result format version 1
+
+ That is: After newline, all spaces need to be skipped
+ unless the previous char was a quote
+
+ This is due to an old bug that has now been fixed, but the
+ version 1 output format is preserved by using this function
+
+*/
+
+void convert_to_format_v1(char* query)
+{
+ int last_c_was_quote= 0;
+ char *p= query, *write= query;
+ char *end= strend(query);
+ char last_c;
+
+ while (p <= end)
+ {
+ if (*p == '\n' && !last_c_was_quote)
+ {
+ *write++ = *p++; /* Save the newline */
+
+ /* Skip any spaces on next line */
+ while (*p && my_isspace(charset_info, *p))
+ p++;
+
+ last_c_was_quote= 0;
+ }
+ else if (*p == '\'' || *p == '"' || *p == '`')
+ {
+ last_c= *p;
+ *write++ = *p++;
+
+ /* Copy anything until the next quote of same type */
+ while (*p && *p != last_c)
+ *write++ = *p++;
+
+ *write++ = *p++;
+
+ last_c_was_quote= 1;
+ }
+ else
+ {
+ *write++ = *p++;
+ last_c_was_quote= 0;
+ }
+ }
+}
+
+
+/*
+ Check a command that is about to be sent (or should have been
+ sent if parsing was enabled) to mysql server for
+ suspicious things and generate warnings.
+*/
+
+void scan_command_for_warnings(struct st_command *command)
+{
+ const char *ptr= command->query;
+ DBUG_ENTER("scan_command_for_warnings");
+ DBUG_PRINT("enter", ("query: %s", command->query));
+
+ while(*ptr)
+ {
+ /*
+ Look for query's that lines that start with a -- comment
+ and has a mysqltest command
+ */
+ if (ptr[0] == '\n' &&
+ ptr[1] && ptr[1] == '-' &&
+ ptr[2] && ptr[2] == '-' &&
+ ptr[3])
+ {
+ uint type;
+ char save;
+ char *end, *start= (char*)ptr+3;
+ /* Skip leading spaces */
+ while (*start && my_isspace(charset_info, *start))
+ start++;
+ end= start;
+ /* Find end of command(next space) */
+ while (*end && !my_isspace(charset_info, *end))
+ end++;
+ save= *end;
+ *end= 0;
+ DBUG_PRINT("info", ("Checking '%s'", start));
+ type= find_type(start, &command_typelib, 1+2);
+ if (type)
+ warning_msg("Embedded mysqltest command '--%s' detected in "
+ "query '%s' was this intentional? ",
+ start, command->query);
+ *end= save;
+ }
+
+ ptr++;
+ }
+ DBUG_VOID_RETURN;
+}
+
+/*
+ Check for unexpected "junk" after the end of query
+ This is normally caused by missing delimiters or when
+ switching between different delimiters
+*/
+
+void check_eol_junk_line(const char *line)
+{
+ const char *p= line;
+ DBUG_ENTER("check_eol_junk_line");
+ DBUG_PRINT("enter", ("line: %s", line));
+
+ /* Check for extra delimiter */
+ if (*p && !strncmp(p, delimiter, delimiter_length))
+ die("Extra delimiter \"%s\" found", delimiter);
+
+ /* Allow trailing # comment */
+ if (*p && *p != '#')
+ {
+ if (*p == '\n')
+ die("Missing delimiter");
+ die("End of line junk detected: \"%s\"", p);
+ }
+ DBUG_VOID_RETURN;
+}
+
+void check_eol_junk(const char *eol)
+{
+ const char *p= eol;
+ DBUG_ENTER("check_eol_junk");
+ DBUG_PRINT("enter", ("eol: %s", eol));
+
+ /* Skip past all spacing chars and comments */
+ while (*p && (my_isspace(charset_info, *p) || *p == '#' || *p == '\n'))
+ {
+ /* Skip past comments started with # and ended with newline */
+ if (*p && *p == '#')
+ {
+ p++;
+ while (*p && *p != '\n')
+ p++;
+ }
+
+ /* Check this line */
+ if (*p && *p == '\n')
+ check_eol_junk_line(p);
+
+ if (*p)
+ p++;
+ }
+
+ check_eol_junk_line(p);
+
+ DBUG_VOID_RETURN;
+}
+
+
+
+/*
+ Create a command from a set of lines
SYNOPSIS
- read_query()
- q_ptr pointer where to return the new query
+ read_command()
+ command_ptr pointer where to return the new query
DESCRIPTION
- Converts lines returned by read_line into a query, this involves
- parsing the first word in the read line to find the query type.
+ Converts lines returned by read_line into a command, this involves
+ parsing the first word in the read line to find the command type.
- A -- comment may contain a valid query as the first word after the
- comment start. Thus it's always checked to see if that is the case.
- The advantage with this approach is to be able to execute commands
- terminated by new line '\n' regardless how many "delimiter" it contain.
+ A -- comment may contain a valid query as the first word after the
+ comment start. Thus it's always checked to see if that is the case.
+ The advantage with this approach is to be able to execute commands
+ terminated by new line '\n' regardless how many "delimiter" it contain.
*/
-static char read_query_buf[MAX_QUERY];
+#define MAX_QUERY (256*1024) /* 256K -- a test in sp-big is >128K */
+static char read_command_buf[MAX_QUERY];
-int read_query(struct st_query** q_ptr)
+int read_command(struct st_command** command_ptr)
{
- char *p= read_query_buf;
- struct st_query* q;
- DBUG_ENTER("read_query");
+ char *p= read_command_buf;
+ struct st_command* command;
+ DBUG_ENTER("read_command");
if (parser.current_line < parser.read_lines)
{
- get_dynamic(&q_lines, (gptr) q_ptr, parser.current_line) ;
+ get_dynamic(&q_lines, (gptr) command_ptr, parser.current_line) ;
DBUG_RETURN(0);
}
- if (!(*q_ptr= q= (struct st_query*) my_malloc(sizeof(*q), MYF(MY_WME))) ||
- insert_dynamic(&q_lines, (gptr) &q))
+ if (!(*command_ptr= command=
+ (struct st_command*) my_malloc(sizeof(*command), MYF(MY_WME))) ||
+ insert_dynamic(&q_lines, (gptr) &command))
die(NullS);
- q->record_file[0]= 0;
- q->require_file= 0;
- q->first_word_len= 0;
+ command->require_file[0]= 0;
+ command->first_word_len= 0;
+ command->query_len= 0;
- q->type= Q_UNKNOWN;
- q->query_buf= q->query= 0;
- read_query_buf[0]= 0;
- if (read_line(read_query_buf, sizeof(read_query_buf)))
+ command->type= Q_UNKNOWN;
+ command->query_buf= command->query= 0;
+ read_command_buf[0]= 0;
+ if (read_line(read_command_buf, sizeof(read_command_buf)))
{
- check_eol_junk(read_query_buf);
+ check_eol_junk(read_command_buf);
DBUG_RETURN(1);
}
-
- DBUG_PRINT("info", ("query: %s", read_query_buf));
- if (*p == '#')
- {
- q->type= Q_COMMENT;
- /* This goto is to avoid losing the "expected error" info. */
- goto end;
- }
- if (!parsing_disabled)
- {
- memcpy((gptr) q->expected_errno, (gptr) global_expected_errno,
- sizeof(global_expected_errno));
- q->expected_errors= global_expected_errors;
- q->abort_on_error= (global_expected_errors == 0 && abort_on_error);
- }
- if (p[0] == '-' && p[1] == '-')
+ convert_to_format_v1(read_command_buf);
+
+ DBUG_PRINT("info", ("query: %s", read_command_buf));
+ if (*p == '#')
{
- q->type= Q_COMMENT_WITH_COMMAND;
- p+= 2; /* To calculate first word */
+ command->type= Q_COMMENT;
}
- else if (!parsing_disabled)
+ else if (p[0] == '-' && p[1] == '-')
{
- while (*p && my_isspace(charset_info, *p))
- p++ ;
+ command->type= Q_COMMENT_WITH_COMMAND;
+ p+= 2; /* Skip past -- */
}
-end:
+ /* Skip leading spaces */
while (*p && my_isspace(charset_info, *p))
p++;
- if (!(q->query_buf= q->query= my_strdup(p, MYF(MY_WME))))
- die(NullS);
+ if (!(command->query_buf= command->query= my_strdup(p, MYF(MY_WME))))
+ die("Out of memory");
/* Calculate first word and first argument */
- for (p= q->query; *p && !my_isspace(charset_info, *p) ; p++) ;
- q->first_word_len= (uint) (p - q->query);
+ for (p= command->query; *p && !my_isspace(charset_info, *p) ; p++) ;
+ command->first_word_len= (uint) (p - command->query);
+
+ /* Skip spaces between command and first argument */
while (*p && my_isspace(charset_info, *p))
p++;
- q->first_argument= p;
- q->end= strend(q->query);
+ command->first_argument= p;
+
+ command->end= strend(command->query);
+ command->query_len= (command->end - command->query);
parser.read_lines++;
DBUG_RETURN(0);
}
@@ -3278,8 +3779,6 @@ static struct my_option my_long_options[] =
0, 0, 0, 0, 0, 0},
{"basedir", 'b', "Basedir for tests.", (gptr*) &opt_basedir,
(gptr*) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"big-test", 'B', "Define BIG_TEST to 1.", (gptr*) &opt_big_test,
- (gptr*) &opt_big_test, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"compress", 'C', "Use the compressed server/client protocol.",
(gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
@@ -3319,8 +3818,8 @@ static struct my_option my_long_options[] =
{"record", 'r', "Record output of test_file into result file.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"result-file", 'R', "Read/Store result from/in this file.",
- (gptr*) &result_file, (gptr*) &result_file, 0, GET_STR, REQUIRED_ARG,
- 0, 0, 0, 0, 0, 0},
+ (gptr*) &result_file_name, (gptr*) &result_file_name, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"server-arg", 'A', "Send option value to embedded server as a parameter.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"server-file", 'F', "Read embedded server arguments from file.",
@@ -3348,8 +3847,6 @@ static struct my_option my_long_options[] =
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"user", 'u', "User for login.", (gptr*) &user, (gptr*) &user, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"valgrind", 'N', "Define VALGRIND_TEST to 1.", (gptr*) &opt_valgrind_test,
- (gptr*) &opt_valgrind_test, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"verbose", 'v', "Write more.", (gptr*) &verbose, (gptr*) &verbose, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Output version information and exit.",
@@ -3363,7 +3860,7 @@ static struct my_option my_long_options[] =
#include <help_start.h>
-static void print_version(void)
+void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,MTEST_VERSION,
MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
@@ -3384,6 +3881,52 @@ void usage()
#include <help_end.h>
+/*
+ Read arguments for embedded server and put them into
+ embedded_server_args[]
+*/
+
+void read_embedded_server_arguments(const char *name)
+{
+ char argument[1024],buff[FN_REFLEN], *str=0;
+ FILE *file;
+
+ if (!test_if_hard_path(name))
+ {
+ strxmov(buff, opt_basedir, name, NullS);
+ name=buff;
+ }
+ fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
+
+ if (!embedded_server_arg_count)
+ {
+ embedded_server_arg_count=1;
+ embedded_server_args[0]= (char*) ""; /* Progname */
+ }
+ if (!(file=my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME))))
+ die("Failed to open file %s", buff);
+
+ while (embedded_server_arg_count < MAX_EMBEDDED_SERVER_ARGS &&
+ (str=fgets(argument,sizeof(argument), file)))
+ {
+ *(strend(str)-1)=0; /* Remove end newline */
+ if (!(embedded_server_args[embedded_server_arg_count]=
+ (char*) my_strdup(str,MYF(MY_WME))))
+ {
+ my_fclose(file,MYF(0));
+ die("Out of memory");
+
+ }
+ embedded_server_arg_count++;
+ }
+ my_fclose(file,MYF(0));
+ if (str)
+ die("Too many arguments in option file: %s",name);
+
+ return;
+}
+
+
static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument)
@@ -3398,35 +3941,35 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
record = 1;
break;
case 'x':
+ {
+ char buff[FN_REFLEN];
+ if (!test_if_hard_path(argument))
{
- char buff[FN_REFLEN];
- if (!test_if_hard_path(argument))
- {
- strxmov(buff, opt_basedir, argument, NullS);
- argument= buff;
- }
- fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
- DBUG_ASSERT(cur_file == file_stack && cur_file->file == 0);
- if (!(cur_file->file=
- my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0))))
- die("Could not open %s: errno = %d", buff, errno);
- cur_file->file_name= my_strdup(buff, MYF(MY_FAE));
- cur_file->lineno= 1;
- break;
+ strxmov(buff, opt_basedir, argument, NullS);
+ argument= buff;
}
+ fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
+ DBUG_ASSERT(cur_file == file_stack && cur_file->file == 0);
+ if (!(cur_file->file=
+ my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0))))
+ die("Could not open %s: errno = %d", buff, errno);
+ cur_file->file_name= my_strdup(buff, MYF(MY_FAE));
+ cur_file->lineno= 1;
+ break;
+ }
case 'm':
+ {
+ static char buff[FN_REFLEN];
+ if (!test_if_hard_path(argument))
{
- static char buff[FN_REFLEN];
- if (!test_if_hard_path(argument))
- {
- strxmov(buff, opt_basedir, argument, NullS);
- argument= buff;
- }
- fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
- timer_file= buff;
- unlink(timer_file); /* Ignore error, may not exist */
- break;
+ strxmov(buff, opt_basedir, argument, NullS);
+ argument= buff;
}
+ fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
+ timer_file= buff;
+ unlink(timer_file); /* Ignore error, may not exist */
+ break;
+ }
case 'p':
if (argument)
{
@@ -3448,7 +3991,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
embedded_server_arg_count=1;
embedded_server_args[0]= (char*) "";
}
- if (embedded_server_arg_count == MAX_SERVER_ARGS-1 ||
+ if (embedded_server_arg_count == MAX_EMBEDDED_SERVER_ARGS-1 ||
!(embedded_server_args[embedded_server_arg_count++]=
my_strdup(argument, MYF(MY_FAE))))
{
@@ -3456,8 +3999,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
}
break;
case 'F':
- if (read_server_arguments(argument))
- die(NullS);
+ read_embedded_server_arguments(argument);
break;
case OPT_SKIP_SAFEMALLOC:
#ifdef SAFEMALLOC
@@ -3498,16 +4040,16 @@ int parse_args(int argc, char **argv)
/*
- Write the content of str into file
+ Write the content of str into file
- SYNOPSIS
- str_to_file
- fname - name of file to truncate/create and write to
- str - content to write to file
- size - size of content witten to file
+ SYNOPSIS
+ str_to_file
+ fname - name of file to truncate/create and write to
+ str - content to write to file
+ size - size of content witten to file
*/
-static void str_to_file(const char *fname, char *str, int size)
+void str_to_file(const char *fname, char *str, int size)
{
int fd;
char buff[FN_REFLEN];
@@ -3519,7 +4061,7 @@ static void str_to_file(const char *fname, char *str, int size)
fn_format(buff, fname, "", "", MY_UNPACK_FILENAME);
if ((fd= my_open(buff, O_WRONLY | O_CREAT | O_TRUNC,
- MYF(MY_WME | MY_FFNF))) < 0)
+ MYF(MY_WME | MY_FFNF))) < 0)
die("Could not open %s: errno = %d", buff, errno);
if (my_write(fd, (byte*)str, size, MYF(MY_WME|MY_FNABP)))
die("write failed");
@@ -3527,236 +4069,48 @@ static void str_to_file(const char *fname, char *str, int size)
}
-void dump_result_to_reject_file(const char *record_file, char *buf, int size)
+void dump_result_to_reject_file(char *buf, int size)
{
char reject_file[FN_REFLEN];
- str_to_file(fn_format(reject_file, record_file, "", ".reject",
+ str_to_file(fn_format(reject_file, result_file_name, "", ".reject",
MY_REPLACE_EXT),
buf, size);
}
-void dump_result_to_log_file(const char *record_file, char *buf, int size)
+void dump_result_to_log_file(char *buf, int size)
{
char log_file[FN_REFLEN];
- str_to_file(fn_format(log_file, record_file, "", ".log",
+ str_to_file(fn_format(log_file, result_file_name, "", ".log",
MY_REPLACE_EXT),
buf, size);
}
-void dump_progress(const char *record_file)
+void dump_progress(void)
{
char log_file[FN_REFLEN];
- str_to_file(fn_format(log_file, record_file, "", ".progress",
+ str_to_file(fn_format(log_file, result_file_name, "", ".progress",
MY_REPLACE_EXT),
ds_progress.str, ds_progress.length);
}
-static void check_regerr(my_regex_t* r, int err)
+void dump_warning_messages(void)
{
- char err_buf[1024];
+ char warn_file[FN_REFLEN];
- if (err)
- {
- my_regerror(err,r,err_buf,sizeof(err_buf));
- die("Regex error: %s\n", err_buf);
- }
+ str_to_file(fn_format(warn_file, result_file_name, "", ".warnings",
+ MY_REPLACE_EXT),
+ ds_warning_messages.str, ds_warning_messages.length);
}
-/*
- auxiluary macro used by reg_replace
- makes sure the result buffer has sufficient length
-*/
-#define SECURE_REG_BUF if (buf_len < need_buf_len)\
- {\
- int off= res_p - buf;\
- buf= (char*)my_realloc(buf,need_buf_len,MYF(MY_WME+MY_FAE));\
- res_p= buf + off;\
- buf_len= need_buf_len;\
- }\
-
-/*
- Performs a regex substitution
-
- IN:
-
- buf_p - result buffer pointer. Will change if reallocated
- buf_len_p - result buffer length. Will change if the buffer is reallocated
- pattern - regexp pattern to match
- replace - replacement expression
- string - the string to perform substituions in
- icase - flag, if set to 1 the match is case insensitive
- */
-static int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
- char *replace, char *string, int icase)
+void check_regerr(my_regex_t* r, int err)
{
- my_regex_t r;
- my_regmatch_t* subs;
- char* buf_end, *replace_end;
- char* buf= *buf_p;
- int len;
- int buf_len,need_buf_len;
- int cflags= REG_EXTENDED;
- int err_code;
- char* res_p,*str_p,*str_end;
-
- buf_len= *buf_len_p;
- len= strlen(string);
- str_end= string + len;
-
- /* start with a buffer of a reasonable size that hopefully will not
- need to be reallocated
- */
- need_buf_len= len * 2 + 1;
- res_p= buf;
+ char err_buf[1024];
- SECURE_REG_BUF
-
- buf_end = buf + buf_len;
-
- if (icase)
- cflags |= REG_ICASE;
-
- if ((err_code=my_regcomp(&r,pattern,cflags,&my_charset_latin1)))
- {
- check_regerr(&r,err_code);
- return 1;
- }
-
- subs= (my_regmatch_t*)my_malloc(sizeof(my_regmatch_t) * (r.re_nsub+1),
- MYF(MY_WME+MY_FAE));
-
- *res_p= 0;
- str_p= string;
- replace_end= replace + strlen(replace);
-
- /* for each pattern match instance perform a replacement */
- while (!err_code)
+ if (err)
{
- /* find the match */
- err_code= my_regexec(&r,str_p, r.re_nsub+1, subs,
- (str_p == string) ? REG_NOTBOL : 0);
-
- /* if regular expression error (eg. bad syntax, or out of memory) */
- if (err_code && err_code != REG_NOMATCH)
- {
- check_regerr(&r,err_code);
- my_regfree(&r);
- return 1;
- }
-
- /* if match found */
- if (!err_code)
- {
- char* expr_p= replace;
- int c;
-
- /*
- we need at least what we have so far in the buffer + the part
- before this match
- */
- need_buf_len= (res_p - buf) + subs[0].rm_so;
-
- /* on this pass, calculate the memory for the result buffer */
- while (expr_p < replace_end)
- {
- int back_ref_num= -1;
- c= *expr_p;
-
- if (c == '\\' && expr_p + 1 < replace_end)
- {
- back_ref_num= expr_p[1] - '0';
- }
-
- /* found a valid back_ref (eg. \1)*/
- if (back_ref_num >= 0 && back_ref_num <= (int)r.re_nsub)
- {
- int start_off,end_off;
- if ((start_off=subs[back_ref_num].rm_so) > -1 &&
- (end_off=subs[back_ref_num].rm_eo) > -1)
- {
- need_buf_len += (end_off - start_off);
- }
- expr_p += 2;
- }
- else
- {
- expr_p++;
- need_buf_len++;
- }
- }
- need_buf_len++;
- /*
- now that we know the size of the buffer,
- make sure it is big enough
- */
- SECURE_REG_BUF
-
- /* copy the pre-match part */
- if (subs[0].rm_so)
- {
- memcpy(res_p,str_p,subs[0].rm_so);
- res_p += subs[0].rm_so;
- }
-
- expr_p= replace;
-
- /* copy the match and expand back_refs */
- while (expr_p < replace_end)
- {
- int back_ref_num= -1;
- c= *expr_p;
-
- if (c == '\\' && expr_p + 1 < replace_end)
- {
- back_ref_num= expr_p[1] - '0';
- }
-
- if (back_ref_num >= 0 && back_ref_num <= (int)r.re_nsub)
- {
- int start_off,end_off;
- if ((start_off=subs[back_ref_num].rm_so) > -1 &&
- (end_off=subs[back_ref_num].rm_eo) > -1)
- {
- int block_len= end_off - start_off;
- memcpy(res_p,str_p + start_off, block_len);
- res_p += block_len;
- }
- expr_p += 2;
- }
- else
- {
- *res_p++ = *expr_p++;
- }
- }
-
- /* handle the post-match part */
- if (subs[0].rm_so == subs[0].rm_eo)
- {
- if (str_p + subs[0].rm_so >= str_end)
- break;
- str_p += subs[0].rm_eo ;
- *res_p++ = *str_p++;
- }
- else
- {
- str_p += subs[0].rm_eo;
- }
- }
- else /* no match this time, just copy the string as is */
- {
- int left_in_str= str_end-str_p;
- need_buf_len= (res_p-buf) + left_in_str;
- SECURE_REG_BUF
- memcpy(res_p,str_p,left_in_str);
- res_p += left_in_str;
- str_p= str_end;
- }
- }
- my_regfree(&r);
- *res_p= 0;
- *buf_p= buf;
- *buf_len_p= buf_len;
- return 0;
+ my_regerror(err,r,err_buf,sizeof(err_buf));
+ die("Regex error: %s\n", err_buf);
+ }
}
@@ -3768,12 +4122,12 @@ DYNAMIC_ARRAY patterns;
init_win_path_patterns
DESCRIPTION
- Setup string patterns that will be used to detect filenames that
- needs to be converted from Win to Unix format
+ Setup string patterns that will be used to detect filenames that
+ needs to be converted from Win to Unix format
*/
-static void init_win_path_patterns()
+void init_win_path_patterns()
{
/* List of string patterns to match in order to find paths */
const char* paths[] = { "$MYSQL_TEST_DIR",
@@ -3800,7 +4154,7 @@ static void init_win_path_patterns()
p= my_strdup(paths[i], MYF(MY_FAE));
if (insert_dynamic(&patterns, (gptr) &p))
- die(NullS);
+ die(NullS);
DBUG_PRINT("info", ("p: %s", p));
while (*p)
@@ -3813,7 +4167,7 @@ static void init_win_path_patterns()
DBUG_VOID_RETURN;
}
-static void free_win_path_patterns()
+void free_win_path_patterns()
{
uint i= 0;
for (i=0 ; i < patterns.elements ; i++)
@@ -3828,17 +4182,17 @@ static void free_win_path_patterns()
fix_win_paths
DESCRIPTION
- Search the string 'val' for the patterns that are known to be
- strings that contain filenames. Convert all \ to / in the
- filenames that are found.
-
- Ex:
- val = 'Error "c:\mysql\mysql-test\var\test\t1.frm" didn't exist'
- => $MYSQL_TEST_DIR is found by strstr
- => all \ from c:\mysql\m... until next space is converted into /
+ Search the string 'val' for the patterns that are known to be
+ strings that contain filenames. Convert all \ to / in the
+ filenames that are found.
+
+ Ex:
+ val = 'Error "c:\mysql\mysql-test\var\test\t1.frm" didn't exist'
+ => $MYSQL_TEST_DIR is found by strstr
+ => all \ from c:\mysql\m... until next space is converted into /
*/
-static void fix_win_paths(const char* val, int len)
+void fix_win_paths(const char *val, int len)
{
uint i;
char *p;
@@ -3868,43 +4222,14 @@ static void fix_win_paths(const char* val, int len)
}
#endif
-/* Append the string to ds, with optional replace */
-static void replace_dynstr_append_mem(DYNAMIC_STRING *ds,
- const char *val, int len)
-{
-#ifdef __WIN__
- fix_win_paths(val, len);
-#endif
-
- if (glob_replace_regex)
- {
- if (!multi_reg_replace(glob_replace_regex, (char*)val))
- {
- val= glob_replace_regex->buf;
- len= strlen(val);
- }
- }
-
- if (glob_replace)
- replace_strings_append(glob_replace, ds, val, len);
- else
- dynstr_append_mem(ds, val, len);
-}
-
-
-/* Append zero-terminated string to ds, with optional replace */
-static void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val)
-{
- replace_dynstr_append_mem(ds, val, strlen(val));
-}
/*
Append the result for one field to the dynamic string ds
*/
-static void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field,
- const char* val, ulonglong len, bool is_null)
+void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field,
+ const char* val, ulonglong len, bool is_null)
{
if (col_idx < max_replace_column && replace_column[col_idx])
{
@@ -3955,7 +4280,7 @@ static void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field,
Values may be converted with 'replace_column'
*/
-static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
+void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
{
MYSQL_ROW row;
uint num_fields= mysql_num_fields(res);
@@ -3972,7 +4297,6 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
if (!display_result_vertically)
dynstr_append_mem(ds, "\n", 1);
}
- free_replace_column();
}
@@ -3981,8 +4305,8 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
with '\t'. Values may be converted with 'replace_column'
*/
-static void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
- MYSQL_FIELD *fields, uint num_fields)
+void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
+ MYSQL_FIELD *fields, uint num_fields)
{
MYSQL_BIND *bind;
my_bool *is_null;
@@ -4007,7 +4331,7 @@ static void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
bind[i].is_null= &is_null[i];
bind[i].length= &length[i];
- DBUG_PRINT("bind", ("col[%d]: buffer_type: %d, buffer_length: %d",
+ DBUG_PRINT("bind", ("col[%d]: buffer_type: %d, buffer_length: %lu",
i, bind[i].buffer_type, bind[i].buffer_length));
}
@@ -4028,8 +4352,6 @@ static void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
die("fetch didn't end with MYSQL_NO_DATA from statement: %d %s",
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
- free_replace_column();
-
for (i= 0; i < num_fields; i++)
{
/* Free data for output */
@@ -4046,9 +4368,9 @@ static void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
Append metadata for fields to output
*/
-static void append_metadata(DYNAMIC_STRING *ds,
- MYSQL_FIELD *field,
- uint num_fields)
+void append_metadata(DYNAMIC_STRING *ds,
+ MYSQL_FIELD *field,
+ uint num_fields)
{
MYSQL_FIELD *field_end;
dynstr_append(ds,"Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
@@ -4059,44 +4381,36 @@ static void append_metadata(DYNAMIC_STRING *ds,
field < field_end ;
field++)
{
- char buff[22];
dynstr_append_mem(ds, field->catalog,
- field->catalog_length);
+ field->catalog_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->db, field->db_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->org_table,
- field->org_table_length);
+ field->org_table_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->table,
- field->table_length);
+ field->table_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->org_name,
- field->org_name_length);
+ field->org_name_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->name, field->name_length);
dynstr_append_mem(ds, "\t", 1);
- int10_to_str((int) field->type, buff, 10);
- dynstr_append(ds, buff);
+ replace_dynstr_append_uint(ds, field->type);
dynstr_append_mem(ds, "\t", 1);
- longlong10_to_str((unsigned int) field->length, buff, 10);
- dynstr_append(ds, buff);
+ replace_dynstr_append_uint(ds, field->length);
dynstr_append_mem(ds, "\t", 1);
- longlong10_to_str((unsigned int) field->max_length, buff, 10);
- dynstr_append(ds, buff);
+ replace_dynstr_append_uint(ds, field->max_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, (char*) (IS_NOT_NULL(field->flags) ?
"N" : "Y"), 1);
dynstr_append_mem(ds, "\t", 1);
-
- int10_to_str((int) field->flags, buff, 10);
- dynstr_append(ds, buff);
+ replace_dynstr_append_uint(ds, field->flags);
dynstr_append_mem(ds, "\t", 1);
- int10_to_str((int) field->decimals, buff, 10);
- dynstr_append(ds, buff);
+ replace_dynstr_append_uint(ds, field->decimals);
dynstr_append_mem(ds, "\t", 1);
- int10_to_str((int) field->charsetnr, buff, 10);
- dynstr_append(ds, buff);
+ replace_dynstr_append_uint(ds, field->charsetnr);
dynstr_append_mem(ds, "\n", 1);
}
}
@@ -4106,8 +4420,8 @@ static void append_metadata(DYNAMIC_STRING *ds,
Append affected row count and other info to output
*/
-static void append_info(DYNAMIC_STRING *ds, ulonglong affected_rows,
- const char *info)
+void append_info(DYNAMIC_STRING *ds, ulonglong affected_rows,
+ const char *info)
{
char buf[40], buff2[21];
sprintf(buf,"affected rows: %s\n", llstr(affected_rows, buff2));
@@ -4122,12 +4436,12 @@ static void append_info(DYNAMIC_STRING *ds, ulonglong affected_rows,
/*
- Display the table headings with the names tab separated
+ Display the table headings with the names tab separated
*/
-static void append_table_headings(DYNAMIC_STRING *ds,
- MYSQL_FIELD *field,
- uint num_fields)
+void append_table_headings(DYNAMIC_STRING *ds,
+ MYSQL_FIELD *field,
+ uint num_fields)
{
uint col_idx;
for (col_idx= 0; col_idx < num_fields; col_idx++)
@@ -4143,10 +4457,10 @@ static void append_table_headings(DYNAMIC_STRING *ds,
Fetch warnings from server and append to ds
RETURN VALUE
- Number of warnings appended to ds
+ Number of warnings appended to ds
*/
-static int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
+int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
{
uint count;
MYSQL_RES *warn_res;
@@ -4195,9 +4509,9 @@ static int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
error - function will not return
*/
-static void run_query_normal(MYSQL *mysql, struct st_query *command,
- int flags, char *query, int query_len,
- DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings)
+void run_query_normal(MYSQL *mysql, struct st_command *command,
+ int flags, char *query, int query_len,
+ DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings)
{
MYSQL_RES *res= 0;
int err= 0, counter= 0;
@@ -4205,20 +4519,20 @@ static void run_query_normal(MYSQL *mysql, struct st_query *command,
DBUG_PRINT("enter",("flags: %d", flags));
DBUG_PRINT("enter", ("query: '%-.60s'", query));
- if (flags & QUERY_SEND)
+ if (flags & QUERY_SEND_FLAG)
{
/*
- Send the query
- */
+ Send the query
+ */
if (mysql_send_query(mysql, query, query_len))
{
- handle_error(query, command, mysql_errno(mysql), mysql_error(mysql),
+ handle_error(command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds);
goto end;
}
}
- if (!(flags & QUERY_REAP))
+ if (!(flags & QUERY_REAP_FLAG))
DBUG_VOID_RETURN;
do
@@ -4226,22 +4540,22 @@ static void run_query_normal(MYSQL *mysql, struct st_query *command,
/*
When on first result set, call mysql_read_query_result to retrieve
answer to the query sent earlier
- */
+ */
if ((counter==0) && mysql_read_query_result(mysql))
{
- handle_error(query, command, mysql_errno(mysql), mysql_error(mysql),
+ handle_error(command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds);
goto end;
}
/*
- Store the result. If res is NULL, use mysql_field_count to
- determine if that was expected
- */
+ Store the result. If res is NULL, use mysql_field_count to
+ determine if that was expected
+ */
if (!(res= mysql_store_result(mysql)) && mysql_field_count(mysql))
{
- handle_error(query, command, mysql_errno(mysql), mysql_error(mysql),
+ handle_error(command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds);
goto end;
}
@@ -4297,7 +4611,7 @@ static void run_query_normal(MYSQL *mysql, struct st_query *command,
if (err > 0)
{
/* We got an error from mysql_next_result, maybe expected */
- handle_error(query, command, mysql_errno(mysql), mysql_error(mysql),
+ handle_error(command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds);
goto end;
}
@@ -4307,8 +4621,6 @@ static void run_query_normal(MYSQL *mysql, struct st_query *command,
handle_no_error(command);
end:
- free_replace();
- free_replace_regex();
/*
We save the return code (mysql_errno(mysql)) from the last call sent
@@ -4324,58 +4636,62 @@ end:
Handle errors which occurred during execution
SYNOPSIS
- handle_error()
- query - query string
- q - query context
- err_errno - error number
- err_error - error message
- err_sqlstate - sql state
- ds - dynamic string which is used for output buffer
+ handle_error()
+ q - query context
+ err_errno - error number
+ err_error - error message
+ err_sqlstate - sql state
+ ds - dynamic string which is used for output buffer
NOTE
- If there is an unexpected error this function will abort mysqltest
- immediately.
+ If there is an unexpected error this function will abort mysqltest
+ immediately.
RETURN VALUE
- error - function will not return
+ error - function will not return
*/
-static void handle_error(const char *query, struct st_query *q,
- unsigned int err_errno, const char *err_error,
- const char *err_sqlstate, DYNAMIC_STRING *ds)
+void handle_error(struct st_command *command,
+ unsigned int err_errno, const char *err_error,
+ const char *err_sqlstate, DYNAMIC_STRING *ds)
{
uint i;
DBUG_ENTER("handle_error");
- if (q->require_file)
+ if (command->require_file[0])
{
/*
The query after a "--require" failed. This is fine as long the server
returned a valid reponse. Don't allow 2013 or 2006 to trigger an
abort_not_supported_test
- */
+ */
if (err_errno == CR_SERVER_LOST ||
err_errno == CR_SERVER_GONE_ERROR)
- die("require query '%s' failed: %d: %s", query, err_errno, err_error);
+ die("require query '%s' failed: %d: %s", command->query,
+ err_errno, err_error);
/* Abort the run of this test, pass the failed query as reason */
- abort_not_supported_test("Query '%s' failed, required functionality not supported", query);
+ abort_not_supported_test("Query '%s' failed, required functionality" \
+ "not supported", command->query);
}
- if (q->abort_on_error)
- die("query '%s' failed: %d: %s", query, err_errno, err_error);
+ if (command->abort_on_error)
+ die("query '%s' failed: %d: %s", command->query, err_errno, err_error);
- for (i= 0 ; (uint) i < q->expected_errors ; i++)
+ DBUG_PRINT("info", ("expected_errors.count: %d",
+ command->expected_errors.count));
+ for (i= 0 ; (uint) i < command->expected_errors.count ; i++)
{
- if (((q->expected_errno[i].type == ERR_ERRNO) &&
- (q->expected_errno[i].code.errnum == err_errno)) ||
- ((q->expected_errno[i].type == ERR_SQLSTATE) &&
- (strcmp(q->expected_errno[i].code.sqlstate, err_sqlstate) == 0)))
+ if (((command->expected_errors.err[i].type == ERR_ERRNO) &&
+ (command->expected_errors.err[i].code.errnum == err_errno)) ||
+ ((command->expected_errors.err[i].type == ERR_SQLSTATE) &&
+ (strncmp(command->expected_errors.err[i].code.sqlstate,
+ err_sqlstate, SQLSTATE_LENGTH) == 0)))
{
if (!disable_result_log)
{
- if (q->expected_errors == 1)
+ if (command->expected_errors.count == 1)
{
/* Only log error if there is one possible error */
dynstr_append_mem(ds, "ERROR ", 6);
@@ -4385,9 +4701,9 @@ static void handle_error(const char *query, struct st_query *q,
dynstr_append_mem(ds,"\n",1);
}
/* Don't log error if we may not get an error */
- else if (q->expected_errno[0].type == ERR_SQLSTATE ||
- (q->expected_errno[0].type == ERR_ERRNO &&
- q->expected_errno[0].code.errnum != 0))
+ else if (command->expected_errors.err[0].type == ERR_SQLSTATE ||
+ (command->expected_errors.err[0].type == ERR_ERRNO &&
+ command->expected_errors.err[0].code.errnum != 0))
dynstr_append(ds,"Got one of the listed errors\n");
}
/* OK */
@@ -4395,7 +4711,8 @@ static void handle_error(const char *query, struct st_query *q,
}
}
- DBUG_PRINT("info",("i: %d expected_errors: %d", i, q->expected_errors));
+ DBUG_PRINT("info",("i: %d expected_errors: %d", i,
+ command->expected_errors.count));
if (!disable_result_log)
{
@@ -4408,13 +4725,14 @@ static void handle_error(const char *query, struct st_query *q,
if (i)
{
- if (q->expected_errno[0].type == ERR_ERRNO)
+ if (command->expected_errors.err[0].type == ERR_ERRNO)
die("query '%s' failed with wrong errno %d: '%s', instead of %d...",
- q->query, err_errno, err_error, q->expected_errno[0].code.errnum);
+ command->query, err_errno, err_error,
+ command->expected_errors.err[0].code.errnum);
else
die("query '%s' failed with wrong sqlstate %s: '%s', instead of %s...",
- q->query, err_sqlstate, err_error,
- q->expected_errno[0].code.sqlstate);
+ command->query, err_sqlstate, err_error,
+ command->expected_errors.err[0].code.sqlstate);
}
DBUG_VOID_RETURN;
@@ -4425,30 +4743,30 @@ static void handle_error(const char *query, struct st_query *q,
Handle absence of errors after execution
SYNOPSIS
- handle_no_error()
- q - context of query
+ handle_no_error()
+ q - context of query
RETURN VALUE
- error - function will not return
+ error - function will not return
*/
-static void handle_no_error(struct st_query *q)
+void handle_no_error(struct st_command *command)
{
DBUG_ENTER("handle_no_error");
- if (q->expected_errno[0].type == ERR_ERRNO &&
- q->expected_errno[0].code.errnum != 0)
+ if (command->expected_errors.err[0].type == ERR_ERRNO &&
+ command->expected_errors.err[0].code.errnum != 0)
{
/* Error code we wanted was != 0, i.e. not an expected success */
die("query '%s' succeeded - should have failed with errno %d...",
- q->query, q->expected_errno[0].code.errnum);
+ command->query, command->expected_errors.err[0].code.errnum);
}
- else if (q->expected_errno[0].type == ERR_SQLSTATE &&
- strcmp(q->expected_errno[0].code.sqlstate,"00000") != 0)
+ else if (command->expected_errors.err[0].type == ERR_SQLSTATE &&
+ strcmp(command->expected_errors.err[0].code.sqlstate,"00000") != 0)
{
/* SQLSTATE we wanted was != "00000", i.e. not an expected success */
die("query '%s' succeeded - should have failed with sqlstate %s...",
- q->query, q->expected_errno[0].code.sqlstate);
+ command->query, command->expected_errors.err[0].code.sqlstate);
}
DBUG_VOID_RETURN;
@@ -4470,9 +4788,9 @@ static void handle_no_error(struct st_query *q)
error - function will not return
*/
-static void run_query_stmt(MYSQL *mysql, struct st_query *command,
- char *query, int query_len, DYNAMIC_STRING *ds,
- DYNAMIC_STRING *ds_warnings)
+void run_query_stmt(MYSQL *mysql, struct st_command *command,
+ char *query, int query_len, DYNAMIC_STRING *ds,
+ DYNAMIC_STRING *ds_warnings)
{
MYSQL_RES *res= NULL; /* Note that here 'res' is meta data result set */
MYSQL_STMT *stmt;
@@ -4503,7 +4821,7 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
*/
if (mysql_stmt_prepare(stmt, query, query_len))
{
- handle_error(query, command, mysql_stmt_errno(stmt),
+ handle_error(command, mysql_stmt_errno(stmt),
mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
goto end;
}
@@ -4520,6 +4838,7 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
parameter markers.
*/
+#if MYSQL_VERSION_ID >= 50000
if (cursor_protocol_enabled)
{
/*
@@ -4530,13 +4849,14 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
die("mysql_stmt_attr_set(STMT_ATTR_CURSOR_TYPE) failed': %d %s",
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
}
+#endif
/*
Execute the query
*/
if (mysql_stmt_execute(stmt))
{
- handle_error(query, command, mysql_stmt_errno(stmt),
+ handle_error(command, mysql_stmt_errno(stmt),
mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
goto end;
}
@@ -4550,8 +4870,8 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
/*
We instruct that we want to update the "max_length" field in
- mysql_stmt_store_result(), this is our only way to know how much
- buffer to allocate for result data
+ mysql_stmt_store_result(), this is our only way to know how much
+ buffer to allocate for result data
*/
{
my_bool one= 1;
@@ -4566,7 +4886,7 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
*/
if (mysql_stmt_store_result(stmt))
{
- handle_error(query, command, mysql_stmt_errno(stmt),
+ handle_error(command, mysql_stmt_errno(stmt),
mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
goto end;
}
@@ -4636,9 +4956,6 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
}
end:
- free_replace();
- free_replace_regex();
-
if (!disable_warnings)
{
dynstr_free(&ds_prepare_warnings);
@@ -4650,7 +4967,7 @@ end:
to the server into the mysqltest builtin variable $mysql_errno. This
variable then can be used from the test case itself.
*/
-
+
var_set_errno(mysql_stmt_errno(stmt));
#ifndef BUG15518_FIXED
mysql_stmt_close(stmt);
@@ -4668,7 +4985,7 @@ end:
as view, sp etc.
*/
-static int util_query(MYSQL* org_mysql, const char* query){
+int util_query(MYSQL* org_mysql, const char* query){
MYSQL* mysql;
DBUG_ENTER("util_query");
@@ -4679,11 +4996,9 @@ static int util_query(MYSQL* org_mysql, const char* query){
if (!(mysql= mysql_init(mysql)))
die("Failed in mysql_init()");
- if (safe_connect(mysql, org_mysql->host, org_mysql->user,
- org_mysql->passwd, org_mysql->db, org_mysql->port,
- org_mysql->unix_socket))
- die("Could not open util connection: %d %s",
- mysql_errno(mysql), mysql_error(mysql));
+ safe_connect(mysql, "util", org_mysql->host, org_mysql->user,
+ org_mysql->passwd, org_mysql->db, org_mysql->port,
+ org_mysql->unix_socket);
cur_con->util_mysql= mysql;
}
@@ -4697,8 +5012,8 @@ static int util_query(MYSQL* org_mysql, const char* query){
Run query
flags control the phased/stages of query execution to be performed
- if QUERY_SEND bit is on, the query will be sent. If QUERY_REAP is on
- the result will be read - for regular query, both bits must be on
+ if QUERY_SEND_FLAG bit is on, the query will be sent. If QUERY_REAP_FLAG
+ is on the result will be read - for regular query, both bits must be on
SYNPOSIS
run_query
@@ -4707,7 +5022,7 @@ static int util_query(MYSQL* org_mysql, const char* query){
*/
-static void run_query(MYSQL *mysql, struct st_query *command, int flags)
+void run_query(MYSQL *mysql, struct st_command *command, int flags)
{
DYNAMIC_STRING *ds;
DYNAMIC_STRING ds_result;
@@ -4716,17 +5031,21 @@ static void run_query(MYSQL *mysql, struct st_query *command, int flags)
char *query;
int query_len;
my_bool view_created= 0, sp_created= 0;
- my_bool complete_query= ((flags & QUERY_SEND) && (flags & QUERY_REAP));
+ my_bool complete_query= ((flags & QUERY_SEND_FLAG) &&
+ (flags & QUERY_REAP_FLAG));
init_dynamic_string(&ds_warnings, NULL, 0, 256);
+ /* Scan for warning before sendign to server */
+ scan_command_for_warnings(command);
+
/*
Evaluate query if this is an eval command
- */
+ */
if (command->type == Q_EVAL)
{
- init_dynamic_string(&eval_query, "", 16384, 65536);
- do_eval(&eval_query, command->query, FALSE);
+ init_dynamic_string(&eval_query, "", command->query_len+256, 1024);
+ do_eval(&eval_query, command->query, command->end, FALSE);
query = eval_query.str;
query_len = eval_query.length;
}
@@ -4737,23 +5056,23 @@ static void run_query(MYSQL *mysql, struct st_query *command, int flags)
}
/*
- When command->record_file is set the output of _this_ query
+ When command->require_file is set the output of _this_ query
should be compared with an already existing file
Create a temporary dynamic string to contain the output from
this query.
- */
- if (command->record_file[0])
+ */
+ if (command->require_file[0])
{
- init_dynamic_string(&ds_result, "", 16384, 65536);
+ init_dynamic_string(&ds_result, "", 1024, 1024);
ds= &ds_result;
}
else
ds= &ds_res;
/*
- Log the query into the output buffer
+ Log the query into the output buffer
*/
- if (!disable_query_log && (flags & QUERY_SEND))
+ if (!disable_query_log && (flags & QUERY_SEND_FLAG))
{
replace_dynstr_append_mem(ds, query, query_len);
dynstr_append_mem(ds, delimiter, delimiter_length);
@@ -4765,8 +5084,8 @@ static void run_query(MYSQL *mysql, struct st_query *command, int flags)
match_re(&view_re, query))
{
/*
- Create the query as a view.
- Use replace since view can exist from a failed mysqltest run
+ Create the query as a view.
+ Use replace since view can exist from a failed mysqltest run
*/
DYNAMIC_STRING query_str;
init_dynamic_string(&query_str,
@@ -4778,7 +5097,7 @@ static void run_query(MYSQL *mysql, struct st_query *command, int flags)
/*
Failed to create the view, this is not fatal
just run the query the normal way
- */
+ */
DBUG_PRINT("view_create_error",
("Failed to create view '%s': %d: %s", query_str.str,
mysql_errno(mysql), mysql_error(mysql)));
@@ -4791,14 +5110,14 @@ static void run_query(MYSQL *mysql, struct st_query *command, int flags)
{
/*
Yes, it was possible to create this query as a view
- */
+ */
view_created= 1;
query= (char*)"SELECT * FROM mysqltest_tmp_v";
query_len = strlen(query);
/*
- Collect warnings from create of the view that should otherwise
- have been produced when the SELECT was executed
+ Collect warnings from create of the view that should otherwise
+ have been produced when the SELECT was executed
*/
append_warnings(&ds_warnings, cur_con->util_mysql);
}
@@ -4877,26 +5196,14 @@ static void run_query(MYSQL *mysql, struct st_query *command, int flags)
mysql_errno(mysql), mysql_error(mysql));
}
- if (command->record_file[0])
+ if (command->require_file[0])
{
- /* A result file was specified for _this_ query */
- if (record)
- {
- /*
- Recording in progress
- Dump the output from _this_ query to the specified record_file
- */
- str_to_file(command->record_file, ds->str, ds->length);
-
- } else {
-
- /*
- The output from _this_ query should be checked against an already
- existing file which has been specified using --require or --result
- */
- check_result(ds, command->record_file, command->require_file);
- }
+ /* A result file was specified for _this_ query
+ and the output should be checked against an already
+ existing file which has been specified using --require or --result
+ */
+ check_require(ds, command->require_file);
}
dynstr_free(&ds_warnings);
@@ -4906,12 +5213,12 @@ static void run_query(MYSQL *mysql, struct st_query *command, int flags)
dynstr_free(&eval_query);
}
+/****************************************************************************/
+/*
+ Functions to detect different SQL statements
+*/
-/****************************************************************************\
- * Functions to detect different SQL statements
-\****************************************************************************/
-
-static char *re_eprint(int err)
+char *re_eprint(int err)
{
static char epbuf[100];
size_t len= my_regerror(REG_ITOA|err, (my_regex_t *)NULL,
@@ -4920,7 +5227,7 @@ static char *re_eprint(int err)
return(epbuf);
}
-static void init_re_comp(my_regex_t *re, const char* str)
+void init_re_comp(my_regex_t *re, const char* str)
{
int err= my_regcomp(re, str, (REG_EXTENDED | REG_ICASE | REG_NOSUB),
&my_charset_latin1);
@@ -4933,11 +5240,11 @@ static void init_re_comp(my_regex_t *re, const char* str)
}
}
-static void init_re(void)
+void init_re(void)
{
/*
- Filter for queries that can be run using the
- MySQL Prepared Statements C API
+ Filter for queries that can be run using the
+ MySQL Prepared Statements C API
*/
const char *ps_re_str =
"^("
@@ -4954,13 +5261,13 @@ static void init_re(void)
"[[:space:]]*INSERT[[:space:]]+SELECT[[:space:]])";
/*
- Filter for queries that can be run using the
- Stored procedures
+ Filter for queries that can be run using the
+ Stored procedures
*/
const char *sp_re_str =ps_re_str;
/*
- Filter for queries that can be run as views
+ Filter for queries that can be run as views
*/
const char *view_re_str =
"^("
@@ -4972,7 +5279,7 @@ static void init_re(void)
}
-static int match_re(my_regex_t *re, char *str)
+int match_re(my_regex_t *re, char *str)
{
int err= my_regexec(re, str, (size_t)0, NULL, 0);
@@ -4990,7 +5297,7 @@ static int match_re(my_regex_t *re, char *str)
return 0;
}
-static void free_re(void)
+void free_re(void)
{
my_regfree(&ps_re);
my_regfree(&sp_re);
@@ -5000,142 +5307,85 @@ static void free_re(void)
/****************************************************************************/
-void get_query_type(struct st_query* q)
+void get_command_type(struct st_command* command)
{
char save;
uint type;
- DBUG_ENTER("get_query_type");
+ DBUG_ENTER("get_command_type");
- if (!parsing_disabled && *q->query == '}')
+ if (*command->query == '}')
{
- q->type = Q_END_BLOCK;
+ command->type = Q_END_BLOCK;
DBUG_VOID_RETURN;
}
- if (q->type != Q_COMMENT_WITH_COMMAND)
- q->type= parsing_disabled ? Q_COMMENT : Q_QUERY;
- save=q->query[q->first_word_len];
- q->query[q->first_word_len]=0;
- type=find_type(q->query, &command_typelib, 1+2);
- q->query[q->first_word_len]=save;
+ save= command->query[command->first_word_len];
+ command->query[command->first_word_len]= 0;
+ type= find_type(command->query, &command_typelib, 1+2);
+ command->query[command->first_word_len]= save;
if (type > 0)
{
- q->type=(enum enum_commands) type; /* Found command */
+ command->type=(enum enum_commands) type; /* Found command */
+
/*
- If queries are disabled, only recognize
- --enable_parsing and --disable_parsing
+ Look for case where "query" was explicitly specified to
+ force command being sent to server
*/
- if (parsing_disabled && q->type != Q_ENABLE_PARSING &&
- q->type != Q_DISABLE_PARSING)
- q->type= Q_COMMENT;
+ if (type == Q_QUERY)
+ {
+ /* Skip the "query" part */
+ command->query= command->first_argument;
+ }
}
- else if (q->type == Q_COMMENT_WITH_COMMAND &&
- q->first_word_len &&
- q->query[q->first_word_len-1] == ';')
+ else
{
- /*
- Detect comment with command using extra delimiter
- Ex --disable_query_log;
- ^ Extra delimiter causing the command
- to be skipped
- */
- save= q->query[q->first_word_len-1];
- q->query[q->first_word_len-1]= 0;
- type= find_type(q->query, &command_typelib, 1+2);
- q->query[q->first_word_len-1]= save;
- if (type > 0)
- die("Extra delimiter \";\" found");
- }
- DBUG_VOID_RETURN;
-}
-
-
-static byte *get_var_key(const byte* var, uint* len,
- my_bool __attribute__((unused)) t)
-{
- register char* key;
- key = ((VAR*)var)->name;
- *len = ((VAR*)var)->name_len;
- return (byte*)key;
-}
+ /* No mysqltest command matched */
-static VAR *var_init(VAR *v, const char *name, int name_len, const char *val,
- int val_len)
-{
- int val_alloc_len;
- VAR *tmp_var;
- if (!name_len && name)
- name_len = strlen(name);
- if (!val_len && val)
- val_len = strlen(val) ;
- val_alloc_len = val_len + 16; /* room to grow */
- if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var)
- + name_len+1, MYF(MY_WME))))
- die("Out of memory");
-
- tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0;
- tmp_var->alloced = (v == 0);
-
- if (!(tmp_var->str_val = my_malloc(val_alloc_len+1, MYF(MY_WME))))
- die("Out of memory");
+ if (command->type != Q_COMMENT_WITH_COMMAND)
+ {
+ /* A query that will sent to mysqld */
+ command->type= Q_QUERY;
+ }
+ else
+ {
+ /* -- comment that didn't contain a mysqltest command */
+ command->type= Q_COMMENT;
+ warning_msg("Suspicious command '--%s' detected, was this intentional? "\
+ "Use # instead of -- to avoid this warning",
+ command->query);
+
+ if (command->first_word_len &&
+ strcmp(command->query + command->first_word_len - 1, delimiter) == 0)
+ {
+ /*
+ Detect comment with command using extra delimiter
+ Ex --disable_query_log;
+ ^ Extra delimiter causing the command
+ to be skipped
+ */
+ save= command->query[command->first_word_len-1];
+ command->query[command->first_word_len-1]= 0;
+ if (find_type(command->query, &command_typelib, 1+2) > 0)
+ die("Extra delimiter \";\" found");
+ command->query[command->first_word_len-1]= save;
- memcpy(tmp_var->name, name, name_len);
- if (val)
- {
- memcpy(tmp_var->str_val, val, val_len);
- tmp_var->str_val[val_len]= 0;
+ }
+ }
}
- tmp_var->name_len = name_len;
- tmp_var->str_val_len = val_len;
- tmp_var->alloced_len = val_alloc_len;
- tmp_var->int_val = (val) ? atoi(val) : 0;
- tmp_var->int_dirty = 0;
- tmp_var->env_s = 0;
- return tmp_var;
-}
-
-static void var_free(void *v)
-{
- my_free(((VAR*) v)->str_val, MYF(MY_WME));
- if (((VAR*)v)->alloced)
- my_free((char*) v, MYF(MY_WME));
-}
-
-
-static VAR* var_from_env(const char *name, const char *def_val)
-{
- const char *tmp;
- VAR *v;
- if (!(tmp = getenv(name)))
- tmp = def_val;
-
- v = var_init(0, name, strlen(name), tmp, strlen(tmp));
- my_hash_insert(&var_hash, (byte*)v);
- return v;
-}
+ /* Set expected error on command */
+ memcpy(&command->expected_errors, &saved_expected_errors,
+ sizeof(saved_expected_errors));
+ DBUG_PRINT("info", ("There are %d expected errors",
+ command->expected_errors.count));
+ command->abort_on_error= (command->expected_errors.count == 0 &&
+ abort_on_error);
-static void init_var_hash(MYSQL *mysql)
-{
- VAR *v;
- DBUG_ENTER("init_var_hash");
- if (hash_init(&var_hash, charset_info,
- 1024, 0, 0, get_var_key, var_free, MYF(0)))
- die("Variable hash initialization failed");
- my_hash_insert(&var_hash, (byte*) var_init(0,"BIG_TEST", 0,
- (opt_big_test) ? "1" : "0", 0));
- my_hash_insert(&var_hash, (byte*) var_init(0,"VALGRIND_TEST", 0,
- (opt_valgrind_test) ? "1" : "0",
- 0));
- v= var_init(0,"MAX_TABLES", 0, (sizeof(ulong) == 4) ? "31" : "62",0);
- my_hash_insert(&var_hash, (byte*) v);
- v= var_init(0,"SERVER_VERSION", 0, mysql_get_server_info(mysql), 0);
- my_hash_insert(&var_hash, (byte*) v); v= var_init(0,"DB", 2, db, 0);
- my_hash_insert(&var_hash, (byte*) v);
DBUG_VOID_RETURN;
}
+
/*
Record how many milliseconds it took to execute the test file
up until the current line and save it in the dynamic string ds_progress.
@@ -5144,7 +5394,9 @@ static void init_var_hash(MYSQL *mysql)
test run completes
*/
-static void mark_progress(struct st_query* q __attribute__((unused)), int line)
+
+void mark_progress(struct st_command* command __attribute__((unused)),
+ int line)
{
char buf[32], *end;
ulonglong timer= timer_now();
@@ -5178,47 +5430,63 @@ static void mark_progress(struct st_query* q __attribute__((unused)), int line)
int main(int argc, char **argv)
{
- struct st_query *q;
- my_bool require_file=0, q_send_flag=0,
- query_executed= 0;
+ struct st_command *command;
+ my_bool q_send_flag= 0, abort_flag= 0;
+ uint command_executed= 0, last_command_executed= 0;
char save_file[FN_REFLEN];
MY_STAT res_info;
MY_INIT(argv[0]);
- /* Use all time until exit if no explicit 'start_timer' */
- timer_start= timer_now();
+ save_file[0]= 0;
+ TMPDIR[0]= 0;
- save_file[0]=0;
- TMPDIR[0]=0;
+ /* Init expected errors */
+ memset(&saved_expected_errors, 0, sizeof(saved_expected_errors));
- /* Init cons */
- memset(cons, 0, sizeof(cons));
- cons_end = cons + MAX_CONS;
- next_con = cons + 1;
- cur_con = cons;
+ /* Init connections */
+ memset(connections, 0, sizeof(connections));
+ connections_end= connections +
+ (sizeof(connections)/sizeof(struct st_connection)) - 1;
+ next_con= connections + 1;
+ cur_con= connections;
/* Init file stack */
memset(file_stack, 0, sizeof(file_stack));
- file_stack_end= file_stack + MAX_INCLUDE_DEPTH - 1;
+ file_stack_end=
+ file_stack + (sizeof(file_stack)/sizeof(struct st_test_file)) - 1;
cur_file= file_stack;
/* Init block stack */
memset(block_stack, 0, sizeof(block_stack));
- block_stack_end= block_stack + BLOCK_STACK_DEPTH - 1;
+ block_stack_end=
+ block_stack + (sizeof(block_stack)/sizeof(struct st_block)) - 1;
cur_block= block_stack;
cur_block->ok= TRUE; /* Outer block should always be executed */
cur_block->cmd= cmd_none;
- my_init_dynamic_array(&q_lines, sizeof(struct st_query*), INIT_Q_LINES,
- INIT_Q_LINES);
+ my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024);
+
+ if (hash_init(&var_hash, charset_info,
+ 1024, 0, 0, get_var_key, var_free, MYF(0)))
+ die("Variable hash initialization failed");
memset(&master_pos, 0, sizeof(master_pos));
- init_dynamic_string(&ds_res, "", 0, 65536);
+ parser.current_line= parser.read_lines= 0;
+ memset(&var_reg, 0, sizeof(var_reg));
+
+#ifdef __WIN__
+ init_tmp_sh_file();
+ init_win_path_patterns();
+#endif
+
+ init_dynamic_string(&ds_res, "", 65536, 65536);
init_dynamic_string(&ds_progress, "", 0, 2048);
+ init_dynamic_string(&ds_warning_messages, "", 0, 2048);
parse_args(argc, argv);
- DBUG_PRINT("info",("result_file: '%s'", result_file ? result_file : ""));
+ DBUG_PRINT("info",("result_file: '%s'",
+ result_file_name ? result_file_name : ""));
if (mysql_server_init(embedded_server_arg_count,
embedded_server_args,
(char**) embedded_server_groups))
@@ -5246,29 +5514,30 @@ int main(int argc, char **argv)
mysql_options(&cur_con->mysql, MYSQL_SET_CHARSET_NAME, charset_name);
#ifdef HAVE_OPENSSL
+
+#if MYSQL_VERSION_ID >= 50000
opt_ssl_verify_server_cert= TRUE; /* Always on in mysqltest */
+#endif
+
if (opt_use_ssl)
{
mysql_ssl_set(&cur_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
+#if MYSQL_VERSION_ID >= 50000
mysql_options(&cur_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
&opt_ssl_verify_server_cert);
+#endif
}
#endif
if (!(cur_con->name = my_strdup("default", MYF(MY_WME))))
die("Out of memory");
- if (safe_connect(&cur_con->mysql, host, user, pass, db, port, unix_sock))
- die("Could not open connection '%s': %d %s", cur_con->name,
- mysql_errno(&cur_con->mysql), mysql_error(&cur_con->mysql));
+ safe_connect(&cur_con->mysql, cur_con->name, host, user, pass,
+ db, port, unix_sock);
- init_var_hash(&cur_con->mysql);
-
-#ifdef __WIN__
- init_tmp_sh_file();
- init_win_path_patterns();
-#endif
+ /* Use all time until exit if no explicit 'start_timer' */
+ timer_start= timer_now();
/*
Initialize $mysql_errno with -1, so we can
@@ -5282,26 +5551,35 @@ int main(int argc, char **argv)
open_file(opt_include);
}
- while (!read_query(&q))
+ while (!read_command(&command) && !abort_flag)
{
int current_line_inc = 1, processed = 0;
- if (q->type == Q_UNKNOWN || q->type == Q_COMMENT_WITH_COMMAND)
- get_query_type(q);
+ if (command->type == Q_UNKNOWN || command->type == Q_COMMENT_WITH_COMMAND)
+ get_command_type(command);
+
+ if (parsing_disabled &&
+ command->type != Q_ENABLE_PARSING &&
+ command->type != Q_DISABLE_PARSING)
+ {
+ command->type= Q_COMMENT;
+ scan_command_for_warnings(command);
+ }
+
if (cur_block->ok)
{
- q->last_argument= q->first_argument;
+ command->last_argument= command->first_argument;
processed = 1;
- switch (q->type) {
+ switch (command->type) {
case Q_CONNECT:
- do_connect(q);
+ do_connect(command);
break;
- case Q_CONNECTION: select_connection(q); break;
+ case Q_CONNECTION: select_connection(command); break;
case Q_DISCONNECT:
case Q_DIRTY_CLOSE:
- close_connection(q); break;
- case Q_RPL_PROBE: do_rpl_probe(q); break;
- case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(q); break;
- case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break;
+ do_close_connection(command); break;
+ case Q_RPL_PROBE: do_rpl_probe(command); break;
+ case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(command); break;
+ case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(command); break;
case Q_ENABLE_QUERY_LOG: disable_query_log=0; break;
case Q_DISABLE_QUERY_LOG: disable_query_log=1; break;
case Q_ENABLE_ABORT_ON_ERROR: abort_on_error=1; break;
@@ -5316,18 +5594,21 @@ int main(int argc, char **argv)
case Q_DISABLE_INFO: disable_info=1; break;
case Q_ENABLE_METADATA: display_metadata=1; break;
case Q_DISABLE_METADATA: display_metadata=0; break;
- case Q_SOURCE: do_source(q); break;
- case Q_SLEEP: do_sleep(q, 0); break;
- case Q_REAL_SLEEP: do_sleep(q, 1); break;
- case Q_WAIT_FOR_SLAVE_TO_STOP: do_wait_for_slave_to_stop(q); break;
- case Q_INC: do_modify_var(q, DO_INC); break;
- case Q_DEC: do_modify_var(q, DO_DEC); break;
- case Q_ECHO: do_echo(q); query_executed= 1; break;
- case Q_SYSTEM: do_system(q); break;
+ case Q_SOURCE: do_source(command); break;
+ case Q_SLEEP: do_sleep(command, 0); break;
+ case Q_REAL_SLEEP: do_sleep(command, 1); break;
+ case Q_WAIT_FOR_SLAVE_TO_STOP: do_wait_for_slave_to_stop(command); break;
+ case Q_INC: do_modify_var(command, DO_INC); break;
+ case Q_DEC: do_modify_var(command, DO_DEC); break;
+ case Q_ECHO: do_echo(command); command_executed++; break;
+ case Q_SYSTEM: do_system(command); break;
+ case Q_REMOVE_FILE: do_remove_file(command); break;
+ case Q_FILE_EXIST: do_file_exist(command); break;
+ case Q_WRITE_FILE: do_write_file(command); break;
+ case Q_COPY_FILE: do_copy_file(command); break;
+ case Q_PERL: do_perl(command); break;
case Q_DELIMITER:
- strmake(delimiter, q->first_argument, sizeof(delimiter) - 1);
- delimiter_length= strlen(delimiter);
- q->last_argument= q->first_argument+delimiter_length;
+ do_delimiter(command);
break;
case Q_DISPLAY_VERTICAL_RESULTS:
display_result_vertically= TRUE;
@@ -5335,133 +5616,128 @@ int main(int argc, char **argv)
case Q_DISPLAY_HORIZONTAL_RESULTS:
display_result_vertically= FALSE;
break;
- case Q_LET: do_let(q); break;
+ case Q_LET: do_let(command); break;
case Q_EVAL_RESULT:
eval_result = 1; break;
case Q_EVAL:
- if (q->query == q->query_buf)
+ if (command->query == command->query_buf)
{
- q->query= q->first_argument;
- q->first_word_len= 0;
+ command->query= command->first_argument;
+ command->first_word_len= 0;
}
/* fall through */
case Q_QUERY_VERTICAL:
case Q_QUERY_HORIZONTAL:
{
my_bool old_display_result_vertically= display_result_vertically;
- /* fix up query pointer if this is first iteration for this line */
- if (q->query == q->query_buf)
- q->query += q->first_word_len + 1;
- display_result_vertically= (q->type==Q_QUERY_VERTICAL);
+
+ /* Remove "query_*" if this is first iteration */
+ if (command->query == command->query_buf)
+ command->query= command->first_argument;
+
+ display_result_vertically= (command->type == Q_QUERY_VERTICAL);
if (save_file[0])
{
- strmov(q->record_file,save_file);
- q->require_file=require_file;
- save_file[0]=0;
+ strmake(command->require_file, save_file, sizeof(save_file));
+ save_file[0]= 0;
}
- run_query(&cur_con->mysql, q, QUERY_REAP|QUERY_SEND);
+ run_query(&cur_con->mysql, command, QUERY_REAP_FLAG|QUERY_SEND_FLAG);
display_result_vertically= old_display_result_vertically;
- q->last_argument= q->end;
- query_executed= 1;
+ command->last_argument= command->end;
+ command_executed++;
break;
}
case Q_QUERY:
case Q_REAP:
{
- /*
- We read the result always regardless of the mode for both full
- query and read-result only (reap)
- */
- int flags = QUERY_REAP;
- if (q->type != Q_REAP) /* for a full query, enable the send stage */
- flags |= QUERY_SEND;
- if (q_send_flag)
- {
- flags= QUERY_SEND;
- q_send_flag=0;
- }
+ int flags;
+ if (q_send_flag)
+ {
+ /* Last command was an empty 'send' */
+ flags= QUERY_SEND_FLAG;
+ q_send_flag= 0;
+ }
+ else if (command->type == Q_REAP)
+ {
+ flags= QUERY_REAP_FLAG;
+ }
+ else
+ {
+ /* full query, both reap and send */
+ flags= QUERY_REAP_FLAG | QUERY_SEND_FLAG;
+ }
+
if (save_file[0])
{
- strmov(q->record_file,save_file);
- q->require_file=require_file;
- save_file[0]=0;
+ strmake(command->require_file, save_file, sizeof(save_file));
+ save_file[0]= 0;
}
- /*
- To force something being sent as a query to the mysqld one can
- use the prefix "query". Remove "query" from string before executing
- */
- if (strncmp(q->query, "query ", 6) == 0)
- {
- q->query= q->first_argument;
- }
- run_query(&cur_con->mysql, q, flags);
- query_executed= 1;
- q->last_argument= q->end;
+ run_query(&cur_con->mysql, command, flags);
+ command_executed++;
+ command->last_argument= command->end;
break;
}
case Q_SEND:
- if (!q->query[q->first_word_len])
- {
- /* This happens when we use 'send' on its own line */
- q_send_flag=1;
- break;
- }
- /* fix up query pointer if this is first iteration for this line */
- if (q->query == q->query_buf)
- q->query += q->first_word_len;
+ if (!*command->first_argument)
+ {
+ /*
+ This is a send without arguments, it indicates that _next_ query
+ should be send only
+ */
+ q_send_flag= 1;
+ break;
+ }
+
+ /* Remove "send" if this is first iteration */
+ if (command->query == command->query_buf)
+ command->query= command->first_argument;
+
/*
run_query() can execute a query partially, depending on the flags.
- QUERY_SEND flag without QUERY_REAP tells it to just send the
- query and read the result some time later when reap instruction
+ QUERY_SEND_FLAG flag without QUERY_REAP_FLAG tells it to just send
+ the query and read the result some time later when reap instruction
is given on this connection.
- */
- run_query(&cur_con->mysql, q, QUERY_SEND);
- query_executed= 1;
- q->last_argument= q->end;
+ */
+ run_query(&cur_con->mysql, command, QUERY_SEND_FLAG);
+ command_executed++;
+ command->last_argument= command->end;
break;
- case Q_RESULT:
- get_file_name(save_file,q);
- require_file=0;
+ case Q_REQUIRE:
+ do_get_file_name(command, save_file, sizeof(save_file));
break;
case Q_ERROR:
- global_expected_errors=get_errcodes(global_expected_errno,q);
- break;
- case Q_REQUIRE:
- get_file_name(save_file,q);
- require_file=1;
+ do_get_errcodes(command);
break;
case Q_REPLACE:
- get_replace(q);
+ do_get_replace(command);
break;
case Q_REPLACE_REGEX:
- get_replace_regex(q);
+ do_get_replace_regex(command);
break;
-
case Q_REPLACE_COLUMN:
- get_replace_column(q);
+ do_get_replace_column(command);
break;
case Q_SAVE_MASTER_POS: do_save_master_pos(); break;
- case Q_SYNC_WITH_MASTER: do_sync_with_master(q); break;
+ case Q_SYNC_WITH_MASTER: do_sync_with_master(command); break;
case Q_SYNC_SLAVE_WITH_MASTER:
{
do_save_master_pos();
- if (*q->first_argument)
- select_connection(q);
+ if (*command->first_argument)
+ select_connection(command);
else
select_connection_name("slave");
do_sync_with_master2(0);
break;
}
case Q_COMMENT: /* Ignore row */
- case Q_COMMENT_WITH_COMMAND:
- q->last_argument= q->end;
+ command->last_argument= command->end;
break;
case Q_PING:
(void) mysql_ping(&cur_con->mysql);
break;
case Q_EXEC:
- do_exec(q);
- query_executed= 1;
+ do_exec(command);
+ command_executed++;
break;
case Q_START_TIMER:
/* Overwrite possible earlier start of timer */
@@ -5470,10 +5746,9 @@ int main(int argc, char **argv)
case Q_END_TIMER:
/* End timer before ending mysqltest */
timer_output();
- got_end_timer= TRUE;
break;
case Q_CHARACTER_SET:
- set_charset(q);
+ do_set_charset(command);
break;
case Q_DISABLE_PS_PROTOCOL:
ps_protocol_enabled= 0;
@@ -5482,31 +5757,38 @@ int main(int argc, char **argv)
ps_protocol_enabled= ps_protocol;
break;
case Q_DISABLE_RECONNECT:
- {
- my_bool reconnect= 0;
- mysql_options(&cur_con->mysql, MYSQL_OPT_RECONNECT, (char *)&reconnect);
+ set_reconnect(&cur_con->mysql, 0);
break;
- }
case Q_ENABLE_RECONNECT:
- {
- my_bool reconnect= 1;
- mysql_options(&cur_con->mysql, MYSQL_OPT_RECONNECT, (char *)&reconnect);
+ set_reconnect(&cur_con->mysql, 1);
break;
- }
case Q_DISABLE_PARSING:
- parsing_disabled++;
+ if (parsing_disabled == 0)
+ parsing_disabled= 1;
+ else
+ die("Parsing is already disabled");
break;
case Q_ENABLE_PARSING:
/*
Ensure we don't get parsing_disabled < 0 as this would accidentally
disable code we don't want to have disabled
*/
- if (parsing_disabled > 0)
- parsing_disabled--;
+ if (parsing_disabled == 1)
+ parsing_disabled= 0;
+ else
+ die("Parsing is already enabled");
break;
-
case Q_DIE:
- die("%s", q->first_argument);
+ /* Abort test with error code and error message */
+ die("%s", command->first_argument);
+ break;
+ case Q_EXIT:
+ /* Stop processing any more commands */
+ abort_flag= 1;
+ break;
+
+ case Q_RESULT:
+ die("result, deprecated command");
break;
default:
@@ -5518,33 +5800,46 @@ int main(int argc, char **argv)
if (!processed)
{
current_line_inc= 0;
- switch (q->type) {
- case Q_WHILE: do_block(cmd_while, q); break;
- case Q_IF: do_block(cmd_if, q); break;
- case Q_END_BLOCK: do_done(q); break;
+ switch (command->type) {
+ case Q_WHILE: do_block(cmd_while, command); break;
+ case Q_IF: do_block(cmd_if, command); break;
+ case Q_END_BLOCK: do_done(command); break;
default: current_line_inc = 1; break;
}
}
else
- check_eol_junk(q->last_argument);
+ check_eol_junk(command->last_argument);
- if (q->type != Q_ERROR)
+ if (command->type != Q_ERROR &&
+ command->type != Q_COMMENT)
{
/*
- As soon as any non "error" command has been executed,
+ As soon as any non "error" command or comment has been executed,
the array with expected errors should be cleared
*/
- global_expected_errors= 0;
- bzero((gptr) global_expected_errno, sizeof(global_expected_errno));
+ memset(&saved_expected_errors, 0, sizeof(saved_expected_errors));
+ }
+
+ if (command_executed != last_command_executed)
+ {
+ /*
+ As soon as any command has been executed,
+ the replace structures should be cleared
+ */
+ free_all_replace();
}
+ last_command_executed= command_executed;
parser.current_line += current_line_inc;
if ( opt_mark_progress )
- mark_progress(q, parser.current_line);
+ mark_progress(command, parser.current_line);
}
start_lineno= 0;
+ if (parsing_disabled)
+ die("Test ended with parsing disabled");
+
/*
The whole test has been executed _sucessfully_.
Time to compare result or save it to record file.
@@ -5552,25 +5847,27 @@ int main(int argc, char **argv)
*/
if (ds_res.length)
{
- if (result_file)
+ if (result_file_name)
{
+ /* A result file has been specified */
+
if (record)
{
- /* Dump the output from test to result file */
- str_to_file(result_file, ds_res.str, ds_res.length);
+ /* Recording - dump the output from test to result file */
+ str_to_file(result_file_name, ds_res.str, ds_res.length);
}
else
{
/* Check that the output from test is equal to result file
- detect missing result file
- detect zero size result file
- */
- check_result(&ds_res, result_file, 0);
+ */
+ check_result(&ds_res);
}
}
else
{
- /* No result_file specified to compare with, print to stdout */
+ /* No result_file_name specified to compare with, print to stdout */
printf("%s", ds_res.str);
}
}
@@ -5579,7 +5876,8 @@ int main(int argc, char **argv)
die("The test didn't produce any output");
}
- if (!query_executed && result_file && my_stat(result_file, &res_info, 0))
+ if (!command_executed &&
+ result_file_name && my_stat(result_file_name, &res_info, 0))
{
/*
my_stat() successful on result file. Check if we have not run a
@@ -5591,14 +5889,16 @@ int main(int argc, char **argv)
die("No queries executed but result file found!");
}
- if ( opt_mark_progress )
- dump_progress(result_file);
- dynstr_free(&ds_progress);
+ if ( opt_mark_progress && result_file_name )
+ dump_progress();
+
+ /* Dump warning messages */
+ if (result_file_name && ds_warning_messages.length)
+ dump_warning_messages();
dynstr_free(&ds_res);
- if (!got_end_timer)
- timer_output(); /* No end_timer cmd, end it */
+ timer_output();
free_used_memory();
my_end(MY_CHECK_ERROR);
@@ -5611,101 +5911,188 @@ int main(int argc, char **argv)
/*
- Read arguments for embedded server and put them into
- embedded_server_args_count and embedded_server_args[]
-*/
+ A primitive timer that give results in milliseconds if the
+ --timer-file=<filename> is given. The timer result is written
+ to that file when the result is available. To not confuse
+ mysql-test-run with an old obsolete result, we remove the file
+ before executing any commands. The time we measure is
+ - If no explicit 'start_timer' or 'end_timer' is given in the
+ test case, the timer measure how long we execute in mysqltest.
-static int read_server_arguments(const char *name)
-{
- char argument[1024],buff[FN_REFLEN], *str=0;
- FILE *file;
+ - If only 'start_timer' is given we measure how long we execute
+ from that point until we terminate mysqltest.
- if (!test_if_hard_path(name))
+ - If only 'end_timer' is given we measure how long we execute
+ from that we enter mysqltest to the 'end_timer' is command is
+ executed.
+
+ - If both 'start_timer' and 'end_timer' are given we measure
+ the time between executing the two commands.
+*/
+
+void timer_output(void)
+{
+ if (timer_file)
{
- strxmov(buff, opt_basedir, name, NullS);
- name=buff;
+ char buf[32], *end;
+ ulonglong timer= timer_now() - timer_start;
+ end= longlong2str(timer, buf, 10);
+ str_to_file(timer_file,buf, (int) (end-buf));
+ /* Timer has been written to the file, don't use it anymore */
+ timer_file= 0;
}
- fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
+}
- if (!embedded_server_arg_count)
+
+ulonglong timer_now(void)
+{
+ return my_getsystime() / 10000;
+}
+
+
+/*
+ Get arguments for replace_columns. The syntax is:
+ replace-column column_number to_string [column_number to_string ...]
+ Where each argument may be quoted with ' or "
+ A argument may also be a variable, in which case the value of the
+ variable is replaced.
+*/
+
+void do_get_replace_column(struct st_command *command)
+{
+ char *from= command->first_argument;
+ char *buff, *start;
+ DBUG_ENTER("get_replace_columns");
+
+ free_replace_column();
+ if (!*from)
+ die("Missing argument in %s", command->query);
+
+ /* Allocate a buffer for results */
+ start= buff= my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
+ while (*from)
{
- embedded_server_arg_count=1;
- embedded_server_args[0]= (char*) ""; /* Progname */
+ char *to;
+ uint column_number;
+
+ to= get_string(&buff, &from, command);
+ if (!(column_number= atoi(to)) || column_number > MAX_COLUMNS)
+ die("Wrong column number to replace_column in '%s'", command->query);
+ if (!*from)
+ die("Wrong number of arguments to replace_column in '%s'", command->query);
+ to= get_string(&buff, &from, command);
+ my_free(replace_column[column_number-1], MY_ALLOW_ZERO_PTR);
+ replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE));
+ set_if_bigger(max_replace_column, column_number);
}
- if (!(file=my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME))))
- return 1;
- while (embedded_server_arg_count < MAX_SERVER_ARGS &&
- (str=fgets(argument,sizeof(argument), file)))
+ my_free(start, MYF(0));
+ command->last_argument= command->end;
+}
+
+
+void free_replace_column()
+{
+ uint i;
+ for (i=0 ; i < max_replace_column ; i++)
{
- *(strend(str)-1)=0; /* Remove end newline */
- if (!(embedded_server_args[embedded_server_arg_count]=
- (char*) my_strdup(str,MYF(MY_WME))))
+ if (replace_column[i])
{
- my_fclose(file,MYF(0));
- return 1;
+ my_free(replace_column[i], 0);
+ replace_column[i]= 0;
}
- embedded_server_arg_count++;
}
- my_fclose(file,MYF(0));
- if (str)
- {
- fprintf(stderr,"Too many arguments in option file: %s\n",name);
- return 1;
- }
- return 0;
+ max_replace_column= 0;
}
-/****************************************************************************\
- *
- * A primitive timer that give results in milliseconds if the
- * --timer-file=<filename> is given. The timer result is written
- * to that file when the result is available. To not confuse
- * mysql-test-run with an old obsolete result, we remove the file
- * before executing any commands. The time we measure is
- *
- * - If no explicit 'start_timer' or 'end_timer' is given in the
- * test case, the timer measure how long we execute in mysqltest.
- *
- * - If only 'start_timer' is given we measure how long we execute
- * from that point until we terminate mysqltest.
- *
- * - If only 'end_timer' is given we measure how long we execute
- * from that we enter mysqltest to the 'end_timer' is command is
- * executed.
- *
- * - If both 'start_timer' and 'end_timer' are given we measure
- * the time between executing the two commands.
- *
-\****************************************************************************/
-
-static void timer_output(void)
+
+/****************************************************************************/
+/*
+ Replace functions
+*/
+
+/* Definitions for replace result */
+
+typedef struct st_pointer_array { /* when using array-strings */
+ TYPELIB typelib; /* Pointer to strings */
+ byte *str; /* Strings is here */
+ int7 *flag; /* Flag about each var. */
+ uint array_allocs,max_count,length,max_length;
+} POINTER_ARRAY;
+
+struct st_replace;
+struct st_replace *init_replace(my_string *from, my_string *to, uint count,
+ my_string word_end_chars);
+int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name);
+void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds,
+ const char *from, int len);
+void free_pointer_array(POINTER_ARRAY *pa);
+
+struct st_replace *glob_replace;
+
+/*
+ Get arguments for replace. The syntax is:
+ replace from to [from to ...]
+ Where each argument may be quoted with ' or "
+ A argument may also be a variable, in which case the value of the
+ variable is replaced.
+*/
+
+void do_get_replace(struct st_command *command)
{
- if (timer_file)
+ uint i;
+ char *from= command->first_argument;
+ char *buff, *start;
+ char word_end_chars[256], *pos;
+ POINTER_ARRAY to_array, from_array;
+ DBUG_ENTER("get_replace");
+
+ free_replace();
+
+ bzero((char*) &to_array,sizeof(to_array));
+ bzero((char*) &from_array,sizeof(from_array));
+ if (!*from)
+ die("Missing argument in %s", command->query);
+ start= buff= my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
+ while (*from)
{
- char buf[32], *end;
- ulonglong timer= timer_now() - timer_start;
- end= longlong2str(timer, buf, 10);
- str_to_file(timer_file,buf, (int) (end-buf));
+ char *to= buff;
+ to= get_string(&buff, &from, command);
+ if (!*from)
+ die("Wrong number of arguments to replace_result in '%s'",
+ command->query);
+ insert_pointer_name(&from_array,to);
+ to= get_string(&buff, &from, command);
+ insert_pointer_name(&to_array,to);
}
+ for (i= 1,pos= word_end_chars ; i < 256 ; i++)
+ if (my_isspace(charset_info,i))
+ *pos++= i;
+ *pos=0; /* End pointer */
+ if (!(glob_replace= init_replace((char**) from_array.typelib.type_names,
+ (char**) to_array.typelib.type_names,
+ (uint) from_array.typelib.count,
+ word_end_chars)))
+ die("Can't initialize replace from '%s'", command->query);
+ free_pointer_array(&from_array);
+ free_pointer_array(&to_array);
+ my_free(start, MYF(0));
+ command->last_argument= command->end;
+ DBUG_VOID_RETURN;
}
-static ulonglong timer_now(void)
+
+void free_replace()
{
- return my_getsystime() / 10000;
+ DBUG_ENTER("free_replace");
+ if (glob_replace)
+ {
+ my_free((char*) glob_replace,MYF(0));
+ glob_replace=0;
+ }
+ DBUG_VOID_RETURN;
}
-/****************************************************************************
-* Handle replacement of strings
-****************************************************************************/
-
-#define PC_MALLOC 256 /* Bytes for pointers */
-#define PS_MALLOC 512 /* Bytes for data */
-
-#define SPACE_CHAR 256
-#define START_OF_LINE 257
-#define END_OF_LINE 258
-#define LAST_CHAR_CODE 259
typedef struct st_replace {
bool found;
@@ -5719,99 +6106,514 @@ typedef struct st_replace_found {
int from_offset;
} REPLACE_STRING;
-#ifndef WORD_BIT
-#define WORD_BIT (8*sizeof(uint))
-#endif
+void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds,
+ const char *str, int len)
+{
+ reg1 REPLACE *rep_pos;
+ reg2 REPLACE_STRING *rep_str;
+ const char *start, *from;
+ DBUG_ENTER("replace_strings_append");
+
+ start= from= str;
+ rep_pos=rep+1;
+ for (;;)
+ {
+ /* Loop through states */
+ DBUG_PRINT("info", ("Looping through states"));
+ while (!rep_pos->found)
+ rep_pos= rep_pos->next[(uchar) *from++];
+
+ /* Does this state contain a string to be replaced */
+ if (!(rep_str = ((REPLACE_STRING*) rep_pos))->replace_string)
+ {
+ /* No match found */
+ dynstr_append_mem(ds, start, from - start - 1);
+ DBUG_PRINT("exit", ("Found no more string to replace, appended: %s", start));
+ DBUG_VOID_RETURN;
+ }
-static int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name)
+ /* Found a string that needs to be replaced */
+ DBUG_PRINT("info", ("found: %d, to_offset: %d, from_offset: %d, string: %s",
+ rep_str->found, rep_str->to_offset,
+ rep_str->from_offset, rep_str->replace_string));
+
+ /* Append part of original string before replace string */
+ dynstr_append_mem(ds, start, (from - rep_str->to_offset) - start);
+
+ /* Append replace string */
+ dynstr_append_mem(ds, rep_str->replace_string,
+ strlen(rep_str->replace_string));
+
+ if (!*(from-=rep_str->from_offset) && rep_pos->found != 2)
+ {
+ /* End of from string */
+ DBUG_PRINT("exit", ("Found end of from string"));
+ DBUG_VOID_RETURN;
+ }
+ DBUG_ASSERT(from <= str+len);
+ start= from;
+ rep_pos=rep;
+ }
+}
+
+
+/*
+ Regex replace functions
+*/
+
+
+/* Stores regex substitutions */
+
+struct st_regex
{
- uint i,length,old_count;
- byte *new_pos;
- const char **new_array;
- DBUG_ENTER("insert_pointer_name");
+ char* pattern; /* Pattern to be replaced */
+ char* replace; /* String or expression to replace the pattern with */
+ int icase; /* true if the match is case insensitive */
+};
- if (! pa->typelib.count)
+struct st_replace_regex
+{
+ DYNAMIC_ARRAY regex_arr; /* stores a list of st_regex subsitutions */
+
+ /*
+ Temporary storage areas for substitutions. To reduce unnessary copying
+ and memory freeing/allocation, we pre-allocate two buffers, and alternate
+ their use, one for input/one for output, the roles changing on the next
+ st_regex substition. At the end of substitutions buf points to the
+ one containing the final result.
+ */
+ char* buf;
+ char* even_buf;
+ char* odd_buf;
+ int even_buf_len;
+ int odd_buf_len;
+};
+
+struct st_replace_regex *glob_replace_regex= 0;
+
+int reg_replace(char** buf_p, int* buf_len_p, char *pattern, char *replace,
+ char *string, int icase);
+
+
+
+/*
+ Finds the next (non-escaped) '/' in the expression.
+ (If the character '/' is needed, it can be escaped using '\'.)
+*/
+
+#define PARSE_REGEX_ARG \
+ while (p < expr_end) \
+ { \
+ char c= *p; \
+ if (c == '/') \
+ { \
+ if (last_c == '\\') \
+ { \
+ buf_p[-1]= '/'; \
+ } \
+ else \
+ { \
+ *buf_p++ = 0; \
+ break; \
+ } \
+ } \
+ else \
+ *buf_p++ = c; \
+ \
+ last_c= c; \
+ p++; \
+ } \
+ \
+/*
+ Initializes the regular substitution expression to be used in the
+ result output of test.
+
+ Returns: st_replace_regex struct with pairs of substitutions
+*/
+
+struct st_replace_regex* init_replace_regex(char* expr)
+{
+ struct st_replace_regex* res;
+ char* buf,*expr_end;
+ char* p;
+ char* buf_p;
+ uint expr_len= strlen(expr);
+ char last_c = 0;
+ struct st_regex reg;
+
+ /* my_malloc() will die on fail with MY_FAE */
+ res=(struct st_replace_regex*)my_malloc(
+ sizeof(*res)+expr_len ,MYF(MY_FAE+MY_WME));
+ my_init_dynamic_array(&res->regex_arr,sizeof(struct st_regex),128,128);
+
+ buf= (char*)res + sizeof(*res);
+ expr_end= expr + expr_len;
+ p= expr;
+ buf_p= buf;
+
+ /* for each regexp substitution statement */
+ while (p < expr_end)
{
- if (!(pa->typelib.type_names=(const char **)
- my_malloc(((PC_MALLOC-MALLOC_OVERHEAD)/
- (sizeof(my_string)+sizeof(*pa->flag))*
- (sizeof(my_string)+sizeof(*pa->flag))),MYF(MY_WME))))
- DBUG_RETURN(-1);
- if (!(pa->str= (byte*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD),
- MYF(MY_WME))))
+ bzero(&reg,sizeof(reg));
+ /* find the start of the statement */
+ while (p < expr_end)
{
- my_free((gptr) pa->typelib.type_names,MYF(0));
- DBUG_RETURN (-1);
+ if (*p == '/')
+ break;
+ p++;
}
- pa->max_count=(PC_MALLOC-MALLOC_OVERHEAD)/(sizeof(byte*)+
- sizeof(*pa->flag));
- pa->flag= (int7*) (pa->typelib.type_names+pa->max_count);
- pa->length=0;
- pa->max_length=PS_MALLOC-MALLOC_OVERHEAD;
- pa->array_allocs=1;
+
+ if (p == expr_end || ++p == expr_end)
+ {
+ if (res->regex_arr.elements)
+ break;
+ else
+ goto err;
+ }
+ /* we found the start */
+ reg.pattern= buf_p;
+
+ /* Find first argument -- pattern string to be removed */
+ PARSE_REGEX_ARG
+
+ if (p == expr_end || ++p == expr_end)
+ goto err;
+
+ /* buf_p now points to the replacement pattern terminated with \0 */
+ reg.replace= buf_p;
+
+ /* Find second argument -- replace string to replace pattern */
+ PARSE_REGEX_ARG
+
+ if (p == expr_end)
+ goto err;
+
+ /* skip the ending '/' in the statement */
+ p++;
+
+ /* Check if we should do matching case insensitive */
+ if (p < expr_end && *p == 'i')
+ reg.icase= 1;
+
+ /* done parsing the statement, now place it in regex_arr */
+ if (insert_dynamic(&res->regex_arr,(gptr) &reg))
+ die("Out of memory");
}
- length=(uint) strlen(name)+1;
- if (pa->length+length >= pa->max_length)
+ res->odd_buf_len= res->even_buf_len= 8192;
+ res->even_buf= (char*)my_malloc(res->even_buf_len,MYF(MY_WME+MY_FAE));
+ res->odd_buf= (char*)my_malloc(res->odd_buf_len,MYF(MY_WME+MY_FAE));
+ res->buf= res->even_buf;
+
+ return res;
+
+err:
+ my_free((gptr)res,0);
+ die("Error parsing replace_regex \"%s\"", expr);
+ return 0;
+}
+
+/*
+ Execute all substitutions on val.
+
+ Returns: true if substituition was made, false otherwise
+ Side-effect: Sets r->buf to be the buffer with all substitutions done.
+
+ IN:
+ struct st_replace_regex* r
+ char* val
+ Out:
+ struct st_replace_regex* r
+ r->buf points at the resulting buffer
+ r->even_buf and r->odd_buf might have been reallocated
+ r->even_buf_len and r->odd_buf_len might have been changed
+
+ TODO: at some point figure out if there is a way to do everything
+ in one pass
+*/
+
+int multi_reg_replace(struct st_replace_regex* r,char* val)
+{
+ uint i;
+ char* in_buf, *out_buf;
+ int* buf_len_p;
+
+ in_buf= val;
+ out_buf= r->even_buf;
+ buf_len_p= &r->even_buf_len;
+ r->buf= 0;
+
+ /* For each substitution, do the replace */
+ for (i= 0; i < r->regex_arr.elements; i++)
{
- if (!(new_pos= (byte*) my_realloc((gptr) pa->str,
- (uint) (pa->max_length+PS_MALLOC),
- MYF(MY_WME))))
- DBUG_RETURN(1);
- if (new_pos != pa->str)
+ struct st_regex re;
+ char* save_out_buf= out_buf;
+
+ get_dynamic(&r->regex_arr,(gptr)&re,i);
+
+ if (!reg_replace(&out_buf, buf_len_p, re.pattern, re.replace,
+ in_buf, re.icase))
{
- my_ptrdiff_t diff=PTR_BYTE_DIFF(new_pos,pa->str);
- for (i=0 ; i < pa->typelib.count ; i++)
- pa->typelib.type_names[i]= ADD_TO_PTR(pa->typelib.type_names[i],diff,
- char*);
- pa->str=new_pos;
+ /* if the buffer has been reallocated, make adjustements */
+ if (save_out_buf != out_buf)
+ {
+ if (save_out_buf == r->even_buf)
+ r->even_buf= out_buf;
+ else
+ r->odd_buf= out_buf;
+ }
+
+ r->buf= out_buf;
+ if (in_buf == val)
+ in_buf= r->odd_buf;
+
+ swap_variables(char*,in_buf,out_buf);
+
+ buf_len_p= (out_buf == r->even_buf) ? &r->even_buf_len :
+ &r->odd_buf_len;
}
- pa->max_length+=PS_MALLOC;
}
- if (pa->typelib.count >= pa->max_count-1)
+
+ return (r->buf == 0);
+}
+
+/*
+ Parse the regular expression to be used in all result files
+ from now on.
+
+ The syntax is --replace_regex /from/to/i /from/to/i ...
+ i means case-insensitive match. If omitted, the match is
+ case-sensitive
+
+*/
+void do_get_replace_regex(struct st_command *command)
+{
+ char *expr= command->first_argument;
+ free_replace_regex();
+ if (!(glob_replace_regex=init_replace_regex(expr)))
+ die("Could not init replace_regex");
+ command->last_argument= command->end;
+}
+
+void free_replace_regex()
+{
+ if (glob_replace_regex)
{
- int len;
- pa->array_allocs++;
- len=(PC_MALLOC*pa->array_allocs - MALLOC_OVERHEAD);
- if (!(new_array=(const char **) my_realloc((gptr) pa->typelib.type_names,
- (uint) len/
- (sizeof(byte*)+sizeof(*pa->flag))*
- (sizeof(byte*)+sizeof(*pa->flag)),
- MYF(MY_WME))))
- DBUG_RETURN(1);
- pa->typelib.type_names=new_array;
- old_count=pa->max_count;
- pa->max_count=len/(sizeof(byte*) + sizeof(*pa->flag));
- pa->flag= (int7*) (pa->typelib.type_names+pa->max_count);
- memcpy((byte*) pa->flag,(my_string) (pa->typelib.type_names+old_count),
- old_count*sizeof(*pa->flag));
+ delete_dynamic(&glob_replace_regex->regex_arr);
+ my_free(glob_replace_regex->even_buf,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(glob_replace_regex->odd_buf,MYF(MY_ALLOW_ZERO_PTR));
+ my_free((char*) glob_replace_regex,MYF(0));
+ glob_replace_regex=0;
}
- pa->flag[pa->typelib.count]=0; /* Reset flag */
- pa->typelib.type_names[pa->typelib.count++]= pa->str+pa->length;
- pa->typelib.type_names[pa->typelib.count]= NullS; /* Put end-mark */
- VOID(strmov(pa->str+pa->length,name));
- pa->length+=length;
- DBUG_RETURN(0);
-} /* insert_pointer_name */
+}
- /* free pointer array */
-void free_pointer_array(POINTER_ARRAY *pa)
+/*
+ auxiluary macro used by reg_replace
+ makes sure the result buffer has sufficient length
+*/
+#define SECURE_REG_BUF if (buf_len < need_buf_len) \
+ { \
+ int off= res_p - buf; \
+ buf= (char*)my_realloc(buf,need_buf_len,MYF(MY_WME+MY_FAE)); \
+ res_p= buf + off; \
+ buf_len= need_buf_len; \
+ } \
+ \
+/*
+ Performs a regex substitution
+
+ IN:
+
+ buf_p - result buffer pointer. Will change if reallocated
+ buf_len_p - result buffer length. Will change if the buffer is reallocated
+ pattern - regexp pattern to match
+ replace - replacement expression
+ string - the string to perform substituions in
+ icase - flag, if set to 1 the match is case insensitive
+*/
+int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
+ char *replace, char *string, int icase)
{
- if (pa->typelib.count)
+ my_regex_t r;
+ my_regmatch_t *subs;
+ char *buf_end, *replace_end;
+ char *buf= *buf_p;
+ int len;
+ int buf_len, need_buf_len;
+ int cflags= REG_EXTENDED;
+ int err_code;
+ char *res_p,*str_p,*str_end;
+
+ buf_len= *buf_len_p;
+ len= strlen(string);
+ str_end= string + len;
+
+ /* start with a buffer of a reasonable size that hopefully will not
+ need to be reallocated
+ */
+ need_buf_len= len * 2 + 1;
+ res_p= buf;
+
+ SECURE_REG_BUF
+
+ buf_end= buf + buf_len;
+
+ if (icase)
+ cflags|= REG_ICASE;
+
+ if ((err_code= my_regcomp(&r,pattern,cflags,&my_charset_latin1)))
{
- pa->typelib.count=0;
- my_free((gptr) pa->typelib.type_names,MYF(0));
- pa->typelib.type_names=0;
- my_free((gptr) pa->str,MYF(0));
+ check_regerr(&r,err_code);
+ return 1;
}
-} /* free_pointer_array */
+ subs= (my_regmatch_t*)my_malloc(sizeof(my_regmatch_t) * (r.re_nsub+1),
+ MYF(MY_WME+MY_FAE));
+
+ *res_p= 0;
+ str_p= string;
+ replace_end= replace + strlen(replace);
+
+ /* for each pattern match instance perform a replacement */
+ while (!err_code)
+ {
+ /* find the match */
+ err_code= my_regexec(&r,str_p, r.re_nsub+1, subs,
+ (str_p == string) ? REG_NOTBOL : 0);
+
+ /* if regular expression error (eg. bad syntax, or out of memory) */
+ if (err_code && err_code != REG_NOMATCH)
+ {
+ check_regerr(&r,err_code);
+ my_regfree(&r);
+ return 1;
+ }
+
+ /* if match found */
+ if (!err_code)
+ {
+ char* expr_p= replace;
+ int c;
+
+ /*
+ we need at least what we have so far in the buffer + the part
+ before this match
+ */
+ need_buf_len= (res_p - buf) + subs[0].rm_so;
+
+ /* on this pass, calculate the memory for the result buffer */
+ while (expr_p < replace_end)
+ {
+ int back_ref_num= -1;
+ c= *expr_p;
+
+ if (c == '\\' && expr_p + 1 < replace_end)
+ {
+ back_ref_num= expr_p[1] - '0';
+ }
+
+ /* found a valid back_ref (eg. \1)*/
+ if (back_ref_num >= 0 && back_ref_num <= (int)r.re_nsub)
+ {
+ int start_off,end_off;
+ if ((start_off=subs[back_ref_num].rm_so) > -1 &&
+ (end_off=subs[back_ref_num].rm_eo) > -1)
+ {
+ need_buf_len += (end_off - start_off);
+ }
+ expr_p += 2;
+ }
+ else
+ {
+ expr_p++;
+ need_buf_len++;
+ }
+ }
+ need_buf_len++;
+ /*
+ now that we know the size of the buffer,
+ make sure it is big enough
+ */
+ SECURE_REG_BUF
+
+ /* copy the pre-match part */
+ if (subs[0].rm_so)
+ {
+ memcpy(res_p, str_p, subs[0].rm_so);
+ res_p+= subs[0].rm_so;
+ }
+
+ expr_p= replace;
+
+ /* copy the match and expand back_refs */
+ while (expr_p < replace_end)
+ {
+ int back_ref_num= -1;
+ c= *expr_p;
+
+ if (c == '\\' && expr_p + 1 < replace_end)
+ {
+ back_ref_num= expr_p[1] - '0';
+ }
- /* Code for replace rutines */
+ if (back_ref_num >= 0 && back_ref_num <= (int)r.re_nsub)
+ {
+ int start_off,end_off;
+ if ((start_off=subs[back_ref_num].rm_so) > -1 &&
+ (end_off=subs[back_ref_num].rm_eo) > -1)
+ {
+ int block_len= end_off - start_off;
+ memcpy(res_p,str_p + start_off, block_len);
+ res_p += block_len;
+ }
+ expr_p += 2;
+ }
+ else
+ {
+ *res_p++ = *expr_p++;
+ }
+ }
+
+ /* handle the post-match part */
+ if (subs[0].rm_so == subs[0].rm_eo)
+ {
+ if (str_p + subs[0].rm_so >= str_end)
+ break;
+ str_p += subs[0].rm_eo ;
+ *res_p++ = *str_p++;
+ }
+ else
+ {
+ str_p += subs[0].rm_eo;
+ }
+ }
+ else /* no match this time, just copy the string as is */
+ {
+ int left_in_str= str_end-str_p;
+ need_buf_len= (res_p-buf) + left_in_str;
+ SECURE_REG_BUF
+ memcpy(res_p,str_p,left_in_str);
+ res_p += left_in_str;
+ str_p= str_end;
+ }
+ }
+ my_free((gptr)subs, MYF(0));
+ my_regfree(&r);
+ *res_p= 0;
+ *buf_p= buf;
+ *buf_len_p= buf_len;
+ return 0;
+}
+
+
+#ifndef WORD_BIT
+#define WORD_BIT (8*sizeof(uint))
+#endif
#define SET_MALLOC_HUNC 64
+#define LAST_CHAR_CODE 259
typedef struct st_rep_set {
uint *bits; /* Pointer to used sets */
@@ -5843,32 +6645,48 @@ typedef struct st_follow {
} FOLLOWS;
-static int init_sets(REP_SETS *sets,uint states);
-static REP_SET *make_new_set(REP_SETS *sets);
-static void make_sets_invisible(REP_SETS *sets);
-static void free_last_set(REP_SETS *sets);
-static void free_sets(REP_SETS *sets);
-static void internal_set_bit(REP_SET *set, uint bit);
-static void internal_clear_bit(REP_SET *set, uint bit);
-static void or_bits(REP_SET *to,REP_SET *from);
-static void copy_bits(REP_SET *to,REP_SET *from);
-static int cmp_bits(REP_SET *set1,REP_SET *set2);
-static int get_next_bit(REP_SET *set,uint lastpos);
-static int find_set(REP_SETS *sets,REP_SET *find);
-static int find_found(FOUND_SET *found_set,uint table_offset,
- int found_offset);
-static uint start_at_word(my_string pos);
-static uint end_of_word(my_string pos);
-static uint replace_len(my_string pos);
+int init_sets(REP_SETS *sets,uint states);
+REP_SET *make_new_set(REP_SETS *sets);
+void make_sets_invisible(REP_SETS *sets);
+void free_last_set(REP_SETS *sets);
+void free_sets(REP_SETS *sets);
+void internal_set_bit(REP_SET *set, uint bit);
+void internal_clear_bit(REP_SET *set, uint bit);
+void or_bits(REP_SET *to,REP_SET *from);
+void copy_bits(REP_SET *to,REP_SET *from);
+int cmp_bits(REP_SET *set1,REP_SET *set2);
+int get_next_bit(REP_SET *set,uint lastpos);
+int find_set(REP_SETS *sets,REP_SET *find);
+int find_found(FOUND_SET *found_set,uint table_offset,
+ int found_offset);
+uint start_at_word(my_string pos);
+uint end_of_word(my_string pos);
static uint found_sets=0;
- /* Init a replace structure for further calls */
+uint replace_len(my_string str)
+{
+ uint len=0;
+ while (*str)
+ {
+ if (str[0] == '\\' && str[1])
+ str++;
+ str++;
+ len++;
+ }
+ return len;
+}
+
+/* Init a replace structure for further calls */
REPLACE *init_replace(my_string *from, my_string *to,uint count,
my_string word_end_chars)
{
+ static const int SPACE_CHAR= 256;
+ static const int START_OF_LINE= 257;
+ static const int END_OF_LINE= 258;
+
uint i,j,states,set_nr,len,result_len,max_length,found_end,bits_set,bit_nr;
int used_sets,chr,default_state;
char used_chars[LAST_CHAR_CODE],is_word_end[256];
@@ -5921,7 +6739,7 @@ REPLACE *init_replace(my_string *from, my_string *to,uint count,
DBUG_RETURN(0);
}
- /* Init follow_ptr[] */
+ /* Init follow_ptr[] */
for (i=0, states=1, follow_ptr=follow+1 ; i < count ; i++)
{
if (from[i][0] == '\\' && from[i][1] == '^')
@@ -6104,7 +6922,7 @@ REPLACE *init_replace(my_string *from, my_string *to,uint count,
}
}
- /* Alloc replace structure for the replace-state-machine */
+ /* Alloc replace structure for the replace-state-machine */
if ((replace=(REPLACE*) my_malloc(sizeof(REPLACE)*(sets.count)+
sizeof(REPLACE_STRING)*(found_sets+1)+
@@ -6147,7 +6965,7 @@ REPLACE *init_replace(my_string *from, my_string *to,uint count,
}
-static int init_sets(REP_SETS *sets,uint states)
+int init_sets(REP_SETS *sets,uint states)
{
bzero((char*) sets,sizeof(*sets));
sets->size_of_bits=((states+7)/8);
@@ -6163,16 +6981,16 @@ static int init_sets(REP_SETS *sets,uint states)
return 0;
}
- /* Make help sets invisible for nicer codeing */
+/* Make help sets invisible for nicer codeing */
-static void make_sets_invisible(REP_SETS *sets)
+void make_sets_invisible(REP_SETS *sets)
{
sets->invisible=sets->count;
sets->set+=sets->count;
sets->count=0;
}
-static REP_SET *make_new_set(REP_SETS *sets)
+REP_SET *make_new_set(REP_SETS *sets)
{
uint i,count,*bit_buffer;
REP_SET *set;
@@ -6190,7 +7008,7 @@ static REP_SET *make_new_set(REP_SETS *sets)
}
count=sets->count+sets->invisible+SET_MALLOC_HUNC;
if (!(set=(REP_SET*) my_realloc((gptr) sets->set_buffer,
- sizeof(REP_SET)*count,
+ sizeof(REP_SET)*count,
MYF(MY_WME))))
return 0;
sets->set_buffer=set;
@@ -6209,34 +7027,34 @@ static REP_SET *make_new_set(REP_SETS *sets)
return make_new_set(sets);
}
-static void free_last_set(REP_SETS *sets)
+void free_last_set(REP_SETS *sets)
{
sets->count--;
sets->extra++;
return;
}
-static void free_sets(REP_SETS *sets)
+void free_sets(REP_SETS *sets)
{
my_free((gptr)sets->set_buffer,MYF(0));
my_free((gptr)sets->bit_buffer,MYF(0));
return;
}
-static void internal_set_bit(REP_SET *set, uint bit)
+void internal_set_bit(REP_SET *set, uint bit)
{
set->bits[bit / WORD_BIT] |= 1 << (bit % WORD_BIT);
return;
}
-static void internal_clear_bit(REP_SET *set, uint bit)
+void internal_clear_bit(REP_SET *set, uint bit)
{
set->bits[bit / WORD_BIT] &= ~ (1 << (bit % WORD_BIT));
return;
}
-static void or_bits(REP_SET *to,REP_SET *from)
+void or_bits(REP_SET *to,REP_SET *from)
{
reg1 uint i;
for (i=0 ; i < to->size_of_bits ; i++)
@@ -6244,22 +7062,22 @@ static void or_bits(REP_SET *to,REP_SET *from)
return;
}
-static void copy_bits(REP_SET *to,REP_SET *from)
+void copy_bits(REP_SET *to,REP_SET *from)
{
memcpy((byte*) to->bits,(byte*) from->bits,
(size_t) (sizeof(uint) * to->size_of_bits));
}
-static int cmp_bits(REP_SET *set1,REP_SET *set2)
+int cmp_bits(REP_SET *set1,REP_SET *set2)
{
return bcmp((byte*) set1->bits,(byte*) set2->bits,
sizeof(uint) * set1->size_of_bits);
}
- /* Get next set bit from set. */
+/* Get next set bit from set. */
-static int get_next_bit(REP_SET *set,uint lastpos)
+int get_next_bit(REP_SET *set,uint lastpos)
{
uint pos,*start,*end,bits;
@@ -6280,11 +7098,11 @@ static int get_next_bit(REP_SET *set,uint lastpos)
return pos;
}
- /* find if there is a same set in sets. If there is, use it and
- free given set, else put in given set in sets and return its
- position */
+/* find if there is a same set in sets. If there is, use it and
+ free given set, else put in given set in sets and return its
+ position */
-static int find_set(REP_SETS *sets,REP_SET *find)
+int find_set(REP_SETS *sets,REP_SET *find)
{
uint i;
for (i=0 ; i < sets->count-1 ; i++)
@@ -6298,14 +7116,14 @@ static int find_set(REP_SETS *sets,REP_SET *find)
return i; /* return new postion */
}
- /* find if there is a found_set with same table_offset & found_offset
- If there is return offset to it, else add new offset and return pos.
- Pos returned is -offset-2 in found_set_structure because it is
- saved in set->next and set->next[] >= 0 points to next set and
- set->next[] == -1 is reserved for end without replaces.
- */
+/* find if there is a found_set with same table_offset & found_offset
+ If there is return offset to it, else add new offset and return pos.
+ Pos returned is -offset-2 in found_set_structure because it is
+ saved in set->next and set->next[] >= 0 points to next set and
+ set->next[] == -1 is reserved for end without replaces.
+*/
-static int find_found(FOUND_SET *found_set,uint table_offset, int found_offset)
+int find_found(FOUND_SET *found_set,uint table_offset, int found_offset)
{
int i;
for (i=0 ; (uint) i < found_sets ; i++)
@@ -6318,145 +7136,153 @@ static int find_found(FOUND_SET *found_set,uint table_offset, int found_offset)
return -i-2; /* return new postion */
}
- /* Return 1 if regexp starts with \b or ends with \b*/
+/* Return 1 if regexp starts with \b or ends with \b*/
-static uint start_at_word(my_string pos)
+uint start_at_word(my_string pos)
{
return (((!bcmp(pos,"\\b",2) && pos[2]) || !bcmp(pos,"\\^",2)) ? 1 : 0);
}
-static uint end_of_word(my_string pos)
+uint end_of_word(my_string pos)
{
my_string end=strend(pos);
return ((end > pos+2 && !bcmp(end-2,"\\b",2)) ||
(end >= pos+2 && !bcmp(end-2,"\\$",2))) ?
- 1 : 0;
+ 1 : 0;
}
+/****************************************************************************
+ * Handle replacement of strings
+ ****************************************************************************/
-static uint replace_len(my_string str)
-{
- uint len=0;
- while (*str)
- {
- if (str[0] == '\\' && str[1])
- str++;
- str++;
- len++;
- }
- return len;
-}
-
+#define PC_MALLOC 256 /* Bytes for pointers */
+#define PS_MALLOC 512 /* Bytes for data */
-/* Replace strings while appending to ds */
-void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds,
- const char *str, int len)
+int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name)
{
- reg1 REPLACE *rep_pos;
- reg2 REPLACE_STRING *rep_str;
- const char *start, *from;
- DBUG_ENTER("replace_strings_append");
+ uint i,length,old_count;
+ byte *new_pos;
+ const char **new_array;
+ DBUG_ENTER("insert_pointer_name");
- start= from= str;
- rep_pos=rep+1;
- for (;;)
+ if (! pa->typelib.count)
{
- /* Loop through states */
- DBUG_PRINT("info", ("Looping through states"));
- while (!rep_pos->found)
- rep_pos= rep_pos->next[(uchar) *from++];
-
- /* Does this state contain a string to be replaced */
- if (!(rep_str = ((REPLACE_STRING*) rep_pos))->replace_string)
+ if (!(pa->typelib.type_names=(const char **)
+ my_malloc(((PC_MALLOC-MALLOC_OVERHEAD)/
+ (sizeof(my_string)+sizeof(*pa->flag))*
+ (sizeof(my_string)+sizeof(*pa->flag))),MYF(MY_WME))))
+ DBUG_RETURN(-1);
+ if (!(pa->str= (byte*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD),
+ MYF(MY_WME))))
{
- /* No match found */
- dynstr_append_mem(ds, start, from - start - 1);
- DBUG_PRINT("exit", ("Found no more string to replace, appended: %s", start));
- DBUG_VOID_RETURN;
+ my_free((gptr) pa->typelib.type_names,MYF(0));
+ DBUG_RETURN (-1);
}
-
- /* Found a string that needs to be replaced */
- DBUG_PRINT("info", ("found: %d, to_offset: %d, from_offset: %d, string: %s",
- rep_str->found, rep_str->to_offset,
- rep_str->from_offset, rep_str->replace_string));
-
- /* Append part of original string before replace string */
- dynstr_append_mem(ds, start, (from - rep_str->to_offset) - start);
-
- /* Append replace string */
- dynstr_append_mem(ds, rep_str->replace_string,
- strlen(rep_str->replace_string));
-
- if (!*(from-=rep_str->from_offset) && rep_pos->found != 2)
+ pa->max_count=(PC_MALLOC-MALLOC_OVERHEAD)/(sizeof(byte*)+
+ sizeof(*pa->flag));
+ pa->flag= (int7*) (pa->typelib.type_names+pa->max_count);
+ pa->length=0;
+ pa->max_length=PS_MALLOC-MALLOC_OVERHEAD;
+ pa->array_allocs=1;
+ }
+ length=(uint) strlen(name)+1;
+ if (pa->length+length >= pa->max_length)
+ {
+ if (!(new_pos= (byte*) my_realloc((gptr) pa->str,
+ (uint) (pa->max_length+PS_MALLOC),
+ MYF(MY_WME))))
+ DBUG_RETURN(1);
+ if (new_pos != pa->str)
{
- /* End of from string */
- DBUG_PRINT("exit", ("Found end of from string"));
- DBUG_VOID_RETURN;
+ my_ptrdiff_t diff=PTR_BYTE_DIFF(new_pos,pa->str);
+ for (i=0 ; i < pa->typelib.count ; i++)
+ pa->typelib.type_names[i]= ADD_TO_PTR(pa->typelib.type_names[i],diff,
+ char*);
+ pa->str=new_pos;
}
- DBUG_ASSERT(from <= str+len);
- start= from;
- rep_pos=rep;
+ pa->max_length+=PS_MALLOC;
}
-}
+ if (pa->typelib.count >= pa->max_count-1)
+ {
+ int len;
+ pa->array_allocs++;
+ len=(PC_MALLOC*pa->array_allocs - MALLOC_OVERHEAD);
+ if (!(new_array=(const char **) my_realloc((gptr) pa->typelib.type_names,
+ (uint) len/
+ (sizeof(byte*)+sizeof(*pa->flag))*
+ (sizeof(byte*)+sizeof(*pa->flag)),
+ MYF(MY_WME))))
+ DBUG_RETURN(1);
+ pa->typelib.type_names=new_array;
+ old_count=pa->max_count;
+ pa->max_count=len/(sizeof(byte*) + sizeof(*pa->flag));
+ pa->flag= (int7*) (pa->typelib.type_names+pa->max_count);
+ memcpy((byte*) pa->flag,(my_string) (pa->typelib.type_names+old_count),
+ old_count*sizeof(*pa->flag));
+ }
+ pa->flag[pa->typelib.count]=0; /* Reset flag */
+ pa->typelib.type_names[pa->typelib.count++]= pa->str+pa->length;
+ pa->typelib.type_names[pa->typelib.count]= NullS; /* Put end-mark */
+ VOID(strmov(pa->str+pa->length,name));
+ pa->length+=length;
+ DBUG_RETURN(0);
+} /* insert_pointer_name */
-/****************************************************************************
- Replace results for a column
-*****************************************************************************/
+/* free pointer array */
-static void free_replace_column()
+void free_pointer_array(POINTER_ARRAY *pa)
{
- uint i;
- for (i=0 ; i < max_replace_column ; i++)
+ if (pa->typelib.count)
{
- if (replace_column[i])
- {
- my_free(replace_column[i], 0);
- replace_column[i]= 0;
- }
+ pa->typelib.count=0;
+ my_free((gptr) pa->typelib.type_names,MYF(0));
+ pa->typelib.type_names=0;
+ my_free((gptr) pa->str,MYF(0));
}
- max_replace_column= 0;
-}
+} /* free_pointer_array */
-/*
- Get arguments for replace_columns. The syntax is:
- replace-column column_number to_string [column_number to_string ...]
- Where each argument may be quoted with ' or "
- A argument may also be a variable, in which case the value of the
- variable is replaced.
-*/
-static void get_replace_column(struct st_query *q)
-{
- char *from=q->first_argument;
- char *buff,*start;
- DBUG_ENTER("get_replace_columns");
+/* Functions that uses replace and replace_regex */
- free_replace_column();
- if (!*from)
- die("Missing argument in %s", q->query);
+/* Append the string to ds, with optional replace */
+void replace_dynstr_append_mem(DYNAMIC_STRING *ds,
+ const char *val, int len)
+{
+#ifdef __WIN__
+ fix_win_paths(val, len);
+#endif
- /* Allocate a buffer for results */
- start=buff=my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
- while (*from)
+ if (glob_replace_regex)
{
- char *to;
- uint column_number;
+ /* Regex replace */
+ if (!multi_reg_replace(glob_replace_regex, (char*)val))
+ {
+ val= glob_replace_regex->buf;
+ len= strlen(val);
+ }
+ }
- to= get_string(&buff, &from, q);
- if (!(column_number= atoi(to)) || column_number > MAX_COLUMNS)
- die("Wrong column number to replace_column in '%s'", q->query);
- if (!*from)
- die("Wrong number of arguments to replace_column in '%s'", q->query);
- to= get_string(&buff, &from, q);
- my_free(replace_column[column_number-1], MY_ALLOW_ZERO_PTR);
- replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE));
- set_if_bigger(max_replace_column, column_number);
+ if (glob_replace)
+ {
+ /* Normal replace */
+ replace_strings_append(glob_replace, ds, val, len);
}
- my_free(start, MYF(0));
- q->last_argument= q->end;
+ else
+ dynstr_append_mem(ds, val, len);
}
+/* Append zero-terminated string to ds, with optional replace */
+void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val)
+{
+ replace_dynstr_append_mem(ds, val, strlen(val));
+}
-
+/* Append uint to ds, with optional replace */
+void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val)
+{
+ char buff[22]; /* This should be enough for any int */
+ char *end= longlong10_to_str(val, buff, 10);
+ replace_dynstr_append_mem(ds, buff, end - buff);
+}
diff --git a/configure.in b/configure.in
index 61eb8a9d259..a58f71e22c2 100644
--- a/configure.in
+++ b/configure.in
@@ -415,6 +415,10 @@ AC_SUBST(HOSTNAME)
AC_SUBST(PERL)
AC_SUBST(PERL5)
+# icheck, used for ABI check
+AC_PATH_PROG(ICHECK, icheck, no)
+AC_SUBST(ICHECK)
+
# Lock for PS
AC_PATH_PROG(PS, ps, ps)
AC_MSG_CHECKING("how to check if pid exists")
@@ -1060,6 +1064,18 @@ EOF
s,\(extra/comp_err\)\$(EXEEXT),\1.linux,
EOF
;;
+ libmysql/Makefile.in)
+ cat > $filesed << EOF
+s,libyassl.la,.libs/libyassl.a,
+s,libtaocrypt.la,.libs/libtaocrypt.a,
+EOF
+ ;;
+ libmysql_r/Makefile.in)
+ cat > $filesed << EOF
+s,libyassl.la,.libs/libyassl.a,
+s,libtaocrypt.la,.libs/libtaocrypt.a,
+EOF
+ ;;
client/Makefile.in)
#
cat > $filesed << EOF
@@ -1696,6 +1712,13 @@ then
AC_MSG_ERROR("MySQL needs a off_t type.")
fi
+dnl
+dnl check if time_t is unsigned
+dnl
+
+MYSQL_CHECK_TIME_T
+
+
# do we need #pragma interface/#pragma implementation ?
# yes if it's gcc 2.x, and not icc pretending to be gcc, and not cygwin
AC_MSG_CHECKING(the need for @%:@pragma interface/implementation)
diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp
index 28e9d237622..0edff289b61 100644
--- a/extra/yassl/include/yassl_int.hpp
+++ b/extra/yassl/include/yassl_int.hpp
@@ -40,6 +40,13 @@
#include "lock.hpp"
#include "openssl/ssl.h" // ASN1_STRING and DH
+// Check if _POSIX_THREADS should be forced
+#if !defined(_POSIX_THREADS) && (defined(__NETWARE__) || defined(__hpux))
+// HPUX does not define _POSIX_THREADS as it's not _fully_ implemented
+// Netware supports pthreads but does not announce it
+#define _POSIX_THREADS
+#endif
+
#ifdef _POSIX_THREADS
#include <pthread.h>
#endif
diff --git a/extra/yassl/taocrypt/include/hmac.hpp b/extra/yassl/taocrypt/include/hmac.hpp
index d46a6d4e7c3..b710c3aa499 100644
--- a/extra/yassl/taocrypt/include/hmac.hpp
+++ b/extra/yassl/taocrypt/include/hmac.hpp
@@ -60,12 +60,12 @@ private:
T mac_;
// MSVC 6 HACK, gives compiler error if calculated in array
- enum { BSIZE = T::BLOCK_SIZE / sizeof(word32),
- DSIZE = T::DIGEST_SIZE / sizeof(word32) };
+ enum { HMAC_BSIZE = T::BLOCK_SIZE / sizeof(word32),
+ HMAC_DSIZE = T::DIGEST_SIZE / sizeof(word32) };
- word32 ip_[BSIZE]; // align ipad_ on word32
- word32 op_[BSIZE]; // align opad_ on word32
- word32 innerH_[DSIZE]; // align innerHash_ on word32
+ word32 ip_[HMAC_BSIZE]; // align ipad_ on word32
+ word32 op_[HMAC_BSIZE]; // align opad_ on word32
+ word32 innerH_[HMAC_DSIZE]; // align innerHash_ on word32
void KeyInnerHash();
diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp
index 0266c802657..b23b36f0ba2 100644
--- a/extra/yassl/testsuite/test.hpp
+++ b/extra/yassl/testsuite/test.hpp
@@ -27,9 +27,12 @@
#endif /* _WIN32 */
-#if !defined(_SOCKLEN_T) && (defined(_WIN32) || defined(__NETWARE__))
+#if !defined(_SOCKLEN_T) && defined(_WIN32)
typedef int socklen_t;
#endif
+#if !defined(_SOCKLEN_T) && defined(__NETWARE__)
+ typedef size_t socklen_t;
+#endif
// Check type of third arg to accept
diff --git a/include/Makefile.am b/include/Makefile.am
index 26161b36ab8..af061f80ff2 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -15,14 +15,14 @@
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA
-BUILT_SOURCES = mysql_version.h m_ctype.h my_config.h
+BUILT_SOURCES = mysql_version.h my_config.h
pkginclude_HEADERS = my_dbug.h m_string.h my_sys.h my_list.h my_xml.h \
mysql.h mysql_com.h mysql_embed.h \
my_semaphore.h my_pthread.h my_no_pthread.h \
errmsg.h my_global.h my_net.h my_alloc.h \
my_getopt.h sslopt-longopts.h my_dir.h typelib.h \
sslopt-vars.h sslopt-case.h sql_common.h keycache.h \
- mysql_time.h mysql/plugin.h $(BUILT_SOURCES)
+ mysql_time.h m_ctype.h mysql/plugin.h $(BUILT_SOURCES)
noinst_HEADERS = config-win.h config-netware.h \
heap.h my_bitmap.h my_uctype.h \
myisam.h myisampack.h myisammrg.h ft_global.h\
@@ -35,8 +35,10 @@ noinst_HEADERS = config-win.h config-netware.h \
atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \
my_libwrap.h
-# mysql_version.h are generated
-CLEANFILES = mysql_version.h my_config.h readline openssl
+# Remove built files and the symlinked directories
+CLEANFILES = $(BUILT_SOURCES) readline openssl
+
+EXTRA_DIST = mysql_h.ic
# Some include files that may be moved and patched by configure
DISTCLEANFILES = sched.h $(CLEANFILES)
@@ -54,5 +56,22 @@ my_config.h: ../config.h
dist-hook:
$(RM) -f $(distdir)/mysql_version.h $(distdir)/my_config.h
+#
+# Rules for checking that ABI has not changed
+#
+
+# Create a icheck file and compare it to the reference
+abi_check: mysql.h mysql_version.h mysql_com.h mysql_time.h my_list.h \
+ my_alloc.h typelib.h mysql_h.ic
+ @set -ex; \
+ if [ @ICHECK@ != no ] ; then \
+ @ICHECK@ --canonify --skip-from-re /usr/ -o $@.ic mysql.h; \
+ @ICHECK@ --compare mysql_h.ic $@.ic; \
+ fi; \
+ touch abi_check;
+
+#all: abi_check
+
+
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/include/abi_check b/include/abi_check
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/include/abi_check
diff --git a/include/hash.h b/include/hash.h
index 8f5ff21ae5e..4d6ee77fa0c 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -65,6 +65,8 @@ my_bool hash_check(HASH *hash); /* Only in debug library */
#define hash_clear(H) bzero((char*) (H),sizeof(*(H)))
#define hash_inited(H) ((H)->array.buffer != 0)
+#define hash_init_opt(A,B,C,D,E,F,G,H) \
+ (!hash_inited(A) && _hash_init(A,B,C,D,E,F,G, H CALLER_INFO))
#ifdef __cplusplus
}
diff --git a/include/my_dbug.h b/include/my_dbug.h
index a397861c1af..f4aaa41b201 100644
--- a/include/my_dbug.h
+++ b/include/my_dbug.h
@@ -39,7 +39,8 @@ extern void _db_enter_(const char *_func_,const char *_file_,uint _line_,
extern void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_,
uint *_slevel_);
extern void _db_pargs_(uint _line_,const char *keyword);
-extern void _db_doprnt_ _VARARGS((const char *format,...));
+extern void _db_doprnt_ _VARARGS((const char *format,...))
+ ATTRIBUTE_FORMAT(printf, 1, 2);
extern void _db_dump_(uint _line_,const char *keyword,const char *memory,
uint length);
extern void _db_end_(void);
diff --git a/include/my_time.h b/include/my_time.h
index d0f2fc323d8..394732236a3 100644
--- a/include/my_time.h
+++ b/include/my_time.h
@@ -43,6 +43,12 @@ typedef long my_time_t;
#define MY_TIME_T_MAX LONG_MAX
#define MY_TIME_T_MIN LONG_MIN
+/* Time handling defaults */
+#define TIMESTAMP_MAX_YEAR 2038
+#define TIMESTAMP_MIN_YEAR (1900 + YY_PART_YEAR - 1)
+#define TIMESTAMP_MAX_VALUE INT_MAX32
+#define TIMESTAMP_MIN_VALUE 1
+
/* two-digit years < this are 20..; >= this are 19.. */
#define YY_PART_YEAR 70
/* apply above magic to years < this */
@@ -57,6 +63,16 @@ typedef long my_time_t;
#define TIME_NO_ZERO_DATE (TIME_NO_ZERO_IN_DATE*2)
#define TIME_INVALID_DATES (TIME_NO_ZERO_DATE*2)
+#define MYSQL_TIME_WARN_TRUNCATED 1
+#define MYSQL_TIME_WARN_OUT_OF_RANGE 2
+
+/* Limits for the TIME data type */
+#define TIME_MAX_HOUR 838
+#define TIME_MAX_MINUTE 59
+#define TIME_MAX_SECOND 59
+#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + \
+ TIME_MAX_SECOND)
+
enum enum_mysql_timestamp_type
str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
uint flags, int *was_cut);
@@ -69,13 +85,39 @@ ulonglong TIME_to_ulonglong(const MYSQL_TIME *time);
my_bool str_to_time(const char *str,uint length, MYSQL_TIME *l_time,
- int *was_cut);
+ int *warning);
+
+int check_time_range(struct st_mysql_time *time, int *warning);
long calc_daynr(uint year,uint month,uint day);
uint calc_days_in_year(uint year);
void init_time(void);
+
+/*
+ Function to check sanity of a TIMESTAMP value
+
+ DESCRIPTION
+ Check if a given MYSQL_TIME value fits in TIMESTAMP range.
+ This function doesn't make precise check, but rather a rough
+ estimate.
+
+ RETURN VALUES
+ FALSE The value seems sane
+ TRUE The MYSQL_TIME value is definitely out of range
+*/
+
+static inline bool validate_timestamp_range(const MYSQL_TIME *t)
+{
+ if ((t->year > TIMESTAMP_MAX_YEAR || t->year < TIMESTAMP_MIN_YEAR) ||
+ (t->year == TIMESTAMP_MAX_YEAR && (t->month > 1 || t->day > 19)) ||
+ (t->year == TIMESTAMP_MIN_YEAR && (t->month < 12 || t->day < 31)))
+ return FALSE;
+
+ return TRUE;
+}
+
my_time_t
my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone,
my_bool *in_dst_time_gap);
@@ -97,15 +139,25 @@ int my_date_to_str(const MYSQL_TIME *l_time, char *to);
int my_datetime_to_str(const MYSQL_TIME *l_time, char *to);
int my_TIME_to_str(const MYSQL_TIME *l_time, char *to);
-/*
- The following must be sorted so that simple intervals comes first.
- (get_interval_value() depends on this)
+/*
+ Available interval types used in any statement.
+
+ 'interval_type' must be sorted so that simple intervals comes first,
+ ie year, quarter, month, week, day, hour, etc. The order based on
+ interval size is also important and the intervals should be kept in a
+ large to smaller order. (get_interval_value() depends on this)
+
+ Note: If you change the order of elements in this enum you should fix
+ order of elements in 'interval_type_to_name' and 'interval_names'
+ arrays
+
+ See also interval_type_to_name, get_interval_value, interval_names
*/
enum interval_type
{
- INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_DAY, INTERVAL_HOUR,
- INTERVAL_MINUTE, INTERVAL_WEEK, INTERVAL_SECOND, INTERVAL_MICROSECOND ,
+ INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_WEEK, INTERVAL_DAY,
+ INTERVAL_HOUR, INTERVAL_MINUTE, INTERVAL_SECOND, INTERVAL_MICROSECOND,
INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, INTERVAL_DAY_MINUTE,
INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND,
INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND, INTERVAL_HOUR_MICROSECOND,
diff --git a/include/mysql.h b/include/mysql.h
index 8ef3f1273ec..f2a82c99fc3 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -14,6 +14,17 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/*
+ This file defines the client API to MySQL and also the ABI of the
+ dynamically linked libmysqlclient.
+
+ The ABI should never be changed in a released product of MySQL
+ thus you need to take great care when changing the file. In case
+ the file is changed so the ABI is broken, you must also
+ update the SHAREDLIB_MAJOR_VERSION in configure.in .
+
+*/
+
#ifndef _mysql_h
#define _mysql_h
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index 22cd64a52c4..2b97a134c6f 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -65,7 +65,7 @@ __MYSQL_DECLARE_PLUGIN(NAME, \
builtin_ ## NAME ## _sizeof_struct_st_plugin, \
builtin_ ## NAME ## _plugin)
-#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0}}
+#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0}}
/*
declarations for SHOW STATUS support in plugins
diff --git a/include/mysql_h.ic b/include/mysql_h.ic
new file mode 100644
index 00000000000..51cbb1fb7eb
--- /dev/null
+++ b/include/mysql_h.ic
@@ -0,0 +1,961 @@
+struct character_set;
+struct rand_struct;
+struct st_list;
+struct st_mem_root;
+struct st_mysql;
+struct st_mysql_bind;
+struct st_mysql_data;
+struct st_mysql_field;
+struct st_mysql_manager;
+struct st_mysql_methods;
+struct st_mysql_options;
+struct st_mysql_parameters;
+struct st_mysql_res;
+struct st_mysql_rows;
+struct st_mysql_stmt;
+struct st_mysql_time;
+struct st_net;
+struct st_typelib;
+struct st_udf_args;
+struct st_udf_init;
+struct st_used_mem;
+enum Item_result;
+enum enum_cursor_type;
+enum enum_field_types;
+enum enum_mysql_set_option;
+enum enum_mysql_stmt_state;
+enum enum_mysql_timestamp_type;
+enum enum_server_command;
+enum enum_stmt_attr_type;
+enum mysql_enum_shutdown_level;
+enum mysql_option;
+enum mysql_protocol_type;
+enum mysql_rpl_type;
+enum mysql_status;
+# 134 "mysql.h"
+typedef struct st_mysql_rows MYSQL_ROWS;
+# 24 "my_list.h"
+typedef struct st_list LIST;
+# 251 "mysql.h"
+typedef struct st_mysql MYSQL;
+# 653 "mysql.h"
+typedef struct st_mysql_bind MYSQL_BIND;
+# 93 "mysql.h"
+typedef struct st_mysql_field MYSQL_FIELD;
+# 117 "mysql.h"
+typedef unsigned int MYSQL_FIELD_OFFSET;
+# 340 "mysql.h"
+typedef struct st_mysql_manager MYSQL_MANAGER;
+# 354 "mysql.h"
+typedef struct st_mysql_parameters MYSQL_PARAMETERS;
+# 309 "mysql.h"
+typedef struct st_mysql_res MYSQL_RES;
+# 116 "mysql.h"
+typedef char * * MYSQL_ROW;
+# 140 "mysql.h"
+typedef MYSQL_ROWS * MYSQL_ROW_OFFSET;
+# 681 "mysql.h"
+typedef struct st_mysql_stmt MYSQL_STMT;
+# 236 "mysql.h"
+typedef struct character_set MY_CHARSET_INFO;
+# 184 "mysql_com.h"
+typedef struct st_net NET;
+# 21 "typelib.h"
+typedef struct st_typelib TYPELIB;
+# 174 "mysql_com.h"
+typedef struct st_vio Vio;
+# 57 "mysql.h"
+typedef char * gptr;
+# 29 "my_list.h"
+typedef int (* list_walk_action)(void *, void *);
+# 48 "mysql.h"
+typedef char my_bool;
+# 63 "mysql.h"
+typedef int my_socket;
+# 125 "mysql.h"
+typedef unsigned long long int my_ulonglong;
+# 144 "mysql.h"
+typedef struct embedded_query_result EMBEDDED_QUERY_RESULT;
+# 35 "my_alloc.h"
+typedef struct st_mem_root MEM_ROOT;
+# 145 "mysql.h"
+typedef struct st_mysql_data MYSQL_DATA;
+# 750 "mysql.h"
+typedef struct st_mysql_methods MYSQL_METHODS;
+# 48 "mysql_time.h"
+typedef struct st_mysql_time MYSQL_TIME;
+# 375 "mysql_com.h"
+typedef struct st_udf_args UDF_ARGS;
+# 388 "mysql_com.h"
+typedef struct st_udf_init UDF_INIT;
+# 27 "my_alloc.h"
+typedef struct st_used_mem USED_MEM;
+# 236 "mysql.h"
+struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(void *)))) character_set
+ {
+ unsigned int number;
+ unsigned int state;
+ char const * csname;
+ char const * name;
+ char const * comment;
+ char const * dir;
+ unsigned int mbminlen;
+ unsigned int mbmaxlen;
+ };
+# 361 "mysql_com.h"
+struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(double)))) rand_struct
+ {
+ unsigned long int seed1;
+ unsigned long int seed2;
+ unsigned long int max_value;
+ double max_value_dbl;
+ };
+# 24 "my_list.h"
+struct __attribute__((aligned(__alignof__(void *)))) st_list
+ {
+ struct st_list * prev;
+ struct st_list * next;
+ void * data;
+ };
+# 35 "my_alloc.h"
+struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned int)))) st_mem_root
+ {
+ USED_MEM * free;
+ USED_MEM * used;
+ USED_MEM * pre_alloc;
+ unsigned int min_malloc;
+ unsigned int block_size;
+ unsigned int block_num;
+ unsigned int first_block_usage;
+ void (* error_handler)(void);
+ };
+# 251 "mysql.h"
+struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long long int)))) st_mysql
+ {
+ NET net;
+ gptr connector_fd;
+ char * host;
+ char * user;
+ char * passwd;
+ char * unix_socket;
+ char * server_version;
+ char * host_info;
+ char * info;
+ char * db;
+ struct charset_info_st * charset;
+ MYSQL_FIELD * fields;
+ MEM_ROOT field_alloc;
+ my_ulonglong affected_rows;
+ my_ulonglong insert_id;
+ my_ulonglong extra_info;
+ unsigned long int thread_id;
+ unsigned long int packet_length;
+ unsigned int port;
+ unsigned long int client_flag;
+ unsigned long int server_capabilities;
+ unsigned int protocol_version;
+ unsigned int field_count;
+ unsigned int server_status;
+ unsigned int server_language;
+ unsigned int warning_count;
+ struct st_mysql_options options;
+ enum mysql_status status;
+ my_bool free_me;
+ my_bool reconnect;
+ char scramble[(20 + 1)];
+ my_bool rpl_pivot;
+ struct st_mysql * master;
+ struct st_mysql * next_slave;
+ struct st_mysql * last_used_slave;
+ struct st_mysql * last_used_con;
+ LIST * stmts;
+ struct st_mysql_methods const * methods;
+ void * thd;
+ my_bool * unbuffered_fetch_owner;
+ };
+# 653 "mysql.h"
+struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_bind
+ {
+ unsigned long int * length;
+ my_bool * is_null;
+ void * buffer;
+ my_bool * error;
+ enum enum_field_types buffer_type;
+ unsigned long int buffer_length;
+ unsigned char * row_ptr;
+ unsigned long int offset;
+ unsigned long int length_value;
+ unsigned int param_number;
+ unsigned int pack_length;
+ my_bool error_value;
+ my_bool is_unsigned;
+ my_bool long_data_used;
+ my_bool is_null_value;
+ void (* store_param_func)(NET * net, struct st_mysql_bind * param);
+ void (* fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *, unsigned char * * row);
+ void (* skip_result)(struct st_mysql_bind *, MYSQL_FIELD *, unsigned char * * row);
+ };
+# 145 "mysql.h"
+struct __attribute__((aligned(__alignof__(unsigned long long int)), aligned(__alignof__(void *)))) st_mysql_data
+ {
+ my_ulonglong rows;
+ unsigned int fields;
+ MYSQL_ROWS * data;
+ MEM_ROOT alloc;
+ struct embedded_query_result * embedded_info;
+ };
+# 93 "mysql.h"
+struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_field
+ {
+ char * name;
+ char * org_name;
+ char * table;
+ char * org_table;
+ char * db;
+ char * catalog;
+ char * def;
+ unsigned long int length;
+ unsigned long int max_length;
+ unsigned int name_length;
+ unsigned int org_name_length;
+ unsigned int table_length;
+ unsigned int org_table_length;
+ unsigned int db_length;
+ unsigned int catalog_length;
+ unsigned int def_length;
+ unsigned int flags;
+ unsigned int decimals;
+ unsigned int charsetnr;
+ enum enum_field_types type;
+ };
+# 340 "mysql.h"
+struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_manager
+ {
+ NET net;
+ char * host;
+ char * user;
+ char * passwd;
+ unsigned int port;
+ my_bool free_me;
+ my_bool eof;
+ int cmd_status;
+ int last_errno;
+ char * net_buf;
+ char * net_buf_pos;
+ char * net_data_end;
+ int net_buf_size;
+ char last_error[256];
+ };
+# 750 "mysql.h"
+struct __attribute__((aligned(__alignof__(void *)))) st_mysql_methods
+ {
+ my_bool (* read_query_result)(MYSQL * mysql);
+ my_bool (* advanced_command)(MYSQL * mysql, enum enum_server_command, char const * header, unsigned long int, char const * arg, unsigned long int, my_bool, MYSQL_STMT * stmt);
+ MYSQL_DATA * (* read_rows)(MYSQL * mysql, MYSQL_FIELD * mysql_fields, unsigned int);
+ MYSQL_RES * (* use_result)(MYSQL * mysql);
+ void (* fetch_lengths)(unsigned long int * to, MYSQL_ROW, unsigned int);
+ void (* flush_use_result)(MYSQL * mysql);
+ MYSQL_FIELD * (* list_fields)(MYSQL * mysql);
+ my_bool (* read_prepare_result)(MYSQL * mysql, MYSQL_STMT * stmt);
+ int (* stmt_execute)(MYSQL_STMT * stmt);
+ int (* read_binary_rows)(MYSQL_STMT * stmt);
+ int (* unbuffered_fetch)(MYSQL * mysql, char * * row);
+ void (* free_embedded_thd)(MYSQL * mysql);
+ char const * (* read_statistics)(MYSQL * mysql);
+ my_bool (* next_result)(MYSQL * mysql);
+ int (* read_change_user_result)(MYSQL * mysql, char * buff, char const * passwd);
+ int (* read_rows_from_cursor)(MYSQL_STMT * stmt);
+ };
+# 167 "mysql.h"
+struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(void *)))) st_mysql_options
+ {
+ unsigned int connect_timeout;
+ unsigned int read_timeout;
+ unsigned int write_timeout;
+ unsigned int port;
+ unsigned int protocol;
+ unsigned long int client_flag;
+ char * host;
+ char * user;
+ char * password;
+ char * unix_socket;
+ char * db;
+ struct st_dynamic_array * init_commands;
+ char * my_cnf_file;
+ char * my_cnf_group;
+ char * charset_dir;
+ char * charset_name;
+ char * ssl_key;
+ char * ssl_cert;
+ char * ssl_ca;
+ char * ssl_capath;
+ char * ssl_cipher;
+ char * shared_memory_base_name;
+ unsigned long int max_allowed_packet;
+ my_bool use_ssl;
+ my_bool compress;
+ my_bool named_pipe;
+ my_bool rpl_probe;
+ my_bool rpl_parse;
+ my_bool no_master_reads;
+ my_bool separate_thread;
+ enum mysql_option methods_to_use;
+ char * client_ip;
+ my_bool secure_auth;
+ my_bool report_data_truncation;
+ int (* local_infile_init)(void * *, char const *, void *);
+ int (* local_infile_read)(void *, char *, unsigned int);
+ void (* local_infile_end)(void);
+ int (* local_infile_error)(void *, char *, unsigned int);
+ void * local_infile_userdata;
+ };
+# 354 "mysql.h"
+struct __attribute__((aligned(__alignof__(void *)))) st_mysql_parameters
+ {
+ unsigned long int * p_max_allowed_packet;
+ unsigned long int * p_net_buffer_length;
+ };
+# 309 "mysql.h"
+struct __attribute__((aligned(__alignof__(unsigned long long int)), aligned(__alignof__(void *)))) st_mysql_res
+ {
+ my_ulonglong row_count;
+ MYSQL_FIELD * fields;
+ MYSQL_DATA * data;
+ MYSQL_ROWS * data_cursor;
+ unsigned long int * lengths;
+ MYSQL * handle;
+ MEM_ROOT field_alloc;
+ unsigned int field_count;
+ unsigned int current_field;
+ MYSQL_ROW row;
+ MYSQL_ROW current_row;
+ my_bool eof;
+ my_bool unbuffered_fetch_cancelled;
+ struct st_mysql_methods const * methods;
+ };
+# 134 "mysql.h"
+struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_rows
+ {
+ struct st_mysql_rows * next;
+ MYSQL_ROW data;
+ unsigned long int length;
+ };
+# 681 "mysql.h"
+struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long long int)))) st_mysql_stmt
+ {
+ MEM_ROOT mem_root;
+ LIST list;
+ MYSQL * mysql;
+ MYSQL_BIND * params;
+ MYSQL_BIND * bind;
+ MYSQL_FIELD * fields;
+ MYSQL_DATA result;
+ MYSQL_ROWS * data_cursor;
+ my_ulonglong affected_rows;
+ my_ulonglong insert_id;
+ int (* read_row_func)(struct st_mysql_stmt * stmt, unsigned char * * row);
+ unsigned long int stmt_id;
+ unsigned long int flags;
+ unsigned long int prefetch_rows;
+ unsigned int server_status;
+ unsigned int last_errno;
+ unsigned int param_count;
+ unsigned int field_count;
+ enum enum_mysql_stmt_state state;
+ char last_error[512];
+ char sqlstate[(5 + 1)];
+ my_bool send_types_to_server;
+ my_bool bind_param_done;
+ unsigned char bind_result_done;
+ my_bool unbuffered_fetch_cancelled;
+ my_bool update_max_length;
+ };
+# 48 "mysql_time.h"
+struct __attribute__((aligned(__alignof__(unsigned long int)))) st_mysql_time
+ {
+ unsigned int year;
+ unsigned int month;
+ unsigned int day;
+ unsigned int hour;
+ unsigned int minute;
+ unsigned int second;
+ unsigned long int second_part;
+ my_bool neg;
+ enum enum_mysql_timestamp_type time_type;
+ };
+# 184 "mysql_com.h"
+struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_net
+ {
+ Vio * vio;
+ unsigned char * buff;
+ unsigned char * buff_end;
+ unsigned char * write_pos;
+ unsigned char * read_pos;
+ my_socket fd;
+ unsigned long int max_packet;
+ unsigned long int max_packet_size;
+ unsigned int pkt_nr;
+ unsigned int compress_pkt_nr;
+ unsigned int write_timeout;
+ unsigned int read_timeout;
+ unsigned int retry_count;
+ int fcntl;
+ my_bool compress;
+ unsigned long int remain_in_buf;
+ unsigned long int length;
+ unsigned long int buf_length;
+ unsigned long int where_b;
+ unsigned int * return_status;
+ unsigned char reading_or_writing;
+ char save_char;
+ my_bool no_send_ok;
+ my_bool no_send_eof;
+ my_bool no_send_error;
+ char last_error[512];
+ char sqlstate[(5 + 1)];
+ unsigned int last_errno;
+ unsigned char error;
+ gptr query_cache_query;
+ my_bool report_error;
+ my_bool return_errno;
+ };
+# 21 "typelib.h"
+struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(void *)))) st_typelib
+ {
+ unsigned int count;
+ char const * name;
+ char const * * type_names;
+ unsigned int * type_lengths;
+ };
+# 375 "mysql_com.h"
+struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(void *)))) st_udf_args
+ {
+ unsigned int arg_count;
+ enum Item_result * arg_type;
+ char * * args;
+ unsigned long int * lengths;
+ char * maybe_null;
+ char * * attributes;
+ unsigned long int * attribute_lengths;
+ };
+# 388 "mysql_com.h"
+struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(void *)))) st_udf_init
+ {
+ my_bool maybe_null;
+ unsigned int decimals;
+ unsigned long int max_length;
+ char * ptr;
+ my_bool const_item;
+ };
+# 27 "my_alloc.h"
+struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned int)))) st_used_mem
+ {
+ struct st_used_mem * next;
+ unsigned int left;
+ unsigned int size;
+ };
+# 372 "mysql_com.h"
+enum Item_result
+ {
+ STRING_RESULT = 0,
+ REAL_RESULT = 1,
+ INT_RESULT = 2,
+ ROW_RESULT = 3,
+ DECIMAL_RESULT = 4,
+ };
+# 318 "mysql_com.h"
+enum enum_cursor_type
+ {
+ CURSOR_TYPE_NO_CURSOR = 0,
+ CURSOR_TYPE_READ_ONLY = 1,
+ CURSOR_TYPE_FOR_UPDATE = 2,
+ CURSOR_TYPE_SCROLLABLE = 4,
+ };
+# 231 "mysql_com.h"
+enum enum_field_types
+ {
+ MYSQL_TYPE_DECIMAL = 0,
+ MYSQL_TYPE_TINY = 1,
+ MYSQL_TYPE_SHORT = 2,
+ MYSQL_TYPE_LONG = 3,
+ MYSQL_TYPE_FLOAT = 4,
+ MYSQL_TYPE_DOUBLE = 5,
+ MYSQL_TYPE_NULL = 6,
+ MYSQL_TYPE_TIMESTAMP = 7,
+ MYSQL_TYPE_LONGLONG = 8,
+ MYSQL_TYPE_INT24 = 9,
+ MYSQL_TYPE_DATE = 10,
+ MYSQL_TYPE_TIME = 11,
+ MYSQL_TYPE_DATETIME = 12,
+ MYSQL_TYPE_YEAR = 13,
+ MYSQL_TYPE_NEWDATE = 14,
+ MYSQL_TYPE_VARCHAR = 15,
+ MYSQL_TYPE_BIT = 16,
+ MYSQL_TYPE_NEWDECIMAL = 246,
+ MYSQL_TYPE_ENUM = 247,
+ MYSQL_TYPE_SET = 248,
+ MYSQL_TYPE_TINY_BLOB = 249,
+ MYSQL_TYPE_MEDIUM_BLOB = 250,
+ MYSQL_TYPE_LONG_BLOB = 251,
+ MYSQL_TYPE_BLOB = 252,
+ MYSQL_TYPE_VAR_STRING = 253,
+ MYSQL_TYPE_STRING = 254,
+ MYSQL_TYPE_GEOMETRY = 255,
+ };
+# 328 "mysql_com.h"
+enum enum_mysql_set_option
+ {
+ MYSQL_OPTION_MULTI_STATEMENTS_ON = 0,
+ MYSQL_OPTION_MULTI_STATEMENTS_OFF = 1,
+ };
+# 583 "mysql.h"
+enum enum_mysql_stmt_state
+ {
+ MYSQL_STMT_INIT_DONE = 1,
+ MYSQL_STMT_PREPARE_DONE = 2,
+ MYSQL_STMT_EXECUTE_DONE = 3,
+ MYSQL_STMT_FETCH_DONE = 4,
+ };
+# 29 "mysql_time.h"
+enum enum_mysql_timestamp_type
+ {
+ MYSQL_TIMESTAMP_NONE = -(2),
+ MYSQL_TIMESTAMP_ERROR = -(1),
+ MYSQL_TIMESTAMP_DATE = 0,
+ MYSQL_TIMESTAMP_DATETIME = 1,
+ MYSQL_TIMESTAMP_TIME = 2,
+ };
+# 52 "mysql_com.h"
+enum enum_server_command
+ {
+ COM_SLEEP = 0,
+ COM_QUIT = 1,
+ COM_INIT_DB = 2,
+ COM_QUERY = 3,
+ COM_FIELD_LIST = 4,
+ COM_CREATE_DB = 5,
+ COM_DROP_DB = 6,
+ COM_REFRESH = 7,
+ COM_SHUTDOWN = 8,
+ COM_STATISTICS = 9,
+ COM_PROCESS_INFO = 10,
+ COM_CONNECT = 11,
+ COM_PROCESS_KILL = 12,
+ COM_DEBUG = 13,
+ COM_PING = 14,
+ COM_TIME = 15,
+ COM_DELAYED_INSERT = 16,
+ COM_CHANGE_USER = 17,
+ COM_BINLOG_DUMP = 18,
+ COM_TABLE_DUMP = 19,
+ COM_CONNECT_OUT = 20,
+ COM_REGISTER_SLAVE = 21,
+ COM_STMT_PREPARE = 22,
+ COM_STMT_EXECUTE = 23,
+ COM_STMT_SEND_LONG_DATA = 24,
+ COM_STMT_CLOSE = 25,
+ COM_STMT_RESET = 26,
+ COM_SET_OPTION = 27,
+ COM_STMT_FETCH = 28,
+ COM_DAEMON = 29,
+ COM_END = 30,
+ };
+# 727 "mysql.h"
+enum enum_stmt_attr_type
+ {
+ STMT_ATTR_UPDATE_MAX_LENGTH = 0,
+ STMT_ATTR_CURSOR_TYPE = 1,
+ STMT_ATTR_PREFETCH_ROWS = 2,
+ };
+# 293 "mysql_com.h"
+enum mysql_enum_shutdown_level
+ {
+ SHUTDOWN_DEFAULT = 0,
+ SHUTDOWN_WAIT_CONNECTIONS = (unsigned char)((1 << 0)),
+ SHUTDOWN_WAIT_TRANSACTIONS = (unsigned char)((1 << 1)),
+ SHUTDOWN_WAIT_UPDATES = (unsigned char)((1 << 3)),
+ SHUTDOWN_WAIT_ALL_BUFFERS = ((unsigned char)((1 << 3)) << 1),
+ SHUTDOWN_WAIT_CRITICAL_BUFFERS = (((unsigned char)((1 << 3)) << 1) + 1),
+ KILL_CONNECTION = 255,
+ };
+# 154 "mysql.h"
+enum mysql_option
+ {
+ MYSQL_OPT_CONNECT_TIMEOUT = 0,
+ MYSQL_OPT_COMPRESS = 1,
+ MYSQL_OPT_NAMED_PIPE = 2,
+ MYSQL_INIT_COMMAND = 3,
+ MYSQL_READ_DEFAULT_FILE = 4,
+ MYSQL_READ_DEFAULT_GROUP = 5,
+ MYSQL_SET_CHARSET_DIR = 6,
+ MYSQL_SET_CHARSET_NAME = 7,
+ MYSQL_OPT_LOCAL_INFILE = 8,
+ MYSQL_OPT_PROTOCOL = 9,
+ MYSQL_SHARED_MEMORY_BASE_NAME = 10,
+ MYSQL_OPT_READ_TIMEOUT = 11,
+ MYSQL_OPT_WRITE_TIMEOUT = 12,
+ MYSQL_OPT_USE_RESULT = 13,
+ MYSQL_OPT_USE_REMOTE_CONNECTION = 14,
+ MYSQL_OPT_USE_EMBEDDED_CONNECTION = 15,
+ MYSQL_OPT_GUESS_CONNECTION = 16,
+ MYSQL_SET_CLIENT_IP = 17,
+ MYSQL_SECURE_AUTH = 18,
+ MYSQL_REPORT_DATA_TRUNCATION = 19,
+ MYSQL_OPT_RECONNECT = 20,
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT = 21,
+ };
+# 221 "mysql.h"
+enum mysql_protocol_type
+ {
+ MYSQL_PROTOCOL_DEFAULT = 0,
+ MYSQL_PROTOCOL_TCP = 1,
+ MYSQL_PROTOCOL_SOCKET = 2,
+ MYSQL_PROTOCOL_PIPE = 3,
+ MYSQL_PROTOCOL_MEMORY = 4,
+ };
+# 231 "mysql.h"
+enum mysql_rpl_type
+ {
+ MYSQL_RPL_MASTER = 0,
+ MYSQL_RPL_SLAVE = 1,
+ MYSQL_RPL_ADMIN = 2,
+ };
+# 216 "mysql.h"
+enum mysql_status
+ {
+ MYSQL_STATUS_READY = 0,
+ MYSQL_STATUS_GET_RESULT = 1,
+ MYSQL_STATUS_USE_RESULT = 2,
+ };
+# 427 "mysql_com.h"
+extern my_bool check_scramble(char const * reply, char const * message, unsigned char const * hash_stage2);
+# 420 "mysql_com.h"
+extern my_bool check_scramble_323(char const *, char const * message, unsigned long int * salt);
+# 415 "mysql_com.h"
+extern void create_random_string(char * to, unsigned int, struct rand_struct * rand_st);
+# 28 "typelib.h"
+extern int find_type(char * x, TYPELIB * typelib, unsigned int);
+# 429 "mysql_com.h"
+extern void get_salt_from_password(unsigned char * res, char const * password);
+# 422 "mysql_com.h"
+extern void get_salt_from_password_323(unsigned long int * res, char const * password);
+# 435 "mysql_com.h"
+extern char * get_tty_password(char const * opt_message);
+# 30 "typelib.h"
+extern char const * get_type(TYPELIB * typelib, unsigned int);
+# 417 "mysql_com.h"
+extern void hash_password(unsigned long int * to, char const * password, unsigned int);
+# 31 "my_list.h"
+extern LIST * list_add(LIST * root, LIST * element);
+# 33 "my_list.h"
+extern LIST * list_cons(void * data, LIST * root);
+# 32 "my_list.h"
+extern LIST * list_delete(LIST * root, LIST * element);
+# 35 "my_list.h"
+extern void list_free(LIST * root, unsigned int);
+# 36 "my_list.h"
+extern unsigned int list_length(LIST *);
+# 34 "my_list.h"
+extern LIST * list_reverse(LIST * root);
+# 37 "my_list.h"
+extern int list_walk(LIST *, list_walk_action, gptr);
+# 430 "mysql_com.h"
+extern void make_password_from_salt(char * to, unsigned char const * hash_stage2);
+# 423 "mysql_com.h"
+extern void make_password_from_salt_323(char * to, unsigned long int const * salt);
+# 425 "mysql_com.h"
+extern void make_scrambled_password(char * to, char const * password);
+# 418 "mysql_com.h"
+extern void make_scrambled_password_323(char * to, char const * password);
+# 29 "typelib.h"
+extern void make_type(char * to, unsigned int, TYPELIB * typelib);
+# 358 "mysql_com.h"
+extern int my_connect(my_socket, struct sockaddr const * name, unsigned int, unsigned int);
+# 340 "mysql_com.h"
+extern my_bool my_net_init(NET * net, Vio * vio);
+# 341 "mysql_com.h"
+extern void my_net_local_init(NET * net);
+# 351 "mysql_com.h"
+extern unsigned long int my_net_read(NET * net);
+# 346 "mysql_com.h"
+extern my_bool my_net_write(NET * net, char const * packet, unsigned long int);
+# 414 "mysql_com.h"
+extern double my_rnd(struct rand_struct *);
+# 441 "mysql_com.h"
+extern void my_thread_end(void);
+# 440 "mysql_com.h"
+extern my_bool my_thread_init(void);
+# 559 "mysql.h"
+extern void myodbc_remove_escape(MYSQL * mysql, char * name);
+# 501 "mysql.h"
+extern int mysql_add_slave(MYSQL * mysql, char const * host, unsigned int, char const * user, char const * passwd);
+# 410 "mysql.h"
+extern my_ulonglong mysql_affected_rows(MYSQL * mysql);
+# 823 "mysql.h"
+extern my_bool mysql_autocommit(MYSQL * mysql, my_bool);
+# 426 "mysql.h"
+extern my_bool mysql_change_user(MYSQL * mysql, char const * user, char const * passwd, char const * db);
+# 418 "mysql.h"
+extern char const * mysql_character_set_name(MYSQL * mysql);
+# 826 "mysql.h"
+extern void mysql_close(MYSQL * sock);
+# 821 "mysql.h"
+extern my_bool mysql_commit(MYSQL * mysql);
+# 530 "mysql.h"
+extern void mysql_data_seek(MYSQL_RES * result, my_ulonglong);
+# 548 "mysql.h"
+extern void mysql_debug(char const * debug);
+# 487 "mysql.h"
+extern void mysql_disable_reads_from_master(MYSQL * mysql);
+# 481 "mysql.h"
+extern void mysql_disable_rpl_parse(MYSQL * mysql);
+# 509 "mysql.h"
+extern int mysql_dump_debug_info(MYSQL * mysql);
+# 561 "mysql.h"
+extern my_bool mysql_embedded(void);
+# 486 "mysql.h"
+extern void mysql_enable_reads_from_master(MYSQL * mysql);
+# 480 "mysql.h"
+extern void mysql_enable_rpl_parse(MYSQL * mysql);
+# 402 "mysql.h"
+extern my_bool mysql_eof(MYSQL_RES * res);
+# 412 "mysql.h"
+extern unsigned int mysql_errno(MYSQL * mysql);
+# 436 "mysql_com.h"
+extern char const * mysql_errno_to_sqlstate(unsigned int);
+# 413 "mysql.h"
+extern char const * mysql_error(MYSQL * mysql);
+# 541 "mysql.h"
+extern unsigned long int mysql_escape_string(char * to, char const * from, unsigned long int);
+# 538 "mysql.h"
+extern MYSQL_FIELD * mysql_fetch_field(MYSQL_RES * result);
+# 403 "mysql.h"
+extern MYSQL_FIELD * mysql_fetch_field_direct(MYSQL_RES * res, unsigned int);
+# 405 "mysql.h"
+extern MYSQL_FIELD * mysql_fetch_fields(MYSQL_RES * res);
+# 537 "mysql.h"
+extern unsigned long int * mysql_fetch_lengths(MYSQL_RES * result);
+# 536 "mysql.h"
+extern MYSQL_ROW mysql_fetch_row(MYSQL_RES * result);
+# 409 "mysql.h"
+extern unsigned int mysql_field_count(MYSQL * mysql);
+# 534 "mysql.h"
+extern MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES * result, MYSQL_FIELD_OFFSET);
+# 407 "mysql.h"
+extern MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES * res);
+# 529 "mysql.h"
+extern void mysql_free_result(MYSQL_RES * result);
+# 454 "mysql.h"
+extern void mysql_get_character_set_info(MYSQL * mysql, MY_CHARSET_INFO * charset);
+# 519 "mysql.h"
+extern char const * mysql_get_client_info(void);
+# 520 "mysql.h"
+extern unsigned long int mysql_get_client_version(void);
+# 521 "mysql.h"
+extern char const * mysql_get_host_info(MYSQL * mysql);
+# 384 "mysql.h"
+extern MYSQL_PARAMETERS * mysql_get_parameters(void);
+# 523 "mysql.h"
+extern unsigned int mysql_get_proto_info(MYSQL * mysql);
+# 518 "mysql.h"
+extern char const * mysql_get_server_info(MYSQL * mysql);
+# 522 "mysql.h"
+extern unsigned long int mysql_get_server_version(MYSQL * mysql);
+# 425 "mysql.h"
+extern char const * mysql_get_ssl_cipher(MYSQL * mysql);
+# 543 "mysql.h"
+extern unsigned long int mysql_hex_string(char * to, char const * from, unsigned long int);
+# 416 "mysql.h"
+extern char const * mysql_info(MYSQL * mysql);
+# 421 "mysql.h"
+extern MYSQL * mysql_init(MYSQL * mysql);
+# 411 "mysql.h"
+extern my_ulonglong mysql_insert_id(MYSQL * mysql);
+# 512 "mysql.h"
+extern int mysql_kill(MYSQL * mysql, unsigned long int);
+# 524 "mysql.h"
+extern MYSQL_RES * mysql_list_dbs(MYSQL * mysql, char const * wild);
+# 539 "mysql.h"
+extern MYSQL_RES * mysql_list_fields(MYSQL * mysql, char const * table, char const * wild);
+# 526 "mysql.h"
+extern MYSQL_RES * mysql_list_processes(MYSQL * mysql);
+# 525 "mysql.h"
+extern MYSQL_RES * mysql_list_tables(MYSQL * mysql, char const * wild);
+# 568 "mysql.h"
+extern void mysql_manager_close(MYSQL_MANAGER * con);
+# 569 "mysql.h"
+extern int mysql_manager_command(MYSQL_MANAGER * con, char const * cmd, int);
+# 563 "mysql.h"
+extern MYSQL_MANAGER * mysql_manager_connect(MYSQL_MANAGER * con, char const * host, char const * user, char const * passwd, unsigned int);
+# 571 "mysql.h"
+extern int mysql_manager_fetch_line(MYSQL_MANAGER * con, char * res_buf, int);
+# 562 "mysql.h"
+extern MYSQL_MANAGER * mysql_manager_init(MYSQL_MANAGER * con);
+# 445 "mysql.h"
+extern my_bool mysql_master_query(MYSQL * mysql, char const * q, unsigned long int);
+# 447 "mysql.h"
+extern my_bool mysql_master_send_query(MYSQL * mysql, char const * q, unsigned long int);
+# 824 "mysql.h"
+extern my_bool mysql_more_results(MYSQL * mysql);
+# 825 "mysql.h"
+extern int mysql_next_result(MYSQL * mysql);
+# 401 "mysql.h"
+extern unsigned int mysql_num_fields(MYSQL_RES * res);
+# 400 "mysql.h"
+extern my_ulonglong mysql_num_rows(MYSQL_RES * res);
+# 549 "mysql.h"
+extern char * mysql_odbc_escape_string(MYSQL * mysql, char * to, unsigned long int, char const * from, unsigned long int, void * param, char * (* extend_buffer)(void *, char * to, unsigned long int * length));
+# 527 "mysql.h"
+extern int mysql_options(MYSQL * mysql, enum mysql_option, char const * arg);
+# 516 "mysql.h"
+extern int mysql_ping(MYSQL * mysql);
+# 75 "mysql.h"
+extern unsigned int mysql_port;
+# 436 "mysql.h"
+extern int mysql_query(MYSQL * mysql, char const * q);
+# 574 "mysql.h"
+extern my_bool mysql_read_query_result(MYSQL * mysql);
+# 489 "mysql.h"
+extern my_bool mysql_reads_from_master_enabled(MYSQL * mysql);
+# 428 "mysql.h"
+extern MYSQL * mysql_real_connect(MYSQL * mysql, char const * host, char const * user, char const * passwd, char const * db, unsigned int, char const * unix_socket, unsigned long int);
+# 545 "mysql.h"
+extern unsigned long int mysql_real_escape_string(MYSQL * mysql, char * to, char const * from, unsigned long int);
+# 439 "mysql.h"
+extern int mysql_real_query(MYSQL * mysql, char const * q, unsigned long int);
+# 510 "mysql.h"
+extern int mysql_refresh(MYSQL * mysql, unsigned int);
+# 822 "mysql.h"
+extern my_bool mysql_rollback(MYSQL * mysql);
+# 532 "mysql.h"
+extern MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES * result, MYSQL_ROW_OFFSET);
+# 406 "mysql.h"
+extern MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES * res);
+# 483 "mysql.h"
+extern int mysql_rpl_parse_enabled(MYSQL * mysql);
+# 494 "mysql.h"
+extern my_bool mysql_rpl_probe(MYSQL * mysql);
+# 491 "mysql.h"
+extern enum mysql_rpl_type mysql_rpl_query_type(char const * q, int);
+# 435 "mysql.h"
+extern int mysql_select_db(MYSQL * mysql, char const * db);
+# 437 "mysql.h"
+extern int mysql_send_query(MYSQL * mysql, char const * q, unsigned long int);
+# 371 "mysql.h"
+extern void mysql_server_end(void);
+# 370 "mysql.h"
+extern int mysql_server_init(int, char * * argv, char * * groups);
+# 419 "mysql.h"
+extern int mysql_set_character_set(MYSQL * mysql, char const * csname);
+# 472 "mysql.h"
+extern void mysql_set_local_infile_default(MYSQL * mysql);
+# 461 "mysql.h"
+extern void mysql_set_local_infile_handler(MYSQL * mysql, int (* local_infile_init)(void * *, char const *, void *), int (* local_infile_read)(void *, char *, unsigned int), void (* local_infile_end)(void), int (* local_infile_error)(void *, char *, unsigned int), void *);
+# 497 "mysql.h"
+extern int mysql_set_master(MYSQL * mysql, char const * host, unsigned int, char const * user, char const * passwd);
+# 513 "mysql.h"
+extern int mysql_set_server_option(MYSQL * mysql, enum enum_mysql_set_option);
+# 506 "mysql.h"
+extern int mysql_shutdown(MYSQL * mysql, enum mysql_enum_shutdown_level);
+# 450 "mysql.h"
+extern my_bool mysql_slave_query(MYSQL * mysql, char const * q, unsigned long int);
+# 452 "mysql.h"
+extern my_bool mysql_slave_send_query(MYSQL * mysql, char const * q, unsigned long int);
+# 414 "mysql.h"
+extern char const * mysql_sqlstate(MYSQL * mysql);
+# 422 "mysql.h"
+extern my_bool mysql_ssl_set(MYSQL * mysql, char const * key, char const * cert, char const * ca, char const * capath, char const * cipher);
+# 517 "mysql.h"
+extern char const * mysql_stat(MYSQL * mysql);
+# 817 "mysql.h"
+extern my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT * stmt);
+# 795 "mysql.h"
+extern my_bool mysql_stmt_attr_get(MYSQL_STMT * stmt, enum enum_stmt_attr_type, void * attr);
+# 792 "mysql.h"
+extern my_bool mysql_stmt_attr_set(MYSQL_STMT * stmt, enum enum_stmt_attr_type, void const * attr);
+# 798 "mysql.h"
+extern my_bool mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
+# 799 "mysql.h"
+extern my_bool mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
+# 800 "mysql.h"
+extern my_bool mysql_stmt_close(MYSQL_STMT * stmt);
+# 815 "mysql.h"
+extern void mysql_stmt_data_seek(MYSQL_STMT * stmt, my_ulonglong);
+# 809 "mysql.h"
+extern unsigned int mysql_stmt_errno(MYSQL_STMT * stmt);
+# 810 "mysql.h"
+extern char const * mysql_stmt_error(MYSQL_STMT * stmt);
+# 785 "mysql.h"
+extern int mysql_stmt_execute(MYSQL_STMT * stmt);
+# 786 "mysql.h"
+extern int mysql_stmt_fetch(MYSQL_STMT * stmt);
+# 787 "mysql.h"
+extern int mysql_stmt_fetch_column(MYSQL_STMT * stmt, MYSQL_BIND * bind, unsigned int, unsigned long int);
+# 819 "mysql.h"
+extern unsigned int mysql_stmt_field_count(MYSQL_STMT * stmt);
+# 802 "mysql.h"
+extern my_bool mysql_stmt_free_result(MYSQL_STMT * stmt);
+# 782 "mysql.h"
+extern MYSQL_STMT * mysql_stmt_init(MYSQL * mysql);
+# 818 "mysql.h"
+extern my_ulonglong mysql_stmt_insert_id(MYSQL_STMT * stmt);
+# 816 "mysql.h"
+extern my_ulonglong mysql_stmt_num_rows(MYSQL_STMT * stmt);
+# 791 "mysql.h"
+extern unsigned long int mysql_stmt_param_count(MYSQL_STMT * stmt);
+# 808 "mysql.h"
+extern MYSQL_RES * mysql_stmt_param_metadata(MYSQL_STMT * stmt);
+# 783 "mysql.h"
+extern int mysql_stmt_prepare(MYSQL_STMT * stmt, char const * query, unsigned long int);
+# 801 "mysql.h"
+extern my_bool mysql_stmt_reset(MYSQL_STMT * stmt);
+# 807 "mysql.h"
+extern MYSQL_RES * mysql_stmt_result_metadata(MYSQL_STMT * stmt);
+# 812 "mysql.h"
+extern MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT * stmt, MYSQL_ROW_OFFSET);
+# 814 "mysql.h"
+extern MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT * stmt);
+# 803 "mysql.h"
+extern my_bool mysql_stmt_send_long_data(MYSQL_STMT * stmt, unsigned int, char const * data, unsigned long int);
+# 811 "mysql.h"
+extern char const * mysql_stmt_sqlstate(MYSQL_STMT * stmt);
+# 790 "mysql.h"
+extern int mysql_stmt_store_result(MYSQL_STMT * stmt);
+# 441 "mysql.h"
+extern MYSQL_RES * mysql_store_result(MYSQL * mysql);
+# 393 "mysql.h"
+extern void mysql_thread_end(void);
+# 417 "mysql.h"
+extern unsigned long int mysql_thread_id(MYSQL * mysql);
+# 392 "mysql.h"
+extern my_bool mysql_thread_init(void);
+# 560 "mysql.h"
+extern unsigned int mysql_thread_safe(void);
+# 76 "mysql.h"
+extern char * mysql_unix_port;
+# 442 "mysql.h"
+extern MYSQL_RES * mysql_use_result(MYSQL * mysql);
+# 415 "mysql.h"
+extern unsigned int mysql_warning_count(MYSQL * mysql);
+# 343 "mysql_com.h"
+extern void net_clear(NET * net);
+# 342 "mysql_com.h"
+extern void net_end(NET * net);
+# 345 "mysql_com.h"
+extern my_bool net_flush(NET * net);
+# 350 "mysql_com.h"
+extern int net_real_write(NET * net, char const * packet, unsigned long int);
+# 344 "mysql_com.h"
+extern my_bool net_realloc(NET * net, unsigned long int);
+# 347 "mysql_com.h"
+extern my_bool net_write_command(NET * net, unsigned char, char const * header, unsigned long int, char const * packet, unsigned long int);
+# 431 "mysql_com.h"
+extern char * octet2hex(char * to, char const * str, unsigned int);
+# 412 "mysql_com.h"
+extern void randominit(struct rand_struct *, unsigned long int, unsigned long int);
+# 426 "mysql_com.h"
+extern void scramble(char * to, char const * message, char const * password);
+# 419 "mysql_com.h"
+extern void scramble_323(char * to, char const * message, char const * password);
+# 32 "typelib.h"
+extern TYPELIB sql_protocol_typelib;
diff --git a/mysql-test/extra/rpl_tests/rpl_flsh_tbls.test b/mysql-test/extra/rpl_tests/rpl_flsh_tbls.test
index 7a097fd1eae..ee6b0ed1426 100644
--- a/mysql-test/extra/rpl_tests/rpl_flsh_tbls.test
+++ b/mysql-test/extra/rpl_tests/rpl_flsh_tbls.test
@@ -7,6 +7,8 @@
-- source include/master-slave.inc
+let $SERVER_VERSION=`select version()`;
+
create table t1 (a int);
insert into t1 values (10);
create table t2 (a int);
diff --git a/mysql-test/extra/rpl_tests/rpl_truncate_helper.test b/mysql-test/extra/rpl_tests/rpl_truncate_helper.test
index 1e485baca36..7f1506c4010 100644
--- a/mysql-test/extra/rpl_tests/rpl_truncate_helper.test
+++ b/mysql-test/extra/rpl_tests/rpl_truncate_helper.test
@@ -36,6 +36,7 @@ SELECT * FROM t1;
--echo **** On Master ****
connection master;
DROP TABLE t1;
+let $SERVER_VERSION=`select version()`;
--replace_result $SERVER_VERSION SERVER_VERSION
--replace_regex /\/\* xid=[0-9]+ \*\//\/* xid= *\// /table_id: [0-9]+/table_id: #/
SHOW BINLOG EVENTS;
diff --git a/mysql-test/include/analyze_failure_sync_with_master.test b/mysql-test/include/analyze_failure_sync_with_master.test
new file mode 100644
index 00000000000..e6fd32d2f46
--- /dev/null
+++ b/mysql-test/include/analyze_failure_sync_with_master.test
@@ -0,0 +1,15 @@
+# Connect to both master and slave
+connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,);
+connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,);
+
+vertical_results;
+
+echo == MASTER ===========================================================;
+connection master;
+show master status;
+show slave status;
+
+echo == SLAVE ===========================================================;
+connection slave;
+show master status;
+show slave status;
diff --git a/mysql-test/include/ctype_like_escape.inc b/mysql-test/include/ctype_like_escape.inc
index ac97fbaa1a0..d4abc33c178 100644
--- a/mysql-test/include/ctype_like_escape.inc
+++ b/mysql-test/include/ctype_like_escape.inc
@@ -11,8 +11,8 @@ insert into t1 values('ab_def');
insert into t1 values('abc_ef');
insert into t1 values('abcd_f');
insert into t1 values('abcde_');
--- should return ab_def
+# should return ab_def
select c1 as c1u from t1 where c1 like 'ab\_def';
--- should return ab_def
+# should return ab_def
select c1 as c2h from t1 where c1 like 'ab#_def' escape '#';
drop table t1;
diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc
index 57070d40c5c..7fe369cfb1e 100644
--- a/mysql-test/include/mix1.inc
+++ b/mysql-test/include/mix1.inc
@@ -31,13 +31,6 @@ eval SET SESSION STORAGE_ENGINE = $engine_type;
drop table if exists t1,t2,t1m,t1i,t2m,t2i,t4;
--enable_warnings
-#
-# Bug#17530: Incorrect key truncation on table creation caused server crash.
-#
-create table t1(f1 varchar(800) binary not null, key(f1))
- character set utf8 collate utf8_general_ci;
-insert into t1 values('aaa');
-drop table t1;
# BUG#16798: Uninitialized row buffer reads in ref-or-null optimizer
# (repeatable only w/innodb).
@@ -154,6 +147,31 @@ SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` =
DROP TABLE t1, t2;
#
+# Bug #22728 - Handler_rollback value is growing
+#
+
+let $before= `show /*!50002 GLOBAL */ status like 'Handler_rollback'`;
+create table t1 (c1 int) engine=innodb;
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+connection con2;
+handler t1 open;
+handler t1 read first;
+disconnect con2;
+connection con1;
+let $after= `show /*!50002 GLOBAL */ status like 'Handler_rollback'`;
+# Compare the before and after value, it should be equal
+--disable_query_log
+eval select STRCMP("$before", "$after") as "Before and after comparison";
+--enable_query_log
+connection default;
+drop table t1;
+disconnect con1;
+
+--echo End of 4.1 tests
+
+
+#
# Bug #12882 min/max inconsistent on empty table
#
@@ -259,6 +277,36 @@ select distinct a1 from t4 where pk_col not in (1,2,3,4);
drop table t1,t4;
+
+#
+# BUG#18819: DELETE IGNORE hangs on foreign key parent delete
+#
+# The bug itself does not relate to InnoDB, but we have to use foreign
+# keys to reproduce it.
+#
+--disable_warnings
+DROP TABLE IF EXISTS t2, t1;
+--enable_warnings
+
+CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE= InnoDB;
+CREATE TABLE t2 (
+ i INT NOT NULL,
+ FOREIGN KEY (i) REFERENCES t1 (i) ON DELETE NO ACTION
+) ENGINE= InnoDB;
+
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+
+DELETE IGNORE FROM t1 WHERE i = 1;
+
+SELECT * FROM t1, t2;
+
+DROP TABLE t2, t1;
+
+
+--echo End of 4.1 tests.
+
+
#
# Bug #6142: a problem with the empty innodb table
# (was part of group_min_max.test)
@@ -395,6 +443,28 @@ create table t1(f1 varchar(800) binary not null, key(f1))
insert into t1 values('aaa');
drop table t1;
+
+#
+# Bug#22781: SQL_BIG_RESULT fails to influence sort plan
+#
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c FLOAT, KEY b(b)) ENGINE = INNODB;
+
+INSERT INTO t1 VALUES ( 1 , 1 , 1);
+INSERT INTO t1 SELECT a + 1 , MOD(a + 1 , 20), 1 FROM t1;
+INSERT INTO t1 SELECT a + 2 , MOD(a + 2 , 20), 1 FROM t1;
+INSERT INTO t1 SELECT a + 4 , MOD(a + 4 , 20), 1 FROM t1;
+INSERT INTO t1 SELECT a + 8 , MOD(a + 8 , 20), 1 FROM t1;
+INSERT INTO t1 SELECT a + 16, MOD(a + 16, 20), 1 FROM t1;
+INSERT INTO t1 SELECT a + 32, MOD(a + 32, 20), 1 FROM t1;
+INSERT INTO t1 SELECT a + 64, MOD(a + 64, 20), 1 FROM t1;
+
+EXPLAIN SELECT b, SUM(c) FROM t1 GROUP BY b;
+EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b;
+DROP TABLE t1;
+
+--echo End of 5.0 tests
+
+
# Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY
# UPDATE": if the row is updated, it's like a regular UPDATE:
# LAST_INSERT_ID() is not affected.
@@ -446,3 +516,5 @@ select last_insert_id();
select * from t2;
drop table t2;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/include/mysqltest_while.inc b/mysql-test/include/mysqltest_while.inc
deleted file mode 100644
index 90b05ee2695..00000000000
--- a/mysql-test/include/mysqltest_while.inc
+++ /dev/null
@@ -1,137 +0,0 @@
-let $1 = 10;
-while ($1)
-{
-while ($1)
-{
-while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- while ($1)
-{
- echo $1;
- dec $1;
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
-}
diff --git a/mysql-test/include/parser_bug21114.inc b/mysql-test/include/parser_bug21114.inc
new file mode 100755
index 00000000000..eb709d5cc03
--- /dev/null
+++ b/mysql-test/include/parser_bug21114.inc
@@ -0,0 +1,59 @@
+#
+# Bug#21114 (Foreign key creation fails to table with name format)
+#
+# Trying to trick the parser into thinking $FCT(...) is a function call,
+# which is not in the CREATE TABLE and FOREIGN KEY ... REFERENCES syntax
+#
+# Usage :
+#
+# let $engine_type=InnoDb;
+# let $verbose=1;
+# let $FCT= <value_1>;
+# -- source parser_stress_func.inc
+# let $FCT= <value_2>;
+# -- source parser_stress_func.inc
+# let $verbose=0;
+# let $FCT= <value_3>;
+# -- source parser_stress_func.inc
+# let $FCT= <value_4>;
+# -- source parser_stress_func.inc
+
+-- disable_warnings
+eval drop table if exists $FCT;
+drop table if exists bug21114_child;
+-- enable_warnings
+
+--disable_query_log
+--disable_result_log
+
+eval CREATE TABLE $FCT(
+ col1 int not null,
+ col2 int not null,
+ col3 varchar(10),
+ CONSTRAINT pk PRIMARY KEY (col1, col2)
+) ENGINE $engine_type;
+
+eval CREATE TABLE bug21114_child(
+ pk int not null,
+ fk_col1 int not null,
+ fk_col2 int not null,
+ fk_col3 int not null,
+ fk_col4 int not null,
+ CONSTRAINT fk_fct FOREIGN KEY (fk_col1, fk_col2)
+ REFERENCES $FCT(col1, col2),
+ CONSTRAINT fk_fct_space FOREIGN KEY (fk_col3, fk_col4)
+ REFERENCES $FCT (col1, col2)
+) ENGINE $engine_type;
+
+--enable_query_log
+--enable_result_log
+
+if ($verbose)
+{
+ eval SHOW CREATE TABLE $FCT;
+ SHOW CREATE TABLE bug21114_child;
+}
+
+DROP TABLE bug21114_child;
+eval DROP TABLE $FCT;
+
diff --git a/mysql-test/include/sourced.inc b/mysql-test/include/sourced.inc
deleted file mode 100644
index be1a270641a..00000000000
--- a/mysql-test/include/sourced.inc
+++ /dev/null
@@ -1 +0,0 @@
-echo here is the sourced script;
diff --git a/mysql-test/include/sourced1.inc b/mysql-test/include/sourced1.inc
deleted file mode 100644
index 920561e5de2..00000000000
--- a/mysql-test/include/sourced1.inc
+++ /dev/null
@@ -1 +0,0 @@
---source include/sourced.inc
diff --git a/mysql-test/include/sp-vars.inc b/mysql-test/include/sp-vars.inc
index 3e02c9d1709..4bac883ee0e 100644
--- a/mysql-test/include/sp-vars.inc
+++ b/mysql-test/include/sp-vars.inc
@@ -119,4 +119,13 @@ END|
---------------------------------------------------------------------------
+CREATE FUNCTION sp_vars_div_zero() RETURNS INTEGER
+BEGIN
+ DECLARE div_zero INTEGER;
+ SELECT 1/0 INTO div_zero;
+ RETURN div_zero;
+END|
+
+---------------------------------------------------------------------------
+
delimiter ;|
diff --git a/mysql-test/include/wait_for_query_to_suceed.inc b/mysql-test/include/wait_for_query_to_suceed.inc
new file mode 100644
index 00000000000..6ac1144620e
--- /dev/null
+++ b/mysql-test/include/wait_for_query_to_suceed.inc
@@ -0,0 +1,25 @@
+#
+# Run a query over and over until it suceeds ot timeout occurs
+#
+
+
+let $counter= 100;
+
+disable_abort_on_error;
+disable_query_log;
+disable_result_log;
+eval $query;
+while ($mysql_errno)
+{
+ eval $query;
+ sleep 0.1;
+ dec $counter;
+
+ if (!$counter)
+ {
+ die("Waited too long for query to suceed");
+ }
+}
+enable_abort_on_error;
+enable_query_log;
+enable_result_log;
diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl
index bb92730444c..d270d72d526 100644
--- a/mysql-test/lib/mtr_cases.pl
+++ b/mysql-test/lib/mtr_cases.pl
@@ -59,7 +59,9 @@ sub collect_test_cases ($) {
if ( @::opt_cases )
{
- foreach my $tname ( @::opt_cases ) { # Run in specified order, no sort
+ foreach my $tname ( @::opt_cases )
+ {
+ # Run in specified order, no sort
my $elem= undef;
my $component_id= undef;
@@ -85,7 +87,7 @@ sub collect_test_cases ($) {
# If target component is known, check that the specified test case
# exists.
- #
+ #
# Otherwise, try to guess the target component.
if ( $component_id )
@@ -127,7 +129,8 @@ sub collect_test_cases ($) {
}
else
{
- foreach my $elem ( sort readdir(TESTDIR) ) {
+ foreach my $elem ( sort readdir(TESTDIR) )
+ {
my $component_id= undef;
my $tname= undef;
@@ -143,8 +146,10 @@ sub collect_test_cases ($) {
{
next;
}
-
- next if $::opt_do_test and ! defined mtr_match_prefix($elem,$::opt_do_test);
+
+ # Skip tests that does not match the --do-test= filter
+ next if $::opt_do_test and
+ ! defined mtr_match_prefix($elem,$::opt_do_test);
collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,\%disabled,
$component_id);
@@ -152,43 +157,79 @@ sub collect_test_cases ($) {
closedir TESTDIR;
}
- # To speed things up, we sort first in if the test require a restart
- # or not, second in alphanumeric order.
-
+ # Reorder the test cases in an order that will make them faster to run
if ( $::opt_reorder )
{
my %sort_criteria;
- my $tinfo;
# Make a mapping of test name to a string that represents how that test
# should be sorted among the other tests. Put the most important criterion
# first, then a sub-criterion, then sub-sub-criterion, et c.
- foreach $tinfo (@$cases)
+ foreach my $tinfo (@$cases)
{
- my @this_criteria = ();
-
- # Append the criteria for sorting, in order of importance.
- push(@this_criteria, join("!", sort @{$tinfo->{'master_opt'}}) . "~"); # Ending with "~" makes empty sort later than filled
- push(@this_criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "1" : "0"));
- push(@this_criteria, "restart=" . ($tinfo->{'master_restart'} ? "1" : "0"));
- push(@this_criteria, "big_test=" . ($tinfo->{'big_test'} ? "1" : "0"));
- push(@this_criteria, join("|", sort keys %{$tinfo})); # Group similar things together. The values may differ substantially. FIXME?
- push(@this_criteria, $tinfo->{'name'}); # Finally, order by the name
-
- $sort_criteria{$tinfo->{"name"}} = join(" ", @this_criteria);
+ my @criteria = ();
+
+ # Look for tests that muct be in run in a defined order
+ # that is defined by test having the same name except for
+ # the ending digit
+
+ # Put variables into hash
+ my $test_name= $tinfo->{'name'};
+ my $depend_on_test_name;
+ if ( $test_name =~ /^([\D]+)([0-9]{1})$/ )
+ {
+ my $base_name= $1;
+ my $idx= $2;
+ mtr_verbose("$test_name => $base_name idx=$idx");
+ if ( $idx > 1 )
+ {
+ $idx-= 1;
+ $base_name= "$base_name$idx";
+ mtr_verbose("New basename $base_name");
+ }
+
+ foreach my $tinfo2 (@$cases)
+ {
+ if ( $tinfo2->{'name'} eq $base_name )
+ {
+ mtr_verbose("found dependent test $tinfo2->{'name'}");
+ $depend_on_test_name=$base_name;
+ }
+ }
+ }
+
+ if ( defined $depend_on_test_name )
+ {
+ mtr_verbose("Giving $test_name same critera as $depend_on_test_name");
+ $sort_criteria{$test_name} = $sort_criteria{$depend_on_test_name};
+ }
+ else
+ {
+ #
+ # Append the criteria for sorting, in order of importance.
+ #
+ push(@criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "1" : "0"));
+ # Group test with equal options together.
+ # Ending with "~" makes empty sort later than filled
+ push(@criteria, join("!", sort @{$tinfo->{'master_opt'}}) . "~");
+
+ $sort_criteria{$test_name} = join(" ", @criteria);
+ }
}
- @$cases = sort { $sort_criteria{$a->{"name"}} cmp $sort_criteria{$b->{"name"}}; } @$cases;
+ @$cases = sort {
+ $sort_criteria{$a->{'name'}} . $a->{'name'} cmp
+ $sort_criteria{$b->{'name'}} . $b->{'name'}; } @$cases;
-### For debugging the sort-order
-# foreach $tinfo (@$cases)
-# {
-# print $sort_criteria{$tinfo->{"name"}};
-# print " -> \t";
-# print $tinfo->{"name"};
-# print "\n";
-# }
+ if ( $::opt_script_debug )
+ {
+ # For debugging the sort-order
+ foreach my $tinfo (@$cases)
+ {
+ print("$sort_criteria{$tinfo->{'name'}} -> \t$tinfo->{'name'}\n");
+ }
+ }
}
return $cases;
@@ -222,9 +263,6 @@ sub collect_one_test_case($$$$$$$) {
return;
}
- # ----------------------------------------------------------------------
- # Skip some tests but include in list, just mark them to skip
- # ----------------------------------------------------------------------
my $tinfo= {};
$tinfo->{'name'}= $tname;
@@ -232,6 +270,10 @@ sub collect_one_test_case($$$$$$$) {
$tinfo->{'component_id'} = $component_id;
push(@$cases, $tinfo);
+ # ----------------------------------------------------------------------
+ # Skip some tests but include in list, just mark them to skip
+ # ----------------------------------------------------------------------
+
if ( $::opt_skip_test and defined mtr_match_prefix($tname,$::opt_skip_test) )
{
$tinfo->{'skip'}= 1;
@@ -245,6 +287,7 @@ sub collect_one_test_case($$$$$$$) {
$tinfo->{'path'}= $path;
$tinfo->{'timezone'}= "GMT-3"; # for UNIX_TIMESTAMP tests to work
+ $tinfo->{'slave_num'}= 0; # Default, no slave
if ( defined mtr_match_prefix($tname,"rpl") )
{
if ( $::opt_skip_rpl )
@@ -254,7 +297,8 @@ sub collect_one_test_case($$$$$$$) {
return;
}
- $tinfo->{'slave_num'}= 1; # Default, use one slave
+
+ $tinfo->{'slave_num'}= 1; # Default for rpl* tests, use one slave
if ( $tname eq 'rpl_failsafe' or $tname eq 'rpl_chain_temp_table' )
{
@@ -268,40 +312,6 @@ sub collect_one_test_case($$$$$$$) {
$tinfo->{'slave_num'}= 1;
}
- if ( $::opt_with_ndbcluster or defined mtr_match_substring($tname,"ndb") )
- {
- # This is an ndb test or all tests should be run with ndb cluster started
- $tinfo->{'ndb_test'}= 1;
- if ( $::opt_skip_ndbcluster )
- {
- # All ndb test's should be skipped
- $tinfo->{'skip'}= 1;
- $tinfo->{'comment'}= "No ndbcluster test(--skip-ndbcluster)";
- return;
- }
- if ( ! $::opt_ndbcluster_supported )
- {
- # Ndb is not supported, skip them
- $tinfo->{'skip'}= 1;
- $tinfo->{'comment'}= "No ndbcluster support";
- return;
- }
- }
- else
- {
- # This is not a ndb test
- $tinfo->{'ndb_test'}= 0;
- if ( $::opt_with_ndbcluster_only )
- {
- # Only the ndb test should be run, all other should be skipped
- $tinfo->{'skip'}= 1;
- $tinfo->{'comment'}= "Only ndbcluster tests(--with-ndbcluster-only)";
- return;
- }
- }
-
- # FIXME what about embedded_server + ndbcluster, skip ?!
-
my $master_opt_file= "$testdir/$tname-master.opt";
my $slave_opt_file= "$testdir/$tname-slave.opt";
my $slave_mi_file= "$testdir/$tname.slave-mi";
@@ -316,57 +326,59 @@ sub collect_one_test_case($$$$$$$) {
if ( -f $master_opt_file )
{
- $tinfo->{'master_restart'}= 1; # We think so for now
- MASTER_OPT:
- {
- my $master_opt= mtr_get_opts_from_file($master_opt_file);
+ my $master_opt= mtr_get_opts_from_file($master_opt_file);
- foreach my $opt ( @$master_opt )
- {
- my $value;
+ foreach my $opt ( @$master_opt )
+ {
+ my $value;
- # This is a dirty hack from old mysql-test-run, we use the opt
- # file to flag other things as well, it is not a opt list at
- # all
+ # The opt file is used both to send special options to the mysqld
+ # as well as pass special test case specific options to this
+ # script
- $value= mtr_match_prefix($opt, "--timezone=");
- if ( defined $value )
- {
- $tinfo->{'timezone'}= $value;
- last MASTER_OPT;
- }
+ $value= mtr_match_prefix($opt, "--timezone=");
+ if ( defined $value )
+ {
+ $tinfo->{'timezone'}= $value;
+ next;
+ }
- $value= mtr_match_prefix($opt, "--result-file=");
- if ( defined $value )
- {
- $tinfo->{'result_file'}= "r/$value.result";
- if ( $::opt_result_ext and $::opt_record or
- -f "$tinfo->{'result_file'}$::opt_result_ext")
- {
- $tinfo->{'result_file'}.= $::opt_result_ext;
- }
- $tinfo->{'master_restart'}= 0;
- last MASTER_OPT;
- }
+ $value= mtr_match_prefix($opt, "--result-file=");
+ if ( defined $value )
+ {
+ # Specifies the file mysqltest should compare
+ # output against
+ $tinfo->{'result_file'}= "r/$value.result";
+ next;
+ }
- # If we set default time zone, remove the one we have
- $value= mtr_match_prefix($opt, "--default-time-zone=");
- if ( defined $value )
- {
- $tinfo->{'master_opt'}= [];
- }
+ # If we set default time zone, remove the one we have
+ $value= mtr_match_prefix($opt, "--default-time-zone=");
+ if ( defined $value )
+ {
+ # Set timezone for this test case to something different
+ $tinfo->{'timezone'}= "GMT-8";
+ # Fallthrough, add the --default-time-zone option
+ }
+ # The --restart option forces a restart even if no special
+ # option is set. If the options are the same as next testcase
+ # there is no need to restart after the testcase
+ # has completed
+ if ( $opt eq "--force-restart" )
+ {
+ $tinfo->{'force_restart'}= 1;
+ next;
}
- # Ok, this was a real option list, add it
- push(@{$tinfo->{'master_opt'}}, @$master_opt);
+ # Ok, this was a real option, add it
+ push(@{$tinfo->{'master_opt'}}, $opt);
}
}
if ( -f $slave_opt_file )
{
- $tinfo->{'slave_restart'}= 1;
my $slave_opt= mtr_get_opts_from_file($slave_opt_file);
foreach my $opt ( @$slave_opt )
@@ -381,7 +393,6 @@ sub collect_one_test_case($$$$$$$) {
if ( -f $slave_mi_file )
{
$tinfo->{'slave_mi'}= mtr_get_opts_from_file($slave_mi_file);
- $tinfo->{'slave_restart'}= 1;
}
if ( -f $master_sh )
@@ -395,7 +406,6 @@ sub collect_one_test_case($$$$$$$) {
else
{
$tinfo->{'master_sh'}= $master_sh;
- $tinfo->{'master_restart'}= 1;
}
}
@@ -410,7 +420,6 @@ sub collect_one_test_case($$$$$$$) {
else
{
$tinfo->{'slave_sh'}= $slave_sh;
- $tinfo->{'slave_restart'}= 1;
}
}
@@ -514,18 +523,50 @@ sub collect_one_test_case($$$$$$$) {
$tinfo->{'comment'}= "Test need debug binaries";
return;
}
- }
- # We can't restart a running server that may be in use
+ if ( $tinfo->{'ndb_test'} )
+ {
+ # This is a NDB test
+ if ( ! $::glob_ndbcluster_supported )
+ {
+ # Ndb is not supported, skip it
+ $tinfo->{'skip'}= 1;
+ $tinfo->{'comment'}= "No ndbcluster support";
+ return;
+ }
+ elsif ( $::opt_skip_ndbcluster )
+ {
+ # All ndb test's should be skipped
+ $tinfo->{'skip'}= 1;
+ $tinfo->{'comment'}= "No ndbcluster tests(--skip-ndbcluster)";
+ return;
+ }
+ }
+ else
+ {
+ # This is not a ndb test
+ if ( $::opt_with_ndbcluster_only )
+ {
+ # Only the ndb test should be run, all other should be skipped
+ $tinfo->{'skip'}= 1;
+ $tinfo->{'comment'}= "Only ndbcluster tests(--with-ndbcluster-only)";
+ return;
+ }
+ }
+
+ if ( $tinfo->{'innodb_test'} )
+ {
+ # This is a test that need inndob
+ if ( $::mysqld_variables{'innodb'} eq "FALSE" )
+ {
+ # innodb is not supported, skip it
+ $tinfo->{'skip'}= 1;
+ $tinfo->{'comment'}= "No innodb support";
+ return;
+ }
+ }
- if ( $::glob_use_running_server and
- ( $tinfo->{'master_restart'} or $tinfo->{'slave_restart'} ) )
- {
- $tinfo->{'skip'}= 1;
- $tinfo->{'comment'}= "Can't restart a running server";
- return;
}
-
}
@@ -536,8 +577,10 @@ our @tags=
["include/have_innodb.inc", "innodb_test", 1],
["include/have_binlog_format_row.inc", "binlog_format", "row"],
["include/have_binlog_format_statement.inc", "binlog_format", "stmt"],
+ ["include/have_binlog_format_mixed.inc", "binlog_format", "mixed"],
["include/big_test.inc", "big_test", 1],
["include/have_debug.inc", "need_debug", 1],
+ ["include/have_ndb.inc", "ndb_test", 1],
["include/have_ndb_extra.inc", "ndb_extra", 1],
["require_manager", "require_manager", 1],
);
@@ -550,8 +593,6 @@ sub mtr_options_from_test_file($$) {
while ( my $line= <$F> )
{
- next if ( $line !~ /^--/ );
-
# Match this line against tag in "tags" array
foreach my $tag (@tags)
{
@@ -563,14 +604,21 @@ sub mtr_options_from_test_file($$) {
}
# If test sources another file, open it as well
- if ( $line =~ /^\-\-([[:space:]]*)source(.*)$/ )
+ if ( $line =~ /^\-\-([[:space:]]*)source(.*)$/ or
+ $line =~ /^([[:space:]]*)source(.*);$/ )
{
my $value= $2;
$value =~ s/^\s+//; # Remove leading space
$value =~ s/[[:space:]]+$//; # Remove ending space
my $sourced_file= "$::glob_mysql_test_dir/$value";
- mtr_options_from_test_file($tinfo, $sourced_file);
+ if ( -f $sourced_file )
+ {
+ # Only source the file if it exists, we may get
+ # false positives in the regexes above if someone
+ # writes "source nnnn;" in a test case(such as mysqltest.test)
+ mtr_options_from_test_file($tinfo, $sourced_file);
+ }
}
}
diff --git a/mysql-test/lib/mtr_gcov.pl b/mysql-test/lib/mtr_gcov.pl
index 07aac1d2017..71d3d6a2a43 100644
--- a/mysql-test/lib/mtr_gcov.pl
+++ b/mysql-test/lib/mtr_gcov.pl
@@ -23,12 +23,28 @@ sub gcov_prepare () {
-or -name \*.da | xargs rm`;
}
+# Used by gcov
+our @mysqld_src_dirs=
+ (
+ "strings",
+ "mysys",
+ "include",
+ "extra",
+ "regex",
+ "isam",
+ "merge",
+ "myisam",
+ "myisammrg",
+ "heap",
+ "sql",
+ );
+
sub gcov_collect () {
print "Collecting source coverage info...\n";
-f $::opt_gcov_msg and unlink($::opt_gcov_msg);
-f $::opt_gcov_err and unlink($::opt_gcov_err);
- foreach my $d ( @::mysqld_src_dirs )
+ foreach my $d ( @mysqld_src_dirs )
{
chdir("$::glob_basedir/$d");
foreach my $f ( (glob("*.h"), glob("*.cc"), glob("*.c")) )
diff --git a/mysql-test/lib/mtr_io.pl b/mysql-test/lib/mtr_io.pl
index e8dcb0262c9..984d834486c 100644
--- a/mysql-test/lib/mtr_io.pl
+++ b/mysql-test/lib/mtr_io.pl
@@ -12,6 +12,7 @@ sub mtr_fromfile ($);
sub mtr_tofile ($@);
sub mtr_tonewfile($@);
sub mtr_lastlinefromfile($);
+sub mtr_appendfile_to_file ($$);
##############################################################################
#
@@ -36,18 +37,16 @@ sub mtr_get_pid_from_file ($) {
open(FILE, '<', $pid_file_path)
or mtr_error("can't open file \"$pid_file_path\": $!");
+ # Read pid number from file
my $pid= <FILE>;
-
- chomp($pid) if defined $pid;
-
close FILE;
- return $pid if defined $pid && $pid ne '';
+ return $pid if $pid=~ /^(\d+)/;
- mtr_debug("Pid file '$pid_file_path' is empty. " .
- "Sleeping $timeout second(s)...");
+ mtr_debug("Pid file '$pid_file_path' does not yet contain pid number.\n" .
+ "Sleeping $timeout second(s) more...");
- sleep(1);
+ sleep($timeout);
}
mtr_error("Pid file '$pid_file_path' is corrupted. " .
@@ -170,4 +169,17 @@ sub mtr_tonewfile ($@) {
close FILE;
}
+sub mtr_appendfile_to_file ($$) {
+ my $from_file= shift;
+ my $to_file= shift;
+
+ open(TOFILE,">>",$to_file) or mtr_error("can't open file \"$to_file\": $!");
+ open(FROMFILE,"<",$from_file)
+ or mtr_error("can't open file \"$from_file\": $!");
+ print TOFILE while (<FROMFILE>);
+ close FROMFILE;
+ close TOFILE;
+}
+
+
1;
diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl
index dd9d24ebc8e..846ca25b725 100644
--- a/mysql-test/lib/mtr_misc.pl
+++ b/mysql-test/lib/mtr_misc.pl
@@ -14,6 +14,7 @@ sub mtr_path_exists(@);
sub mtr_script_exists(@);
sub mtr_file_exists(@);
sub mtr_exe_exists(@);
+sub mtr_exe_maybe_exists(@);
sub mtr_copy_dir($$);
sub mtr_same_opts($$);
sub mtr_cmp_opts($$);
@@ -65,6 +66,10 @@ sub mtr_add_arg ($$@) {
##############################################################################
+#
+# NOTE! More specific paths should be given before less specific.
+# For example /client/debug should be listed before /client
+#
sub mtr_path_exists (@) {
foreach my $path ( @_ )
{
@@ -80,6 +85,11 @@ sub mtr_path_exists (@) {
}
}
+
+#
+# NOTE! More specific paths should be given before less specific.
+# For example /client/debug should be listed before /client
+#
sub mtr_script_exists (@) {
foreach my $path ( @_ )
{
@@ -102,6 +112,11 @@ sub mtr_script_exists (@) {
}
}
+
+#
+# NOTE! More specific paths should be given before less specific.
+# For example /client/debug should be listed before /client
+#
sub mtr_file_exists (@) {
foreach my $path ( @_ )
{
@@ -110,8 +125,14 @@ sub mtr_file_exists (@) {
return "";
}
-sub mtr_exe_exists (@) {
+
+#
+# NOTE! More specific paths should be given before less specific.
+# For example /client/debug should be listed before /client
+#
+sub mtr_exe_maybe_exists (@) {
my @path= @_;
+
map {$_.= ".exe"} @path if $::glob_win32;
foreach my $path ( @path )
{
@@ -124,6 +145,21 @@ sub mtr_exe_exists (@) {
return $path if -x $path;
}
}
+ return "";
+}
+
+
+#
+# NOTE! More specific paths should be given before less specific.
+# For example /client/debug should be listed before /client
+#
+sub mtr_exe_exists (@) {
+ my @path= @_;
+ if (my $path= mtr_exe_maybe_exists(@path))
+ {
+ return $path;
+ }
+ # Could not find exe, show error
if ( @path == 1 )
{
mtr_error("Could not find $path[0]");
@@ -139,7 +175,7 @@ sub mtr_copy_dir($$) {
my $from_dir= shift;
my $to_dir= shift;
-# mtr_verbose("Copying from $from_dir to $to_dir");
+ # mtr_verbose("Copying from $from_dir to $to_dir");
mkpath("$to_dir");
opendir(DIR, "$from_dir")
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index 868b6d4f1ec..9d0c1f601ba 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -4,12 +4,10 @@
# and is part of the translation of the Bourne shell script with the
# same name.
-#use Carp qw(cluck);
use Socket;
use Errno;
use strict;
-#use POSIX ":sys_wait_h";
use POSIX 'WNOHANG';
sub mtr_run ($$$$$$;$);
@@ -93,8 +91,6 @@ sub spawn_impl ($$$$$$$$) {
my $pid_file= shift; # FIXME
my $spawn_opts= shift;
- mtr_error("Can't spawn with empty \"path\"") unless defined $path;
-
if ( $::opt_script_debug )
{
print STDERR "\n";
@@ -118,6 +114,9 @@ sub spawn_impl ($$$$$$$$) {
print STDERR "#### ", "-" x 78, "\n";
}
+ mtr_error("Can't spawn with empty \"path\"") unless defined $path;
+
+
FORK:
{
my $pid= fork();
@@ -339,19 +338,6 @@ sub mtr_kill_leftovers () {
mtr_report("Killing Possible Leftover Processes");
mtr_debug("mtr_kill_leftovers(): started.");
- mkpath("$::opt_vardir/log"); # Needed for mysqladmin log
-
- # Stop or kill Instance Manager and all its children. If we failed to do
- # that, we can only abort -- there is nothing left to do.
-
- mtr_error("Failed to stop Instance Manager.")
- unless mtr_im_stop($::instance_manager);
-
- # Start shutdown of masters and slaves. Don't touch IM-managed mysqld
- # instances -- they should be stopped by mtr_im_stop().
-
- mtr_debug("Shutting down mysqld-instances...");
-
my @kill_pids;
my %admin_pids;
@@ -377,40 +363,41 @@ sub mtr_kill_leftovers () {
$srv->{'pid'}= 0; # Assume we are done with it
}
- # Start shutdown of clusters.
-
- mtr_debug("Shutting down cluster...");
-
- foreach my $cluster (@{$::clusters})
+ if ( ! $::opt_skip_ndbcluster )
{
- mtr_debug(" - cluster " .
- "(pid: $cluster->{pid}; " .
- "pid file: '$cluster->{path_pid})");
-
- my $pid= mtr_ndbmgm_start($cluster, "shutdown");
-
- # Save the pid of the ndb_mgm process
- $admin_pids{$pid}= 1;
-
- push(@kill_pids,{
- pid => $cluster->{'pid'},
- pidfile => $cluster->{'path_pid'}
- });
+ # Start shutdown of clusters.
+ mtr_debug("Shutting down cluster...");
- $cluster->{'pid'}= 0; # Assume we are done with it
+ foreach my $cluster (@{$::clusters})
+ {
+ mtr_debug(" - cluster " .
+ "(pid: $cluster->{pid}; " .
+ "pid file: '$cluster->{path_pid})");
+ my $pid= mtr_ndbmgm_start($cluster, "shutdown");
- foreach my $ndbd (@{$cluster->{'ndbds'}})
- {
- mtr_debug(" - ndbd " .
- "(pid: $ndbd->{pid}; " .
- "pid file: '$ndbd->{path_pid})");
+ # Save the pid of the ndb_mgm process
+ $admin_pids{$pid}= 1;
push(@kill_pids,{
- pid => $ndbd->{'pid'},
- pidfile => $ndbd->{'path_pid'},
+ pid => $cluster->{'pid'},
+ pidfile => $cluster->{'path_pid'}
});
- $ndbd->{'pid'}= 0; # Assume we are done with it
+
+ $cluster->{'pid'}= 0; # Assume we are done with it
+
+ foreach my $ndbd (@{$cluster->{'ndbds'}})
+ {
+ mtr_debug(" - ndbd " .
+ "(pid: $ndbd->{pid}; " .
+ "pid file: '$ndbd->{path_pid})");
+
+ push(@kill_pids,{
+ pid => $ndbd->{'pid'},
+ pidfile => $ndbd->{'path_pid'},
+ });
+ $ndbd->{'pid'}= 0; # Assume we are done with it
+ }
}
}
@@ -451,25 +438,35 @@ sub mtr_kill_leftovers () {
while ( my $elem= readdir(RUNDIR) )
{
- my $pidfile= "$rundir/$elem";
-
- if ( -f $pidfile )
+ # Only read pid from files that end with .pid
+ if ( $elem =~ /.*[.]pid$/)
{
- mtr_debug("Processing PID file: '$pidfile'...");
+ my $pidfile= "$rundir/$elem";
- my $pid= mtr_get_pid_from_file($pidfile);
+ if ( -f $pidfile )
+ {
+ mtr_debug("Processing PID file: '$pidfile'...");
- mtr_debug("Got pid: $pid from file '$pidfile'");
+ my $pid= mtr_get_pid_from_file($pidfile);
- if ( $::glob_cygwin_perl or kill(0, $pid) )
- {
- mtr_debug("There is process with pid $pid -- scheduling for kill.");
- push(@pids, $pid); # We know (cygwin guess) it exists
- }
- else
- {
- mtr_debug("There is no process with pid $pid -- skipping.");
- }
+ mtr_debug("Got pid: $pid from file '$pidfile'");
+
+ if ( $::glob_cygwin_perl or kill(0, $pid) )
+ {
+ mtr_debug("There is process with pid $pid -- scheduling for kill.");
+ push(@pids, $pid); # We know (cygwin guess) it exists
+ }
+ else
+ {
+ mtr_debug("There is no process with pid $pid -- skipping.");
+ }
+ }
+ }
+ else
+ {
+ mtr_warning("Found non pid file $elem in $rundir")
+ if -f "$rundir/$elem";
+ next;
}
}
closedir(RUNDIR);
@@ -1100,7 +1097,6 @@ sub mtr_kill_processes ($) {
sub mtr_exit ($) {
my $code= shift;
-# cluck("Called mtr_exit()");
mtr_timer_stop_all($::glob_timers);
local $SIG{HUP} = 'IGNORE';
# ToDo: Signalling -$$ will only work if we are the process group
diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl
index 6e3796133f2..8d7de9d1a4b 100644
--- a/mysql-test/lib/mtr_report.pl
+++ b/mysql-test/lib/mtr_report.pl
@@ -53,13 +53,6 @@ sub mtr_show_failed_diff ($) {
{
$result_file= $eval_file;
}
- elsif ( $::opt_result_ext and
- ( $::opt_record or -f "$result_file$::opt_result_ext" ))
- {
- # If we have an special externsion for result files we use it if we are
- # recording or a result file with that extension exists.
- $result_file= "$result_file$::opt_result_ext";
- }
my $diffopts= $::opt_udiff ? "-u" : "-c";
@@ -137,13 +130,9 @@ sub mtr_report_test_failed ($) {
my $tinfo= shift;
$tinfo->{'result'}= 'MTR_RES_FAILED';
- if ( $tinfo->{'timeout'} )
+ if ( defined $tinfo->{'timeout'} )
{
print "[ fail ] timeout\n";
- }
- elsif ( $tinfo->{'ndb_test'} and $::cluster->[0]->{'installed_ok'} eq "NO")
- {
- print "[ fail ] ndbcluster start failure\n";
return;
}
else
@@ -151,9 +140,11 @@ sub mtr_report_test_failed ($) {
print "[ fail ]\n";
}
- # FIXME Instead of this test, and meaningless error message in 'else'
- # we should write out into $::path_timefile when the error occurs.
- if ( -f $::path_timefile )
+ if ( $tinfo->{'comment'} )
+ {
+ print "\nERROR: $tinfo->{'comment'}\n";
+ }
+ elsif ( -f $::path_timefile )
{
print "\nErrors are (from $::path_timefile) :\n";
print mtr_fromfile($::path_timefile); # FIXME print_file() instead
@@ -177,7 +168,7 @@ sub mtr_report_stats ($) {
my $tot_failed= 0;
my $tot_tests= 0;
my $tot_restarts= 0;
- my $found_problems= 0; # Some warnings are errors...
+ my $found_problems= 0; # Some warnings in the logfiles are errors...
foreach my $tinfo (@$tests)
{
@@ -212,8 +203,9 @@ sub mtr_report_stats ($) {
else
{
my $ratio= $tot_passed * 100 / $tot_tests;
- printf "Failed $tot_failed/$tot_tests tests, " .
- "%.2f\% were successful.\n\n", $ratio;
+ print "Failed $tot_failed/$tot_tests tests, ";
+ printf("%.2f", $ratio);
+ print "\% were successful.\n\n";
print
"The log files in var/log may give you some hint\n",
"of what went wrong.\n",
@@ -288,6 +280,7 @@ sub mtr_report_stats ($) {
print "\n";
+ # Print a list of testcases that failed
if ( $tot_failed != 0 )
{
my $test_mode= join(" ", @::glob_test_mode) || "default";
@@ -301,7 +294,30 @@ sub mtr_report_stats ($) {
}
}
print "\n";
+
+ }
+
+ # Print a list of check_testcases that failed(if any)
+ if ( $::opt_check_testcases )
+ {
+ my @check_testcases= ();
+
+ foreach my $tinfo (@$tests)
+ {
+ if ( defined $tinfo->{'check_testcase_failed'} )
+ {
+ push(@check_testcases, $tinfo->{'name'});
+ }
+ }
+
+ if ( @check_testcases )
+ {
+ print "Check of testcase failed for: ";
+ print join(" ", @check_testcases);
+ print "\n\n";
+ }
}
+
if ( $tot_failed != 0 || $found_problems)
{
mtr_error("there where failing test cases");
diff --git a/mysql-test/lib/mtr_stress.pl b/mysql-test/lib/mtr_stress.pl
index a7d4b68b69d..1371eaa44c6 100644
--- a/mysql-test/lib/mtr_stress.pl
+++ b/mysql-test/lib/mtr_stress.pl
@@ -122,7 +122,7 @@ sub run_stress_test ()
mtr_init_args(\$args);
- mtr_add_arg($args, "--server-socket=%s", $::master->[0]->{'path_mysock'});
+ mtr_add_arg($args, "--server-socket=%s", $::master->[0]->{'path_sock'});
mtr_add_arg($args, "--server-user=%s", $::opt_user);
mtr_add_arg($args, "--server-database=%s", "test");
mtr_add_arg($args, "--stress-suite-basedir=%s", $::glob_mysql_test_dir);
@@ -140,7 +140,7 @@ sub run_stress_test ()
if ( $::opt_stress_init_file )
{
- mtr_add_arg($args, "--stress-init-file=%", $::opt_stress_init_file);
+ mtr_add_arg($args, "--stress-init-file=%s", $::opt_stress_init_file);
}
if ( !$::opt_stress_loop_count && !$::opt_stress_test_count &&
@@ -168,10 +168,9 @@ sub run_stress_test ()
#Run stress test
mtr_run("$::glob_mysql_test_dir/mysql-stress-test.pl", $args, "", "", "", "");
-
if ( ! $::glob_use_embedded_server )
{
- stop_masters();
+ stop_all_servers();
}
}
diff --git a/mysql-test/lib/mtr_timer.pl b/mysql-test/lib/mtr_timer.pl
index a85ab8c6122..06374716c62 100644
--- a/mysql-test/lib/mtr_timer.pl
+++ b/mysql-test/lib/mtr_timer.pl
@@ -4,23 +4,19 @@
# and is part of the translation of the Bourne shell script with the
# same name.
-use Carp qw(cluck);
use Socket;
use Errno;
use strict;
-#use POSIX ":sys_wait_h";
-use POSIX 'WNOHANG';
-
sub mtr_init_timers ();
sub mtr_timer_start($$$);
sub mtr_timer_stop($$);
sub mtr_timer_stop_all($);
-sub mtr_timer_waitpid($$$);
+
##############################################################################
#
-# Initiate a structure shared by all timers
+# Initiate the structure shared by all timers
#
##############################################################################
@@ -35,17 +31,19 @@ sub mtr_init_timers () {
# Start, stop and poll a timer
#
# As alarm() isn't portable to Windows, we use separate processes to
-# implement timers. That is why there is a mtr_timer_waitpid(), as this
-# is where we catch a timeout.
+# implement timers.
#
##############################################################################
sub mtr_timer_start($$$) {
my ($timers,$name,$duration)= @_;
+ mtr_verbose("mtr_timer_start: $name, $duration");
+
if ( exists $timers->{'timers'}->{$name} )
{
# We have an old running timer, kill it
+ mtr_verbose("There is an old timer running");
mtr_timer_stop($timers,$name);
}
@@ -57,7 +55,7 @@ sub mtr_timer_start($$$) {
{
if ( $! == $!{EAGAIN} ) # See "perldoc Errno"
{
- mtr_debug("Got EAGAIN from fork(), sleep 1 second and redo");
+ mtr_warning("Got EAGAIN from fork(), sleep 1 second and redo");
sleep(1);
redo FORK;
}
@@ -70,6 +68,7 @@ sub mtr_timer_start($$$) {
if ( $tpid )
{
# Parent, record the information
+ mtr_verbose("timer parent, record info($name, $tpid, $duration)");
$timers->{'timers'}->{$name}->{'pid'}= $tpid;
$timers->{'timers'}->{$name}->{'duration'}= $duration;
$timers->{'pids'}->{$tpid}= $name;
@@ -85,6 +84,7 @@ sub mtr_timer_start($$$) {
$SIG{INT}= 'DEFAULT';
$0= "mtr_timer(timers,$name,$duration)";
+ mtr_verbose("timer child $name, sleep $duration");
sleep($duration);
exit(0);
}
@@ -95,9 +95,12 @@ sub mtr_timer_start($$$) {
sub mtr_timer_stop ($$) {
my ($timers,$name)= @_;
+ mtr_verbose("mtr_timer_stop: $name");
+
if ( exists $timers->{'timers'}->{$name} )
{
my $tpid= $timers->{'timers'}->{$name}->{'pid'};
+ mtr_verbose("Stopping timer with pid $tpid");
# FIXME as Cygwin reuses pids fast, maybe check that is
# the expected process somehow?!
@@ -114,7 +117,7 @@ sub mtr_timer_stop ($$) {
}
else
{
- mtr_debug("Asked to stop timer \"$name\" not started");
+ mtr_error("Asked to stop timer \"$name\" not started");
return 0;
}
}
@@ -136,10 +139,8 @@ sub mtr_timer_timeout ($$) {
return "" unless exists $timers->{'pids'}->{$pid};
- # We got a timeout
- my $name= $timers->{'pids'}->{$pid};
- mtr_timer_stop($timers, $timers->{'timers'}->{$name});
- return $name;
+ # We got a timeout, return the name ot the timer
+ return $timers->{'pids'}->{$pid};
}
1;
diff --git a/mysql-test/mysql-test-run-shell.sh b/mysql-test/mysql-test-run-shell.sh
index f2200c4be07..99c844b2f78 100644
--- a/mysql-test/mysql-test-run-shell.sh
+++ b/mysql-test/mysql-test-run-shell.sh
@@ -1815,10 +1815,13 @@ run_testcase ()
--result-file=*)
result_file=`$ECHO "$EXTRA_MASTER_OPT" | $SED -e "s;--result-file=;;"`
result_file="r/$result_file.result"
- # Note that this must be set to space, not "" for test-reset to
-# work
+ # Note that this must be set to space, not "" for test-reset to work
EXTRA_MASTER_OPT=" "
;;
+ --force-restart)
+ # Note that this must be set to space, not "" for test-reset to work
+ EXTRA_MASTER_OPT=" "
+ ;;
esac
stop_master
stop_master 1
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index e5ed8a99304..fe97c7fa8ad 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -1,30 +1,24 @@
#!/usr/bin/perl
# -*- cperl -*-
-# This is a transformation of the "mysql-test-run" Bourne shell script
-# to Perl. There are reasons this rewrite is not the prettiest Perl
-# you have seen
#
-# - The original script is huge and for most part uncommented,
-# not even a usage description of the flags.
+##############################################################################
+#
+# mysql-test-run.pl
+#
+# Tool used for executing a suite of .test file
#
-# - There has been an attempt to write a replacement in C for the
-# original Bourne shell script. It was kind of working but lacked
-# lot of functionality to really be a replacement. Not to redo
-# that mistake and catch all the obscure features of the original
-# script, the rewrite in Perl is more close to the original script
-# meaning it also share some of the ugly parts as well.
+# See the "MySQL Test framework manual" for more information
+# http://dev.mysql.com/doc/mysqltest/en/index.html
#
-# - The original intention was that this script was to be a prototype
-# to be the base for a new C version with full functionality. Since
-# then it was decided that the Perl version should replace the
-# Bourne shell version, but the Perl style still reflects the wish
-# to make the Perl to C step easy.
+# Please keep the test framework tools identical in all versions!
+#
+##############################################################################
#
-# Some coding style from the original intent has been kept
+# Coding style directions for this perl script
#
# - To make this Perl script easy to alter even for those that not
-# code Perl that often, the coding style is as close as possible to
+# code Perl that often, keeep the coding style as close as possible to
# the C/C++ MySQL coding standard.
#
# - All lists of arguments to send to commands are Perl lists/arrays,
@@ -42,15 +36,6 @@
# the information. This separates the "find information" from the
# "do the work" and makes the program more easy to maintain.
#
-# - At the moment, there are tons of "global" variables that control
-# this script, even accessed from the files in "lib/*.pl". This
-# will change over time, for now global variables are used instead
-# of using %opt, %path and %exe hashes, because I want more
-# compile time checking, that hashes would not give me. Once this
-# script is debugged, hashes will be used and passed as parameters
-# to functions, to more closely mimic how it would be coded in C
-# using structs.
-#
# - The rule when it comes to the logic of this program is
#
# command_line_setup() - is to handle the logic between flags
@@ -66,10 +51,6 @@
# "http://www.plover.com/~mjd/perl/Trace/" and run this script like
# "perl -d:Trace mysql-test-run.pl"
#
-# FIXME Save a PID file from this code as well, to record the process
-# id we think it has. In Cygwin, a fork creates one Cygwin process,
-# and then the real Win32 process. Cygwin Perl can only kill Cygwin
-# processes. And "mysqld --bootstrap ..." doesn't save a PID file.
$Devel::Trace::TRACE= 0; # Don't trace boring init stuff
@@ -80,12 +61,20 @@ use File::Copy;
use Cwd;
use Getopt::Long;
use Sys::Hostname;
-#use Carp;
use IO::Socket;
use IO::Socket::INET;
use Data::Dumper;
use strict;
-#use diagnostics;
+use warnings;
+use diagnostics;
+
+select(STDOUT);
+$| = 1; # Automatically flush STDOUT
+
+our $glob_win32_perl= ($^O eq "MSWin32"); # ActiveState Win32 Perl
+our $glob_cygwin_perl= ($^O eq "cygwin"); # Cygwin Perl
+our $glob_win32= ($glob_win32_perl or $glob_cygwin_perl);
+our $glob_netware= ($^O eq "NetWare"); # NetWare
require "lib/mtr_cases.pl";
require "lib/mtr_im.pl";
@@ -102,38 +91,14 @@ require "lib/mtr_stress.pl";
$Devel::Trace::TRACE= 1;
-# Used by gcov
-our @mysqld_src_dirs=
- (
- "strings",
- "mysys",
- "include",
- "extra",
- "regex",
- "isam",
- "merge",
- "myisam",
- "myisammrg",
- "heap",
- "sql",
- );
-
##############################################################################
#
# Default settings
#
##############################################################################
-# We are to use handle_options() in "mysys/my_getopt.c" for the C version
-#
-# In the C version we want to use structs and, in some cases, arrays of
-# structs. We let each struct be a separate hash.
-
# Misc global variables
-
-our $glob_win32= 0; # OS and native Win32 executables
-our $glob_win32_perl= 0; # ActiveState Win32 Perl
-our $glob_cygwin_perl= 0; # Cygwin Perl
+our $mysql_version_id;
our $glob_mysql_test_dir= undef;
our $glob_mysql_bench_dir= undef;
our $glob_hostname= undef;
@@ -147,42 +112,44 @@ our @glob_test_mode;
our $glob_basedir;
-# The total result
-
our $path_charsetsdir;
our $path_client_bindir;
our $path_language;
our $path_timefile;
our $path_snapshot;
-our $path_slave_load_tmpdir; # What is this?!
our $path_mysqltest_log;
our $path_current_test_log;
our $path_my_basedir;
+
our $opt_vardir; # A path but set directly on cmd line
-our $opt_vardir_trace; # unix formatted opt_vardir for trace files
+our $path_vardir_trace; # unix formatted opt_vardir for trace files
our $opt_tmpdir; # A path but set directly on cmd line
+# Visual Studio produces executables in different sub-directories based on the
+# configuration used to build them. To make life easier, an environment
+# variable or command-line option may be specified to control which set of
+# executables will be used by the test suite.
+our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
+
+our $default_vardir;
+
our $opt_usage;
our $opt_suite;
-our $opt_netware;
-
our $opt_script_debug= 0; # Script debugging, enable with --script-debug
our $opt_verbose= 0; # Verbose output, enable with --verbose
-# Options FIXME not all....
-
our $exe_master_mysqld;
our $exe_mysql;
our $exe_mysqladmin;
our $exe_mysqlbinlog;
our $exe_mysql_client_test;
our $exe_mysqld;
-our $exe_mysqlcheck; # Called from test case
-our $exe_mysqldump; # Called from test case
-our $exe_mysqlslap; # Called from test case
-our $exe_mysqlimport; # Called from test case
-our $exe_mysqlshow; # Called from test case
+our $exe_mysqlcheck;
+our $exe_mysqldump;
+our $exe_mysqlslap;
+our $exe_mysqlimport;
+our $exe_mysqlshow;
our $exe_mysql_fix_system_tables;
our $exe_mysqltest;
our $exe_ndbd;
@@ -218,6 +185,7 @@ our $opt_fast;
our $opt_force;
our $opt_reorder= 0;
our $opt_enable_disabled;
+our $opt_mem= $ENV{'MTR_MEM'};
our $opt_gcov;
our $opt_gcov_err;
@@ -239,7 +207,7 @@ our $opt_gprof_dir;
our $opt_gprof_master;
our $opt_gprof_slave;
-our $master; # Will be struct in C
+our $master;
our $slave;
our $clusters;
@@ -253,8 +221,6 @@ our $opt_ndbconnectstring_slave;
our $opt_record;
our $opt_check_testcases;
-our $opt_result_ext;
-
our $opt_skip;
our $opt_skip_rpl;
our $max_slave_num= 0;
@@ -316,7 +282,7 @@ our $opt_skip_ndbcluster= 0;
our $opt_skip_ndbcluster_slave= 0;
our $opt_with_ndbcluster= 0;
our $opt_with_ndbcluster_only= 0;
-our $opt_ndbcluster_supported= 0;
+our $glob_ndbcluster_supported= 0;
our $opt_ndb_extra_test= 0;
our $opt_skip_master_binlog= 0;
our $opt_skip_slave_binlog= 0;
@@ -326,7 +292,7 @@ our $exe_ndb_waiter;
our $path_ndb_tools_dir;
our $path_ndb_examples_dir;
our $exe_ndb_example;
-our $file_ndb_testrun_log;
+our $path_ndb_testrun_log;
our @data_dir_lst;
@@ -334,6 +300,9 @@ our $used_binlog_format;
our $debug_compiled_binaries;
our $glob_tot_real_time= 0;
+our %mysqld_variables;
+
+
######################################################################
#
# Function declarations
@@ -343,14 +312,14 @@ our $glob_tot_real_time= 0;
sub main ();
sub initial_setup ();
sub command_line_setup ();
-sub snapshot_setup ();
+sub datadir_setup ();
sub executable_setup ();
sub environment_setup ();
-sub kill_running_server ();
+sub kill_running_servers ();
sub cleanup_stale_files ();
-sub check_ssl_support ();
+sub check_ssl_support ($);
sub check_running_as_root();
-sub check_ndbcluster_support ();
+sub check_ndbcluster_support ($);
sub rm_ndbcluster_tables ($);
sub ndbcluster_start_install ($);
sub ndbcluster_start ($$);
@@ -366,8 +335,8 @@ sub run_testcase_stop_servers ($$$);
sub run_testcase_start_servers ($);
sub run_testcase_check_skip_test($);
sub report_failure_and_restart ($);
-sub do_before_start_master ($$);
-sub do_before_start_slave ($$);
+sub do_before_start_master ($);
+sub do_before_start_slave ($);
sub ndbd_start ($$$);
sub ndb_mgmd_start ($);
sub mysqld_start ($$$);
@@ -386,13 +355,13 @@ main();
sub main () {
- initial_setup();
command_line_setup();
- executable_setup();
- check_ndbcluster_support();
- check_ssl_support();
- check_debug_support();
+ check_ndbcluster_support(\%mysqld_variables);
+ check_ssl_support(\%mysqld_variables);
+ check_debug_support(\%mysqld_variables);
+
+ executable_setup();
environment_setup();
signal_setup();
@@ -426,6 +395,8 @@ sub main () {
my ($need_ndbcluster,$need_im);
foreach my $test (@$tests)
{
+ next if $test->{skip};
+
$need_ndbcluster||= $test->{ndb_test};
$need_im||= $test->{component_id} eq 'im';
@@ -437,77 +408,35 @@ sub main () {
}
$use_innodb||= $test->{'innodb_test'};
}
- $opt_skip_ndbcluster= $opt_skip_ndbcluster_slave= 1
- unless $need_ndbcluster;
- $opt_skip_im= 1 unless $need_im;
-
- snapshot_setup();
- initialize_servers();
-
- run_suite($opt_suite, $tests);
- }
-
- mtr_exit(0);
-}
-
-##############################################################################
-#
-# Initial setup independent on command line arguments
-#
-##############################################################################
-
-sub initial_setup () {
-
- select(STDOUT);
- $| = 1; # Make unbuffered
- $glob_scriptname= basename($0);
-
- $glob_win32_perl= ($^O eq "MSWin32");
- $glob_cygwin_perl= ($^O eq "cygwin");
- $glob_win32= ($glob_win32_perl or $glob_cygwin_perl);
-
- # We require that we are in the "mysql-test" directory
- # to run mysql-test-run
+ # Check if cluster can be skipped
+ if ( !$need_ndbcluster )
+ {
+ $opt_skip_ndbcluster= 1;
+ $opt_skip_ndbcluster_slave= 1;
+ }
- if (! -f $glob_scriptname)
- {
- mtr_error("Can't find the location for the mysql-test-run script\n" .
- "Go to to the mysql-test directory and execute the script " .
- "as follows:\n./$glob_scriptname");
- }
+ # Check if slave cluster can be skipped
+ if ($max_slave_num == 0)
+ {
+ $opt_skip_ndbcluster_slave= 1;
+ }
- if ( -d "../sql" )
- {
- $opt_source_dist= 1;
- }
+ # Check if im can be skipped
+ if ( ! $need_im )
+ {
+ $opt_skip_im= 1;
+ }
- $glob_hostname= mtr_short_hostname();
+ initialize_servers();
- # 'basedir' is always parent of "mysql-test" directory
- $glob_mysql_test_dir= cwd();
- if ( $glob_cygwin_perl )
- {
- # Windows programs like 'mysqld' needs Windows paths
- $glob_mysql_test_dir= `cygpath -m "$glob_mysql_test_dir"`;
- chomp($glob_mysql_test_dir);
+ run_suite($opt_suite, $tests);
}
- $glob_basedir= dirname($glob_mysql_test_dir);
- # Expect mysql-bench to be located adjacent to the source tree, by default
- $glob_mysql_bench_dir= "$glob_basedir/../mysql-bench"
- unless defined $glob_mysql_bench_dir;
- # needs to be same length to test logging (FIXME what???)
- $path_slave_load_tmpdir= "../../var/tmp";
-
- $path_my_basedir=
- $opt_source_dist ? $glob_mysql_test_dir : $glob_basedir;
-
- $glob_timers= mtr_init_timers();
+ mtr_exit(0);
}
-
##############################################################################
#
# Default settings
@@ -583,10 +512,11 @@ sub command_line_setup () {
'compress' => \$opt_compress,
'bench' => \$opt_bench,
'small-bench' => \$opt_small_bench,
+ 'with-ndbcluster' => \$opt_with_ndbcluster,
+ 'vs-config' => \$opt_vs_config,
# Control what test suites or cases to run
'force' => \$opt_force,
- 'with-ndbcluster' => \$opt_with_ndbcluster,
'with-ndbcluster-only' => \$opt_with_ndbcluster_only,
'skip-ndbcluster|skip-ndb' => \$opt_skip_ndbcluster,
'skip-ndbcluster-slave|skip-ndb-slave'
@@ -661,12 +591,12 @@ sub command_line_setup () {
'tmpdir=s' => \$opt_tmpdir,
'vardir=s' => \$opt_vardir,
'benchdir=s' => \$glob_mysql_bench_dir,
+ 'mem' => \$opt_mem,
# Misc
'comment=s' => \$opt_comment,
'debug' => \$opt_debug,
'fast' => \$opt_fast,
- 'netware' => \$opt_netware,
'reorder' => \$opt_reorder,
'enable-disabled' => \$opt_enable_disabled,
'script-debug' => \$opt_script_debug,
@@ -689,6 +619,69 @@ sub command_line_setup () {
usage("") if $opt_usage;
+ $glob_scriptname= basename($0);
+
+ # We require that we are in the "mysql-test" directory
+ # to run mysql-test-run
+ if (! -f $glob_scriptname)
+ {
+ mtr_error("Can't find the location for the mysql-test-run script\n" .
+ "Go to to the mysql-test directory and execute the script " .
+ "as follows:\n./$glob_scriptname");
+ }
+
+ if ( -d "../sql" )
+ {
+ $opt_source_dist= 1;
+ }
+
+ $glob_hostname= mtr_short_hostname();
+
+ # 'basedir' is always parent of "mysql-test" directory
+ $glob_mysql_test_dir= cwd();
+ if ( $glob_cygwin_perl )
+ {
+ # Windows programs like 'mysqld' needs Windows paths
+ $glob_mysql_test_dir= `cygpath -m "$glob_mysql_test_dir"`;
+ chomp($glob_mysql_test_dir);
+ }
+ $glob_basedir= dirname($glob_mysql_test_dir);
+
+ # Expect mysql-bench to be located adjacent to the source tree, by default
+ $glob_mysql_bench_dir= "$glob_basedir/../mysql-bench"
+ unless defined $glob_mysql_bench_dir;
+
+ $path_my_basedir=
+ $opt_source_dist ? $glob_mysql_test_dir : $glob_basedir;
+
+ $glob_timers= mtr_init_timers();
+
+ #
+ # Find the mysqld executable to be able to find the mysqld version
+ # number as early as possible
+ #
+
+ # Look for the client binaries
+ $path_client_bindir= mtr_path_exists(vs_config_dirs('client', ''),
+ "$glob_basedir/client_release",
+ "$glob_basedir/client_debug",
+ "$glob_basedir/client",
+ "$glob_basedir/bin");
+
+ $exe_mysqld= mtr_exe_exists (vs_config_dirs('sql', 'mysqld'),
+ "$glob_basedir/sql/mysqld",
+ "$path_client_bindir/mysqld-max-nt",
+ "$path_client_bindir/mysqld-max",
+ "$path_client_bindir/mysqld-nt",
+ "$path_client_bindir/mysqld",
+ "$path_client_bindir/mysqld-debug",
+ "$path_client_bindir/mysqld-max",
+ "$glob_basedir/libexec/mysqld",
+ "$glob_basedir/bin/mysqld");
+
+ # Use the mysqld found above to find out what features are available
+ collect_mysqld_features();
+
if ( $opt_comment )
{
print "\n";
@@ -722,29 +715,75 @@ sub command_line_setup () {
# --------------------------------------------------------------------------
# Find out type of logging that are being used
# --------------------------------------------------------------------------
-
# NOTE if the default binlog format is changed, this has to be changed
$used_binlog_format= "stmt";
- foreach my $arg ( @opt_extra_mysqld_opt )
+ if ( $mysql_version_id >= 50100 )
{
- if ( defined mtr_match_substring($arg,"binlog-format=row"))
+ $used_binlog_format= "mixed"; # Default value for binlog format
+
+ foreach my $arg ( @opt_extra_mysqld_opt )
{
- $used_binlog_format= "row";
+ if ( $arg =~ /binlog-format=(\S+)/ )
+ {
+ $used_binlog_format= $1;
+ }
}
+ mtr_report("Using binlog format '$used_binlog_format'");
}
- mtr_report("Using binlog format '$used_binlog_format'");
# --------------------------------------------------------------------------
- # Set the "var/" directory, as it is the base for everything else
+ # Check if we should speed up tests by trying to run on tmpfs
# --------------------------------------------------------------------------
+ if ( $opt_mem )
+ {
+ mtr_error("Can't use --mem and --vardir at the same time ")
+ if $opt_vardir;
+ mtr_error("Can't use --mem and --tmpdir at the same time ")
+ if $opt_tmpdir;
+
+ # Use /dev/shm as the preferred location for vardir and
+ # thus implicitly also tmpdir. Add other locations to list
+ my @tmpfs_locations= ($opt_mem, "/dev/shm");
+ # One could maybe use "mount" to find tmpfs location(s)
+ foreach my $fs (@tmpfs_locations)
+ {
+ if ( -d $fs )
+ {
+ mtr_report("Using tmpfs in $fs");
+ $opt_mem= "$fs/var";
+ $opt_mem .= $ENV{'MTR_BUILD_THREAD'} if $ENV{'MTR_BUILD_THREAD'};
+ last;
+ }
+ }
+ }
+ # --------------------------------------------------------------------------
+ # Set the "var/" directory, as it is the base for everything else
+ # --------------------------------------------------------------------------
+ $default_vardir= "$glob_mysql_test_dir/var";
if ( ! $opt_vardir )
{
- $opt_vardir= "$glob_mysql_test_dir/var";
+ $opt_vardir= $default_vardir;
+ }
+ elsif ( $mysql_version_id < 50000 and
+ $opt_vardir ne $default_vardir)
+ {
+ # Version 4.1 and --vardir was specified
+ # Only supported as a symlink from var/
+ # by setting up $opt_mem that symlink will be created
+ if ( ! $glob_win32 )
+ {
+ # Only platforms that have native symlinks can use the vardir trick
+ $opt_mem= $opt_vardir;
+ mtr_report("Using 4.1 vardir trick");
+ }
+
+ $opt_vardir= $default_vardir;
}
- $opt_vardir_trace= $opt_vardir;
+
+ $path_vardir_trace= $opt_vardir;
# Chop off any "c:", DBUG likes a unix path ex: c:/src/... => /src/...
- $opt_vardir_trace=~ s/^\w://;
+ $path_vardir_trace=~ s/^\w://;
# We make the path absolute, as the server will do a chdir() before usage
unless ( $opt_vardir =~ m,^/, or
@@ -755,31 +794,46 @@ sub command_line_setup () {
}
# --------------------------------------------------------------------------
- # If not set, set these to defaults
+ # Set tmpdir
# --------------------------------------------------------------------------
-
$opt_tmpdir= "$opt_vardir/tmp" unless $opt_tmpdir;
$opt_tmpdir =~ s,/+$,,; # Remove ending slash if any
# --------------------------------------------------------------------------
- # Do sanity checks of command line arguments
+ # Set socket
# --------------------------------------------------------------------------
-
- if ( ! $opt_socket )
- { # FIXME set default before reading options?
-# $opt_socket= '@MYSQL_UNIX_ADDR@';
- $opt_socket= "/tmp/mysql.sock"; # FIXME
+ if (!$opt_socket)
+ {
+ $opt_socket= $mysqld_variables{'socket'};
}
# --------------------------------------------------------------------------
- # Look at the command line options and set script flags
+ # Check im suport
# --------------------------------------------------------------------------
+ if ( $mysql_version_id < 50000 )
+ {
+ # Instance manager is not supported until 5.0
+ $opt_skip_im= 1;
+
+ }
+
+ if ( $glob_win32 )
+ {
+ mtr_report("Disable Instance manager - not supported on Windows");
+ $opt_skip_im= 1;
+ }
+ # --------------------------------------------------------------------------
+ # Record flag
+ # --------------------------------------------------------------------------
if ( $opt_record and ! @opt_cases )
{
mtr_error("Will not run in record mode without a specific test case");
}
+ # --------------------------------------------------------------------------
+ # Embedded server flag
+ # --------------------------------------------------------------------------
if ( $opt_embedded_server )
{
$glob_use_embedded_server= 1;
@@ -794,14 +848,21 @@ sub command_line_setup () {
}
}
+
+ # --------------------------------------------------------------------------
+ # ps protcol flag
+ # --------------------------------------------------------------------------
if ( $opt_ps_protocol )
{
push(@glob_test_mode, "ps-protocol");
}
- if ( $opt_with_ndbcluster and $opt_skip_ndbcluster)
+ # --------------------------------------------------------------------------
+ # Ndb cluster flags
+ # --------------------------------------------------------------------------
+ if ( $opt_with_ndbcluster and !$opt_bench)
{
- mtr_error("Can't specify both --with-ndbcluster and --skip-ndbcluster");
+ mtr_error("Can only use --with-ndbcluster togheter with --bench");
}
if ( $opt_ndbconnectstring )
@@ -834,22 +895,33 @@ sub command_line_setup () {
$opt_ndbconnectstring_slave= "host=localhost:$opt_ndbcluster_port_slave";
}
+ # --------------------------------------------------------------------------
+ # Bench flags
+ # --------------------------------------------------------------------------
if ( $opt_small_bench )
{
$opt_bench= 1;
}
+ # --------------------------------------------------------------------------
+ # Sleep flag
+ # --------------------------------------------------------------------------
if ( $opt_sleep )
{
$opt_sleep_time_after_restart= $opt_sleep;
}
+ # --------------------------------------------------------------------------
+ # Gcov flag
+ # --------------------------------------------------------------------------
if ( $opt_gcov and ! $opt_source_dist )
{
mtr_error("Coverage test needs the source - please use source dist");
}
+ # --------------------------------------------------------------------------
# Check debug related options
+ # --------------------------------------------------------------------------
if ( $opt_gdb || $opt_client_gdb || $opt_ddd || $opt_client_ddd ||
$opt_manual_gdb || $opt_manual_ddd || $opt_manual_debug ||
$opt_debugger || $opt_client_debugger )
@@ -864,13 +936,15 @@ sub command_line_setup () {
}
}
- # Check IM arguments
- if ( $glob_win32 )
- {
- mtr_report("Disable Instance manager - not supported on Windows");
- $opt_skip_im= 1;
- }
+ # --------------------------------------------------------------------------
+ # Check if special exe was selected for master or slave
+ # --------------------------------------------------------------------------
+ $exe_master_mysqld= $exe_master_mysqld || $exe_mysqld;
+ $exe_slave_mysqld= $exe_slave_mysqld || $exe_mysqld;
+
+ # --------------------------------------------------------------------------
# Check valgrind arguments
+ # --------------------------------------------------------------------------
if ( $opt_valgrind or $opt_valgrind_path or defined $opt_valgrind_options)
{
mtr_report("Turning on valgrind for all executables");
@@ -885,7 +959,7 @@ sub command_line_setup () {
}
elsif ( $opt_valgrind_mysqltest )
{
- mtr_report("Turning on valgrind for mysqltest only");
+ mtr_report("Turning on valgrind for mysqltest and mysql_client_test only");
$opt_valgrind= 1;
}
@@ -1120,11 +1194,12 @@ sub command_line_setup () {
$path_timefile= "$opt_vardir/log/mysqltest-time";
$path_mysqltest_log= "$opt_vardir/log/mysqltest.log";
$path_current_test_log= "$opt_vardir/log/current_test";
+ $path_ndb_testrun_log= "$opt_vardir/log/ndb_testrun.log";
$path_snapshot= "$opt_tmpdir/snapshot_$opt_master_myport/";
}
-sub snapshot_setup () {
+sub datadir_setup () {
# Make a list of all data_dirs
@data_dir_lst = (
@@ -1152,6 +1227,135 @@ sub snapshot_setup () {
#
##############################################################################
+
+sub collect_mysqld_features () {
+ #
+ # Execute "mysqld --no-defaults --help --verbose", that will
+ # print out version and a list of all features and settings
+ #
+ my $found_variable_list_start= 0;
+ my $spec_file= "$glob_mysql_test_dir/mysqld.spec.$$";
+ if ( mtr_run($exe_mysqld,
+ ["--no-defaults",
+ "--verbose",
+ "--help"],
+ "", "$spec_file", "$spec_file", "") != 0 )
+ {
+ mtr_error("Failed to get version and list of features from %s",
+ $exe_mysqld);
+ }
+
+ my $F= IO::File->new($spec_file) or
+ mtr_error("can't open file \"$spec_file\": $!");
+
+ while ( my $line= <$F> )
+ {
+ # First look for version
+ if ( !$mysql_version_id )
+ {
+ # Look for version
+ my $exe_name= basename($exe_mysqld);
+ mtr_verbose("exe_name: $exe_name");
+ if ( $line =~ /^\S*$exe_name\s\sVer\s([0-9]*)\.([0-9]*)\.([0-9]*)/ )
+ {
+ #print "Major: $1 Minor: $2 Build: $3\n";
+ $mysql_version_id= $1*10000 + $2*100 + $3;
+ #print "mysql_version_id: $mysql_version_id\n";
+ mtr_report("MySQL Version $1.$2.$3");
+ }
+ }
+ else
+ {
+ if (!$found_variable_list_start)
+ {
+ # Look for start of variables list
+ if ( $line =~ /[\-]+\s[\-]+/ )
+ {
+ $found_variable_list_start= 1;
+ }
+ }
+ else
+ {
+ # Put variables into hash
+ if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ )
+ {
+ # print "$1=\"$2\"\n";
+ $mysqld_variables{$1}= $2;
+ }
+ else
+ {
+ # The variable list is ended with a blank line
+ if ( $line =~ /^[\s]*$/ )
+ {
+ last;
+ }
+ else
+ {
+ # Send out a warning, we should fix the variables that has no
+ # space between variable name and it's value
+ # or should it be fixed width column parsing? It does not
+ # look like that in function my_print_variables in my_getopt.c
+ mtr_warning("Could not parse variable list line : $line");
+ }
+ }
+ }
+ }
+ }
+ unlink($spec_file);
+ mtr_error("Could not find version of MySQL") unless $mysql_version_id;
+ mtr_error("Could not find variabes list") unless $found_variable_list_start;
+
+}
+
+
+sub executable_setup_im () {
+
+ # Look for instance manager binary - mysqlmanager
+ $exe_im=
+ mtr_exe_maybe_exists(
+ "$glob_basedir/server-tools/instance-manager/mysqlmanager",
+ "$glob_basedir/libexec/mysqlmanager");
+
+ return ($exe_im eq "");
+}
+
+sub executable_setup_ndb () {
+
+ # Look for ndb tols and binaries
+ my $ndb_path= mtr_file_exists("$glob_basedir/ndb",
+ "$glob_basedir/storage/ndb",
+ "$glob_basedir/bin");
+
+ $exe_ndbd=
+ mtr_exe_maybe_exists("$ndb_path/src/kernel/ndbd",
+ "$ndb_path/ndbd");
+ $exe_ndb_mgm=
+ mtr_exe_maybe_exists("$ndb_path/src/mgmclient/ndb_mgm",
+ "$ndb_path/ndb_mgm");
+ $exe_ndb_mgmd=
+ mtr_exe_maybe_exists("$ndb_path/src/mgmsrv/ndb_mgmd",
+ "$ndb_path/ndb_mgmd");
+ $exe_ndb_waiter=
+ mtr_exe_maybe_exists("$ndb_path/tools/ndb_waiter",
+ "$ndb_path/ndb_waiter");
+
+ # May not exist
+ $path_ndb_tools_dir= mtr_file_exists("$ndb_path/tools",
+ "$ndb_path");
+ # May not exist
+ $path_ndb_examples_dir=
+ mtr_file_exists("$ndb_path/ndbapi-examples",
+ "$ndb_path/examples");
+ # May not exist
+ $exe_ndb_example=
+ mtr_file_exists("$path_ndb_examples_dir/ndbapi_simple/ndbapi_simple");
+
+ return ( $exe_ndbd eq "" or
+ $exe_ndb_mgm eq "" or
+ $exe_ndb_mgmd eq "" or
+ $exe_ndb_waiter eq "");
+}
+
sub executable_setup () {
#
@@ -1169,161 +1373,101 @@ sub executable_setup () {
}
}
- if ( $opt_source_dist )
+ # Look for language files and charsetsdir, use same share
+ my $path_share= mtr_path_exists("$glob_basedir/share/mysql",
+ "$glob_basedir/sql/share",
+ "$glob_basedir/share");
+
+ $path_language= mtr_path_exists("$path_share/english");
+ $path_charsetsdir= mtr_path_exists("$path_share/charsets");
+
+ # Look for my_print_defaults
+ $exe_my_print_defaults=
+ mtr_exe_exists(vs_config_dirs('extra', 'my_print_defaults'),
+ "$path_client_bindir/my_print_defaults",
+ "$glob_basedir/extra/my_print_defaults");
+
+ # Look for perror
+ $exe_perror= mtr_exe_exists(vs_config_dirs('extra', 'perror'),
+ "$glob_basedir/extra/perror",
+ "$path_client_bindir/perror");
+
+ # Look for the client binaries
+ $exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck");
+ $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump");
+ $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport");
+ $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow");
+ $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog");
+ $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin");
+ $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql");
+ if ( $mysql_version_id >= 50100 )
{
- if ( $glob_win32 )
- {
- $path_client_bindir= mtr_path_exists("$glob_basedir/client_release",
- "$glob_basedir/client_debug",
- "$glob_basedir/bin",
- # New CMake locations.
- "$glob_basedir/client/release",
- "$glob_basedir/client/debug");
- $exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-max-nt",
- "$path_client_bindir/mysqld-max",
- "$path_client_bindir/mysqld-nt",
- "$path_client_bindir/mysqld",
- "$path_client_bindir/mysqld-max",
- "$path_client_bindir/mysqld-debug",
- "$glob_basedir/sql/release/mysqld",
- "$glob_basedir/sql/debug/mysqld");
- $path_language= mtr_path_exists("$glob_basedir/share/english/",
- "$glob_basedir/sql/share/english/");
- $path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets",
- "$glob_basedir/sql/share/charsets");
- $exe_my_print_defaults=
- mtr_exe_exists("$path_client_bindir/my_print_defaults",
- "$glob_basedir/extra/release/my_print_defaults",
- "$glob_basedir/extra/debug/my_print_defaults");
- $exe_perror=
- mtr_exe_exists("$path_client_bindir/perror",
- "$glob_basedir/extra/release/perror",
- "$glob_basedir/extra/debug/perror");
- }
- else
- {
- $path_client_bindir= mtr_path_exists("$glob_basedir/client");
- $exe_mysqld= mtr_exe_exists ("$glob_basedir/sql/mysqld");
- $exe_mysqlslap= mtr_exe_exists ("$path_client_bindir/mysqlslap");
- $path_language= mtr_path_exists("$glob_basedir/sql/share/english/");
- $path_charsetsdir= mtr_path_exists("$glob_basedir/sql/share/charsets");
-
- $exe_im= mtr_exe_exists(
- "$glob_basedir/server-tools/instance-manager/mysqlmanager");
- $exe_my_print_defaults=
- mtr_exe_exists("$glob_basedir/extra/my_print_defaults");
- $exe_perror=
- mtr_exe_exists("$glob_basedir/extra/perror");
- }
+ $exe_mysqlslap= mtr_exe_exists("$path_client_bindir/mysqlslap");
+ }
- if ( $glob_use_embedded_server )
- {
- my $path_examples= "$glob_basedir/libmysqld/examples";
- $exe_mysqltest= mtr_exe_exists("$path_examples/mysqltest_embedded");
- $exe_mysql_client_test=
- mtr_exe_exists("$path_examples/mysql_client_test_embedded",
- "/usr/bin/false");
- }
- else
- {
- $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest");
- $exe_mysql_client_test=
- mtr_exe_exists("$glob_basedir/tests/mysql_client_test",
- "$glob_basedir/tests/release/mysql_client_test",
- "$glob_basedir/tests/debug/mysql_client_test",
- "$path_client_bindir/mysql_client_test",
- "/usr/bin/false");
- }
- $exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck");
- $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump");
- $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport");
- $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow");
- $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog");
- $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin");
- $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql");
+ if ( ! $glob_win32 )
+ {
+ # Look for mysql_fix_system_table script
$exe_mysql_fix_system_tables=
mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables",
- "/usr/bin/false");
- $path_ndb_tools_dir= mtr_path_exists("$glob_basedir/storage/ndb/tools");
- $path_ndb_examples_dir= mtr_path_exists("$glob_basedir/storage/ndb/ndbapi-examples");
- $exe_ndb_example= mtr_file_exists("$path_ndb_examples_dir/ndbapi_simple/ndbapi_simple");
- $exe_ndb_mgm= "$glob_basedir/storage/ndb/src/mgmclient/ndb_mgm";
- $exe_ndb_waiter= "$glob_basedir/storage/ndb/tools/ndb_waiter";
- $exe_ndbd= "$glob_basedir/storage/ndb/src/kernel/ndbd";
- $exe_ndb_mgmd= "$glob_basedir/storage/ndb/src/mgmsrv/ndb_mgmd";
- $lib_udf_example=
- mtr_file_exists("$glob_basedir/sql/.libs/udf_example.so",
- "$glob_basedir/sql/release/udf_example.dll",
- "$glob_basedir/sql/debug/udf_example.dll");
+ "$path_client_bindir/mysql_fix_privilege_tables");
}
- else
+
+
+ if ( ! $opt_skip_ndbcluster and executable_setup_ndb())
{
- $path_client_bindir= mtr_path_exists("$glob_basedir/bin");
- $exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck");
- $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump");
- $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport");
- $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow");
- $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog");
- $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin");
- $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql");
- $exe_mysql_fix_system_tables=
- mtr_script_exists("$path_client_bindir/mysql_fix_privilege_tables",
- "$glob_basedir/scripts/mysql_fix_privilege_tables",
- "/usr/bin/false");
- $exe_my_print_defaults=
- mtr_exe_exists("$path_client_bindir/my_print_defaults");
- $exe_perror=
- mtr_exe_exists("$path_client_bindir/perror");
-
- $path_language= mtr_path_exists("$glob_basedir/share/mysql/english/",
- "$glob_basedir/share/english/");
- $path_charsetsdir= mtr_path_exists("$glob_basedir/share/mysql/charsets",
- "$glob_basedir/share/charsets");
-
- if ( $glob_win32 )
- {
- $exe_mysqld= mtr_exe_exists ("$glob_basedir/bin/mysqld-nt",
- "$glob_basedir/bin/mysqld",
- "$glob_basedir/bin/mysqld-debug",);
- }
- else
- {
- $exe_mysqld= mtr_exe_exists ("$glob_basedir/libexec/mysqld",
- "$glob_basedir/bin/mysqld");
- $exe_mysqlslap= mtr_exe_exists("$path_client_bindir/mysqlslap");
- }
- $exe_im= mtr_exe_exists("$glob_basedir/libexec/mysqlmanager",
- "$glob_basedir/bin/mysqlmanager");
- if ( $glob_use_embedded_server )
- {
- $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest_embedded");
- $exe_mysql_client_test=
- mtr_exe_exists("$glob_basedir/tests/mysql_client_test_embedded",
- "$path_client_bindir/mysql_client_test_embedded",
- "/usr/bin/false");
- }
- else
+ mtr_warning("Could not find all required ndb binaries, " .
+ "all ndb tests will fail, use --skip-ndbcluster to " .
+ "skip testing it.");
+
+ foreach my $cluster (@{$clusters})
{
- $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest");
- $exe_mysql_client_test=
- mtr_exe_exists("$path_client_bindir/mysql_client_test",
- "$glob_basedir/tests/release/mysql_client_test",
- "$glob_basedir/tests/debug/mysql_client_test",
- "/usr/bin/false"); # FIXME temporary
+ $cluster->{"executable_setup_failed"}= 1;
}
+ }
- $path_ndb_tools_dir= "$glob_basedir/bin";
- $path_ndb_examples_dir= "$glob_basedir/ndbapi-examples";
- $exe_ndb_mgm= "$glob_basedir/bin/ndb_mgm";
- $exe_ndb_waiter= "$glob_basedir/bin/ndb_waiter";
- $exe_ndbd= "$glob_basedir/bin/ndbd";
- $exe_ndb_mgmd= "$glob_basedir/bin/ndb_mgmd";
+ if ( ! $opt_skip_im and executable_setup_im())
+ {
+ mtr_warning("Could not find all required instance manager binaries, " .
+ "all im tests will fail, use --skip-im to " .
+ "continue without instance manager");
+ $instance_manager->{"executable_setup_failed"}= 1;
}
- $exe_master_mysqld= $exe_master_mysqld || $exe_mysqld;
- $exe_slave_mysqld= $exe_slave_mysqld || $exe_mysqld;
+ # Look for the udf_example library
+ $lib_udf_example=
+ mtr_file_exists(vs_config_dirs('sql', 'udf_example.dll'),
+ "$glob_basedir/sql/.libs/udf_example.so",);
+
+ # Look for mysqltest executable
+ if ( $glob_use_embedded_server )
+ {
+ $exe_mysqltest=
+ mtr_exe_exists(vs_config_dirs('libmysqld/examples', 'mysqltest_embedded'),
+ "$glob_basedir/libmysqld/examples/mysqltest_embedded",
+ "$path_client_bindir/mysqltest_embedded");
+ }
+ else
+ {
+ $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest");
+ }
- $file_ndb_testrun_log= "$opt_vardir/log/ndb_testrun.log";
+ # Look for mysql_client_test executable which may _not_ exist in
+ # some versions, test using it should be skipped
+ if ( $glob_use_embedded_server )
+ {
+ $exe_mysql_client_test=
+ mtr_exe_maybe_exists(
+ vs_config_dirs('libmysqld/examples', 'mysql_client_test_embedded'),
+ "$glob_basedir/libmysqld/examples/mysql_client_test_embedded");
+ }
+ else
+ {
+ $exe_mysql_client_test=
+ mtr_exe_maybe_exists(vs_config_dirs('tests', 'mysql_client_test'),
+ "$glob_basedir/tests/mysql_client_test",
+ "$glob_basedir/bin");
+ }
}
@@ -1343,6 +1487,47 @@ sub generate_cmdline_mysqldump ($) {
#
##############################################################################
+sub mysql_client_test_arguments()
+{
+ my $exe= $exe_mysql_client_test;
+
+ my $args;
+ mtr_init_args(\$args);
+ if ( $opt_valgrind_mysqltest )
+ {
+ valgrind_arguments($args, \$exe);
+ }
+
+ mtr_add_arg($args, "--no-defaults");
+ mtr_add_arg($args, "--testcase");
+ mtr_add_arg($args, "--user=root");
+ mtr_add_arg($args, "--port=$master->[0]->{'port'}");
+ mtr_add_arg($args, "--socket=$master->[0]->{'path_sock'}");
+
+ if ( $mysql_version_id >= 50000 )
+ {
+ mtr_add_arg($args, "--vardir=$opt_vardir")
+ }
+
+ if ( $opt_debug )
+ {
+ mtr_add_arg($args,
+ "--debug=d:t:A,$path_vardir_trace/log/mysql_client_test.trace");
+ }
+
+ if ( $glob_use_embedded_server )
+ {
+ mtr_add_arg($args,
+ " -A --language=$path_language");
+ mtr_add_arg($args,
+ " -A --datadir=$slave->[0]->{'path_myddir'}");
+ mtr_add_arg($args,
+ " -A --character-sets-dir=$path_charsetsdir");
+ }
+
+ return join(" ", $exe, @$args);
+}
+
# Note that some env is setup in spawn/run, in "mtr_process.pl"
sub environment_setup () {
@@ -1368,7 +1553,7 @@ sub environment_setup () {
# --------------------------------------------------------------------------
# Add the path where libndbclient can be found
# --------------------------------------------------------------------------
- if ( $opt_ndbcluster_supported )
+ if ( $glob_ndbcluster_supported )
{
push(@ld_library_paths, "$glob_basedir/storage/ndb/src/.libs");
}
@@ -1394,11 +1579,13 @@ sub environment_setup () {
}
$ENV{'LD_LIBRARY_PATH'}= join(":", @ld_library_paths,
- split(':', $ENV{'LD_LIBRARY_PATH'}));
+ $ENV{'LD_LIBRARY_PATHS'} ?
+ split(':', $ENV{'LD_LIBRARY_PATH'}) : ());
mtr_debug("LD_LIBRARY_PATH: $ENV{'LD_LIBRARY_PATH'}");
$ENV{'DYLD_LIBRARY_PATH'}= join(":", @ld_library_paths,
- split(':', $ENV{'DYLD_LIBRARY_PATH'}));
+ $ENV{'DYLD_LIBRARY_PATH'} ?
+ split(':', $ENV{'DYLD_LIBRARY_PATH'}) : ());
mtr_debug("DYLD_LIBRARY_PATH: $ENV{'DYLD_LIBRARY_PATH'}");
@@ -1422,47 +1609,67 @@ sub environment_setup () {
$ENV{'SLAVE_MYPORT'}= $slave->[0]->{'port'};
$ENV{'SLAVE_MYPORT1'}= $slave->[1]->{'port'};
$ENV{'SLAVE_MYPORT2'}= $slave->[2]->{'port'};
-# $ENV{'MYSQL_TCP_PORT'}= '@MYSQL_TCP_PORT@'; # FIXME
- $ENV{'MYSQL_TCP_PORT'}= 3306;
+ $ENV{'MYSQL_TCP_PORT'}= $mysqld_variables{'port'};
+ $ENV{'IM_PATH_SOCK'}= $instance_manager->{path_sock};
+ $ENV{'IM_USERNAME'}= $instance_manager->{admin_login};
+ $ENV{'IM_PASSWORD'}= $instance_manager->{admin_password};
$ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set
+ $ENV{'EXE_MYSQL'}= $exe_mysql;
+
+
# ----------------------------------------------------
# Setup env for NDB
# ----------------------------------------------------
- $ENV{'NDB_MGM'}= $exe_ndb_mgm;
+ if ( ! $opt_skip_ndbcluster )
+ {
+ $ENV{'NDB_MGM'}= $exe_ndb_mgm;
- $ENV{'NDBCLUSTER_PORT'}= $opt_ndbcluster_port;
- $ENV{'NDBCLUSTER_PORT_SLAVE'}= $opt_ndbcluster_port_slave;
+ $ENV{'NDBCLUSTER_PORT'}= $opt_ndbcluster_port;
+ $ENV{'NDBCLUSTER_PORT_SLAVE'}= $opt_ndbcluster_port_slave;
- $ENV{'NDB_EXTRA_TEST'}= $opt_ndb_extra_test;
+ $ENV{'NDB_EXTRA_TEST'}= $opt_ndb_extra_test;
- $ENV{'NDB_BACKUP_DIR'}= $clusters->[0]->{'data_dir'};
- $ENV{'NDB_DATA_DIR'}= $clusters->[0]->{'data_dir'};
- $ENV{'NDB_TOOLS_DIR'}= $path_ndb_tools_dir;
- $ENV{'NDB_TOOLS_OUTPUT'}= $file_ndb_testrun_log;
- $ENV{'NDB_CONNECTSTRING'}= $opt_ndbconnectstring;
+ $ENV{'NDB_BACKUP_DIR'}= $clusters->[0]->{'data_dir'};
+ $ENV{'NDB_DATA_DIR'}= $clusters->[0]->{'data_dir'};
+ $ENV{'NDB_TOOLS_DIR'}= $path_ndb_tools_dir;
+ $ENV{'NDB_TOOLS_OUTPUT'}= $path_ndb_testrun_log;
+ $ENV{'NDB_CONNECTSTRING'}= $opt_ndbconnectstring;
- $ENV{'NDB_EXAMPLES_DIR'}= $path_ndb_examples_dir;
- $ENV{'MY_NDB_EXAMPLES_BINARY'}= $exe_ndb_example;
- $ENV{'NDB_EXAMPLES_OUTPUT'}= $file_ndb_testrun_log;
+ if ( $mysql_version_id >= 50000 )
+ {
+ $ENV{'NDB_EXAMPLES_DIR'}= $path_ndb_examples_dir;
+ $ENV{'MY_NDB_EXAMPLES_BINARY'}= $exe_ndb_example;
+ }
+ $ENV{'NDB_EXAMPLES_OUTPUT'}= $path_ndb_testrun_log;
+ }
# ----------------------------------------------------
# Setup env for IM
# ----------------------------------------------------
- $ENV{'IM_EXE'}= $exe_im;
- $ENV{'IM_PATH_PID'}= $instance_manager->{path_pid};
- $ENV{'IM_PATH_ANGEL_PID'}= $instance_manager->{path_angel_pid};
- $ENV{'IM_PORT'}= $instance_manager->{port};
- $ENV{'IM_DEFAULTS_PATH'}= $instance_manager->{defaults_file};
- $ENV{'IM_PASSWORD_PATH'}= $instance_manager->{password_file};
-
- $ENV{'IM_MYSQLD1_SOCK'}= $instance_manager->{instances}->[0]->{path_sock};
- $ENV{'IM_MYSQLD1_PORT'}= $instance_manager->{instances}->[0]->{port};
- $ENV{'IM_MYSQLD1_PATH_PID'}=$instance_manager->{instances}->[0]->{path_pid};
- $ENV{'IM_MYSQLD2_SOCK'}= $instance_manager->{instances}->[1]->{path_sock};
- $ENV{'IM_MYSQLD2_PORT'}= $instance_manager->{instances}->[1]->{port};
- $ENV{'IM_MYSQLD2_PATH_PID'}=$instance_manager->{instances}->[1]->{path_pid};
+ if ( ! $opt_skip_im )
+ {
+ $ENV{'IM_EXE'}= $exe_im;
+ $ENV{'IM_PATH_PID'}= $instance_manager->{path_pid};
+ $ENV{'IM_PATH_ANGEL_PID'}= $instance_manager->{path_angel_pid};
+ $ENV{'IM_PORT'}= $instance_manager->{port};
+ $ENV{'IM_DEFAULTS_PATH'}= $instance_manager->{defaults_file};
+ $ENV{'IM_PASSWORD_PATH'}= $instance_manager->{password_file};
+
+ $ENV{'IM_MYSQLD1_SOCK'}=
+ $instance_manager->{instances}->[0]->{path_sock};
+ $ENV{'IM_MYSQLD1_PORT'}=
+ $instance_manager->{instances}->[0]->{port};
+ $ENV{'IM_MYSQLD1_PATH_PID'}=
+ $instance_manager->{instances}->[0]->{path_pid};
+ $ENV{'IM_MYSQLD2_SOCK'}=
+ $instance_manager->{instances}->[1]->{path_sock};
+ $ENV{'IM_MYSQLD2_PORT'}=
+ $instance_manager->{instances}->[1]->{port};
+ $ENV{'IM_MYSQLD2_PATH_PID'}=
+ $instance_manager->{instances}->[1]->{path_pid};
+ }
# ----------------------------------------------------
# Setup env so childs can execute mysqlcheck
@@ -1475,7 +1682,7 @@ sub environment_setup () {
if ( $opt_debug )
{
$cmdline_mysqlcheck .=
- " --debug=d:t:A,$opt_vardir_trace/log/mysqlcheck.trace";
+ " --debug=d:t:A,$path_vardir_trace/log/mysqlcheck.trace";
}
$ENV{'MYSQL_CHECK'}= $cmdline_mysqlcheck;
@@ -1488,9 +1695,9 @@ sub environment_setup () {
if ( $opt_debug )
{
$cmdline_mysqldump .=
- " --debug=d:t:A,$opt_vardir_trace/log/mysqldump-master.trace";
+ " --debug=d:t:A,$path_vardir_trace/log/mysqldump-master.trace";
$cmdline_mysqldumpslave .=
- " --debug=d:t:A,$opt_vardir_trace/log/mysqldump-slave.trace";
+ " --debug=d:t:A,$path_vardir_trace/log/mysqldump-slave.trace";
}
$ENV{'MYSQL_DUMP'}= $cmdline_mysqldump;
$ENV{'MYSQL_DUMP_SLAVE'}= $cmdline_mysqldumpslave;
@@ -1499,7 +1706,7 @@ sub environment_setup () {
# ----------------------------------------------------
# Setup env so childs can execute mysqlslap
# ----------------------------------------------------
- unless ( $glob_win32 )
+ if ( $exe_mysqlslap )
{
my $cmdline_mysqlslap=
"$exe_mysqlslap -uroot " .
@@ -1508,9 +1715,9 @@ sub environment_setup () {
"--lock-directory=$opt_tmpdir";
if ( $opt_debug )
- {
+ {
$cmdline_mysqlslap .=
- " --debug=d:t:A,$opt_vardir_trace/log/mysqlslap.trace";
+ " --debug=d:t:A,$path_vardir_trace/log/mysqlslap.trace";
}
$ENV{'MYSQL_SLAP'}= $cmdline_mysqlslap;
}
@@ -1526,7 +1733,7 @@ sub environment_setup () {
if ( $opt_debug )
{
$cmdline_mysqlimport .=
- " --debug=d:t:A,$opt_vardir_trace/log/mysqlimport.trace";
+ " --debug=d:t:A,$path_vardir_trace/log/mysqlimport.trace";
}
$ENV{'MYSQL_IMPORT'}= $cmdline_mysqlimport;
@@ -1542,7 +1749,7 @@ sub environment_setup () {
if ( $opt_debug )
{
$cmdline_mysqlshow .=
- " --debug=d:t:A,$opt_vardir_trace/log/mysqlshow.trace";
+ " --debug=d:t:A,$path_vardir_trace/log/mysqlshow.trace";
}
$ENV{'MYSQL_SHOW'}= $cmdline_mysqlshow;
@@ -1551,13 +1758,16 @@ sub environment_setup () {
# ----------------------------------------------------
my $cmdline_mysqlbinlog=
"$exe_mysqlbinlog" .
- " --no-defaults --local-load=$opt_tmpdir" .
- " --character-sets-dir=$path_charsetsdir";
+ " --no-defaults --local-load=$opt_tmpdir";
+ if ( $mysql_version_id >= 50000 )
+ {
+ $cmdline_mysqlbinlog .=" --character-sets-dir=$path_charsetsdir";
+ }
if ( $opt_debug )
{
$cmdline_mysqlbinlog .=
- " --debug=d:t:A,$opt_vardir_trace/log/mysqlbinlog.trace";
+ " --debug=d:t:A,$path_vardir_trace/log/mysqlbinlog.trace";
}
$ENV{'MYSQL_BINLOG'}= $cmdline_mysqlbinlog;
@@ -1575,38 +1785,21 @@ sub environment_setup () {
# ----------------------------------------------------
# Setup env so childs can execute mysql_client_test
# ----------------------------------------------------
- my $cmdline_mysql_client_test=
- "$exe_mysql_client_test --no-defaults --testcase --user=root --silent " .
- "--port=$master->[0]->{'port'} " .
- "--vardir=$opt_vardir " .
- "--socket=$master->[0]->{'path_sock'}";
-
- if ( $opt_debug )
- {
- $cmdline_mysql_client_test .=
- " --debug=d:t:A,$opt_vardir_trace/log/mysql_client_test.trace";
- }
-
- if ( $glob_use_embedded_server )
- {
- $cmdline_mysql_client_test.=
- " -A --language=$path_language" .
- " -A --datadir=$slave->[0]->{'path_myddir'}" .
- " -A --character-sets-dir=$path_charsetsdir";
- }
- $ENV{'MYSQL_CLIENT_TEST'}= $cmdline_mysql_client_test;
-
+ $ENV{'MYSQL_CLIENT_TEST'}= mysql_client_test_arguments();
# ----------------------------------------------------
# Setup env so childs can execute mysql_fix_system_tables
# ----------------------------------------------------
- my $cmdline_mysql_fix_system_tables=
- "$exe_mysql_fix_system_tables --no-defaults --host=localhost --user=root --password= " .
- "--basedir=$glob_basedir --bindir=$path_client_bindir --verbose " .
- "--port=$master->[0]->{'port'} " .
- "--socket=$master->[0]->{'path_sock'}";
-
- $ENV{'MYSQL_FIX_SYSTEM_TABLES'}= $cmdline_mysql_fix_system_tables;
+ if ( ! $glob_win32 )
+ {
+ my $cmdline_mysql_fix_system_tables=
+ "$exe_mysql_fix_system_tables --no-defaults --host=localhost " .
+ "--user=root --password= " .
+ "--basedir=$glob_basedir --bindir=$path_client_bindir --verbose " .
+ "--port=$master->[0]->{'port'} " .
+ "--socket=$master->[0]->{'path_sock'}";
+ $ENV{'MYSQL_FIX_SYSTEM_TABLES'}= $cmdline_mysql_fix_system_tables;
+ }
# ----------------------------------------------------
# Setup env so childs can execute my_print_defaults
@@ -1633,7 +1826,7 @@ sub environment_setup () {
# ----------------------------------------------------
# We are nice and report a bit about our settings
# ----------------------------------------------------
- if (!$opt_extern)
+ if (!$opt_extern && $opt_verbose)
{
print "Using MTR_BUILD_THREAD = $ENV{MTR_BUILD_THREAD}\n";
print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n";
@@ -1641,12 +1834,26 @@ sub environment_setup () {
print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n";
print "Using SLAVE_MYPORT1 = $ENV{SLAVE_MYPORT1}\n";
print "Using SLAVE_MYPORT2 = $ENV{SLAVE_MYPORT2}\n";
- print "Using NDBCLUSTER_PORT = $ENV{NDBCLUSTER_PORT}\n";
- print "Using NDBCLUSTER_PORT_SLAVE = $ENV{NDBCLUSTER_PORT_SLAVE}\n";
- print "Using IM_PORT = $ENV{IM_PORT}\n";
- print "Using IM_MYSQLD1_PORT = $ENV{IM_MYSQLD1_PORT}\n";
- print "Using IM_MYSQLD2_PORT = $ENV{IM_MYSQLD2_PORT}\n";
+ if ( ! $opt_skip_ndbcluster )
+ {
+ print "Using NDBCLUSTER_PORT = $ENV{NDBCLUSTER_PORT}\n";
+ if ( ! $opt_skip_ndbcluster_slave )
+ {
+ print "Using NDBCLUSTER_PORT_SLAVE = $ENV{NDBCLUSTER_PORT_SLAVE}\n";
+ }
+ }
+ if ( ! $opt_skip_im )
+ {
+ print "Using IM_PORT = $ENV{IM_PORT}\n";
+ print "Using IM_MYSQLD1_PORT = $ENV{IM_MYSQLD1_PORT}\n";
+ print "Using IM_MYSQLD2_PORT = $ENV{IM_MYSQLD2_PORT}\n";
+ }
}
+
+ # Create an environment variable to make it possible
+ # to detect that valgrind is being used from test cases
+ $ENV{'VALGRIND_TEST'}= $opt_valgrind;
+
}
@@ -1676,7 +1883,7 @@ sub handle_int_signal () {
#
##############################################################################
-sub kill_running_server () {
+sub kill_running_servers () {
if ( $opt_fast or $glob_use_embedded_server )
{
@@ -1694,28 +1901,55 @@ sub kill_running_server () {
# started from this run of the script, this is terminating
# leftovers from previous runs.
+ if ( ! -d $opt_vardir )
+ {
+ if ( -l $opt_vardir and ! -d readlink($opt_vardir) )
+ {
+ mtr_report("Removing $opt_vardir symlink without destination");
+ unlink($opt_vardir);
+ }
+ # The "var" dir does not exist already
+ # the processes that mtr_kill_leftovers start will write
+ # their log files to var/log so it should be created
+ mkpath("$opt_vardir/log");
+ }
mtr_kill_leftovers();
}
}
sub cleanup_stale_files () {
+ my $created_by_mem_file= "$glob_mysql_test_dir/var/created_by_mem";
+
mtr_report("Removing Stale Files");
- if ( $opt_vardir eq "$glob_mysql_test_dir/var" )
+ if ( $opt_vardir eq $default_vardir )
{
#
# Running with "var" in mysql-test dir
#
- if ( -l "$glob_mysql_test_dir/var" )
+ if ( -l $opt_vardir)
{
- # Some users creates a soft link in mysql-test/var to another area
- # - allow it
- mtr_report("WARNING: Using the 'mysql-test/var' symlink");
- rmtree("$opt_vardir/log");
- rmtree("$opt_vardir/ndbcluster-$opt_ndbcluster_port");
- rmtree("$opt_vardir/run");
- rmtree("$opt_vardir/tmp");
+ # var is a symlink
+ if (-f $created_by_mem_file)
+ {
+ # Remove the directory which the link points at
+ rmtree(readlink($opt_vardir));
+ # Remove the entire "var" dir
+ rmtree("$opt_vardir/");
+ # Remove the "var" symlink
+ unlink($opt_vardir);
+ }
+ else
+ {
+ # Some users creates a soft link in mysql-test/var to another area
+ # - allow it
+ mtr_report("WARNING: Using the 'mysql-test/var' symlink");
+ rmtree("$opt_vardir/log");
+ rmtree("$opt_vardir/ndbcluster-$opt_ndbcluster_port");
+ rmtree("$opt_vardir/run");
+ rmtree("$opt_vardir/tmp");
+ }
}
else
{
@@ -1731,12 +1965,23 @@ sub cleanup_stale_files () {
# Remove the var/ dir in mysql-test dir if any
# this could be an old symlink that shouldn't be there
- rmtree("$glob_mysql_test_dir/var");
+ rmtree($default_vardir);
# Remove the "var" dir
rmtree("$opt_vardir/");
}
+ if ( $opt_mem )
+ {
+ # Runinng with var as a link to some "memory" location, normally tmpfs
+ rmtree($opt_mem);
+ mkpath($opt_mem);
+ mtr_report("Creating symlink from $opt_vardir to $opt_mem");
+ symlink($opt_mem, $opt_vardir);
+ # Put a small file to recognize this dir was created by --mem
+ mtr_tofile($created_by_mem_file, $opt_mem);
+ }
+
mkpath("$opt_vardir/log");
mkpath("$opt_vardir/run");
mkpath("$opt_vardir/tmp");
@@ -1797,8 +2042,8 @@ sub check_running_as_root () {
}
-
-sub check_ssl_support () {
+sub check_ssl_support ($) {
+ my $mysqld_variables= shift;
if ($opt_skip_ssl || $opt_extern)
{
@@ -1808,13 +2053,7 @@ sub check_ssl_support () {
return;
}
- # check ssl support by testing using a switch
- # that is only available in that case
- if ( mtr_run($exe_mysqld,
- ["--no-defaults",
- "--ssl",
- "--help"],
- "", "/dev/null", "/dev/null", "") != 0 )
+ if ( ! $mysqld_variables->{'ssl'} )
{
if ( $opt_ssl)
{
@@ -1831,17 +2070,12 @@ sub check_ssl_support () {
}
-sub check_debug_support () {
+sub check_debug_support ($) {
+ my $mysqld_variables= shift;
- # check debug support by testing using a switch
- # that is only available in that case
- if ( mtr_run($exe_mysqld,
- ["--no-defaults",
- "--debug",
- "--help"],
- "", "/dev/null", "/dev/null", "") != 0 )
+ if ( ! $mysqld_variables->{'debug'} )
{
- # mtr_report("Binaries are not debug compiled");
+ #mtr_report("Binaries are not debug compiled");
$debug_compiled_binaries= 0;
if ( $opt_debug )
@@ -1856,11 +2090,37 @@ sub check_debug_support () {
##############################################################################
#
+# Helper function to handle configuration-based subdirectories which Visual
+# Studio uses for storing binaries. If opt_vs_config is set, this returns
+# a path based on that setting; if not, it returns paths for the default
+# /release/ and /debug/ subdirectories.
+#
+# $exe can be undefined, if the directory itself will be used
+#
+###############################################################################
+
+sub vs_config_dirs ($$) {
+ my ($path_part, $exe) = @_;
+
+ $exe = "" if not defined $exe;
+
+ if ($opt_vs_config)
+ {
+ return ("$glob_basedir/$path_part/$opt_vs_config/$exe");
+ }
+
+ return ("$glob_basedir/$path_part/release/$exe",
+ "$glob_basedir/$path_part/debug/$exe");
+}
+
+##############################################################################
+#
# Start the ndb cluster
#
##############################################################################
-sub check_ndbcluster_support () {
+sub check_ndbcluster_support ($) {
+ my $mysqld_variables= shift;
if ($opt_skip_ndbcluster)
{
@@ -1869,21 +2129,23 @@ sub check_ndbcluster_support () {
return;
}
- # check ndbcluster support by runnning mysqld using a switch
- # that is only available in that case
- if ( mtr_run($exe_mysqld,
- ["--no-defaults",
- "--ndb-use-exact-count",
- "--help"],
- "", "/dev/null", "/dev/null", "") != 0 )
+ if ( ! $mysqld_variables->{'ndb-connectstring'} )
{
mtr_report("Skipping ndbcluster, mysqld not compiled with ndbcluster");
$opt_skip_ndbcluster= 1;
$opt_skip_ndbcluster_slave= 1;
return;
}
- $opt_ndbcluster_supported= 1;
+ $glob_ndbcluster_supported= 1;
mtr_report("Using ndbcluster when necessary, mysqld supports it");
+
+ if ( $mysql_version_id < 50100 )
+ {
+ # Slave cluster is not supported until 5.1
+ $opt_skip_ndbcluster_slave= 1;
+
+ }
+
return;
}
@@ -1891,11 +2153,6 @@ sub check_ndbcluster_support () {
sub ndbcluster_start_install ($) {
my $cluster= shift;
- if ( $opt_skip_ndbcluster or $glob_use_running_ndbcluster )
- {
- return 0;
- }
-
mtr_report("Installing $cluster->{'name'} Cluster");
mkdir($cluster->{'data_dir'});
@@ -1914,11 +2171,22 @@ sub ndbcluster_start_install ($) {
if (!$opt_bench)
{
# Use a smaller configuration
- $ndb_no_ord=32;
- $ndb_con_op=5000;
- $ndb_dmem="20M";
- $ndb_imem="1M";
- $ndb_pbmem="4M";
+ if ( $mysql_version_id < 50100 )
+ {
+ # 4.1 and 5.0 is using a "larger" --small configuration
+ $ndb_no_ord=128;
+ $ndb_con_op=10000;
+ $ndb_dmem="40M";
+ $ndb_imem="12M";
+ }
+ else
+ {
+ $ndb_no_ord=32;
+ $ndb_con_op=5000;
+ $ndb_dmem="20M";
+ $ndb_imem="1M";
+ $ndb_pbmem="4M";
+ }
}
my $config_file_template= "ndb/ndb_config_${nodes}_node.ini";
@@ -1941,6 +2209,11 @@ sub ndbcluster_start_install ($) {
s/CHOOSE_HOSTNAME_.*/$ndb_host/;
s/CHOOSE_FILESYSTEM/$cluster->{'data_dir'}/;
s/CHOOSE_PORT_MGM/$cluster->{'port'}/;
+ if ( $mysql_version_id < 50000 )
+ {
+ my $base_port= $cluster->{'port'} + 1;
+ s/CHOOSE_PORT_TRANSPORTER/$base_port/;
+ }
s/CHOOSE_DiskPageBufferMemory/$ndb_pbmem/;
print OUT "$_ \n";
@@ -2062,7 +2335,10 @@ sub ndbd_start ($$$) {
mtr_add_arg($args, "--no-defaults");
mtr_add_arg($args, "--core");
mtr_add_arg($args, "--ndb-connectstring=%s", "$cluster->{'connect_string'}");
- mtr_add_arg($args, "--character-sets-dir=%s", "$path_charsetsdir");
+ if ( $mysql_version_id >= 50000)
+ {
+ mtr_add_arg($args, "--character-sets-dir=%s", "$path_charsetsdir");
+ }
mtr_add_arg($args, "--nodaemon");
mtr_add_arg($args, "$extra_args");
@@ -2163,8 +2439,6 @@ sub run_benchmarks ($) {
chdir($glob_mysql_bench_dir)
or mtr_error("Couldn't chdir to '$glob_mysql_bench_dir': $!");
- # FIXME write shorter....
-
if ( ! $benchmark )
{
mtr_add_arg($args, "--log");
@@ -2196,9 +2470,6 @@ sub run_benchmarks ($) {
#
##############################################################################
-# FIXME how to specify several suites to run? Comma separated list?
-
-
sub run_suite () {
my ($suite, $tests)= @_;
@@ -2255,11 +2526,14 @@ sub run_suite () {
##############################################################################
sub initialize_servers () {
+
+ datadir_setup();
+
if ( ! $glob_use_running_server )
{
- kill_running_server();
+ kill_running_servers();
- unless ( $opt_start_dirty )
+ if ( ! $opt_start_dirty )
{
cleanup_stale_files();
mysql_install_db();
@@ -2270,6 +2544,11 @@ sub initialize_servers () {
}
check_running_as_root();
}
+ else
+ {
+ # We have to create the 'var' and related directories
+ cleanup_stale_files();
+ }
}
sub mysql_install_db () {
@@ -2292,10 +2571,26 @@ sub mysql_install_db () {
my $cluster_started_ok= 1; # Assume it can be started
- if (ndbcluster_start_install($clusters->[0]) ||
- $max_slave_num && ndbcluster_start_install($clusters->[1]))
+ if ($opt_skip_ndbcluster || $glob_use_running_ndbcluster ||
+ $clusters->[0]->{executable_setup_failed})
{
- mtr_warning("Failed to start install of cluster");
+ # Don't install master cluster
+ }
+ elsif (ndbcluster_start_install($clusters->[0]))
+ {
+ mtr_warning("Failed to start install of $clusters->[0]->{name}");
+ $cluster_started_ok= 0;
+ }
+
+ if ($max_slave_num == 0 ||
+ $opt_skip_ndbcluster_slave || $glob_use_running_ndbcluster_slave ||
+ $clusters->[1]->{executable_setup_failed})
+ {
+ # Don't install slave cluster
+ }
+ elsif (ndbcluster_start_install($clusters->[1]))
+ {
+ mtr_warning("Failed to start install of $clusters->[1]->{name}");
$cluster_started_ok= 0;
}
@@ -2328,9 +2623,6 @@ sub mysql_install_db () {
}
}
- # Stop clusters...
- stop_all_servers();
-
return 0;
}
@@ -2392,14 +2684,15 @@ sub install_db ($$) {
mtr_add_arg($args, "--skip-innodb");
mtr_add_arg($args, "--skip-ndbcluster");
mtr_add_arg($args, "--tmpdir=.");
+ mtr_add_arg($args, "--core-file");
if ( $opt_debug )
{
mtr_add_arg($args, "--debug=d:t:i:A,%s/log/bootstrap_%s.trace",
- $opt_vardir_trace, $type);
+ $path_vardir_trace, $type);
}
- if ( ! $opt_netware )
+ if ( ! $glob_netware )
{
mtr_add_arg($args, "--language=%s", $path_language);
mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir);
@@ -2492,9 +2785,15 @@ skip-innodb
skip-ndbcluster
EOF
;
-
+ if ( $mysql_version_id < 50100 )
+ {
+ print OUT "skip-bdb\n";
+ }
print OUT "nonguarded\n" if $instance->{'nonguarded'};
- print OUT "log-output=FILE\n" if $instance->{'old_log_format'};
+ if ( $mysql_version_id >= 50100 )
+ {
+ print OUT "log-output=FILE\n" if $instance->{'old_log_format'};
+ }
print OUT "\n";
}
@@ -2553,21 +2852,47 @@ sub run_testcase_check_skip_test($)
return 1;
}
- # If test needs cluster, check that master installed ok
- if ( $tinfo->{'ndb_test'} and !$clusters->[0]->{'installed_ok'} )
+ if ($tinfo->{'ndb_test'})
{
- mtr_report_test_name($tinfo);
- mtr_report_test_failed($tinfo);
- return 1;
+ foreach my $cluster (@{$clusters})
+ {
+ last if ($opt_skip_ndbcluster_slave and
+ $cluster->{'name'} eq 'Slave');
+
+ # If test needs this cluster, check binaries was found ok
+ if ( $cluster->{'executable_setup_failed'} )
+ {
+ mtr_report_test_name($tinfo);
+ $tinfo->{comment}=
+ "Failed to find cluster binaries";
+ mtr_report_test_failed($tinfo);
+ return 1;
+ }
+
+ # If test needs this cluster, check it was installed ok
+ if ( !$cluster->{'installed_ok'} )
+ {
+ mtr_report_test_name($tinfo);
+ $tinfo->{comment}=
+ "Cluster $cluster->{'name'} was not installed ok";
+ mtr_report_test_failed($tinfo);
+ return 1;
+ }
+
+ }
}
- # If test needs slave cluster, check that it installed ok
- if ( $tinfo->{'ndb_test'} and $tinfo->{'slave_num'} and
- !$clusters->[1]->{'installed_ok'} )
+ if ( $tinfo->{'component_id'} eq 'im' )
{
- mtr_report_test_name($tinfo);
- mtr_report_test_failed($tinfo);
- return 1;
+ # If test needs im, check binaries was found ok
+ if ( $instance_manager->{'executable_setup_failed'} )
+ {
+ mtr_report_test_name($tinfo);
+ $tinfo->{comment}=
+ "Failed to find MySQL manager binaries";
+ mtr_report_test_failed($tinfo);
+ return 1;
+ }
}
return 0;
@@ -2579,27 +2904,42 @@ sub do_before_run_mysqltest($)
my $tinfo= shift;
my $tname= $tinfo->{'name'};
- # Remove old reject file
- if ( $opt_suite eq "main" )
+ # Remove old files produced by mysqltest
+ my $result_dir= "r";
+ if ( $opt_suite ne "main" )
{
- unlink("r/$tname.reject");
- }
- else
- {
- unlink("suite/$opt_suite/r/$tname.reject");
+ $result_dir= "suite/$opt_suite/r";
}
+ unlink("$result_dir/$tname.reject");
+ unlink("$result_dir/$tname.progress");
+ unlink("$result_dir/$tname.log");
+ unlink("$result_dir/$tname.warnings");
+ if (!$opt_extern)
+ {
+ mtr_tonewfile($path_current_test_log,"$tname\n"); # Always tell where we are
-# MASV cleanup...
- mtr_tonewfile($path_current_test_log,"$tname\n"); # Always tell where we are
+ # output current test to ndbcluster log file to enable diagnostics
+ mtr_tofile($path_ndb_testrun_log,"CURRENT TEST $tname\n");
- # output current test to ndbcluster log file to enable diagnostics
- mtr_tofile($file_ndb_testrun_log,"CURRENT TEST $tname\n");
+ mtr_tofile($master->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n");
+ if ( $master->[1]->{'pid'} )
+ {
+ mtr_tofile($master->[1]->{'path_myerr'},"CURRENT_TEST: $tname\n");
+ }
+ }
- mtr_tofile($master->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n");
- if ( $master->[1]->{'pid'} )
+ if ( $mysql_version_id < 50000 )
{
- mtr_tofile($master->[1]->{'path_myerr'},"CURRENT_TEST: $tname\n");
+ # Set envirnoment variable NDB_STATUS_OK to 1
+ # if script decided to run mysqltest cluster _is_ installed ok
+ $ENV{'NDB_STATUS_OK'} = "1";
+ }
+ elsif ( $mysql_version_id < 50100 )
+ {
+ # Set envirnoment variable NDB_STATUS_OK to YES
+ # if script decided to run mysqltest cluster _is_ installed ok
+ $ENV{'NDB_STATUS_OK'} = "YES";
}
}
@@ -2608,13 +2948,94 @@ sub do_after_run_mysqltest($)
my $tinfo= shift;
my $tname= $tinfo->{'name'};
- #MASV cleanup
- # Save info from this testcase run to mysqltest.log
- my $testcase_log= mtr_fromfile($path_timefile) if -f $path_timefile;
- mtr_tofile($path_mysqltest_log,"CURRENT TEST $tname\n");
- mtr_tofile($path_mysqltest_log, $testcase_log);
+ mtr_tofile($path_mysqltest_log,"CURRENT TEST $tname\n");
+
+ # Save info from this testcase run to mysqltest.log
+ mtr_appendfile_to_file($path_timefile, $path_mysqltest_log)
+ if -f $path_timefile;
+
+ # Remove the file that mysqltest writes info to
+ unlink($path_timefile);
+
+}
+
+
+sub find_testcase_skipped_reason($)
+{
+ my ($tinfo)= @_;
+
+ # Open mysqltest.log
+ my $F= IO::File->new($path_timefile) or
+ mtr_error("can't open file \"$path_timefile\": $!");
+ my $reason;
+
+ while ( my $line= <$F> )
+ {
+ # Look for "reason: <reason fo skiping test>"
+ if ( $line =~ /reason: (.*)/ )
+ {
+ $reason= $1;
+ }
+ }
+
+ if ( ! $reason )
+ {
+ mtr_warning("Could not find reason for skipping test in $path_timefile");
+ $reason= "Detected by testcase(reason unknown) ";
}
+ $tinfo->{'comment'}= $reason;
+}
+
+
+sub analyze_testcase_failure_sync_with_master($)
+{
+ my ($tinfo)= @_;
+
+ my $args;
+ mtr_init_args(\$args);
+
+ mtr_add_arg($args, "--no-defaults");
+ mtr_add_arg($args, "--silent");
+ mtr_add_arg($args, "-v");
+ mtr_add_arg($args, "--skip-safemalloc");
+ mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir);
+
+ mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_sock'});
+ mtr_add_arg($args, "--port=%d", $master->[0]->{'port'});
+ mtr_add_arg($args, "--database=test");
+ mtr_add_arg($args, "--user=%s", $opt_user);
+ mtr_add_arg($args, "--password=");
+
+ # Run the test file and append output to log file
+ mtr_run_test($exe_mysqltest,$args,
+ "include/analyze_failure_sync_with_master.test",
+ "$path_timefile", "$path_timefile","",
+ { append_log_file => 1 });
+
+}
+
+sub analyze_testcase_failure($)
+{
+ my ($tinfo)= @_;
+
+ # Open mysqltest.log
+ my $F= IO::File->new($path_timefile) or
+ mtr_error("can't open file \"$path_timefile\": $!");
+ while ( my $line= <$F> )
+ {
+ # Look for "mysqltest: At line nnn: <error>
+ if ( $line =~ /mysqltest: At line [0-9]*: (.*)/ )
+ {
+ my $error= $1;
+ # Look for "could not sync with master"
+ if ( $error =~ /could not sync with master/ )
+ {
+ analyze_testcase_failure_sync_with_master($tinfo);
+ }
+ }
+ }
+}
##############################################################################
#
@@ -2635,17 +3056,38 @@ sub do_after_run_mysqltest($)
sub run_testcase ($) {
my $tinfo= shift;
+ # -------------------------------------------------------
+ # Init variables that can change between each test case
+ # -------------------------------------------------------
+
+ $ENV{'TZ'}= $tinfo->{'timezone'};
+ mtr_verbose("Starting server with timezone: $tinfo->{'timezone'}");
+
my $master_restart= run_testcase_need_master_restart($tinfo);
my $slave_restart= run_testcase_need_slave_restart($tinfo);
if ($master_restart or $slave_restart)
{
+ # Can't restart a running server that may be in use
+ if ( $glob_use_running_server )
+ {
+ mtr_report_test_name($tinfo);
+ $tinfo->{comment}= "Can't restart a running server";
+ mtr_report_test_skipped($tinfo);
+ return;
+ }
+
run_testcase_stop_servers($tinfo, $master_restart, $slave_restart);
}
my $died= mtr_record_dead_children();
if ($died or $master_restart or $slave_restart)
{
- run_testcase_start_servers($tinfo);
+ if (run_testcase_start_servers($tinfo))
+ {
+ mtr_report_test_name($tinfo);
+ report_failure_and_restart($tinfo);
+ return 1;
+ }
}
# ----------------------------------------------------------------------
@@ -2654,6 +3096,7 @@ sub run_testcase ($) {
# ----------------------------------------------------------------------
if ( $opt_start_and_exit or $opt_start_dirty )
{
+ mtr_timer_stop_all($glob_timers);
mtr_report("\nServers started, exiting");
exit(0);
}
@@ -2672,10 +3115,7 @@ sub run_testcase ($) {
# Testcase itself tell us to skip this one
# Try to get reason from mysqltest.log
- my $last_line= mtr_lastlinefromfile($path_timefile) if -f $path_timefile;
- my $reason= mtr_match_prefix($last_line, "reason: ");
- $tinfo->{'comment'}=
- defined $reason ? $reason : "Detected by testcase(reason unknown) ";
+ find_testcase_skipped_reason($tinfo);
mtr_report_test_skipped($tinfo);
}
elsif ( $res == 63 )
@@ -2683,16 +3123,20 @@ sub run_testcase ($) {
$tinfo->{'timeout'}= 1; # Mark as timeout
report_failure_and_restart($tinfo);
}
- else
+ elsif ( $res == 1 )
{
- # Test case failed, if in control mysqltest returns 1
- if ( $res != 1 )
+ if ( $opt_force )
{
- mtr_tofile($path_timefile,
- "mysqltest returned unexpected code $res, " .
- "it has probably crashed");
+ analyze_testcase_failure($tinfo);
}
-
+ # Test case failure reported by mysqltest
+ report_failure_and_restart($tinfo);
+ }
+ else
+ {
+ # mysqltest failed, probably crashed
+ $tinfo->{comment}=
+ "mysqltest returned unexpected code $res, it has probably crashed";
report_failure_and_restart($tinfo);
}
@@ -2702,13 +3146,10 @@ sub run_testcase ($) {
# ----------------------------------------------------------------------
# Stop Instance Manager if we are processing an IM-test case.
# ----------------------------------------------------------------------
-
- if ( ! $glob_use_running_server and $tinfo->{'component_id'} eq 'im' )
+ if ( $tinfo->{'component_id'} eq 'im' and
+ !mtr_im_stop($instance_manager, $tinfo->{'name'}) )
{
- unless ( mtr_im_stop($instance_manager, $tinfo->{'name'}) )
- {
- mtr_error("Failed to stop Instance Manager.")
- }
+ mtr_error("Failed to stop Instance Manager.")
}
}
@@ -2824,24 +3265,17 @@ sub report_failure_and_restart ($) {
##############################################################################
-# The embedded server needs the cleanup so we do some of the start work
-# but stop before actually running mysqld or anything.
-sub do_before_start_master ($$) {
- my $tname= shift;
- my $init_script= shift;
+sub do_before_start_master ($) {
+ my ($tinfo)= @_;
+
+ my $tname= $tinfo->{'name'};
+ my $init_script= $tinfo->{'master_sh'};
# FIXME what about second master.....
- # Remove stale binary logs except for 2 tests which need them FIXME here????
- if ( $tname ne "rpl_crash_binlog_ib_1b" and
- $tname ne "rpl_crash_binlog_ib_2b" and
- $tname ne "rpl_crash_binlog_ib_3b")
+ foreach my $bin ( glob("$opt_vardir/log/master*-bin*") )
{
- # FIXME we really want separate dir for binlogs
- foreach my $bin ( glob("$opt_vardir/log/master*-bin*") )
- {
- unlink($bin);
- }
+ unlink($bin);
}
# FIXME only remove the ones that are tied to this master
@@ -2861,31 +3295,23 @@ sub do_before_start_master ($$) {
# mtr_warning("$init_script exited with code $ret");
}
}
- # for gcov FIXME needed? If so we need more absolute paths
- # chdir($glob_basedir);
}
-sub do_before_start_slave ($$) {
- my $tname= shift;
- my $init_script= shift;
+sub do_before_start_slave ($) {
+ my ($tinfo)= @_;
+
+ my $tname= $tinfo->{'name'};
+ my $init_script= $tinfo->{'master_sh'};
- # Remove stale binary logs and old master.info files
- # except for too tests which need them
- if ( $tname ne "rpl_crash_binlog_ib_1b" and
- $tname ne "rpl_crash_binlog_ib_2b" and
- $tname ne "rpl_crash_binlog_ib_3b" )
+ foreach my $bin ( glob("$opt_vardir/log/slave*-bin*") )
{
- # FIXME we really want separate dir for binlogs
- foreach my $bin ( glob("$opt_vardir/log/slave*-bin*") )
- {
- unlink($bin);
- }
- # FIXME really master?!
- unlink("$slave->[0]->{'path_myddir'}/master.info");
- unlink("$slave->[0]->{'path_myddir'}/relay-log.info");
+ unlink($bin);
}
+ unlink("$slave->[0]->{'path_myddir'}/master.info");
+ unlink("$slave->[0]->{'path_myddir'}/relay-log.info");
+
# Run slave initialization shell script if one exists
if ( $init_script )
{
@@ -2924,14 +3350,18 @@ sub mysqld_arguments ($$$$$) {
$prefix= "--server-arg=";
} else {
# We can't pass embedded server --no-defaults
- mtr_add_arg($args, "%s--no-defaults", $prefix);
+ mtr_add_arg($args, "--no-defaults");
}
mtr_add_arg($args, "%s--console", $prefix);
mtr_add_arg($args, "%s--basedir=%s", $prefix, $path_my_basedir);
mtr_add_arg($args, "%s--character-sets-dir=%s", $prefix, $path_charsetsdir);
- mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix);
+ if ( $mysql_version_id >= 50000 )
+ {
+ mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix);
+ }
+
mtr_add_arg($args, "%s--default-character-set=latin1", $prefix);
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
@@ -2939,6 +3369,11 @@ sub mysqld_arguments ($$$$$) {
if ( $opt_valgrind_mysqld )
{
mtr_add_arg($args, "%s--skip-safemalloc", $prefix);
+
+ if ( $mysql_version_id < 50100 )
+ {
+ mtr_add_arg($args, "%s--skip-bdb", $prefix);
+ }
}
my $pidfile;
@@ -2980,7 +3415,10 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--ndbcluster", $prefix);
mtr_add_arg($args, "%s--ndb-connectstring=%s", $prefix,
$cluster->{'connect_string'});
- mtr_add_arg($args, "%s--ndb-extra-logging", $prefix);
+ if ( $mysql_version_id >= 50100 )
+ {
+ mtr_add_arg($args, "%s--ndb-extra-logging", $prefix);
+ }
}
}
@@ -2998,7 +3436,7 @@ sub mysqld_arguments ($$$$$) {
$opt_vardir, $sidx); # FIXME use own dir for binlogs
mtr_add_arg($args, "%s--log-slave-updates", $prefix);
}
- # FIXME option duplicated for slave
+
mtr_add_arg($args, "%s--log=%s", $prefix,
$slave->[$idx]->{'path_mylog'});
mtr_add_arg($args, "%s--master-retry-count=10", $prefix);
@@ -3019,8 +3457,9 @@ sub mysqld_arguments ($$$$$) {
# Directory where slaves find the dumps generated by "load data"
# on the server. The path need to have constant length otherwise
# test results will vary, thus a relative path is used.
+ my $slave_load_path= "../tmp";
mtr_add_arg($args, "%s--slave-load-tmpdir=%s", $prefix,
- "../tmp");
+ $slave_load_path);
mtr_add_arg($args, "%s--socket=%s", $prefix,
$slave->[$idx]->{'path_sock'});
mtr_add_arg($args, "%s--set-variable=slave_net_timeout=10", $prefix);
@@ -3055,7 +3494,10 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--ndbcluster", $prefix);
mtr_add_arg($args, "%s--ndb-connectstring=%s", $prefix,
$clusters->[$slave->[$idx]->{'cluster'}]->{'connect_string'});
- mtr_add_arg($args, "%s--ndb-extra-logging", $prefix);
+ if ( $mysql_version_id >= 50100 )
+ {
+ mtr_add_arg($args, "%s--ndb-extra-logging", $prefix);
+ }
}
} # end slave
@@ -3064,12 +3506,12 @@ sub mysqld_arguments ($$$$$) {
if ( $type eq 'master' )
{
mtr_add_arg($args, "%s--debug=d:t:i:A,%s/log/master%s.trace",
- $prefix, $opt_vardir_trace, $sidx);
+ $prefix, $path_vardir_trace, $sidx);
}
if ( $type eq 'slave' )
{
mtr_add_arg($args, "%s--debug=d:t:i:A,%s/log/slave%s.trace",
- $prefix, $opt_vardir_trace, $sidx);
+ $prefix, $path_vardir_trace, $sidx);
}
}
@@ -3077,7 +3519,6 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--key_buffer_size=1M", $prefix);
mtr_add_arg($args, "%s--sort_buffer=256K", $prefix);
mtr_add_arg($args, "%s--max_heap_table_size=1M", $prefix);
- mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix);
if ( $opt_ssl_supported )
{
@@ -3160,6 +3601,9 @@ sub mysqld_start ($$$) {
my $type= $mysqld->{'type'};
my $idx= $mysqld->{'idx'};
+ mtr_error("Internal error: mysqld should never be started for embedded")
+ if $glob_use_embedded_server;
+
if ( $type eq 'master' )
{
$exe= $exe_master_mysqld;
@@ -3211,15 +3655,6 @@ sub mysqld_start ($$$) {
$wait_for_pid_file= 0;
}
- if ($exe_libtool and $opt_valgrind)
- {
- # Add "libtool --mode-execute"
- # if running in valgrind(to avoid valgrinding bash)
- unshift(@$args, "--mode=execute", $exe);
- $exe= $exe_libtool;
- }
-
-
if ( defined $exe )
{
$pid= mtr_spawn($exe, $args, "",
@@ -3255,10 +3690,13 @@ sub stop_all_servers () {
print "Stopping All Servers\n";
- print "Shutting-down Instance Manager\n";
- unless (mtr_im_stop($instance_manager, "stop_all_servers"))
+ if ( ! $opt_skip_im )
{
- mtr_error("Failed to stop Instance Manager.")
+ print "Shutting-down Instance Manager\n";
+ unless (mtr_im_stop($instance_manager, "stop_all_servers"))
+ {
+ mtr_error("Failed to stop Instance Manager.")
+ }
}
my %admin_pids; # hash of admin processes that requests shutdown
@@ -3333,46 +3771,46 @@ sub run_testcase_need_master_restart($)
# We try to find out if we are to restart the master(s)
my $do_restart= 0; # Assumes we don't have to
- if ( $tinfo->{'master_sh'} )
+ if ( $glob_use_embedded_server )
+ {
+ mtr_verbose("Never start or restart for embedded server");
+ return $do_restart;
+ }
+ elsif ( $tinfo->{'master_sh'} )
{
$do_restart= 1; # Always restart if script to run
- mtr_verbose("Restart because: Always restart if script to run");
+ mtr_verbose("Restart master: Always restart if script to run");
+ }
+ if ( $tinfo->{'force_restart'} )
+ {
+ $do_restart= 1; # Always restart if --force-restart in -opt file
+ mtr_verbose("Restart master: Restart forced with --force-restart");
}
elsif ( ! $opt_skip_ndbcluster and
- $tinfo->{'ndb_test'} == 0 and
+ !$tinfo->{'ndb_test'} and
$clusters->[0]->{'pid'} != 0 )
{
$do_restart= 1; # Restart without cluster
- mtr_verbose("Restart because: Test does not need cluster");
+ mtr_verbose("Restart master: Test does not need cluster");
}
elsif ( ! $opt_skip_ndbcluster and
- $tinfo->{'ndb_test'} == 1 and
+ $tinfo->{'ndb_test'} and
$clusters->[0]->{'pid'} == 0 )
{
$do_restart= 1; # Restart with cluster
- mtr_verbose("Restart because: Test need cluster");
+ mtr_verbose("Restart master: Test need cluster");
}
- elsif ( $master->[0]->{'running_master_is_special'} and
- $master->[0]->{'running_master_is_special'}->{'timezone'} eq
- $tinfo->{'timezone'} and
- mtr_same_opts($master->[0]->{'running_master_is_special'}->{'master_opt'},
- $tinfo->{'master_opt'}) )
- {
- # If running master was started with special settings, but
- # the current test requires the same ones, we *don't* restart.
- $do_restart= 0;
- mtr_verbose("Skip restart: options are equal " .
- join(" ", @{$tinfo->{'master_opt'}}));
- }
- elsif ( $tinfo->{'master_restart'} )
+ elsif( $tinfo->{'component_id'} eq 'im' )
{
$do_restart= 1;
- mtr_verbose("Restart because: master_restart");
+ mtr_verbose("Restart master: Always restart for im tests");
}
- elsif ( $master->[0]->{'running_master_is_special'} )
+ elsif ( $master->[0]->{'running_master_options'} and
+ $master->[0]->{'running_master_options'}->{'timezone'} ne
+ $tinfo->{'timezone'})
{
$do_restart= 1;
- mtr_verbose("Restart because: running_master_is_special");
+ mtr_verbose("Restart master: Different timezone");
}
# Check that running master was started with same options
# as the current test requires
@@ -3380,10 +3818,15 @@ sub run_testcase_need_master_restart($)
$tinfo->{'master_opt'}) )
{
$do_restart= 1;
- mtr_verbose("Restart because: running with different options '" .
+ mtr_verbose("Restart master: running with different options '" .
join(" ", @{$tinfo->{'master_opt'}}) . "' != '" .
join(" ", @{$master->[0]->{'start_opts'}}) . "'" );
}
+ elsif( ! $master->[0]->{'pid'} )
+ {
+ $do_restart= 1;
+ mtr_verbose("Restart master: master is not started");
+ }
return $do_restart;
}
@@ -3395,57 +3838,40 @@ sub run_testcase_need_slave_restart($)
# We try to find out if we are to restart the slaves
my $do_slave_restart= 0; # Assumes we don't have to
- # FIXME only restart slave when necessary
- $do_slave_restart= 1;
-
-# if ( ! $slave->[0]->{'pid'} )
-# {
-# # mtr_verbose("Slave not started, no need to check slave restart");
-# }
-# elsif ( $do_restart )
-# {
-# $do_slave_restart= 1; # Always restart if master restart
-# mtr_verbose("Restart slave because: Master restart");
-# }
-# elsif ( $tinfo->{'slave_sh'} )
-# {
-# $do_slave_restart= 1; # Always restart if script to run
-# mtr_verbose("Restart slave because: Always restart if script to run");
-# }
-# elsif ( ! $opt_skip_ndbcluster_slave and
-# $tinfo->{'ndb_test'} == 0 and
-# $clusters->[1]->{'pid'} != 0 )
-# {
-# $do_slave_restart= 1; # Restart without slave cluster
-# mtr_verbose("Restart slave because: Test does not need slave cluster");
-# }
-# elsif ( ! $opt_with_ndbcluster_slave and
-# $tinfo->{'ndb_test'} == 1 and
-# $clusters->[1]->{'pid'} == 0 )
-# {
-# $do_slave_restart= 1; # Restart with slave cluster
-# mtr_verbose("Restart slave because: Test need slave cluster");
-# }
-# elsif ( $tinfo->{'slave_restart'} )
-# {
-# $do_slave_restart= 1;
-# mtr_verbose("Restart slave because: slave_restart");
-# }
-# elsif ( $slave->[0]->{'running_slave_is_special'} )
-# {
-# $do_slave_restart= 1;
-# mtr_verbose("Restart slave because: running_slave_is_special");
-# }
-# # Check that running slave was started with same options
-# # as the current test requires
-# elsif (! mtr_same_opts($slave->[0]->{'start_opts'},
-# $tinfo->{'slave_opt'}) )
-# {
-# $do_slave_restart= 1;
-# mtr_verbose("Restart slave because: running with different options '" .
-# join(" ", @{$tinfo->{'slave_opt'}}) . "' != '" .
-# join(" ", @{$slave->[0]->{'start_opts'}}) . "'" );
-# }
+ if ( $glob_use_embedded_server )
+ {
+ mtr_verbose("Never start or restart for embedded server");
+ return $do_slave_restart;
+ }
+ elsif ( $max_slave_num == 0)
+ {
+ mtr_verbose("Skip slave restart: No testcase use slaves");
+ }
+ else
+ {
+
+ # Check if any slave is currently started
+ my $any_slave_started= 0;
+ foreach my $mysqld (@{$slave})
+ {
+ if ( $mysqld->{'pid'} )
+ {
+ $any_slave_started= 1;
+ last;
+ }
+ }
+
+ if ($any_slave_started)
+ {
+ mtr_verbose("Restart slave: Slave is started, always restart");
+ $do_slave_restart= 1;
+ }
+ elsif ( $tinfo->{'slave_num'} )
+ {
+ mtr_verbose("Restart slave: Test need slave");
+ $do_slave_restart= 1;
+ }
+ }
return $do_slave_restart;
@@ -3464,22 +3890,16 @@ sub run_testcase_need_slave_restart($)
sub run_testcase_stop_servers($$$) {
my ($tinfo, $do_restart, $do_slave_restart)= @_;
-
- if ( $glob_use_running_server || $glob_use_embedded_server )
- {
- return;
- }
-
my $pid;
my %admin_pids; # hash of admin processes that requests shutdown
my @kill_pids; # list of processes to shutdown/kill
- # Remember if we restarted for this test case
+ # Remember if we restarted for this test case (count restarts)
$tinfo->{'restarted'}= $do_restart;
if ( $do_restart )
{
- delete $master->[0]->{'running_master_is_special'}; # Forget history
+ delete $master->[0]->{'running_master_options'}; # Forget history
# Start shutdown of all started masters
foreach my $mysqld (@{$master})
@@ -3528,8 +3948,7 @@ sub run_testcase_stop_servers($$$) {
if ( $do_restart || $do_slave_restart )
{
-
- delete $slave->[0]->{'running_slave_is_special'}; # Forget history
+ delete $slave->[0]->{'running_slave_options'}; # Forget history
# Start shutdown of all started slaves
foreach my $mysqld (@{$slave})
@@ -3600,16 +4019,21 @@ sub run_testcase_stop_servers($$$) {
}
}
+
+#
+# run_testcase_start_servers
+#
+# Start the servers needed by this test case
+#
+# RETURN
+# 0 OK
+# 1 Start failed
+#
+
sub run_testcase_start_servers($) {
my $tinfo= shift;
-
my $tname= $tinfo->{'name'};
- if ( $glob_use_running_server or $glob_use_embedded_server )
- {
- return;
- }
-
if ( $tinfo->{'component_id'} eq 'mysqld' )
{
if ( ! $opt_skip_ndbcluster and
@@ -3623,7 +4047,7 @@ sub run_testcase_start_servers($) {
if ( !$master->[0]->{'pid'} )
{
# Master mysqld is not started
- do_before_start_master($tname,$tinfo->{'master_sh'});
+ do_before_start_master($tinfo);
mysqld_start($master->[0],$tinfo->{'master_opt'},[]);
@@ -3633,27 +4057,28 @@ sub run_testcase_start_servers($) {
{
# Test needs cluster, start an extra mysqld connected to cluster
- # First wait for first mysql server to have created ndb system tables ok
- # FIXME This is a workaround so that only one mysqld creates the tables
- if ( ! sleep_until_file_created(
- "$master->[0]->{'path_myddir'}/cluster/apply_status.ndb",
- $master->[0]->{'start_timeout'},
- $master->[0]->{'pid'}))
+ if ( $mysql_version_id >= 50100 )
{
- mtr_report("Failed to create 'cluster/apply_status' table");
- report_failure_and_restart($tinfo);
- return;
+ # First wait for first mysql server to have created ndb system
+ # tables ok FIXME This is a workaround so that only one mysqld
+ # create the tables
+ if ( ! sleep_until_file_created(
+ "$master->[0]->{'path_myddir'}/cluster/apply_status.ndb",
+ $master->[0]->{'start_timeout'},
+ $master->[0]->{'pid'}))
+ {
+
+ $tinfo->{'comment'}= "Failed to create 'cluster/apply_status' table";
+ return 1;
+ }
}
mtr_tofile($master->[1]->{'path_myerr'},"CURRENT_TEST: $tname\n");
mysqld_start($master->[1],$tinfo->{'master_opt'},[]);
}
- if ( $tinfo->{'master_restart'} )
- {
- # Save this test case information, so next can examine it
- $master->[0]->{'running_master_is_special'}= $tinfo;
- }
+ # Save this test case information, so next can examine it
+ $master->[0]->{'running_master_options'}= $tinfo;
}
elsif ( ! $opt_skip_im and $tinfo->{'component_id'} eq 'im' )
{
@@ -3664,12 +4089,10 @@ sub run_testcase_start_servers($) {
im_create_defaults_file($instance_manager);
- unless ( mtr_im_start($instance_manager, $tinfo->{im_opts}) )
+ if ( ! mtr_im_start($instance_manager, $tinfo->{im_opts}) )
{
- report_failure_and_restart($tinfo);
- mtr_report("Failed to start Instance Manager. " .
- "The test '$tname' is marked as failed.");
- return;
+ $tinfo->{'comment'}= "Failed to start Instance Manager. ";
+ return 1;
}
}
@@ -3682,7 +4105,7 @@ sub run_testcase_start_servers($) {
restore_slave_databases($tinfo->{'slave_num'});
- do_before_start_slave($tname,$tinfo->{'slave_sh'});
+ do_before_start_slave($tinfo);
if ( ! $opt_skip_ndbcluster_slave and
!$clusters->[1]->{'pid'} and
@@ -3702,12 +4125,8 @@ sub run_testcase_start_servers($) {
}
}
- if ( $tinfo->{'slave_restart'} )
- {
- # Save this test case information, so next can examine it
- $slave->[0]->{'running_slave_is_special'}= $tinfo;
- }
-
+ # Save this test case information, so next can examine it
+ $slave->[0]->{'running_slave_options'}= $tinfo;
}
# Wait for clusters to start
@@ -3719,7 +4138,8 @@ sub run_testcase_start_servers($) {
if (ndbcluster_wait_started($cluster, ""))
{
# failed to start
- mtr_report("Start of $cluster->{'name'} cluster failed, ");
+ $tinfo->{'comment'}= "Start of $cluster->{'name'} cluster failed";
+ return 1;
}
}
@@ -3731,9 +4151,13 @@ sub run_testcase_start_servers($) {
if (mysqld_wait_started($mysqld))
{
- mtr_warning("Failed to start $mysqld->{'type'} mysqld $mysqld->{'idx'}");
+ # failed to start
+ $tinfo->{'comment'}=
+ "Failed to start $mysqld->{'type'} mysqld $mysqld->{'idx'}";
+ return 1;
}
}
+ return 0;
}
#
@@ -3741,6 +4165,10 @@ sub run_testcase_start_servers($) {
# Before a testcase, run in record mode, save result file to var
# After testcase, run and compare with the recorded file, they should be equal!
#
+# RETURN VALUE
+# 0 OK
+# 1 Check failed
+#
sub run_check_testcase ($$) {
my $mode= shift;
@@ -3774,7 +4202,7 @@ sub run_check_testcase ($$) {
my $res = mtr_run_test($exe_mysqltest,$args,
"include/check-testcase.test", "", "", "");
- if ( $res == 1 and $mode = "after")
+ if ( $res == 1 and $mode eq "after")
{
mtr_run("diff",["-u",
"$opt_vardir/tmp/$name.result",
@@ -3785,6 +4213,7 @@ sub run_check_testcase ($$) {
{
mtr_error("Could not execute 'check-testcase' $mode testcase");
}
+ return $res;
}
@@ -3856,11 +4285,6 @@ sub run_mysqltest ($) {
mtr_add_arg($args, "--big-test");
}
- if ( $opt_valgrind )
- {
- mtr_add_arg($args, "--valgrind");
- }
-
if ( $opt_compress )
{
mtr_add_arg($args, "--compress");
@@ -3874,7 +4298,7 @@ sub run_mysqltest ($) {
if ( $opt_debug )
{
mtr_add_arg($args, "--debug=d:t:A,%s/log/mysqltest.trace",
- $opt_vardir_trace);
+ $path_vardir_trace);
}
if ( $opt_ssl_supported )
@@ -3952,14 +4376,6 @@ sub run_mysqltest ($) {
debugger_arguments(\$args, \$exe, "client");
}
- if ($exe_libtool and $opt_valgrind)
- {
- # Add "libtool --mode-execute" before the test to execute
- # if running in valgrind(to avoid valgrinding bash)
- unshift(@$args, "--mode=execute", $exe);
- $exe= $exe_libtool;
- }
-
if ( $opt_check_testcases )
{
foreach my $mysqld (@{$master}, @{$slave})
@@ -3971,11 +4387,6 @@ sub run_mysqltest ($) {
}
}
- # -------------------------------------------------------
- # Init variables that change for each testcase
- # -------------------------------------------------------
- $ENV{'TZ'}= $tinfo->{'timezone'};
-
my $res = mtr_run_test($exe,$args,"","",$path_timefile,"");
if ( $opt_check_testcases )
@@ -3984,13 +4395,16 @@ sub run_mysqltest ($) {
{
if ($mysqld->{'pid'})
{
- run_check_testcase("after", $mysqld);
+ if (run_check_testcase("after", $mysqld))
+ {
+ # Check failed, mark the test case with that info
+ $tinfo->{'check_testcase_failed'}= 1;
+ }
}
}
}
return $res;
-
}
@@ -4186,6 +4600,14 @@ sub valgrind_arguments {
mtr_add_arg($args, $$exe);
$$exe= $opt_valgrind_path || "valgrind";
+
+ if ($exe_libtool)
+ {
+ # Add "libtool --mode-execute" before the test to execute
+ # if running in valgrind(to avoid valgrinding bash)
+ unshift(@$args, "--mode=execute", $$exe);
+ $$exe= $exe_libtool;
+ }
}
@@ -4205,9 +4627,7 @@ sub usage ($) {
print STDERR <<HERE;
-mysql-test-run [ OPTIONS ] [ TESTCASE ]
-
-FIXME when is TESTCASE arg used or not?!
+$0 [ OPTIONS ] [ TESTCASE ]
Options to control what engine/variation to run
@@ -4222,6 +4642,9 @@ Options to control what engine/variation to run
skip-ssl Dont start server with support for ssl connections
bench Run the benchmark suite
small-bench Run the benchmarks with --small-tests --small-tables
+ with-ndbcluster Use cluster as default table type for benchmark
+ vs-config Visual Studio configuration used to create executables
+ (default: MTR_VS_CONFIG environment variable)
Options to control directories to use
benchdir=DIR The directory where the benchmark suite is stored
@@ -4231,11 +4654,13 @@ Options to control directories to use
vardir=DIR The directory where files generated from the test run
is stored (default: ./var). Specifying a ramdisk or
tmpfs will speed up tests.
+ mem Run testsuite in "memory" using tmpfs if
+ available(default: /dev/shm)
+ reads path from MTR_MEM environment variable
Options to control what test suites or cases to run
force Continue to run the suite after failure
- with-ndbcluster Use cluster in all tests
with-ndbcluster-only Run only tests that include "ndb" in the filename
skip-ndb[cluster] Skip all tests that need cluster
skip-ndb[cluster]-slave Skip all tests that need a slave cluster
@@ -4297,7 +4722,8 @@ Options for coverage, profiling etc
valgrind Run the "mysqltest" and "mysqld" executables using
valgrind with options($default_valgrind_options)
valgrind-all Synonym for --valgrind
- valgrind-mysqltest Run the "mysqltest" executable with valgrind
+ valgrind-mysqltest Run the "mysqltest" and "mysql_client_test" executable
+ with valgrind
valgrind-mysqld Run the "mysqld" executable with valgrind
valgrind-options=ARGS Options to give valgrind, replaces default options
valgrind-path=[EXE] Path to the valgrind executable
diff --git a/mysql-test/r/binlog_row_mix_innodb_myisam.result b/mysql-test/r/binlog_row_mix_innodb_myisam.result
index a192d243bb0..e063d7371a9 100644
--- a/mysql-test/r/binlog_row_mix_innodb_myisam.result
+++ b/mysql-test/r/binlog_row_mix_innodb_myisam.result
@@ -220,7 +220,7 @@ select (@before:=unix_timestamp())*0;
(@before:=unix_timestamp())*0
0
begin;
- select * from t1 for update;
+select * from t1 for update;
insert into t2 values (20);
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
select (@after:=unix_timestamp())*0;
diff --git a/mysql-test/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/r/binlog_stm_mix_innodb_myisam.result
index 95b6eb953a2..8ab6840d441 100644
--- a/mysql-test/r/binlog_stm_mix_innodb_myisam.result
+++ b/mysql-test/r/binlog_stm_mix_innodb_myisam.result
@@ -195,7 +195,7 @@ select (@before:=unix_timestamp())*0;
(@before:=unix_timestamp())*0
0
begin;
- select * from t1 for update;
+select * from t1 for update;
insert into t2 values (20);
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
select (@after:=unix_timestamp())*0;
diff --git a/mysql-test/r/check.result b/mysql-test/r/check.result
index 4c565f4f1b1..60806e7393e 100644
--- a/mysql-test/r/check.result
+++ b/mysql-test/r/check.result
@@ -1,6 +1,6 @@
drop table if exists t1;
create table t1(n int not null, key(n), key(n), key(n), key(n));
- check table t1 extended;
+check table t1 extended;
insert into t1 values (200000);
Table Op Msg_type Msg_text
test.t1 check status OK
diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result
index 222d4de8059..32ca47e20d2 100644
--- a/mysql-test/r/csv.result
+++ b/mysql-test/r/csv.result
@@ -4913,8 +4913,7 @@ bonfire
Colombo
nondecreasing
DROP TABLE t1;
-ALTER TABLE t2 RENAME t1
-#;
+ALTER TABLE t2 RENAME t1;
DROP TABLE t1;
CREATE TABLE t1 (
Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result
index 53b2ea8c84a..24f1b654733 100644
--- a/mysql-test/r/drop.result
+++ b/mysql-test/r/drop.result
@@ -79,9 +79,9 @@ drop table if exists t1;
create table t1 (i int);
lock tables t1 read;
create database mysqltest;
- drop table t1;
+drop table t1;
show open tables;
- drop database mysqltest;
+drop database mysqltest;
select 1;
1
1
diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result
index 08be6924e03..363033e487a 100644
--- a/mysql-test/r/events_bugs.result
+++ b/mysql-test/r/events_bugs.result
@@ -206,13 +206,13 @@ drop event events_test.mysqltest_user1;
drop user mysqltest_user1@localhost;
drop database mysqltest_db1;
create event e_53 on schedule at (select s1 from ttx) do drop table t;
-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 s1 from ttx) do drop table t' at line 1
+ERROR 42000: This version of MySQL doesn't yet support 'Usage of subqueries or stored function calls as part of this statement'
create event e_53 on schedule every (select s1 from ttx) second do drop table t;
-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 s1 from ttx) second do drop table t' at line 1
+ERROR 42000: This version of MySQL doesn't yet support 'Usage of subqueries or stored function calls as part of this statement'
create event e_53 on schedule every 5 second starts (select s1 from ttx) do drop table t;
-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 s1 from ttx) do drop table t' at line 1
+ERROR 42000: This version of MySQL doesn't yet support 'Usage of subqueries or stored function calls as part of this statement'
create event e_53 on schedule every 5 second ends (select s1 from ttx) do drop table t;
-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 s1 from ttx) do drop table t' at line 1
+ERROR 42000: This version of MySQL doesn't yet support 'Usage of subqueries or stored function calls as part of this statement'
drop event if exists e_16;
drop procedure if exists p_16;
create event e_16 on schedule every 1 second do set @a=5;
@@ -226,4 +226,46 @@ set @a= 6;
call p_16();
drop procedure p_16;
drop event e_16;
+drop function if exists f22830;
+drop event if exists e22830;
+drop event if exists e22830_1;
+drop event if exists e22830_2;
+drop event if exists e22830_3;
+drop event if exists e22830_4;
+drop table if exists t1;
+drop table if exists t2;
+create table t1 (a int);
+insert into t1 values (2);
+create table t2 (a char(20));
+insert into t2 values ("e22830_1");
+create function f22830 () returns int return 5;
+create event e22830 on schedule every f22830() second do select 123;
+ERROR 42000: This version of MySQL doesn't yet support 'Usage of subqueries or stored function calls as part of this statement'
+create event e22830_1 on schedule every 1 hour do alter event e22830_1 on schedule every (select 8 from dual) hour;
+create event e22830_2 on schedule every 1 hour do alter event e22830_2 on schedule every (select 8 from t1) hour;
+create event e22830_3 on schedule every 1 hour do alter event e22830_3 on schedule every f22830() hour;
+create event e22830_4 on schedule every 1 hour do alter event e22830_4 on schedule every (select f22830() from dual) hour;
+select event_name, event_definition, interval_value, interval_field from information_schema.events order by event_name;
+event_name event_definition interval_value interval_field
+e22830_1 alter event e22830_1 on schedule every (select 8 from dual) hour 1 HOUR
+e22830_2 alter event e22830_2 on schedule every (select 8 from t1) hour 1 HOUR
+e22830_3 alter event e22830_3 on schedule every f22830() hour 1 HOUR
+e22830_4 alter event e22830_4 on schedule every (select f22830() from dual) hour 1 HOUR
+set global event_scheduler=on;
+set global event_scheduler=off;
+select event_name, event_definition, interval_value, interval_field from information_schema.events order by event_name;
+event_name event_definition interval_value interval_field
+e22830_1 alter event e22830_1 on schedule every (select 8 from dual) hour 8 HOUR
+e22830_2 alter event e22830_2 on schedule every (select 8 from t1) hour 1 HOUR
+e22830_3 alter event e22830_3 on schedule every f22830() hour 1 HOUR
+e22830_4 alter event e22830_4 on schedule every (select f22830() from dual) hour 1 HOUR
+drop function f22830;
+drop event (select a from t2);
+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 a from t2)' at line 1
+drop event e22830_1;
+drop event e22830_2;
+drop event e22830_3;
+drop event e22830_4;
+drop table t1;
+drop table t2;
drop database events_test;
diff --git a/mysql-test/r/events_grant.result b/mysql-test/r/events_grant.result
index eda0759d518..a28c30a9345 100644
--- a/mysql-test/r/events_grant.result
+++ b/mysql-test/r/events_grant.result
@@ -4,7 +4,7 @@ CREATE EVENT one_event ON SCHEDULE EVERY 10 SECOND DO SELECT 123;
SHOW EVENTS;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test one_event root@localhost RECURRING NULL 10 SECOND # # ENABLED
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from information_schema.events;
+SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME;
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
NULL events_test one_event root@localhost SQL SELECT 123 RECURRING NULL 10 SECOND ENABLED NOT PRESERVE
CREATE DATABASE events_test2;
@@ -57,37 +57,37 @@ USE events_test2;
CREATE EVENT four_event ON SCHEDULE EVERY 20 SECOND DO SELECT 42;
USE events_test;
"We should see 4 events : one_event, two_event, three_event & four_event"
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS;
+SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME;
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
NULL events_test one_event root@localhost SQL SELECT 123 RECURRING NULL 10 SECOND ENABLED NOT PRESERVE
-NULL events_test two_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE two event
NULL events_test three_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED PRESERVE three event
+NULL events_test two_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE two event
NULL events_test2 four_event ev_test@localhost SQL SELECT 42 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE
DROP DATABASE events_test2;
"We should see 3 events : one_event, two_event, three_event"
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS;
+SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME;
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
NULL events_test one_event root@localhost SQL SELECT 123 RECURRING NULL 10 SECOND ENABLED NOT PRESERVE
-NULL events_test two_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE two event
NULL events_test three_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED PRESERVE three event
+NULL events_test two_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE two event
CREATE DATABASE events_test2;
USE events_test2;
CREATE EVENT five_event ON SCHEDULE EVERY 20 SECOND DO SELECT 42;
"Should see 4 events - one, two, three & five"
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS;
+SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME;
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
NULL events_test one_event root@localhost SQL SELECT 123 RECURRING NULL 10 SECOND ENABLED NOT PRESERVE
-NULL events_test two_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE two event
NULL events_test three_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED PRESERVE three event
+NULL events_test two_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE two event
NULL events_test2 five_event root@localhost SQL SELECT 42 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE
REVOKE EVENT ON events_test2.* FROM ev_test@localhost;
USE test;
"Should see 3 events - one, two & three"
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS;
+SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME;
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
NULL events_test one_event root@localhost SQL SELECT 123 RECURRING NULL 10 SECOND ENABLED NOT PRESERVE
-NULL events_test two_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE two event
NULL events_test three_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED PRESERVE three event
+NULL events_test two_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE two event
"Let's test ALTER EVENT which changes the definer"
USE events_test;
ALTER EVENT one_event ON SCHEDULE EVERY 10 SECOND;
@@ -111,10 +111,10 @@ ALTER EVENT one_event COMMENT "new comment";
"test DROP by another user"
DROP EVENT one_event;
"One event should not be there"
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS;
+SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME;
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
-NULL events_test two_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE two event
NULL events_test three_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED PRESERVE three event
+NULL events_test two_event ev_test@localhost SQL SELECT 123 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE two event
NULL events_test2 five_event root@localhost SQL SELECT 42 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE
DROP USER ev_test@localhost;
DROP DATABASE events_test2;
diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result
index a7f5e5e8fec..7eb7fd16edb 100644
--- a/mysql-test/r/flush.result
+++ b/mysql-test/r/flush.result
@@ -9,13 +9,13 @@ n
flush tables with read lock;
drop table t2;
ERROR HY000: Can't execute the query because you have a conflicting read lock
- drop table t2;
+drop table t2;
unlock tables;
create database mysqltest;
create table mysqltest.t1(n int);
insert into mysqltest.t1 values (23);
flush tables with read lock;
- drop database mysqltest;
+drop database mysqltest;
select * from mysqltest.t1;
n
23
@@ -51,7 +51,7 @@ drop table t1, t2, t3;
create table t1 (c1 int);
create table t2 (c1 int);
lock table t1 write;
- flush tables with read lock;
- insert into t2 values(1);
+flush tables with read lock;
+insert into t2 values(1);
unlock tables;
drop table t1, t2;
diff --git a/mysql-test/r/flush_block_commit.result b/mysql-test/r/flush_block_commit.result
index e4a9dfcfff1..56f8acab896 100644
--- a/mysql-test/r/flush_block_commit.result
+++ b/mysql-test/r/flush_block_commit.result
@@ -5,7 +5,7 @@ insert into t1 values(1);
flush tables with read lock;
select * from t1;
a
- commit;
+commit;
select * from t1;
a
unlock tables;
@@ -14,8 +14,8 @@ select * from t1 for update;
a
1
begin;
- select * from t1 for update;
- flush tables with read lock;
+select * from t1 for update;
+flush tables with read lock;
commit;
a
1
@@ -45,7 +45,7 @@ flush tables with read lock;
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 102
- commit;
+commit;
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 102
diff --git a/mysql-test/r/flush_read_lock_kill.result b/mysql-test/r/flush_read_lock_kill.result
index dfdcf51457a..6703b6bd533 100644
--- a/mysql-test/r/flush_read_lock_kill.result
+++ b/mysql-test/r/flush_read_lock_kill.result
@@ -1,7 +1,7 @@
drop table if exists t1;
create table t1 (kill_id int);
insert into t1 values(connection_id());
- flush tables with read lock;
+flush tables with read lock;
select ((@id := kill_id) - kill_id) from t1;
((@id := kill_id) - kill_id)
0
diff --git a/mysql-test/r/flush_table.result b/mysql-test/r/flush_table.result
index b29c83eb574..8821bade6b4 100644
--- a/mysql-test/r/flush_table.result
+++ b/mysql-test/r/flush_table.result
@@ -9,7 +9,7 @@ test.t1 check status OK
unlock tables;
lock table t1 read;
lock table t1 read;
- flush table t1;
+flush table t1;
select * from t1;
a
1
@@ -19,7 +19,7 @@ a
1
unlock tables;
lock table t1 write;
- lock table t1 read;
+lock table t1 read;
flush table t1;
select * from t1;
a
@@ -27,7 +27,7 @@ a
unlock tables;
unlock tables;
lock table t1 read;
- lock table t1 write;
+lock table t1 write;
flush table t1;
select * from t1;
a
diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result
index 1a5e64978e6..715f319198c 100644
--- a/mysql-test/r/func_compress.result
+++ b/mysql-test/r/func_compress.result
@@ -79,6 +79,16 @@ uncompress(a) uncompressed_length(a)
NULL NULL
a 1
drop table t1;
+create table t1(a blob);
+insert into t1 values ('0'), (NULL), ('0');
+select compress(a), compress(a) from t1;
+select compress(a) is null from t1;
+compress(a) is null
+0
+1
+0
+drop table t1;
+End of 4.1 tests
create table t1 (a varchar(32) not null);
insert into t1 values ('foo');
explain select * from t1 where uncompress(a) is null;
diff --git a/mysql-test/r/func_date_add.result b/mysql-test/r/func_date_add.result
index 841d13a6ea6..ac5709260fd 100644
--- a/mysql-test/r/func_date_add.result
+++ b/mysql-test/r/func_date_add.result
@@ -71,3 +71,17 @@ NULL
NULL
NULL
drop table t1;
+End of 4.1 tests
+SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 DAY;
+CAST('2006-09-26' AS DATE) + INTERVAL 1 DAY
+2006-09-27
+SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 MONTH;
+CAST('2006-09-26' AS DATE) + INTERVAL 1 MONTH
+2006-10-26
+SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR;
+CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR
+2007-09-26
+SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK;
+CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK
+2006-10-03
+End of 5.0 tests
diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result
index 4bd18ae589e..9a2c55b802d 100644
--- a/mysql-test/r/func_math.result
+++ b/mysql-test/r/func_math.result
@@ -102,6 +102,18 @@ Note 1003 select pi() AS `pi()`,format(sin((pi() / 2)),6) AS `format(sin(pi()/2)
select degrees(pi()),radians(360);
degrees(pi()) radians(360)
180 6.2831853071796
+select format(atan(-2, 2), 6);
+format(atan(-2, 2), 6)
+-0.785398
+select format(atan(pi(), 0), 6);
+format(atan(pi(), 0), 6)
+1.570796
+select format(atan2(-2, 2), 6);
+format(atan2(-2, 2), 6)
+-0.785398
+select format(atan2(pi(), 0), 6);
+format(atan2(pi(), 0), 6)
+1.570796
SELECT ACOS(1.0);
ACOS(1.0)
0
diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
index f383a717a85..3ebf071a5bb 100644
--- a/mysql-test/r/func_misc.result
+++ b/mysql-test/r/func_misc.result
@@ -63,7 +63,7 @@ FROM t1
WHERE conn = 'default';
IS_USED_LOCK('bug16501') = connection_id
1
- SELECT GET_LOCK('bug16501',600);
+SELECT GET_LOCK('bug16501',600);
SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID();
IS_USED_LOCK('bug16501') = CONNECTION_ID()
1
diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result
index 7e9bba9710c..29ceb6ecaa4 100644
--- a/mysql-test/r/func_sapdb.result
+++ b/mysql-test/r/func_sapdb.result
@@ -107,7 +107,9 @@ subtime("02:01:01.999999", "01:01:01.999999")
01:00:00.000000
select timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002");
timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002")
-8807:59:59.999999
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '8807:59:59.999999'
select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002");
timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002")
46:58:57.999999
@@ -219,13 +221,16 @@ SELECT TIMEDIFF(t1, t4) As ttt, TIMEDIFF(t2, t3) As qqq,
TIMEDIFF(t3, t2) As eee, TIMEDIFF(t2, t4) As rrr from test;
ttt qqq eee rrr
-744:00:00 NULL NULL NULL
-26305:01:02 22:58:58 -22:58:58 NULL
--26305:01:02 -22:58:58 22:58:58 NULL
+838:59:59 22:58:58 -22:58:58 NULL
+-838:59:59 -22:58:58 22:58:58 NULL
NULL 26:02:02 -26:02:02 NULL
00:00:00 -26:02:02 26:02:02 NULL
NULL NULL NULL NULL
NULL NULL NULL NULL
00:00:00 -24:00:00 24:00:00 NULL
+Warnings:
+Warning 1292 Truncated incorrect time value: '26305:01:02'
+Warning 1292 Truncated incorrect time value: '-26305:01:02'
drop table t1, test;
select addtime("-01:01:01.01", "-23:59:59.1") as a;
a
@@ -235,7 +240,9 @@ a
10000
select microsecond(19971231235959.01) as a;
a
-10000
+0
+Warnings:
+Warning 1292 Truncated incorrect time value: '19971231235959.01'
select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a;
a
1997-12-31 00:00:10.090000
diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result
index e421fa04ecc..9a5cc666ca8 100644
--- a/mysql-test/r/func_test.result
+++ b/mysql-test/r/func_test.result
@@ -182,6 +182,81 @@ select 5.1 mod 3, 5.1 mod -3, -5.1 mod 3, -5.1 mod -3;
select 5 mod 3, 5 mod -3, -5 mod 3, -5 mod -3;
5 mod 3 5 mod -3 -5 mod 3 -5 mod -3
2 2 -2 -2
+select (12%0) <=> null as '1';
+1
+1
+select (12%0) is null as '1';
+1
+1
+select 12%0 as 'NULL';
+NULL
+NULL
+select 12%2 as '0';
+0
+0
+select 12%NULL as 'NULL';
+NULL
+NULL
+select 12 % null as 'NULL';
+NULL
+NULL
+select null % 12 as 'NULL';
+NULL
+NULL
+select null % 0 as 'NULL';
+NULL
+NULL
+select 0 % null as 'NULL';
+NULL
+NULL
+select null % null as 'NULL';
+NULL
+NULL
+select (12 mod 0) <=> null as '1';
+1
+1
+select (12 mod 0) is null as '1';
+1
+1
+select 12 mod 0 as 'NULL';
+NULL
+NULL
+select 12 mod 2 as '0';
+0
+0
+select 12 mod null as 'NULL';
+NULL
+NULL
+select null mod 12 as 'NULL';
+NULL
+NULL
+select null mod 0 as 'NULL';
+NULL
+NULL
+select 0 mod null as 'NULL';
+NULL
+NULL
+select null mod null as 'NULL';
+NULL
+NULL
+select mod(12.0, 0) as 'NULL';
+NULL
+NULL
+select mod(12, 0.0) as 'NULL';
+NULL
+NULL
+select mod(12, NULL) as 'NULL';
+NULL
+NULL
+select mod(12.0, NULL) as 'NULL';
+NULL
+NULL
+select mod(NULL, 2) as 'NULL';
+NULL
+NULL
+select mod(NULL, 2.0) as 'NULL';
+NULL
+NULL
create table t1 (a int, b int);
insert into t1 values (1,2), (2,3), (3,4), (4,5);
select * from t1 where a not between 1 and 2;
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 82c361edd39..d7f65e84462 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -339,7 +339,9 @@ extract(DAY_MINUTE FROM "02 10:11:12")
21011
select extract(DAY_SECOND FROM "225 10:11:12");
extract(DAY_SECOND FROM "225 10:11:12")
-225101112
+8385959
+Warnings:
+Warning 1292 Truncated incorrect time value: '225 10:11:12'
select extract(HOUR FROM "1999-01-02 10:11:12");
extract(HOUR FROM "1999-01-02 10:11:12")
10
@@ -548,12 +550,48 @@ unix_timestamp('1969-12-01 19:00:01')
select from_unixtime(-1);
from_unixtime(-1)
NULL
-select from_unixtime(2145916800);
-from_unixtime(2145916800)
+select from_unixtime(2147483647);
+from_unixtime(2147483647)
+2038-01-19 06:14:07
+select from_unixtime(2147483648);
+from_unixtime(2147483648)
NULL
select from_unixtime(0);
from_unixtime(0)
1970-01-01 03:00:00
+select unix_timestamp(from_unixtime(2147483647));
+unix_timestamp(from_unixtime(2147483647))
+2147483647
+select unix_timestamp(from_unixtime(2147483648));
+unix_timestamp(from_unixtime(2147483648))
+NULL
+select unix_timestamp('2039-01-20 01:00:00');
+unix_timestamp('2039-01-20 01:00:00')
+0
+select unix_timestamp('1968-01-20 01:00:00');
+unix_timestamp('1968-01-20 01:00:00')
+0
+select unix_timestamp('2038-02-10 01:00:00');
+unix_timestamp('2038-02-10 01:00:00')
+0
+select unix_timestamp('1969-11-20 01:00:00');
+unix_timestamp('1969-11-20 01:00:00')
+0
+select unix_timestamp('2038-01-20 01:00:00');
+unix_timestamp('2038-01-20 01:00:00')
+0
+select unix_timestamp('1969-12-30 01:00:00');
+unix_timestamp('1969-12-30 01:00:00')
+0
+select unix_timestamp('2038-01-17 12:00:00');
+unix_timestamp('2038-01-17 12:00:00')
+2147331600
+select unix_timestamp('1970-01-01 03:00:01');
+unix_timestamp('1970-01-01 03:00:01')
+1
+select unix_timestamp('2038-01-19 07:14:07');
+unix_timestamp('2038-01-19 07:14:07')
+0
CREATE TABLE t1 (datetime datetime, timestamp timestamp, date date, time time);
INSERT INTO t1 values ("2001-01-02 03:04:05", "2002-01-02 03:04:05", "2003-01-02", "06:07:08");
SELECT * from t1;
@@ -612,7 +650,7 @@ date_add(date,INTERVAL "1 1:1:1" DAY_SECOND)
2003-01-03 01:01:01
select date_add(date,INTERVAL "1" WEEK) from t1;
date_add(date,INTERVAL "1" WEEK)
-2003-01-09 00:00:00
+2003-01-09
select date_add(date,INTERVAL "1" QUARTER) from t1;
date_add(date,INTERVAL "1" QUARTER)
2003-04-02
@@ -621,7 +659,7 @@ timestampadd(MINUTE, 1, date)
2003-01-02 00:01:00
select timestampadd(WEEK, 1, date) from t1;
timestampadd(WEEK, 1, date)
-2003-01-09 00:00:00
+2003-01-09
select timestampadd(SQL_TSI_SECOND, 1, date) from t1;
timestampadd(SQL_TSI_SECOND, 1, date)
2003-01-02 00:00:01
@@ -890,6 +928,93 @@ t1 CREATE TABLE `t1` (
`from_unixtime(1) + 0` double(23,6) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+SELECT SEC_TO_TIME(3300000);
+SEC_TO_TIME(3300000)
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '3300000'
+SELECT SEC_TO_TIME(3300000)+0;
+SEC_TO_TIME(3300000)+0
+8385959.000000
+Warnings:
+Warning 1292 Truncated incorrect time value: '3300000'
+SELECT SEC_TO_TIME(3600 * 4294967296);
+SEC_TO_TIME(3600 * 4294967296)
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '15461882265600'
+SELECT TIME_TO_SEC('916:40:00');
+TIME_TO_SEC('916:40:00')
+3020399
+Warnings:
+Warning 1292 Truncated incorrect time value: '916:40:00'
+SELECT ADDTIME('500:00:00', '416:40:00');
+ADDTIME('500:00:00', '416:40:00')
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '916:40:00'
+SELECT ADDTIME('916:40:00', '416:40:00');
+ADDTIME('916:40:00', '416:40:00')
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '916:40:00'
+Warning 1292 Truncated incorrect time value: '1255:39:59'
+SELECT SUBTIME('916:40:00', '416:40:00');
+SUBTIME('916:40:00', '416:40:00')
+422:19:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '916:40:00'
+SELECT SUBTIME('-916:40:00', '416:40:00');
+SUBTIME('-916:40:00', '416:40:00')
+-838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '-916:40:00'
+Warning 1292 Truncated incorrect time value: '-1255:39:59'
+SELECT MAKETIME(916,0,0);
+MAKETIME(916,0,0)
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '916:00:00'
+SELECT MAKETIME(4294967296, 0, 0);
+MAKETIME(4294967296, 0, 0)
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '4294967296:00:00'
+SELECT MAKETIME(-4294967296, 0, 0);
+MAKETIME(-4294967296, 0, 0)
+-838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '-4294967296:00:00'
+SELECT MAKETIME(0, 4294967296, 0);
+MAKETIME(0, 4294967296, 0)
+NULL
+SELECT MAKETIME(0, 0, 4294967296);
+MAKETIME(0, 0, 4294967296)
+NULL
+SELECT MAKETIME(CAST(-1 AS UNSIGNED), 0, 0);
+MAKETIME(CAST(-1 AS UNSIGNED), 0, 0)
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '18446744073709551615:00:00'
+SELECT EXTRACT(HOUR FROM '100000:02:03');
+EXTRACT(HOUR FROM '100000:02:03')
+838
+Warnings:
+Warning 1292 Truncated incorrect time value: '100000:02:03'
+CREATE TABLE t1(f1 TIME);
+INSERT INTO t1 VALUES('916:00:00 a');
+Warnings:
+Warning 1265 Data truncated for column 'f1' at row 1
+Warning 1264 Out of range value for column 'f1' at row 1
+SELECT * FROM t1;
+f1
+838:59:59
+DROP TABLE t1;
+SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED));
+SEC_TO_TIME(CAST(-1 AS UNSIGNED))
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '18446744073709551615'
SET NAMES latin1;
SET character_set_results = NULL;
SHOW VARIABLES LIKE 'character_set_results';
@@ -922,18 +1047,6 @@ union
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%k') As H);
H
5
-SET NAMES latin1;
-SET character_set_results = NULL;
-SHOW VARIABLES LIKE 'character_set_results';
-Variable_name Value
-character_set_results
-CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY);
-INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd');
-SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868;
-fmtddate field2
-Sep-4 12:00AM abcd
-DROP TABLE testBug8868;
-SET NAMES DEFAULT;
End of 4.1 tests
explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1,
timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2;
diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result
index 79ba073a856..4b089c1d5e9 100644
--- a/mysql-test/r/grant2.result
+++ b/mysql-test/r/grant2.result
@@ -336,12 +336,12 @@ drop database mysqltest_1;
set password = password("changed");
ERROR 42000: Access denied for user ''@'localhost' to database 'mysql'
lock table mysql.user write;
- flush privileges;
- grant all on *.* to 'mysqltest_1'@'localhost';
+flush privileges;
+grant all on *.* to 'mysqltest_1'@'localhost';
unlock tables;
lock table mysql.user write;
- set password for 'mysqltest_1'@'localhost' = password('');
- revoke all on *.* from 'mysqltest_1'@'localhost';
+set password for 'mysqltest_1'@'localhost' = password('');
+revoke all on *.* from 'mysqltest_1'@'localhost';
unlock tables;
drop user 'mysqltest_1'@'localhost';
create database TESTDB;
diff --git a/mysql-test/r/handler_innodb.result b/mysql-test/r/handler_innodb.result
index 89569d918ca..1bd50612a3f 100644
--- a/mysql-test/r/handler_innodb.result
+++ b/mysql-test/r/handler_innodb.result
@@ -476,7 +476,7 @@ handler t1 read first;
c1
1
send the below to another connection, do not wait for the result
- optimize table t1;
+optimize table t1;
proceed with the normal connection
handler t1 read next;
c1
@@ -502,7 +502,7 @@ flush tables with read lock;
drop table t1;
ERROR HY000: Can't execute the query because you have a conflicting read lock
send the below to another connection, do not wait for the result
- drop table t1;
+drop table t1;
proceed with the normal connection
select * from t1;
c1
diff --git a/mysql-test/r/handler_myisam.result b/mysql-test/r/handler_myisam.result
index 8edf191b1b0..beb1a40c318 100644
--- a/mysql-test/r/handler_myisam.result
+++ b/mysql-test/r/handler_myisam.result
@@ -476,7 +476,7 @@ handler t1 read first;
c1
1
send the below to another connection, do not wait for the result
- optimize table t1;
+optimize table t1;
proceed with the normal connection
handler t1 read next;
c1
@@ -502,7 +502,7 @@ flush tables with read lock;
drop table t1;
ERROR HY000: Can't execute the query because you have a conflicting read lock
send the below to another connection, do not wait for the result
- drop table t1;
+drop table t1;
proceed with the normal connection
select * from t1;
c1
diff --git a/mysql-test/r/im_daemon_life_cycle.result b/mysql-test/r/im_daemon_life_cycle.result
index eee8479888a..397f4d5d503 100644
--- a/mysql-test/r/im_daemon_life_cycle.result
+++ b/mysql-test/r/im_daemon_life_cycle.result
@@ -8,6 +8,7 @@ mysqld2 offline
Killing the process...
Sleeping...
Success: the process was restarted.
+Success: server is ready to accept connection on socket.
--------------------------------------------------------------------
-- Test for BUG#12751
@@ -17,6 +18,7 @@ Success: the process has been started.
Killing the process...
Sleeping...
Success: the process was restarted.
+Success: server is ready to accept connection on socket.
SHOW INSTANCE STATUS mysqld1;
instance_name state version_number version mysqld_compatible
mysqld1 online VERSION_NUMBER VERSION no
diff --git a/mysql-test/r/im_life_cycle.result b/mysql-test/r/im_life_cycle.result
index e462a8b53d6..c403411c399 100644
--- a/mysql-test/r/im_life_cycle.result
+++ b/mysql-test/r/im_life_cycle.result
@@ -25,7 +25,7 @@ Success: the process has been stopped.
-- 1.1.4.
--------------------------------------------------------------------
START INSTANCE mysqld3;
-ERROR HY000: Bad instance name. Check that the instance with such a name exists
+ERROR HY000: Unknown instance name
START INSTANCE mysqld1;
ERROR HY000: The instance is already started
@@ -33,7 +33,7 @@ ERROR HY000: The instance is already started
-- 1.1.5.
--------------------------------------------------------------------
STOP INSTANCE mysqld3;
-ERROR HY000: Bad instance name. Check that the instance with such a name exists
+ERROR HY000: Unknown instance name
--------------------------------------------------------------------
-- 1.1.6.
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index b73b59a433a..305e89f0325 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -759,6 +759,7 @@ select table_schema,table_name, column_name from
information_schema.columns
where data_type = 'longtext';
table_schema table_name column_name
+information_schema COLUMNS COLUMN_DEFAULT
information_schema COLUMNS COLUMN_TYPE
information_schema EVENTS EVENT_DEFINITION
information_schema EVENTS SQL_MODE
@@ -1315,6 +1316,19 @@ WHERE table_name=(SELECT MAX(table_name)
FROM information_schema.tables);
table_name
VIEWS
+DROP TABLE IF EXISTS bug23037;
+DROP FUNCTION IF EXISTS get_value;
+SELECT COLUMN_NAME, MD5(COLUMN_DEFAULT), LENGTH(COLUMN_DEFAULT) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='bug23037';
+COLUMN_NAME MD5(COLUMN_DEFAULT) LENGTH(COLUMN_DEFAULT)
+fld1 7cf7a6782be951a1f2464a350da926a5 65532
+SELECT MD5(get_value());
+MD5(get_value())
+7cf7a6782be951a1f2464a350da926a5
+SELECT COLUMN_NAME, MD5(COLUMN_DEFAULT), LENGTH(COLUMN_DEFAULT), COLUMN_DEFAULT=get_value() FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='bug23037';
+COLUMN_NAME MD5(COLUMN_DEFAULT) LENGTH(COLUMN_DEFAULT) COLUMN_DEFAULT=get_value()
+fld1 7cf7a6782be951a1f2464a350da926a5 65532 1
+DROP TABLE bug23037;
+DROP FUNCTION get_value;
End of 5.0 tests.
select * from information_schema.engines WHERE ENGINE="MyISAM";
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index 4acfaf58a7d..fb854ed7992 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -1,11 +1,5 @@
SET SESSION STORAGE_ENGINE = InnoDB;
drop table if exists t1,t2,t1m,t1i,t2m,t2i,t4;
-create table t1(f1 varchar(800) binary not null, key(f1))
-character set utf8 collate utf8_general_ci;
-Warnings:
-Warning 1071 Specified key was too long; max key length is 765 bytes
-insert into t1 values('aaa');
-drop table t1;
create table t1 (
c_id int(11) not null default '0',
org_id int(11) default null,
@@ -111,6 +105,14 @@ SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` =
id1
2
DROP TABLE t1, t2;
+create table t1 (c1 int) engine=innodb;
+handler t1 open;
+handler t1 read first;
+c1
+Before and after comparison
+0
+drop table t1;
+End of 4.1 tests
create table t1m (a int) engine = MEMORY;
create table t1i (a int);
create table t2m (a int) engine = MEMORY;
@@ -248,6 +250,22 @@ b
c
d
drop table t1,t4;
+DROP TABLE IF EXISTS t2, t1;
+CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE= InnoDB;
+CREATE TABLE t2 (
+i INT NOT NULL,
+FOREIGN KEY (i) REFERENCES t1 (i) ON DELETE NO ACTION
+) ENGINE= InnoDB;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+DELETE IGNORE FROM t1 WHERE i = 1;
+Warnings:
+Error 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`i`) REFERENCES `t1` (`i`) ON DELETE NO ACTION)
+SELECT * FROM t1, t2;
+i i
+1 1
+DROP TABLE t2, t1;
+End of 4.1 tests.
create table t1 (
a varchar(30), b varchar(30), primary key(a), key(b)
);
@@ -369,6 +387,23 @@ Warnings:
Warning 1071 Specified key was too long; max key length is 765 bytes
insert into t1 values('aaa');
drop table t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c FLOAT, KEY b(b)) ENGINE = INNODB;
+INSERT INTO t1 VALUES ( 1 , 1 , 1);
+INSERT INTO t1 SELECT a + 1 , MOD(a + 1 , 20), 1 FROM t1;
+INSERT INTO t1 SELECT a + 2 , MOD(a + 2 , 20), 1 FROM t1;
+INSERT INTO t1 SELECT a + 4 , MOD(a + 4 , 20), 1 FROM t1;
+INSERT INTO t1 SELECT a + 8 , MOD(a + 8 , 20), 1 FROM t1;
+INSERT INTO t1 SELECT a + 16, MOD(a + 16, 20), 1 FROM t1;
+INSERT INTO t1 SELECT a + 32, MOD(a + 32, 20), 1 FROM t1;
+INSERT INTO t1 SELECT a + 64, MOD(a + 64, 20), 1 FROM t1;
+EXPLAIN SELECT b, SUM(c) FROM t1 GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL b 5 NULL 128
+EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 128 Using filesort
+DROP TABLE t1;
+End of 5.0 tests
CREATE TABLE `t2` (
`k` int(11) NOT NULL auto_increment,
`a` int(11) default NULL,
@@ -437,3 +472,4 @@ k a c
11 15 1
12 20 1
drop table t2;
+End of 5.1 tests
diff --git a/mysql-test/r/innodb_notembedded.result b/mysql-test/r/innodb_notembedded.result
index 9aac20e515d..cc13a429dfc 100644
--- a/mysql-test/r/innodb_notembedded.result
+++ b/mysql-test/r/innodb_notembedded.result
@@ -10,7 +10,7 @@ start transaction;
select f1();
f1()
100
- update t1 set col2=0 where col1=1;
+update t1 set col2=0 where col1=1;
select * from t1;
col1 col2
1 100
diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result
index b78c677fb02..d198c943496 100644
--- a/mysql-test/r/kill.result
+++ b/mysql-test/r/kill.result
@@ -16,13 +16,13 @@ select 4;
4
drop table t1;
kill (select count(*) from mysql.user);
-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 count(*) from mysql.user)' at line 1
+ERROR 42000: This version of MySQL doesn't yet support 'Usage of subqueries or stored function calls as part of this statement'
create table t1 (id int primary key);
create table t2 (id int unsigned not null);
insert into t2 select id from t1;
create table t3 (kill_id int);
insert into t3 values(connection_id());
- select id from t1 where id in (select distinct id from t2);
+select id from t1 where id in (select distinct id from t2);
select ((@id := kill_id) - kill_id) from t3;
((@id := kill_id) - kill_id)
0
@@ -32,7 +32,7 @@ drop table t1, t2, t3;
select get_lock("a", 10);
get_lock("a", 10)
1
- select get_lock("a", 10);
+select get_lock("a", 10);
get_lock("a", 10)
NULL
select 1;
diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result
index 8ff02d898a3..2445b3e0c69 100644
--- a/mysql-test/r/lock_multi.result
+++ b/mysql-test/r/lock_multi.result
@@ -2,8 +2,8 @@ drop table if exists t1,t2;
create table t1(n int);
insert into t1 values (1);
lock tables t1 write;
- update low_priority t1 set n = 4;
- select n from t1;
+update low_priority t1 set n = 4;
+select n from t1;
unlock tables;
n
4
@@ -11,8 +11,8 @@ drop table t1;
create table t1(n int);
insert into t1 values (1);
lock tables t1 read;
- update low_priority t1 set n = 4;
- select n from t1;
+update low_priority t1 set n = 4;
+select n from t1;
unlock tables;
n
1
@@ -23,7 +23,7 @@ insert into t1 values(1,1);
insert into t1 values(2,2);
insert into t2 values(1,2);
lock table t1 read;
- update t1,t2 set c=a where b=d;
+update t1,t2 set c=a where b=d;
select c from t2;
c
2
@@ -32,14 +32,14 @@ drop table t2;
create table t1 (a int);
create table t2 (a int);
lock table t1 write, t2 write;
- insert t1 select * from t2;
+insert t1 select * from t2;
drop table t2;
ERROR 42S02: Table 'test.t2' doesn't exist
drop table t1;
create table t1 (a int);
create table t2 (a int);
lock table t1 write, t2 write, t1 as t1_2 write, t2 as t2_2 write;
- insert t1 select * from t2;
+insert t1 select * from t2;
drop table t2;
ERROR 42S02: Table 'test.t2' doesn't exist
drop table t1;
@@ -54,7 +54,7 @@ use mysql;
LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE;
FLUSH TABLES;
use mysql;
- SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
+SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
OPTIMIZE TABLES columns_priv, db, host, user;
Table Op Msg_type Msg_text
mysql.columns_priv optimize status OK
@@ -68,14 +68,14 @@ use test;
use test;
CREATE TABLE t1 (c1 int);
LOCK TABLE t1 WRITE;
- FLUSH TABLES WITH READ LOCK;
+FLUSH TABLES WITH READ LOCK;
CREATE TABLE t2 (c1 int);
UNLOCK TABLES;
UNLOCK TABLES;
DROP TABLE t1, t2;
CREATE TABLE t1 (c1 int);
LOCK TABLE t1 WRITE;
- FLUSH TABLES WITH READ LOCK;
+FLUSH TABLES WITH READ LOCK;
CREATE TABLE t2 AS SELECT * FROM t1;
ERROR HY000: Table 't2' was not locked with LOCK TABLES
UNLOCK TABLES;
@@ -83,7 +83,7 @@ UNLOCK TABLES;
DROP TABLE t1;
CREATE DATABASE mysqltest_1;
FLUSH TABLES WITH READ LOCK;
- DROP DATABASE mysqltest_1;
+DROP DATABASE mysqltest_1;
DROP DATABASE mysqltest_1;
ERROR HY000: Can't execute the query because you have a conflicting read lock
UNLOCK TABLES;
@@ -91,7 +91,7 @@ DROP DATABASE mysqltest_1;
ERROR HY000: Can't drop database 'mysqltest_1'; database doesn't exist
create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)) engine=innodb;
lock tables t1 write;
- alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; //
- alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; //
+alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; //
+alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; //
unlock tables;
drop table t1;
diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result
index a9683cc7c56..2836b96d7b5 100644
--- a/mysql-test/r/log_tables.result
+++ b/mysql-test/r/log_tables.result
@@ -39,14 +39,14 @@ ERROR HY000: You can't use usual read lock with log tables. Try READ LOCAL inste
lock tables mysql.slow_log READ LOCAL, mysql.general_log READ LOCAL;
unlock tables;
lock tables mysql.general_log READ LOCAL;
- flush logs;
+flush logs;
unlock tables;
select "Mark that we woke up from flush logs in the test"
as "test passed";
test passed
Mark that we woke up from flush logs in the test
lock tables mysql.general_log READ LOCAL;
- truncate mysql.general_log;
+truncate mysql.general_log;
unlock tables;
select "Mark that we woke up from TRUNCATE in the test"
as "test passed";
@@ -218,3 +218,71 @@ unlock tables;
use mysql;
lock tables general_log read local, help_category read local;
unlock tables;
+use mysql;
+RENAME TABLE general_log TO renamed_general_log;
+ERROR HY000: Cannot rename 'general_log'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to 'general_log'
+RENAME TABLE slow_log TO renamed_slow_log;
+ERROR HY000: Cannot rename 'slow_log'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to 'slow_log'
+truncate table general_log;
+select * from general_log;
+event_time user_host thread_id server_id command_type argument
+TIMESTAMP USER_HOST THREAD_ID 1 Query select * from general_log
+truncate table slow_log;
+select * from slow_log;
+start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text
+create table general_log_new like general_log;
+rename table general_log TO renamed_general_log, general_log_new TO general_log;
+create table slow_log_new like slow_log;
+rename table slow_log TO renamed_slow_log, slow_log_new TO slow_log;
+rename table general_log TO general_log_new, renamed_general_log TO general_log, slow_log to renamed_slow_log;
+ERROR HY000: Cannot rename 'slow_log'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to 'slow_log'
+select * from general_log;
+event_time user_host thread_id server_id command_type argument
+TIMESTAMP USER_HOST THREAD_ID 1 Query create table slow_log_new like slow_log
+TIMESTAMP USER_HOST THREAD_ID 1 Query rename table slow_log TO renamed_slow_log, slow_log_new TO slow_log
+TIMESTAMP USER_HOST THREAD_ID 1 Query rename table general_log TO general_log_new, renamed_general_log TO general_log, slow_log to renamed_slow_log
+TIMESTAMP USER_HOST THREAD_ID 1 Query select * from general_log
+select * from renamed_general_log;
+event_time user_host thread_id server_id command_type argument
+TIMESTAMP USER_HOST THREAD_ID 1 Query select * from general_log
+TIMESTAMP USER_HOST THREAD_ID 1 Query truncate table slow_log
+TIMESTAMP USER_HOST THREAD_ID 1 Query select * from slow_log
+TIMESTAMP USER_HOST THREAD_ID 1 Query create table general_log_new like general_log
+TIMESTAMP USER_HOST THREAD_ID 1 Query rename table general_log TO renamed_general_log, general_log_new TO general_log
+select * from slow_log;
+start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text
+select * from renamed_slow_log;
+start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text
+set global general_log='OFF';
+RENAME TABLE general_log TO general_log2;
+set global slow_query_log='OFF';
+RENAME TABLE slow_log TO slow_log2;
+set global general_log='ON';
+ERROR HY000: Cannot activate 'general' log
+set global slow_query_log='ON';
+ERROR HY000: Cannot activate 'slow query' log
+RENAME TABLE general_log2 TO general_log;
+RENAME TABLE slow_log2 TO slow_log;
+set global general_log='ON';
+set global slow_query_log='ON';
+flush logs;
+flush logs;
+drop table renamed_general_log, renamed_slow_log;
+use test;
+use mysql;
+repair table general_log;
+Table Op Msg_type Msg_text
+mysql.general_log repair status OK
+repair table slow_log;
+Table Op Msg_type Msg_text
+mysql.slow_log repair status OK
+create table general_log_new like general_log;
+create table slow_log_new like slow_log;
+show tables like "%log%";
+Tables_in_mysql (%log%)
+general_log
+general_log_new
+slow_log
+slow_log_new
+drop table slow_log_new, general_log_new;
+use test;
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result
index 3ed0222fcdb..6d8e5dfdf2c 100644
--- a/mysql-test/r/multi_update.result
+++ b/mysql-test/r/multi_update.result
@@ -509,8 +509,8 @@ create table t2 (a int);
insert into t2 values (10), (20), (30);
create view v1 as select a as b, a/10 as a from t2;
lock table t1 write;
- alter table t1 add column c int default 100 after a;
- update t1, v1 set t1.b=t1.a+t1.b+v1.b where t1.a=v1.a;
+alter table t1 add column c int default 100 after a;
+update t1, v1 set t1.b=t1.a+t1.b+v1.b where t1.a=v1.a;
unlock tables;
select * from t1;
a c b
diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result
index 1053b1918fb..14267afc27e 100644
--- a/mysql-test/r/mysql.result
+++ b/mysql-test/r/mysql.result
@@ -149,4 +149,33 @@ ERROR at line 1: USE must be followed by a database name
\\
';
';
+create table t17583 (a int);
+insert into t17583 (a) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+select count(*) from t17583;
+count(*)
+1280
+drop table t17583;
+Test connect without db- or host-name => reconnect
+Test connect with dbname only => new dbname, old hostname
+ERROR 1064 (42000) at line 1: 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 'connecttest' at line 1
+Test connect with _invalid_ dbname only => new invalid dbname, old hostname
+ERROR 1049 (42000) at line 1: Unknown database 'invalid'
+ERROR 1049 (42000) at line 1: Unknown database 'invalid'
+Test connect with dbname + hostname
+Test connect with dbname + _invalid_ hostname
+ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'invalid_hostname' (errno)
+ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'invalid_hostname' (errno)
+The commands reported in the bug report
+ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'cyril has found a bug :)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' (errno)
+Too long dbname
+ERROR 1049 (42000) at line 1: Unknown database 'test_really_long_dbnamexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
+Too long hostname
+ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'cyrils_superlonghostnameXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' (errno)
End of 5.0 tests
diff --git a/mysql-test/r/mysqldump-max.result b/mysql-test/r/mysqldump-max.result
index 613db96be93..e78fc4d386a 100644
--- a/mysql-test/r/mysqldump-max.result
+++ b/mysql-test/r/mysqldump-max.result
@@ -1,21 +1,4 @@
-drop table if exists t1;
-Warnings:
-Note 1051 Unknown table 't1'
-drop table if exists t2;
-Warnings:
-Note 1051 Unknown table 't2'
-drop table if exists t3;
-Warnings:
-Note 1051 Unknown table 't3'
-drop table if exists t4;
-Warnings:
-Note 1051 Unknown table 't4'
-drop table if exists t5;
-Warnings:
-Note 1051 Unknown table 't5'
-drop table if exists t6;
-Warnings:
-Note 1051 Unknown table 't6'
+drop table if exists t1, t2, t3, t4, t5, t6;
create table t1 (id int(8), name varchar(32));
create table t2 (id int(8), name varchar(32)) ENGINE="MyISAM";
create table t3 (id int(8), name varchar(32)) ENGINE="MEMORY";
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index b59f63d207e..54c68701f78 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -3195,6 +3195,28 @@ UNLOCK TABLES;
DROP TABLE `t1`;
#
+# Bug #19745: mysqldump --xml produces invalid xml
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (f1 int(10), data MEDIUMBLOB);
+INSERT INTO t1 VALUES(1,0xff00fef0);
+<?xml version="1.0"?>
+<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<database name="test">
+ <table_structure name="t1">
+ <field Field="f1" Type="int(10)" Null="YES" Key="" Extra="" />
+ <field Field="data" Type="mediumblob" Null="YES" Key="" Extra="" />
+ </table_structure>
+ <table_data name="t1">
+ <row>
+ <field name="f1">1</field>
+ <field name="data" xsi:type="xs:hexBinary">FF00FEF0</field>
+ </row>
+ </table_data>
+</database>
+</mysqldump>
+DROP TABLE t1;
+#
# End of 5.0 tests
#
drop table if exists t1;
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index ce9fb6941f3..1cfc482416e 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -152,8 +152,38 @@ mysqltest: At line 1: Missing delimiter
mysqltest: At line 1: End of line junk detected: "sleep 7
# Another comment
"
+mysqltest: At line 1: Missing delimiter
+mysqltest: At line 1: Missing delimiter
+mysqltest: At line 1: End of line junk detected: "disconnect default
+
+#
+# comment
+# comment2
+
+# comment 3
+--disable_query_log
+"
+mysqltest: At line 1: End of line junk detected: "disconnect default # comment
+# comment part2
+
+# comment 3
+--disable_query_log
+"
mysqltest: At line 1: Extra delimiter ";" found
mysqltest: At line 1: Extra delimiter ";" found
+mysqltest: At line 1: Missing argument(s) to 'error'
+mysqltest: At line 1: Missing argument(s) to 'error'
+mysqltest: At line 1: The sqlstate definition must start with an uppercase S
+mysqltest: At line 1: The error name definition must start with an uppercase E
+mysqltest: At line 1: Invalid argument to error: '9eeeee' - the errno may only consist of digits[0-9]
+mysqltest: At line 1: Invalid argument to error: '1sssss' - the errno may only consist of digits[0-9]
+mysqltest: At line 1: The sqlstate must be exactly 5 chars long
+mysqltest: At line 1: The sqlstate may only consist of digits[0-9] and _uppercase_ letters
+mysqltest: At line 1: The sqlstate must be exactly 5 chars long
+mysqltest: At line 1: Unknown SQL error name 'E9999'
+mysqltest: At line 1: Invalid argument to error: '999e9' - the errno may only consist of digits[0-9]
+mysqltest: At line 1: Invalid argument to error: '9b' - the errno may only consist of digits[0-9]
+mysqltest: At line 1: Too many errorcodes specified
MySQL
"MySQL"
MySQL: The world''s most popular open source database
@@ -239,7 +269,7 @@ mysqltest: At line 1: Missing assignment operator in let
1
# Execute: echo $success ;
1
-mysqltest: At line 1: Missing file name in source
+mysqltest: At line 1: Missing required argument 'filename' to command 'source'
mysqltest: At line 1: Could not open file ./non_existingFile
mysqltest: In included file "MYSQLTEST_VARDIR/tmp/recursive.sql": At line 1: Source directives are nesting too deep
mysqltest: In included file "MYSQLTEST_VARDIR/tmp/error.sql": At line 1: query 'garbage ' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
@@ -332,16 +362,16 @@ Counter is greater than 0, (counter=10)
Counter is not 0, (counter=0)
1
Testing while with not
-mysqltest: In included file "./include/mysqltest_while.inc": At line 64: Nesting too deeply
+mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest_while.inc": At line 64: Nesting too deeply
mysqltest: At line 1: missing '(' in while
mysqltest: At line 1: missing ')' in while
mysqltest: At line 1: Missing '{' after while. Found "dec $i"
mysqltest: At line 1: Stray '}' - end of block before beginning
mysqltest: At line 1: Stray 'end' command - end of block before beginning
-mysqltest: At line 1: query '' failed: 1065: Query was empty
+mysqltest: At line 1: query '{' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{' at line 1
mysqltest: At line 1: Missing '{' after while. Found "echo hej"
mysqltest: At line 3: Missing end of block
-mysqltest: At line 1: Missing newline between while and '{'
+mysqltest: At line 3: Missing end of block
mysqltest: At line 1: missing '(' in if
mysqltest: At line 1: Stray 'end' command - end of block before beginning
select "b" bs col1, "c" bs col2;
@@ -371,17 +401,15 @@ mysqltest: At line 1: Wrong column number to replace_column in 'replace_column 1
mysqltest: At line 1: Invalid integer argument "10!"
mysqltest: At line 1: End of line junk detected: "!"
mysqltest: At line 1: Invalid integer argument "a"
-mysqltest: At line 1: Syntax error in connect - expected '(' found 'mysqltest: At line 1: Missing connection host
-mysqltest: At line 1: Missing connection host
-mysqltest: At line 1: Missing connection user
-mysqltest: At line 1: Missing connection user
-mysqltest: At line 1: Missing connection password
-mysqltest: At line 1: Missing connection db
-mysqltest: At line 1: Could not open connection 'con2': 1049 Unknown database 'illegal_db'
+mysqltest: At line 1: Missing required argument 'connection name' to command 'connect'
+mysqltest: At line 1: Missing required argument 'connection name' to command 'connect'
+mysqltest: At line 1: Missing required argument 'host' to command 'connect'
+mysqltest: At line 1: Missing required argument 'host' to command 'connect'
+mysqltest: At line 1: query 'connect con2,localhost,root,,illegal_db' failed: 1049: Unknown database 'illegal_db'
mysqltest: At line 1: Illegal argument for port: 'illegal_port'
mysqltest: At line 1: Illegal option to connect: SMTP
OK
-mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 7: Connection limit exhausted - increase MAX_CONS in mysqltest.c
+mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 7: Connection limit exhausted, you can have max 128 connections
mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 3: connection 'test_con1' not found in connection pool
mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 2: Connection test_con1 already exists
connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET);
@@ -449,7 +477,6 @@ sleep;
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 'sleep' at line 1
;
ERROR 42000: Query was empty
-End of 5.0 tests
select "b" as col1, "c" as col2;
col1 col2
b c
@@ -477,4 +504,20 @@ a D
1 1
1 4
drop table t1;
-End of 5.1 tests
+mysqltest: At line 1: Missing required argument 'filename' to command 'remove_file'
+mysqltest: At line 1: Missing required argument 'filename' to command 'write_file'
+mysqltest: At line 1: End of file encountered before 'EOF' delimiter was found
+mysqltest: At line 1: End of line junk detected: "write_file filename ";
+"
+mysqltest: At line 1: Missing required argument 'filename' to command 'file_exists'
+mysqltest: At line 1: Missing required argument 'from_file' to command 'copy_file'
+mysqltest: At line 1: Missing required argument 'to_file' to command 'copy_file'
+hello
+hello
+hello
+mysqltest: At line 1: Max delimiter length(16) exceeded
+hello
+hello
+mysqltest: At line 1: test of die
+Some output
+End of tests
diff --git a/mysql-test/r/not_partition.require b/mysql-test/r/not_partition.require
new file mode 100644
index 00000000000..808242277cb
--- /dev/null
+++ b/mysql-test/r/not_partition.require
@@ -0,0 +1,2 @@
+Variable_name Value
+have_partitioning NO
diff --git a/mysql-test/r/not_partition.result b/mysql-test/r/not_partition.result
new file mode 100644
index 00000000000..9e205a09d78
--- /dev/null
+++ b/mysql-test/r/not_partition.result
@@ -0,0 +1,48 @@
+CREATE TABLE t1 (
+firstname VARCHAR(25) NOT NULL,
+lastname VARCHAR(25) NOT NULL,
+username VARCHAR(16) NOT NULL,
+email VARCHAR(35),
+joined DATE NOT NULL
+)
+PARTITION BY KEY(joined)
+PARTITIONS 6;
+ERROR HY000: The 'partitioning' feature is disabled; you need MySQL built with '--with-partition' to have it working
+ALTER TABLE t1 PARTITION BY KEY(joined) PARTITIONS 2;
+ERROR HY000: The 'partitioning' feature is disabled; you need MySQL built with '--with-partition' to have it working
+drop table t1;
+ERROR 42S02: Unknown table 't1'
+CREATE TABLE t1 (
+firstname VARCHAR(25) NOT NULL,
+lastname VARCHAR(25) NOT NULL,
+username VARCHAR(16) NOT NULL,
+email VARCHAR(35),
+joined DATE NOT NULL
+)
+PARTITION BY RANGE( YEAR(joined) ) (
+PARTITION p0 VALUES LESS THAN (1960),
+PARTITION p1 VALUES LESS THAN (1970),
+PARTITION p2 VALUES LESS THAN (1980),
+PARTITION p3 VALUES LESS THAN (1990),
+PARTITION p4 VALUES LESS THAN MAXVALUE
+);
+ERROR HY000: The 'partitioning' feature is disabled; you need MySQL built with '--with-partition' to have it working
+drop table t1;
+ERROR 42S02: Unknown table 't1'
+CREATE TABLE t1 (id INT, purchased DATE)
+PARTITION BY RANGE( YEAR(purchased) )
+SUBPARTITION BY HASH( TO_DAYS(purchased) )
+SUBPARTITIONS 2 (
+PARTITION p0 VALUES LESS THAN (1990),
+PARTITION p1 VALUES LESS THAN (2000),
+PARTITION p2 VALUES LESS THAN MAXVALUE
+);
+ERROR HY000: The 'partitioning' feature is disabled; you need MySQL built with '--with-partition' to have it working
+drop table t1;
+ERROR 42S02: Unknown table 't1'
+create table t1 (a varchar(10) charset latin1 collate latin1_bin);
+insert into t1 values (''),(' '),('a'),('a '),('a ');
+explain partitions select * from t1 where a='a ' OR a='a';
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 5 Using where
+drop table t1;
diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result
index 8f9fd50eced..914fe25119f 100644
--- a/mysql-test/r/openssl_1.result
+++ b/mysql-test/r/openssl_1.result
@@ -47,7 +47,7 @@ drop table t1;
mysqltest: Could not open connection 'default': 2026 SSL connection error
mysqltest: Could not open connection 'default': 2026 SSL connection error
mysqltest: Could not open connection 'default': 2026 SSL connection error
-Error when connection to server using SSL:Unable to get private key from ''
+SSL error: Unable to get private key from ''
mysqltest: Could not open connection 'default': 2026 SSL connection error
-Error when connection to server using SSL:Unable to get certificate from ''
+SSL error: Unable to get certificate from ''
mysqltest: Could not open connection 'default': 2026 SSL connection error
diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result
new file mode 100644
index 00000000000..afd78561898
--- /dev/null
+++ b/mysql-test/r/parser.result
@@ -0,0 +1,388 @@
+SET @save_sql_mode=@@sql_mode;
+set SQL_MODE='';
+create table ADDDATE(a int);
+drop table ADDDATE;
+create table ADDDATE (a int);
+drop table ADDDATE;
+create table BIT_AND(a int);
+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 'BIT_AND(a int)' at line 1
+create table BIT_AND (a int);
+drop table BIT_AND;
+create table BIT_OR(a int);
+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 'BIT_OR(a int)' at line 1
+create table BIT_OR (a int);
+drop table BIT_OR;
+create table BIT_XOR(a int);
+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 'BIT_XOR(a int)' at line 1
+create table BIT_XOR (a int);
+drop table BIT_XOR;
+create table CAST(a int);
+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 'CAST(a int)' at line 1
+create table CAST (a int);
+drop table CAST;
+create table COUNT(a int);
+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 'COUNT(a int)' at line 1
+create table COUNT (a int);
+drop table COUNT;
+create table CURDATE(a int);
+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 'CURDATE(a int)' at line 1
+create table CURDATE (a int);
+drop table CURDATE;
+create table CURTIME(a int);
+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 'CURTIME(a int)' at line 1
+create table CURTIME (a int);
+drop table CURTIME;
+create table DATE_ADD(a int);
+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 'DATE_ADD(a int)' at line 1
+create table DATE_ADD (a int);
+drop table DATE_ADD;
+create table DATE_SUB(a int);
+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 'DATE_SUB(a int)' at line 1
+create table DATE_SUB (a int);
+drop table DATE_SUB;
+create table EXTRACT(a int);
+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 'EXTRACT(a int)' at line 1
+create table EXTRACT (a int);
+drop table EXTRACT;
+create table GROUP_CONCAT(a int);
+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 'GROUP_CONCAT(a int)' at line 1
+create table GROUP_CONCAT (a int);
+drop table GROUP_CONCAT;
+create table GROUP_UNIQUE_USERS(a int);
+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 'GROUP_UNIQUE_USERS(a int)' at line 1
+create table GROUP_UNIQUE_USERS (a int);
+drop table GROUP_UNIQUE_USERS;
+create table MAX(a int);
+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 'MAX(a int)' at line 1
+create table MAX (a int);
+drop table MAX;
+create table MID(a int);
+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 'MID(a int)' at line 1
+create table MID (a int);
+drop table MID;
+create table MIN(a int);
+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 'MIN(a int)' at line 1
+create table MIN (a int);
+drop table MIN;
+create table NOW(a int);
+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 'NOW(a int)' at line 1
+create table NOW (a int);
+drop table NOW;
+create table POSITION(a int);
+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 'POSITION(a int)' at line 1
+create table POSITION (a int);
+drop table POSITION;
+create table SESSION_USER(a int);
+drop table SESSION_USER;
+create table SESSION_USER (a int);
+drop table SESSION_USER;
+create table STD(a int);
+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 'STD(a int)' at line 1
+create table STD (a int);
+drop table STD;
+create table STDDEV(a int);
+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 'STDDEV(a int)' at line 1
+create table STDDEV (a int);
+drop table STDDEV;
+create table STDDEV_POP(a int);
+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 'STDDEV_POP(a int)' at line 1
+create table STDDEV_POP (a int);
+drop table STDDEV_POP;
+create table STDDEV_SAMP(a int);
+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 'STDDEV_SAMP(a int)' at line 1
+create table STDDEV_SAMP (a int);
+drop table STDDEV_SAMP;
+create table SUBDATE(a int);
+drop table SUBDATE;
+create table SUBDATE (a int);
+drop table SUBDATE;
+create table SUBSTR(a int);
+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 'SUBSTR(a int)' at line 1
+create table SUBSTR (a int);
+drop table SUBSTR;
+create table SUBSTRING(a int);
+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 'SUBSTRING(a int)' at line 1
+create table SUBSTRING (a int);
+drop table SUBSTRING;
+create table SUM(a int);
+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 'SUM(a int)' at line 1
+create table SUM (a int);
+drop table SUM;
+create table SYSDATE(a int);
+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 'SYSDATE(a int)' at line 1
+create table SYSDATE (a int);
+drop table SYSDATE;
+create table SYSTEM_USER(a int);
+drop table SYSTEM_USER;
+create table SYSTEM_USER (a int);
+drop table SYSTEM_USER;
+create table TRIM(a int);
+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 'TRIM(a int)' at line 1
+create table TRIM (a int);
+drop table TRIM;
+create table UNIQUE_USERS(a int);
+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 'UNIQUE_USERS(a int)' at line 1
+create table UNIQUE_USERS (a int);
+drop table UNIQUE_USERS;
+create table VARIANCE(a int);
+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 'VARIANCE(a int)' at line 1
+create table VARIANCE (a int);
+drop table VARIANCE;
+create table VAR_POP(a int);
+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 'VAR_POP(a int)' at line 1
+create table VAR_POP (a int);
+drop table VAR_POP;
+create table VAR_SAMP(a int);
+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 'VAR_SAMP(a int)' at line 1
+create table VAR_SAMP (a int);
+drop table VAR_SAMP;
+set SQL_MODE='IGNORE_SPACE';
+create table ADDDATE(a int);
+drop table ADDDATE;
+create table ADDDATE (a int);
+drop table ADDDATE;
+create table BIT_AND(a int);
+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 'BIT_AND(a int)' at line 1
+create table BIT_AND (a int);
+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 'BIT_AND (a int)' at line 1
+create table BIT_OR(a int);
+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 'BIT_OR(a int)' at line 1
+create table BIT_OR (a int);
+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 'BIT_OR (a int)' at line 1
+create table BIT_XOR(a int);
+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 'BIT_XOR(a int)' at line 1
+create table BIT_XOR (a int);
+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 'BIT_XOR (a int)' at line 1
+create table CAST(a int);
+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 'CAST(a int)' at line 1
+create table CAST (a int);
+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 'CAST (a int)' at line 1
+create table COUNT(a int);
+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 'COUNT(a int)' at line 1
+create table COUNT (a int);
+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 'COUNT (a int)' at line 1
+create table CURDATE(a int);
+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 'CURDATE(a int)' at line 1
+create table CURDATE (a int);
+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 'CURDATE (a int)' at line 1
+create table CURTIME(a int);
+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 'CURTIME(a int)' at line 1
+create table CURTIME (a int);
+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 'CURTIME (a int)' at line 1
+create table DATE_ADD(a int);
+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 'DATE_ADD(a int)' at line 1
+create table DATE_ADD (a int);
+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 'DATE_ADD (a int)' at line 1
+create table DATE_SUB(a int);
+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 'DATE_SUB(a int)' at line 1
+create table DATE_SUB (a int);
+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 'DATE_SUB (a int)' at line 1
+create table EXTRACT(a int);
+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 'EXTRACT(a int)' at line 1
+create table EXTRACT (a int);
+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 'EXTRACT (a int)' at line 1
+create table GROUP_CONCAT(a int);
+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 'GROUP_CONCAT(a int)' at line 1
+create table GROUP_CONCAT (a int);
+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 'GROUP_CONCAT (a int)' at line 1
+create table GROUP_UNIQUE_USERS(a int);
+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 'GROUP_UNIQUE_USERS(a int)' at line 1
+create table GROUP_UNIQUE_USERS (a int);
+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 'GROUP_UNIQUE_USERS (a int)' at line 1
+create table MAX(a int);
+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 'MAX(a int)' at line 1
+create table MAX (a int);
+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 'MAX (a int)' at line 1
+create table MID(a int);
+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 'MID(a int)' at line 1
+create table MID (a int);
+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 'MID (a int)' at line 1
+create table MIN(a int);
+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 'MIN(a int)' at line 1
+create table MIN (a int);
+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 'MIN (a int)' at line 1
+create table NOW(a int);
+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 'NOW(a int)' at line 1
+create table NOW (a int);
+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 'NOW (a int)' at line 1
+create table POSITION(a int);
+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 'POSITION(a int)' at line 1
+create table POSITION (a int);
+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 'POSITION (a int)' at line 1
+create table SESSION_USER(a int);
+drop table SESSION_USER;
+create table SESSION_USER (a int);
+drop table SESSION_USER;
+create table STD(a int);
+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 'STD(a int)' at line 1
+create table STD (a int);
+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 'STD (a int)' at line 1
+create table STDDEV(a int);
+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 'STDDEV(a int)' at line 1
+create table STDDEV (a int);
+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 'STDDEV (a int)' at line 1
+create table STDDEV_POP(a int);
+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 'STDDEV_POP(a int)' at line 1
+create table STDDEV_POP (a int);
+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 'STDDEV_POP (a int)' at line 1
+create table STDDEV_SAMP(a int);
+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 'STDDEV_SAMP(a int)' at line 1
+create table STDDEV_SAMP (a int);
+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 'STDDEV_SAMP (a int)' at line 1
+create table SUBDATE(a int);
+drop table SUBDATE;
+create table SUBDATE (a int);
+drop table SUBDATE;
+create table SUBSTR(a int);
+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 'SUBSTR(a int)' at line 1
+create table SUBSTR (a int);
+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 'SUBSTR (a int)' at line 1
+create table SUBSTRING(a int);
+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 'SUBSTRING(a int)' at line 1
+create table SUBSTRING (a int);
+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 'SUBSTRING (a int)' at line 1
+create table SUM(a int);
+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 'SUM(a int)' at line 1
+create table SUM (a int);
+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 'SUM (a int)' at line 1
+create table SYSDATE(a int);
+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 'SYSDATE(a int)' at line 1
+create table SYSDATE (a int);
+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 'SYSDATE (a int)' at line 1
+create table SYSTEM_USER(a int);
+drop table SYSTEM_USER;
+create table SYSTEM_USER (a int);
+drop table SYSTEM_USER;
+create table TRIM(a int);
+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 'TRIM(a int)' at line 1
+create table TRIM (a int);
+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 'TRIM (a int)' at line 1
+create table UNIQUE_USERS(a int);
+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 'UNIQUE_USERS(a int)' at line 1
+create table UNIQUE_USERS (a int);
+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 'UNIQUE_USERS (a int)' at line 1
+create table VARIANCE(a int);
+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 'VARIANCE(a int)' at line 1
+create table VARIANCE (a int);
+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 'VARIANCE (a int)' at line 1
+create table VAR_POP(a int);
+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 'VAR_POP(a int)' at line 1
+create table VAR_POP (a int);
+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 'VAR_POP (a int)' at line 1
+create table VAR_SAMP(a int);
+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 'VAR_SAMP(a int)' at line 1
+create table VAR_SAMP (a int);
+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 'VAR_SAMP (a int)' at line 1
+SET @@sql_mode=@save_sql_mode;
+select pi(3.14);
+ERROR 42000: Incorrect parameter count in the call to native function 'pi'
+select tan();
+ERROR 42000: Incorrect parameter count in the call to native function 'tan'
+select tan(1, 2);
+ERROR 42000: Incorrect parameter count in the call to native function 'tan'
+select makedate(1);
+ERROR 42000: Incorrect parameter count in the call to native function 'makedate'
+select makedate(1, 2, 3);
+ERROR 42000: Incorrect parameter count in the call to native function 'makedate'
+select maketime();
+ERROR 42000: Incorrect parameter count in the call to native function 'maketime'
+select maketime(1);
+ERROR 42000: Incorrect parameter count in the call to native function 'maketime'
+select maketime(1, 2);
+ERROR 42000: Incorrect parameter count in the call to native function 'maketime'
+select maketime(1, 2, 3, 4);
+ERROR 42000: Incorrect parameter count in the call to native function 'maketime'
+select atan();
+ERROR 42000: Incorrect parameter count in the call to native function 'atan'
+select atan2(1, 2, 3);
+ERROR 42000: Incorrect parameter count in the call to native function 'atan2'
+select benchmark(10, 1+1);
+benchmark(10, 1+1)
+0
+select benchmark(5+5, 2);
+ERROR 42000: Incorrect parameters in the call to native function 'BENCHMARK'
+select concat();
+ERROR 42000: Incorrect parameter count in the call to native function 'concat'
+select concat("foo");
+concat("foo")
+foo
+select concat_ws();
+ERROR 42000: Incorrect parameter count in the call to native function 'concat_ws'
+select concat_ws("foo");
+ERROR 42000: Incorrect parameter count in the call to native function 'concat_ws'
+set @pwd="my password";
+select encode("secret", @pwd);
+ERROR 42000: Incorrect parameters in the call to native function 'ENCODE'
+select decode("encoded-secret", @pwd);
+ERROR 42000: Incorrect parameters in the call to native function 'DECODE'
+select encrypt();
+ERROR 42000: Incorrect parameter count in the call to native function 'encrypt'
+select encrypt(1, 2, 3);
+ERROR 42000: Incorrect parameter count in the call to native function 'encrypt'
+select des_encrypt("p1", "p2", "not expected");
+ERROR 42000: Incorrect parameter count in the call to native function 'des_encrypt'
+select des_decrypt("p1", "p2", "not expected");
+ERROR 42000: Incorrect parameter count in the call to native function 'des_decrypt'
+select elt();
+ERROR 42000: Incorrect parameter count in the call to native function 'elt'
+select elt(1);
+ERROR 42000: Incorrect parameter count in the call to native function 'elt'
+select export_set();
+ERROR 42000: Incorrect parameter count in the call to native function 'export_set'
+select export_set("p1");
+ERROR 42000: Incorrect parameter count in the call to native function 'export_set'
+select export_set("p1", "p2");
+ERROR 42000: Incorrect parameter count in the call to native function 'export_set'
+select export_set("p1", "p2", "p3", "p4", "p5", "p6");
+ERROR 42000: Incorrect parameter count in the call to native function 'export_set'
+select field();
+ERROR 42000: Incorrect parameter count in the call to native function 'field'
+select field("p1");
+ERROR 42000: Incorrect parameter count in the call to native function 'field'
+set @dec=2;
+select format(pi(), @dec);
+ERROR 42000: Incorrect parameters in the call to native function 'FORMAT'
+select from_unixtime();
+ERROR 42000: Incorrect parameter count in the call to native function 'from_unixtime'
+select from_unixtime(1, 2, 3);
+ERROR 42000: Incorrect parameter count in the call to native function 'from_unixtime'
+select unix_timestamp(1, 2);
+ERROR 42000: Incorrect parameter count in the call to native function 'unix_timestamp'
+select greatest();
+ERROR 42000: Incorrect parameter count in the call to native function 'greatest'
+select greatest(12);
+ERROR 42000: Incorrect parameter count in the call to native function 'greatest'
+select last_insert_id(1, 2);
+ERROR 42000: Incorrect parameter count in the call to native function 'last_insert_id'
+select least();
+ERROR 42000: Incorrect parameter count in the call to native function 'least'
+select least(12);
+ERROR 42000: Incorrect parameter count in the call to native function 'least'
+select locate();
+ERROR 42000: Incorrect parameter count in the call to native function 'locate'
+select locate(1);
+ERROR 42000: Incorrect parameter count in the call to native function 'locate'
+select locate(1, 2, 3, 4);
+ERROR 42000: Incorrect parameter count in the call to native function 'locate'
+select log();
+ERROR 42000: Incorrect parameter count in the call to native function 'log'
+select log(1, 2, 3);
+ERROR 42000: Incorrect parameter count in the call to native function 'log'
+select make_set();
+ERROR 42000: Incorrect parameter count in the call to native function 'make_set'
+select make_set(1);
+ERROR 42000: Incorrect parameter count in the call to native function 'make_set'
+select master_pos_wait();
+ERROR 42000: Incorrect parameter count in the call to native function 'master_pos_wait'
+select master_pos_wait(1);
+ERROR 42000: Incorrect parameter count in the call to native function 'master_pos_wait'
+select master_pos_wait(1, 2, 3, 4);
+ERROR 42000: Incorrect parameter count in the call to native function 'master_pos_wait'
+select rand(1, 2, 3);
+ERROR 42000: Incorrect parameter count in the call to native function 'rand'
+select round(1, 2, 3);
+ERROR 42000: Incorrect parameter count in the call to native function 'round'
+select yearweek();
+ERROR 42000: Incorrect parameter count in the call to native function 'yearweek'
+select yearweek(1, 2, 3);
+ERROR 42000: Incorrect parameter count in the call to native function 'yearweek'
diff --git a/mysql-test/r/parser_bug21114_innodb.result b/mysql-test/r/parser_bug21114_innodb.result
new file mode 100644
index 00000000000..e39b63f571d
--- /dev/null
+++ b/mysql-test/r/parser_bug21114_innodb.result
@@ -0,0 +1,867 @@
+drop table if exists abs;
+drop table if exists bug21114_child;
+SHOW CREATE TABLE abs;
+Table Create Table
+abs CREATE TABLE `abs` (
+ `col1` int(11) NOT NULL,
+ `col2` int(11) NOT NULL,
+ `col3` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`col1`,`col2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW CREATE TABLE bug21114_child;
+Table Create Table
+bug21114_child CREATE TABLE `bug21114_child` (
+ `pk` int(11) NOT NULL,
+ `fk_col1` int(11) NOT NULL,
+ `fk_col2` int(11) NOT NULL,
+ `fk_col3` int(11) NOT NULL,
+ `fk_col4` int(11) NOT NULL,
+ KEY `fk_fct` (`fk_col1`,`fk_col2`),
+ KEY `fk_fct_space` (`fk_col3`,`fk_col4`),
+ CONSTRAINT `fk_fct` FOREIGN KEY (`fk_col1`, `fk_col2`) REFERENCES `abs` (`col1`, `col2`),
+ CONSTRAINT `fk_fct_space` FOREIGN KEY (`fk_col3`, `fk_col4`) REFERENCES `abs` (`col1`, `col2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE bug21114_child;
+DROP TABLE abs;
+drop table if exists field;
+drop table if exists bug21114_child;
+SHOW CREATE TABLE field;
+Table Create Table
+field CREATE TABLE `field` (
+ `col1` int(11) NOT NULL,
+ `col2` int(11) NOT NULL,
+ `col3` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`col1`,`col2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW CREATE TABLE bug21114_child;
+Table Create Table
+bug21114_child CREATE TABLE `bug21114_child` (
+ `pk` int(11) NOT NULL,
+ `fk_col1` int(11) NOT NULL,
+ `fk_col2` int(11) NOT NULL,
+ `fk_col3` int(11) NOT NULL,
+ `fk_col4` int(11) NOT NULL,
+ KEY `fk_fct` (`fk_col1`,`fk_col2`),
+ KEY `fk_fct_space` (`fk_col3`,`fk_col4`),
+ CONSTRAINT `fk_fct` FOREIGN KEY (`fk_col1`, `fk_col2`) REFERENCES `field` (`col1`, `col2`),
+ CONSTRAINT `fk_fct_space` FOREIGN KEY (`fk_col3`, `fk_col4`) REFERENCES `field` (`col1`, `col2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE bug21114_child;
+DROP TABLE field;
+drop table if exists format;
+drop table if exists bug21114_child;
+SHOW CREATE TABLE format;
+Table Create Table
+format CREATE TABLE `format` (
+ `col1` int(11) NOT NULL,
+ `col2` int(11) NOT NULL,
+ `col3` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`col1`,`col2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SHOW CREATE TABLE bug21114_child;
+Table Create Table
+bug21114_child CREATE TABLE `bug21114_child` (
+ `pk` int(11) NOT NULL,
+ `fk_col1` int(11) NOT NULL,
+ `fk_col2` int(11) NOT NULL,
+ `fk_col3` int(11) NOT NULL,
+ `fk_col4` int(11) NOT NULL,
+ KEY `fk_fct` (`fk_col1`,`fk_col2`),
+ KEY `fk_fct_space` (`fk_col3`,`fk_col4`),
+ CONSTRAINT `fk_fct` FOREIGN KEY (`fk_col1`, `fk_col2`) REFERENCES `format` (`col1`, `col2`),
+ CONSTRAINT `fk_fct_space` FOREIGN KEY (`fk_col3`, `fk_col4`) REFERENCES `format` (`col1`, `col2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE bug21114_child;
+DROP TABLE format;
+drop table if exists acos;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE acos;
+drop table if exists adddate;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE adddate;
+drop table if exists addtime;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE addtime;
+drop table if exists aes_decrypt;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE aes_decrypt;
+drop table if exists aes_encrypt;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE aes_encrypt;
+drop table if exists area;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE area;
+drop table if exists asbinary;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE asbinary;
+drop table if exists asin;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE asin;
+drop table if exists astext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE astext;
+drop table if exists aswkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE aswkb;
+drop table if exists aswkt;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE aswkt;
+drop table if exists atan;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE atan;
+drop table if exists atan2;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE atan2;
+drop table if exists benchmark;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE benchmark;
+drop table if exists bin;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE bin;
+drop table if exists bit_count;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE bit_count;
+drop table if exists bit_length;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE bit_length;
+drop table if exists ceil;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE ceil;
+drop table if exists ceiling;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE ceiling;
+drop table if exists centroid;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE centroid;
+drop table if exists character_length;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE character_length;
+drop table if exists char_length;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE char_length;
+drop table if exists coercibility;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE coercibility;
+drop table if exists compress;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE compress;
+drop table if exists concat;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE concat;
+drop table if exists concat_ws;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE concat_ws;
+drop table if exists connection_id;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE connection_id;
+drop table if exists conv;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE conv;
+drop table if exists convert_tz;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE convert_tz;
+drop table if exists cos;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE cos;
+drop table if exists cot;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE cot;
+drop table if exists crc32;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE crc32;
+drop table if exists crosses;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE crosses;
+drop table if exists datediff;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE datediff;
+drop table if exists date_format;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE date_format;
+drop table if exists dayname;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE dayname;
+drop table if exists dayofmonth;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE dayofmonth;
+drop table if exists dayofweek;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE dayofweek;
+drop table if exists dayofyear;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE dayofyear;
+drop table if exists decode;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE decode;
+drop table if exists degrees;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE degrees;
+drop table if exists des_decrypt;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE des_decrypt;
+drop table if exists des_encrypt;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE des_encrypt;
+drop table if exists dimension;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE dimension;
+drop table if exists disjoint;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE disjoint;
+drop table if exists elt;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE elt;
+drop table if exists encode;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE encode;
+drop table if exists encrypt;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE encrypt;
+drop table if exists endpoint;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE endpoint;
+drop table if exists envelope;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE envelope;
+drop table if exists equals;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE equals;
+drop table if exists exp;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE exp;
+drop table if exists export_set;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE export_set;
+drop table if exists exteriorring;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE exteriorring;
+drop table if exists extractvalue;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE extractvalue;
+drop table if exists find_in_set;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE find_in_set;
+drop table if exists floor;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE floor;
+drop table if exists found_rows;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE found_rows;
+drop table if exists from_days;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE from_days;
+drop table if exists from_unixtime;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE from_unixtime;
+drop table if exists geomcollfromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE geomcollfromtext;
+drop table if exists geomcollfromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE geomcollfromwkb;
+drop table if exists geometrycollectionfromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE geometrycollectionfromtext;
+drop table if exists geometrycollectionfromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE geometrycollectionfromwkb;
+drop table if exists geometryfromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE geometryfromtext;
+drop table if exists geometryfromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE geometryfromwkb;
+drop table if exists geometryn;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE geometryn;
+drop table if exists geometrytype;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE geometrytype;
+drop table if exists geomfromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE geomfromtext;
+drop table if exists geomfromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE geomfromwkb;
+drop table if exists get_lock;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE get_lock;
+drop table if exists glength;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE glength;
+drop table if exists greatest;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE greatest;
+drop table if exists hex;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE hex;
+drop table if exists ifnull;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE ifnull;
+drop table if exists inet_aton;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE inet_aton;
+drop table if exists inet_ntoa;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE inet_ntoa;
+drop table if exists instr;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE instr;
+drop table if exists interiorringn;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE interiorringn;
+drop table if exists intersects;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE intersects;
+drop table if exists isclosed;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE isclosed;
+drop table if exists isempty;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE isempty;
+drop table if exists isnull;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE isnull;
+drop table if exists issimple;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE issimple;
+drop table if exists is_free_lock;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE is_free_lock;
+drop table if exists is_used_lock;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE is_used_lock;
+drop table if exists last_day;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE last_day;
+drop table if exists last_insert_id;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE last_insert_id;
+drop table if exists lcase;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE lcase;
+drop table if exists least;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE least;
+drop table if exists length;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE length;
+drop table if exists linefromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE linefromtext;
+drop table if exists linefromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE linefromwkb;
+drop table if exists linestringfromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE linestringfromtext;
+drop table if exists linestringfromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE linestringfromwkb;
+drop table if exists ln;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE ln;
+drop table if exists load_file;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE load_file;
+drop table if exists locate;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE locate;
+drop table if exists log;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE log;
+drop table if exists log10;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE log10;
+drop table if exists log2;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE log2;
+drop table if exists lower;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE lower;
+drop table if exists lpad;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE lpad;
+drop table if exists ltrim;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE ltrim;
+drop table if exists makedate;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE makedate;
+drop table if exists maketime;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE maketime;
+drop table if exists make_set;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE make_set;
+drop table if exists master_pos_wait;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE master_pos_wait;
+drop table if exists mbrcontains;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE mbrcontains;
+drop table if exists mbrdisjoint;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE mbrdisjoint;
+drop table if exists mbrequal;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE mbrequal;
+drop table if exists mbrintersects;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE mbrintersects;
+drop table if exists mbroverlaps;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE mbroverlaps;
+drop table if exists mbrtouches;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE mbrtouches;
+drop table if exists mbrwithin;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE mbrwithin;
+drop table if exists md5;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE md5;
+drop table if exists mlinefromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE mlinefromtext;
+drop table if exists mlinefromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE mlinefromwkb;
+drop table if exists monthname;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE monthname;
+drop table if exists mpointfromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE mpointfromtext;
+drop table if exists mpointfromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE mpointfromwkb;
+drop table if exists mpolyfromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE mpolyfromtext;
+drop table if exists mpolyfromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE mpolyfromwkb;
+drop table if exists multilinestringfromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE multilinestringfromtext;
+drop table if exists multilinestringfromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE multilinestringfromwkb;
+drop table if exists multipointfromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE multipointfromtext;
+drop table if exists multipointfromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE multipointfromwkb;
+drop table if exists multipolygonfromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE multipolygonfromtext;
+drop table if exists multipolygonfromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE multipolygonfromwkb;
+drop table if exists name_const;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE name_const;
+drop table if exists nullif;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE nullif;
+drop table if exists numgeometries;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE numgeometries;
+drop table if exists numinteriorrings;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE numinteriorrings;
+drop table if exists numpoints;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE numpoints;
+drop table if exists oct;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE oct;
+drop table if exists octet_length;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE octet_length;
+drop table if exists ord;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE ord;
+drop table if exists overlaps;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE overlaps;
+drop table if exists period_add;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE period_add;
+drop table if exists period_diff;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE period_diff;
+drop table if exists pi;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE pi;
+drop table if exists pointfromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE pointfromtext;
+drop table if exists pointfromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE pointfromwkb;
+drop table if exists pointn;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE pointn;
+drop table if exists polyfromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE polyfromtext;
+drop table if exists polyfromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE polyfromwkb;
+drop table if exists polygonfromtext;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE polygonfromtext;
+drop table if exists polygonfromwkb;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE polygonfromwkb;
+drop table if exists pow;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE pow;
+drop table if exists power;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE power;
+drop table if exists quote;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE quote;
+drop table if exists radians;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE radians;
+drop table if exists rand;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE rand;
+drop table if exists release_lock;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE release_lock;
+drop table if exists reverse;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE reverse;
+drop table if exists round;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE round;
+drop table if exists row_count;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE row_count;
+drop table if exists rpad;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE rpad;
+drop table if exists rtrim;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE rtrim;
+drop table if exists sec_to_time;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE sec_to_time;
+drop table if exists session_user;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE session_user;
+drop table if exists sha;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE sha;
+drop table if exists sha1;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE sha1;
+drop table if exists sign;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE sign;
+drop table if exists sin;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE sin;
+drop table if exists sleep;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE sleep;
+drop table if exists soundex;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE soundex;
+drop table if exists space;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE space;
+drop table if exists sqrt;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE sqrt;
+drop table if exists srid;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE srid;
+drop table if exists startpoint;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE startpoint;
+drop table if exists strcmp;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE strcmp;
+drop table if exists str_to_date;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE str_to_date;
+drop table if exists subdate;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE subdate;
+drop table if exists substring_index;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE substring_index;
+drop table if exists subtime;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE subtime;
+drop table if exists system_user;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE system_user;
+drop table if exists tan;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE tan;
+drop table if exists timediff;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE timediff;
+drop table if exists time_format;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE time_format;
+drop table if exists time_to_sec;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE time_to_sec;
+drop table if exists touches;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE touches;
+drop table if exists to_days;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE to_days;
+drop table if exists ucase;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE ucase;
+drop table if exists uncompress;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE uncompress;
+drop table if exists uncompressed_length;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE uncompressed_length;
+drop table if exists unhex;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE unhex;
+drop table if exists unix_timestamp;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE unix_timestamp;
+drop table if exists updatexml;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE updatexml;
+drop table if exists upper;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE upper;
+drop table if exists uuid;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE uuid;
+drop table if exists version;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE version;
+drop table if exists weekday;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE weekday;
+drop table if exists weekofyear;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE weekofyear;
+drop table if exists within;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE within;
+drop table if exists x;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE x;
+drop table if exists y;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE y;
+drop table if exists yearweek;
+drop table if exists bug21114_child;
+DROP TABLE bug21114_child;
+DROP TABLE yearweek;
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index f3e44a1df60..5a8f5a3137d 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -1090,41 +1090,15 @@ drop table t1;
create table t1 (a int) engine myisam
partition by range (a)
subpartition by hash (a)
-(partition p0 VALUES LESS THAN (1) DATA DIRECTORY = 'hello/master-data/tmpdata' INDEX DIRECTORY = 'hello/master-data/tmpinx'
+(partition p0 VALUES LESS THAN (1) DATA DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpdata' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpinx'
(SUBPARTITION subpart00, SUBPARTITION subpart01));
-hello/master-data/test/t1.frm
-hello/master-data/test/t1.par
-hello/master-data/test/t1#P#p0#SP#subpart00.MYD
-hello/master-data/test/t1#P#p0#SP#subpart00.MYI
-hello/master-data/test/t1#P#p0#SP#subpart01.MYD
-hello/master-data/test/t1#P#p0#SP#subpart01.MYI
-hello/master-data/tmpdata/t1#P#p0#SP#subpart00.MYD
-hello/master-data/tmpdata/t1#P#p0#SP#subpart01.MYD
-hello/master-data/tmpinx/t1#P#p0#SP#subpart00.MYI
-hello/master-data/tmpinx/t1#P#p0#SP#subpart01.MYI
+Checking if file exists before alter
ALTER TABLE t1 REORGANIZE PARTITION p0 INTO
-(partition p1 VALUES LESS THAN (1) DATA DIRECTORY = 'hello/master-data/tmpdata' INDEX DIRECTORY = 'hello/master-data/tmpinx'
+(partition p1 VALUES LESS THAN (1) DATA DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpdata' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpinx'
(SUBPARTITION subpart10, SUBPARTITION subpart11),
-partition p2 VALUES LESS THAN (2) DATA DIRECTORY = 'hello/master-data/tmpdata' INDEX DIRECTORY = 'hello/master-data/tmpinx'
+partition p2 VALUES LESS THAN (2) DATA DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpdata' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpinx'
(SUBPARTITION subpart20, SUBPARTITION subpart21));
-hello/master-data/test/t1.frm
-hello/master-data/test/t1.par
-hello/master-data/test/t1#P#p1#SP#subpart10.MYD
-hello/master-data/test/t1#P#p1#SP#subpart10.MYI
-hello/master-data/test/t1#P#p1#SP#subpart11.MYD
-hello/master-data/test/t1#P#p1#SP#subpart11.MYI
-hello/master-data/test/t1#P#p2#SP#subpart20.MYD
-hello/master-data/test/t1#P#p2#SP#subpart20.MYI
-hello/master-data/test/t1#P#p2#SP#subpart21.MYD
-hello/master-data/test/t1#P#p2#SP#subpart21.MYI
-hello/master-data/tmpdata/t1#P#p1#SP#subpart10.MYD
-hello/master-data/tmpdata/t1#P#p1#SP#subpart11.MYD
-hello/master-data/tmpdata/t1#P#p2#SP#subpart20.MYD
-hello/master-data/tmpdata/t1#P#p2#SP#subpart21.MYD
-hello/master-data/tmpinx/t1#P#p1#SP#subpart10.MYI
-hello/master-data/tmpinx/t1#P#p1#SP#subpart11.MYI
-hello/master-data/tmpinx/t1#P#p2#SP#subpart20.MYI
-hello/master-data/tmpinx/t1#P#p2#SP#subpart21.MYI
+Checking if file exists after alter
drop table t1;
create table t1 (a bigint unsigned not null, primary key(a))
engine = myisam
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index f7a9f0440a3..617e289d30d 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -502,7 +502,8 @@ deallocate prepare stmt;
create table t1 (a varchar(20));
insert into t1 values ('foo');
prepare stmt FROM 'SELECT char_length (a) FROM t1';
-ERROR 42000: FUNCTION test.char_length does not exist
+prepare stmt2 FROM 'SELECT not_a_function (a) FROM t1';
+ERROR 42000: FUNCTION test.not_a_function does not exist
drop table t1;
prepare stmt from "SELECT SQL_CALC_FOUND_ROWS 'foo' UNION SELECT 'bar' LIMIT 0";
execute stmt;
@@ -956,11 +957,108 @@ GROUP_CONCAT(Track SEPARATOR ', ')
CAD
DEALLOCATE PREPARE STMT;
DROP TABLE t1;
-End of 4.1 tests
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (i INT, INDEX(i));
+INSERT INTO t1 VALUES (1);
+PREPARE stmt FROM "SELECT (COUNT(i) = 1), COUNT(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+(COUNT(i) = 1) COUNT(i)
+0 0
+SET @a = 1;
+EXECUTE stmt USING @a;
+(COUNT(i) = 1) COUNT(i)
+1 1
+SET @a = 0;
+EXECUTE stmt USING @a;
+(COUNT(i) = 1) COUNT(i)
+0 0
+PREPARE stmt FROM "SELECT (AVG(i) = 1), AVG(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+(AVG(i) = 1) AVG(i)
+NULL NULL
+SET @a = 1;
+EXECUTE stmt USING @a;
+(AVG(i) = 1) AVG(i)
+1 1.0000
+SET @a = 0;
+EXECUTE stmt USING @a;
+(AVG(i) = 1) AVG(i)
+NULL NULL
+PREPARE stmt FROM "SELECT (VARIANCE(i) = 1), VARIANCE(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+(VARIANCE(i) = 1) VARIANCE(i)
+NULL NULL
+SET @a = 1;
+EXECUTE stmt USING @a;
+(VARIANCE(i) = 1) VARIANCE(i)
+0 0.0000
+SET @a = 0;
+EXECUTE stmt USING @a;
+(VARIANCE(i) = 1) VARIANCE(i)
+NULL NULL
+PREPARE stmt FROM "SELECT (STDDEV(i) = 1), STDDEV(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+(STDDEV(i) = 1) STDDEV(i)
+NULL NULL
+SET @a = 1;
+EXECUTE stmt USING @a;
+(STDDEV(i) = 1) STDDEV(i)
+0 0.0000
+SET @a = 0;
+EXECUTE stmt USING @a;
+(STDDEV(i) = 1) STDDEV(i)
+NULL NULL
+PREPARE stmt FROM "SELECT (BIT_OR(i) = 1), BIT_OR(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+(BIT_OR(i) = 1) BIT_OR(i)
+0 0
+SET @a = 1;
+EXECUTE stmt USING @a;
+(BIT_OR(i) = 1) BIT_OR(i)
+1 1
+SET @a = 0;
+EXECUTE stmt USING @a;
+(BIT_OR(i) = 1) BIT_OR(i)
+0 0
+PREPARE stmt FROM "SELECT (BIT_AND(i) = 1), BIT_AND(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+(BIT_AND(i) = 1) BIT_AND(i)
+0 18446744073709551615
+SET @a = 1;
+EXECUTE stmt USING @a;
+(BIT_AND(i) = 1) BIT_AND(i)
+1 1
+SET @a = 0;
+EXECUTE stmt USING @a;
+(BIT_AND(i) = 1) BIT_AND(i)
+0 18446744073709551615
+PREPARE stmt FROM "SELECT (BIT_XOR(i) = 1), BIT_XOR(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+(BIT_XOR(i) = 1) BIT_XOR(i)
+0 0
+SET @a = 1;
+EXECUTE stmt USING @a;
+(BIT_XOR(i) = 1) BIT_XOR(i)
+1 1
+SET @a = 0;
+EXECUTE stmt USING @a;
+(BIT_XOR(i) = 1) BIT_XOR(i)
+0 0
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+End of 4.1 tests.
create table t1 (a varchar(20));
insert into t1 values ('foo');
prepare stmt FROM 'SELECT char_length (a) FROM t1';
-ERROR 42000: FUNCTION test.char_length does not exist
+prepare stmt2 FROM 'SELECT not_a_function (a) FROM t1';
+ERROR 42000: FUNCTION test.not_a_function does not exist
drop table t1;
create table t1 (a char(3) not null, b char(3) not null,
c char(3) not null, primary key (a, b, c));
@@ -1379,6 +1477,24 @@ i
1
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2;
+DROP PROCEDURE IF EXISTS p1;
+flush status;
+prepare sq from 'show status like "slow_queries"';
+execute sq;
+Variable_name Value
+Slow_queries 0
+prepare no_index from 'select 1 from information_schema.tables limit 1';
+execute sq;
+Variable_name Value
+Slow_queries 0
+execute no_index;
+1
+1
+execute sq;
+Variable_name Value
+Slow_queries 1
+deallocate prepare no_index;
+deallocate prepare sq;
End of 5.0 tests.
create procedure proc_1() reset query cache;
call proc_1();
@@ -1520,54 +1636,62 @@ flush tables;
show open tables from mysql;
Database Table In_use Name_locked
mysql general_log 1 0
+mysql slow_log 1 0
select Host, User from mysql.user limit 0;
Host User
select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql user 0 0
mysql general_log 1 0
+mysql slow_log 1 0
mysql host 0 0
+mysql user 0 0
call proc_1();
show open tables from mysql;
Database Table In_use Name_locked
mysql general_log 1 0
+mysql slow_log 1 0
select Host, User from mysql.user limit 0;
Host User
select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql user 0 0
mysql general_log 1 0
+mysql slow_log 1 0
mysql host 0 0
+mysql user 0 0
call proc_1();
show open tables from mysql;
Database Table In_use Name_locked
mysql general_log 1 0
+mysql slow_log 1 0
select Host, User from mysql.user limit 0;
Host User
select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql user 0 0
mysql general_log 1 0
+mysql slow_log 1 0
mysql host 0 0
+mysql user 0 0
call proc_1();
show open tables from mysql;
Database Table In_use Name_locked
mysql general_log 1 0
+mysql slow_log 1 0
select Host, User from mysql.user limit 0;
Host User
select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql user 0 0
mysql general_log 1 0
+mysql slow_log 1 0
mysql host 0 0
+mysql user 0 0
flush tables;
create function func_1() returns int begin flush tables; return 1; end|
ERROR 0A000: FLUSH is not allowed in stored function or trigger
@@ -1583,49 +1707,56 @@ select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql user 0 0
mysql general_log 1 0
+mysql slow_log 1 0
mysql host 0 0
+mysql user 0 0
prepare abc from "flush tables";
execute abc;
show open tables from mysql;
Database Table In_use Name_locked
mysql general_log 1 0
+mysql slow_log 1 0
select Host, User from mysql.user limit 0;
Host User
select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql user 0 0
mysql general_log 1 0
+mysql slow_log 1 0
mysql host 0 0
+mysql user 0 0
execute abc;
show open tables from mysql;
Database Table In_use Name_locked
mysql general_log 1 0
+mysql slow_log 1 0
select Host, User from mysql.user limit 0;
Host User
select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql user 0 0
mysql general_log 1 0
+mysql slow_log 1 0
mysql host 0 0
+mysql user 0 0
execute abc;
show open tables from mysql;
Database Table In_use Name_locked
mysql general_log 1 0
+mysql slow_log 1 0
select Host, User from mysql.user limit 0;
Host User
select Host, Db from mysql.host limit 0;
Host Db
show open tables from mysql;
Database Table In_use Name_locked
-mysql user 0 0
mysql general_log 1 0
+mysql slow_log 1 0
mysql host 0 0
+mysql user 0 0
flush tables;
deallocate prepare abc;
create procedure proc_1() flush logs;
diff --git a/mysql-test/r/ps_11bugs.result b/mysql-test/r/ps_11bugs.result
index c849c25d646..ebe161f46b3 100644
--- a/mysql-test/r/ps_11bugs.result
+++ b/mysql-test/r/ps_11bugs.result
@@ -130,3 +130,36 @@ prepare st_18492 from 'select * from t1 where 3 in (select (1+1) union select 1)
execute st_18492;
a
drop table t1;
+create table t1 (a int, b varchar(4));
+create table t2 (a int, b varchar(4), primary key(a));
+prepare stmt1 from 'insert into t1 (a, b) values (?, ?)';
+prepare stmt2 from 'insert into t2 (a, b) values (?, ?)';
+set @intarg= 11;
+set @varchararg= '2222';
+execute stmt1 using @intarg, @varchararg;
+execute stmt2 using @intarg, @varchararg;
+set @intarg= 12;
+execute stmt1 using @intarg, @UNDEFINED;
+execute stmt2 using @intarg, @UNDEFINED;
+set @intarg= 13;
+execute stmt1 using @UNDEFINED, @varchararg;
+execute stmt2 using @UNDEFINED, @varchararg;
+ERROR 23000: Column 'a' cannot be null
+set @intarg= 14;
+set @nullarg= Null;
+execute stmt1 using @UNDEFINED, @nullarg;
+execute stmt2 using @nullarg, @varchararg;
+ERROR 23000: Column 'a' cannot be null
+select * from t1;
+a b
+11 2222
+12 NULL
+NULL 2222
+NULL NULL
+select * from t2;
+a b
+11 2222
+12 NULL
+drop table t1;
+drop table t2;
+End of 5.0 tests.
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index 96289305da1..d5996ee8163 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -934,8 +934,7 @@ abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzab
zyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcba
flush query cache;
drop table t1, t2;
-set GLOBAL query_cache_size=1355776
-#;
+set GLOBAL query_cache_size=1355776;
flush status;
CREATE TABLE t1 (
`date` datetime NOT NULL default '0000-00-00 00:00:00',
diff --git a/mysql-test/r/query_cache_notembedded.result b/mysql-test/r/query_cache_notembedded.result
index 4226738725a..8e5df012cfb 100644
--- a/mysql-test/r/query_cache_notembedded.result
+++ b/mysql-test/r/query_cache_notembedded.result
@@ -326,7 +326,7 @@ insert into t1 values(3);
set i_var = sleep(3);
return 0;
end;|
- select f1();
+select f1();
select sleep(4);
sleep(4)
0
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index cfdee6e630e..04923c9e24c 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -665,6 +665,16 @@ OR ((pk4 =1) AND (((pk1 IN ( 7, 2, 1 ))) OR (pk1 =522)) AND ((pk2 IN ( 0, 2635))
pk1 pk2 pk3 pk4 filler
2621 2635 1000015 0 filler
drop table t1, t2;
+create table t1(a char(2), key(a(1)));
+insert into t1 values ('x'), ('xx');
+explain select a from t1 where a > 'x';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 2 NULL 2 Using where
+select a from t1 where a > 'x';
+a
+xx
+drop table t1;
+End of 4.1 tests
CREATE TABLE t1 (
id int(11) NOT NULL auto_increment,
status varchar(20),
diff --git a/mysql-test/r/rename.result b/mysql-test/r/rename.result
index 345270231ef..1257a668cce 100644
--- a/mysql-test/r/rename.result
+++ b/mysql-test/r/rename.result
@@ -43,7 +43,7 @@ Note 1051 Unknown table 't4'
CREATE TABLE t1 (a int);
CREATE TABLE t3 (a int);
FLUSH TABLES WITH READ LOCK;
- RENAME TABLE t1 TO t2, t3 to t4;
+RENAME TABLE t1 TO t2, t3 to t4;
show tables;
Tables_in_test
t1
@@ -54,6 +54,7 @@ Tables_in_test
t2
t4
drop table t2, t4;
+End of 4.1 tests
create table t1(f1 int);
create view v1 as select * from t1;
alter table v1 rename to v2;
@@ -64,3 +65,4 @@ rename table v2 to v1;
ERROR 42S01: Table 'v1' already exists
drop view v1;
drop table t1;
+End of 5.0 tests
diff --git a/mysql-test/r/rpl_err_ignoredtable.result b/mysql-test/r/rpl_err_ignoredtable.result
index 27db9c0372c..f211d5d9a2f 100644
--- a/mysql-test/r/rpl_err_ignoredtable.result
+++ b/mysql-test/r/rpl_err_ignoredtable.result
@@ -26,7 +26,7 @@ create table t2 (a int primary key);
insert into t2 values(1);
create table t3 (id int);
insert into t3 values(connection_id());
- update t2 set a = a + 1 + get_lock('crash_lock%20C', 10);
+update t2 set a = a + 1 + get_lock('crash_lock%20C', 10);
select (@id := id) - id from t3;
(@id := id) - id
0
diff --git a/mysql-test/r/rpl_master_pos_wait.result b/mysql-test/r/rpl_master_pos_wait.result
index 81d9043c8ce..951e944fddc 100644
--- a/mysql-test/r/rpl_master_pos_wait.result
+++ b/mysql-test/r/rpl_master_pos_wait.result
@@ -12,7 +12,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select master_pos_wait(_latin1'master-bin.999999',0,2) AS `master_pos_wait('master-bin.999999',0,2)`
- select master_pos_wait('master-bin.999999',0);
+select master_pos_wait('master-bin.999999',0);
stop slave sql_thread;
master_pos_wait('master-bin.999999',0)
NULL
diff --git a/mysql-test/r/rpl_ndb_sp003.result b/mysql-test/r/rpl_ndb_sp003.result
index 94f320f387b..d7922c61b52 100644
--- a/mysql-test/r/rpl_ndb_sp003.result
+++ b/mysql-test/r/rpl_ndb_sp003.result
@@ -21,7 +21,7 @@ END|
SELECT get_lock("test", 200);
get_lock("test", 200)
1
- CALL test.p1();
+CALL test.p1();
CALL test.p2();
SELECT release_lock("test");
release_lock("test")
diff --git a/mysql-test/r/rpl_row_sp003.result b/mysql-test/r/rpl_row_sp003.result
index 01e352c3d46..df3e2a7ceed 100644
--- a/mysql-test/r/rpl_row_sp003.result
+++ b/mysql-test/r/rpl_row_sp003.result
@@ -21,7 +21,7 @@ END|
SELECT get_lock("test", 200);
get_lock("test", 200)
1
- CALL test.p1();
+CALL test.p1();
CALL test.p2();
SELECT release_lock("test");
release_lock("test")
diff --git a/mysql-test/r/rpl_stm_000001.result b/mysql-test/r/rpl_stm_000001.result
index ef4226e07b5..3b4cd05f640 100644
--- a/mysql-test/r/rpl_stm_000001.result
+++ b/mysql-test/r/rpl_stm_000001.result
@@ -44,7 +44,7 @@ create table t2(id int);
insert into t2 values(connection_id());
create temporary table t3(n int);
insert into t3 select get_lock('crash_lock%20C', 1) from t2;
- update t1 set n = n + get_lock('crash_lock%20C', 2);
+update t1 set n = n + get_lock('crash_lock%20C', 2);
select (@id := id) - id from t2;
(@id := id) - id
0
diff --git a/mysql-test/r/rpl_trigger.result b/mysql-test/r/rpl_trigger.result
index bd6d6e63d57..50bcd071d23 100644
--- a/mysql-test/r/rpl_trigger.result
+++ b/mysql-test/r/rpl_trigger.result
@@ -74,8 +74,6 @@ get_lock("bug12480",2)
1
create table t1 (a datetime,b datetime, c datetime);
drop function if exists bug12480;
-Warnings:
-Note 1305 FUNCTION bug12480 does not exist
create function bug12480() returns datetime
begin
set @a=get_lock("bug12480",2);
diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result
index b473bbac923..7a1ef7cedcf 100644
--- a/mysql-test/r/show_check.result
+++ b/mysql-test/r/show_check.result
@@ -148,12 +148,14 @@ flush tables;
show open tables;
Database Table In_use Name_locked
mysql general_log 1 0
+mysql slow_log 1 0
create table t1(n int);
insert into t1 values (1);
show open tables;
Database Table In_use Name_locked
-test t1 0 0
mysql general_log 1 0
+mysql slow_log 1 0
+test t1 0 0
drop table t1;
create table t1 (a int not null, b VARCHAR(10), INDEX (b) ) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" ENGINE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed;
show create table t1;
@@ -566,21 +568,23 @@ SELECT 1 FROM mysql.db, mysql.proc, mysql.user, mysql.time_zone, mysql.time_zone
1
SHOW OPEN TABLES;
Database Table In_use Name_locked
-mysql db 0 0
+mysql proc 0 0
test urkunde 0 0
mysql time_zone 0 0
-mysql general_log 1 0
+mysql db 0 0
test txt1 0 0
-mysql proc 0 0
+mysql slow_log 1 0
test tyt2 0 0
+mysql general_log 1 0
mysql user 0 0
mysql time_zone_name 0 0
SHOW OPEN TABLES FROM mysql;
Database Table In_use Name_locked
-mysql db 0 0
+mysql proc 0 0
mysql time_zone 0 0
+mysql db 0 0
+mysql slow_log 1 0
mysql general_log 1 0
-mysql proc 0 0
mysql user 0 0
mysql time_zone_name 0 0
SHOW OPEN TABLES FROM mysql LIKE 'u%';
@@ -594,14 +598,16 @@ test tyt2 0 0
mysql time_zone_name 0 0
SHOW OPEN TABLES LIKE '%o%';
Database Table In_use Name_locked
+mysql proc 0 0
mysql time_zone 0 0
+mysql slow_log 1 0
mysql general_log 1 0
-mysql proc 0 0
mysql time_zone_name 0 0
FLUSH TABLES;
SHOW OPEN TABLES;
Database Table In_use Name_locked
mysql general_log 1 0
+mysql slow_log 1 0
DROP TABLE txt1;
DROP TABLE tyt2;
DROP TABLE urkunde;
@@ -672,6 +678,21 @@ SHOW TABLES FROM no_such_database;
ERROR 42000: Unknown database 'no_such_database'
SHOW COLUMNS FROM no_such_table;
ERROR 42S02: Table 'test.no_such_table' doesn't exist
+flush status;
+show status like 'slow_queries';
+Variable_name Value
+Slow_queries 0
+show tables;
+Tables_in_test
+show status like 'slow_queries';
+Variable_name Value
+Slow_queries 1
+select 1 from information_schema.tables limit 1;
+1
+1
+show status like 'slow_queries';
+Variable_name Value
+Slow_queries 2
End of 5.0 tests.
SHOW AUTHORS;
create database mysqltest;
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index a2d783dbcbe..d955b69bde2 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -1226,6 +1226,30 @@ END;
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 'IF NOT EXISTS bug14702()
BEGIN
END' at line 1
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (i INT);
+CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO @a;
+ERROR HY000: View's SELECT contains a 'INTO' clause
+CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO DUMPFILE "file";
+ERROR HY000: View's SELECT contains a 'INTO' clause
+CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO OUTFILE "file";
+ERROR HY000: View's SELECT contains a 'INTO' clause
+CREATE PROCEDURE bug20953()
+CREATE VIEW v AS SELECT i FROM t1 PROCEDURE ANALYSE();
+ERROR HY000: View's SELECT contains a 'PROCEDURE' clause
+CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 FROM (SELECT 1) AS d1;
+ERROR HY000: View's SELECT contains a subquery in the FROM clause
+CREATE PROCEDURE bug20953(i INT) CREATE VIEW v AS SELECT i;
+ERROR HY000: View's SELECT contains a variable or parameter
+CREATE PROCEDURE bug20953()
+BEGIN
+DECLARE i INT;
+CREATE VIEW v AS SELECT i;
+END |
+ERROR HY000: View's SELECT contains a variable or parameter
+PREPARE stmt FROM "CREATE VIEW v AS SELECT ?";
+ERROR HY000: View's SELECT contains a variable or parameter
+DROP TABLE t1;
End of 5.0 tests
drop function if exists bug16164;
create function bug16164() returns int
@@ -1234,9 +1258,9 @@ show authors;
return 42;
end|
ERROR 0A000: Not allowed to return a result set from a function
-drop function if exists bug20701|
-create function bug20701() returns varchar(25) binary return "test"|
+drop function if exists bug20701;
+create function bug20701() returns varchar(25) binary return "test";
ERROR 42000: This version of MySQL doesn't yet support 'return value collation'
-create function bug20701() returns varchar(25) return "test"|
-drop function bug20701|
+create function bug20701() returns varchar(25) return "test";
+drop function bug20701;
End of 5.1 tests
diff --git a/mysql-test/r/sp-threads.result b/mysql-test/r/sp-threads.result
index c516d7a643f..953830ecc87 100644
--- a/mysql-test/r/sp-threads.result
+++ b/mysql-test/r/sp-threads.result
@@ -31,7 +31,7 @@ create procedure bug9486()
update t1, t2 set val= 1 where id1=id2;
call bug9486();
lock tables t2 write;
- call bug9486();
+call bug9486();
show processlist;
Id User Host db Command Time State Info
# root localhost test Sleep # NULL
@@ -77,7 +77,7 @@ select * from t1;
end|
use test;
lock table t1 write;
- call p2();
+call p2();
use test;
drop procedure p1;
create procedure p1() select * from t1;
diff --git a/mysql-test/r/sp-vars.result b/mysql-test/r/sp-vars.result
index d41d98113a1..8b59fa371cc 100644
--- a/mysql-test/r/sp-vars.result
+++ b/mysql-test/r/sp-vars.result
@@ -4,6 +4,7 @@ DROP FUNCTION IF EXISTS sp_vars_check_ret1;
DROP FUNCTION IF EXISTS sp_vars_check_ret2;
DROP FUNCTION IF EXISTS sp_vars_check_ret3;
DROP FUNCTION IF EXISTS sp_vars_check_ret4;
+DROP FUNCTION IF EXISTS sp_vars_div_zero;
SET @@sql_mode = 'ansi';
CREATE PROCEDURE sp_vars_check_dflt()
BEGIN
@@ -88,6 +89,12 @@ CREATE FUNCTION sp_vars_check_ret4() RETURNS DECIMAL(64, 2)
BEGIN
RETURN 12 * 10 + 34 + 0.1234;
END|
+CREATE FUNCTION sp_vars_div_zero() RETURNS INTEGER
+BEGIN
+DECLARE div_zero INTEGER;
+SELECT 1/0 INTO div_zero;
+RETURN div_zero;
+END|
---------------------------------------------------------------
Calling the routines, created in ANSI mode.
@@ -172,6 +179,9 @@ sp_vars_check_ret4()
154.12
Warnings:
Note 1265 Data truncated for column 'sp_vars_check_ret4()' at row 1
+SELECT sp_vars_div_zero();
+sp_vars_div_zero()
+NULL
SET @@sql_mode = 'traditional';
---------------------------------------------------------------
@@ -257,12 +267,16 @@ sp_vars_check_ret4()
154.12
Warnings:
Note 1265 Data truncated for column 'sp_vars_check_ret4()' at row 1
+SELECT sp_vars_div_zero();
+sp_vars_div_zero()
+NULL
DROP PROCEDURE sp_vars_check_dflt;
DROP PROCEDURE sp_vars_check_assignment;
DROP FUNCTION sp_vars_check_ret1;
DROP FUNCTION sp_vars_check_ret2;
DROP FUNCTION sp_vars_check_ret3;
DROP FUNCTION sp_vars_check_ret4;
+DROP FUNCTION sp_vars_div_zero;
CREATE PROCEDURE sp_vars_check_dflt()
BEGIN
DECLARE v1 TINYINT DEFAULT 1e200;
@@ -346,6 +360,12 @@ CREATE FUNCTION sp_vars_check_ret4() RETURNS DECIMAL(64, 2)
BEGIN
RETURN 12 * 10 + 34 + 0.1234;
END|
+CREATE FUNCTION sp_vars_div_zero() RETURNS INTEGER
+BEGIN
+DECLARE div_zero INTEGER;
+SELECT 1/0 INTO div_zero;
+RETURN div_zero;
+END|
---------------------------------------------------------------
Calling the routines, created in TRADITIONAL mode.
@@ -366,6 +386,8 @@ sp_vars_check_ret4()
154.12
Warnings:
Note 1265 Data truncated for column 'sp_vars_check_ret4()' at row 1
+SELECT sp_vars_div_zero();
+ERROR 22012: Division by 0
SET @@sql_mode = 'ansi';
DROP PROCEDURE sp_vars_check_dflt;
DROP PROCEDURE sp_vars_check_assignment;
@@ -373,6 +395,7 @@ DROP FUNCTION sp_vars_check_ret1;
DROP FUNCTION sp_vars_check_ret2;
DROP FUNCTION sp_vars_check_ret3;
DROP FUNCTION sp_vars_check_ret4;
+DROP FUNCTION sp_vars_div_zero;
---------------------------------------------------------------
BIT data type tests
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 79e32b921cc..aeccfd9c951 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -5470,5 +5470,161 @@ CAD
CHF
DROP FUNCTION bug21493|
DROP TABLE t3,t4|
+drop function if exists func_20028_a|
+drop function if exists func_20028_b|
+drop function if exists func_20028_c|
+drop procedure if exists proc_20028_a|
+drop procedure if exists proc_20028_b|
+drop procedure if exists proc_20028_c|
+drop table if exists table_20028|
+create table table_20028 (i int)|
+SET @save_sql_mode=@@sql_mode|
+SET sql_mode=''|
+create function func_20028_a() returns integer
+begin
+declare temp integer;
+select i into temp from table_20028 limit 1;
+return ifnull(temp, 0);
+end|
+create function func_20028_b() returns integer
+begin
+return func_20028_a();
+end|
+create function func_20028_c() returns integer
+begin
+declare div_zero integer;
+set SQL_MODE='TRADITIONAL';
+select 1/0 into div_zero;
+return div_zero;
+end|
+create procedure proc_20028_a()
+begin
+declare temp integer;
+select i into temp from table_20028 limit 1;
+end|
+create procedure proc_20028_b()
+begin
+call proc_20028_a();
+end|
+create procedure proc_20028_c()
+begin
+declare div_zero integer;
+set SQL_MODE='TRADITIONAL';
+select 1/0 into div_zero;
+end|
+select func_20028_a()|
+func_20028_a()
+0
+Warnings:
+Warning 1329 No data - zero rows fetched, selected, or processed
+select func_20028_b()|
+func_20028_b()
+0
+Warnings:
+Warning 1329 No data - zero rows fetched, selected, or processed
+select func_20028_c()|
+ERROR 22012: Division by 0
+call proc_20028_a()|
+Warnings:
+Warning 1329 No data - zero rows fetched, selected, or processed
+call proc_20028_b()|
+Warnings:
+Warning 1329 No data - zero rows fetched, selected, or processed
+call proc_20028_c()|
+ERROR 22012: Division by 0
+SET sql_mode='TRADITIONAL'|
+drop function func_20028_a|
+drop function func_20028_b|
+drop function func_20028_c|
+drop procedure proc_20028_a|
+drop procedure proc_20028_b|
+drop procedure proc_20028_c|
+create function func_20028_a() returns integer
+begin
+declare temp integer;
+select i into temp from table_20028 limit 1;
+return ifnull(temp, 0);
+end|
+create function func_20028_b() returns integer
+begin
+return func_20028_a();
+end|
+create function func_20028_c() returns integer
+begin
+declare div_zero integer;
+set SQL_MODE='';
+select 1/0 into div_zero;
+return div_zero;
+end|
+create procedure proc_20028_a()
+begin
+declare temp integer;
+select i into temp from table_20028 limit 1;
+end|
+create procedure proc_20028_b()
+begin
+call proc_20028_a();
+end|
+create procedure proc_20028_c()
+begin
+declare div_zero integer;
+set SQL_MODE='';
+select 1/0 into div_zero;
+end|
+select func_20028_a()|
+func_20028_a()
+0
+Warnings:
+Warning 1329 No data - zero rows fetched, selected, or processed
+select func_20028_b()|
+func_20028_b()
+0
+Warnings:
+Warning 1329 No data - zero rows fetched, selected, or processed
+select func_20028_c()|
+func_20028_c()
+NULL
+call proc_20028_a()|
+Warnings:
+Warning 1329 No data - zero rows fetched, selected, or processed
+call proc_20028_b()|
+Warnings:
+Warning 1329 No data - zero rows fetched, selected, or processed
+call proc_20028_c()|
+SET @@sql_mode=@save_sql_mode|
+drop function func_20028_a|
+drop function func_20028_b|
+drop function func_20028_c|
+drop procedure proc_20028_a|
+drop procedure proc_20028_b|
+drop procedure proc_20028_c|
+drop table table_20028|
+drop procedure if exists proc_21462_a|
+drop procedure if exists proc_21462_b|
+create procedure proc_21462_a()
+begin
+select "Called A";
+end|
+create procedure proc_21462_b(x int)
+begin
+select "Called B";
+end|
+call proc_21462_a|
+Called A
+Called A
+call proc_21462_a()|
+Called A
+Called A
+call proc_21462_a(1)|
+ERROR 42000: Incorrect number of arguments for PROCEDURE test.proc_21462_a; expected 0, got 1
+call proc_21462_b|
+ERROR 42000: Incorrect number of arguments for PROCEDURE test.proc_21462_b; expected 1, got 0
+call proc_21462_b()|
+ERROR 42000: Incorrect number of arguments for PROCEDURE test.proc_21462_b; expected 1, got 0
+call proc_21462_b(1)|
+Called B
+Called B
+drop procedure proc_21462_a|
+drop procedure proc_21462_b|
End of 5.0 tests
drop table t1,t2;
diff --git a/mysql-test/r/sp_notembedded.result b/mysql-test/r/sp_notembedded.result
index 564b8031c35..0b1fa565d28 100644
--- a/mysql-test/r/sp_notembedded.result
+++ b/mysql-test/r/sp_notembedded.result
@@ -74,8 +74,7 @@ flush status|
flush query cache|
delete from t1|
drop procedure bug3583|
-drop table t1;
-#|
+drop table t1|
drop procedure if exists bug6807|
create procedure bug6807()
begin
diff --git a/mysql-test/r/ssl_des.result b/mysql-test/r/ssl_des.result
new file mode 100644
index 00000000000..cd8bf52139e
--- /dev/null
+++ b/mysql-test/r/ssl_des.result
@@ -0,0 +1,2159 @@
+SHOW STATUS LIKE 'Ssl_cipher';
+Variable_name Value
+Ssl_cipher DHE-RSA-AES256-SHA
+drop table if exists t1,t2,t3,t4;
+CREATE TABLE t1 (
+Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
+Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL
+);
+INSERT INTO t1 VALUES (9410,9412);
+select period from t1;
+period
+9410
+select * from t1;
+Period Varor_period
+9410 9412
+select t1.* from t1;
+Period Varor_period
+9410 9412
+CREATE TABLE t2 (
+auto int not null auto_increment,
+fld1 int(6) unsigned zerofill DEFAULT '000000' NOT NULL,
+companynr tinyint(2) unsigned zerofill DEFAULT '00' NOT NULL,
+fld3 char(30) DEFAULT '' NOT NULL,
+fld4 char(35) DEFAULT '' NOT NULL,
+fld5 char(35) DEFAULT '' NOT NULL,
+fld6 char(4) DEFAULT '' NOT NULL,
+UNIQUE fld1 (fld1),
+KEY fld3 (fld3),
+PRIMARY KEY (auto)
+);
+select t2.fld3 from t2 where companynr = 58 and fld3 like "%imaginable%";
+fld3
+imaginable
+select fld3 from t2 where fld3 like "%cultivation" ;
+fld3
+cultivation
+select t2.fld3,companynr from t2 where companynr = 57+1 order by fld3;
+fld3 companynr
+concoct 58
+druggists 58
+engrossing 58
+Eurydice 58
+exclaimers 58
+ferociousness 58
+hopelessness 58
+Huey 58
+imaginable 58
+judges 58
+merging 58
+ostrich 58
+peering 58
+Phelps 58
+presumes 58
+Ruth 58
+sentences 58
+Shylock 58
+straggled 58
+synergy 58
+thanking 58
+tying 58
+unlocks 58
+select fld3,companynr from t2 where companynr = 58 order by fld3;
+fld3 companynr
+concoct 58
+druggists 58
+engrossing 58
+Eurydice 58
+exclaimers 58
+ferociousness 58
+hopelessness 58
+Huey 58
+imaginable 58
+judges 58
+merging 58
+ostrich 58
+peering 58
+Phelps 58
+presumes 58
+Ruth 58
+sentences 58
+Shylock 58
+straggled 58
+synergy 58
+thanking 58
+tying 58
+unlocks 58
+select fld3 from t2 order by fld3 desc limit 10;
+fld3
+youthfulness
+yelped
+Wotan
+workers
+Witt
+witchcraft
+Winsett
+Willy
+willed
+wildcats
+select fld3 from t2 order by fld3 desc limit 5;
+fld3
+youthfulness
+yelped
+Wotan
+workers
+Witt
+select fld3 from t2 order by fld3 desc limit 5,5;
+fld3
+witchcraft
+Winsett
+Willy
+willed
+wildcats
+select t2.fld3 from t2 where fld3 = 'honeysuckle';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckl_';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'hon_ysuckl_';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckle%';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'h%le';
+fld3
+honeysuckle
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckle_';
+fld3
+select t2.fld3 from t2 where fld3 LIKE 'don_t_find_me_please%';
+fld3
+explain select t2.fld3 from t2 where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index
+explain select fld3 from t2 ignore index (fld3) where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select fld3 from t2 use index (fld1) where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select fld3 from t2 use index (fld3) where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index
+explain select fld3 from t2 use index (fld1,fld3) where fld3 = 'honeysuckle';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index
+explain select fld3 from t2 ignore index (fld3,not_used);
+ERROR HY000: Key 'not_used' doesn't exist in table 't2'
+explain select fld3 from t2 use index (not_used);
+ERROR HY000: Key 'not_used' doesn't exist in table 't2'
+select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3;
+fld3
+honeysuckle
+honoring
+explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range fld3 fld3 30 NULL 2 Using where; Using index
+select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3;
+fld1 fld3
+148504 Colombo
+068305 Colombo
+000000 nondecreasing
+select fld1,fld3 from t2 where companynr = 37 and fld3 = 'appendixes';
+fld1 fld3
+232605 appendixes
+1232605 appendixes
+1232606 appendixes
+1232607 appendixes
+1232608 appendixes
+1232609 appendixes
+select fld1 from t2 where fld1=250501 or fld1="250502";
+fld1
+250501
+250502
+explain select fld1 from t2 where fld1=250501 or fld1="250502";
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range fld1 fld1 4 NULL 2 Using where; Using index
+select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502;
+fld1
+250501
+250502
+250505
+250601
+explain select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index
+select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
+fld1 fld3
+218401 faithful
+018007 fanatic
+228311 fated
+018017 featherweight
+218022 feed
+088303 feminine
+058004 Fenton
+038017 fetched
+018054 fetters
+208101 fiftieth
+238007 filial
+013606 fingerings
+218008 finishers
+038205 firearm
+188505 fitting
+202301 Fitzpatrick
+238008 fixedly
+012001 flanking
+018103 flint
+018104 flopping
+188007 flurried
+013602 foldout
+226205 foothill
+232102 forgivably
+228306 forthcoming
+186002 freakish
+208113 freest
+231315 freezes
+036002 funereal
+226209 furnishings
+198006 furthermore
+select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
+fld3
+select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
+fld3
+Chantilly
+select fld1,fld3 from t2 where fld1 like "25050%";
+fld1 fld3
+250501 poisoning
+250502 Iraqis
+250503 heaving
+250504 population
+250505 bomb
+select fld1,fld3 from t2 where fld1 like "25050_";
+fld1 fld3
+250501 poisoning
+250502 Iraqis
+250503 heaving
+250504 population
+250505 bomb
+select distinct companynr from t2;
+companynr
+00
+37
+36
+50
+58
+29
+40
+53
+65
+41
+34
+68
+select distinct companynr from t2 order by companynr;
+companynr
+00
+29
+34
+36
+37
+40
+41
+50
+53
+58
+65
+68
+select distinct companynr from t2 order by companynr desc;
+companynr
+68
+65
+58
+53
+50
+41
+40
+37
+36
+34
+29
+00
+select distinct t2.fld3,period from t2,t1 where companynr=37 and fld3 like "O%";
+fld3 period
+obliterates 9410
+offload 9410
+opaquely 9410
+organizer 9410
+overestimating 9410
+overlay 9410
+select distinct fld3 from t2 where companynr = 34 order by fld3;
+fld3
+absentee
+accessed
+ahead
+alphabetic
+Asiaticizations
+attitude
+aye
+bankruptcies
+belays
+Blythe
+bomb
+boulevard
+bulldozes
+cannot
+caressing
+charcoal
+checksumming
+chess
+clubroom
+colorful
+cosy
+creator
+crying
+Darius
+diffusing
+duality
+Eiffel
+Epiphany
+Ernestine
+explorers
+exterminated
+famine
+forked
+Gershwins
+heaving
+Hodges
+Iraqis
+Italianization
+Lagos
+landslide
+libretto
+Majorca
+mastering
+narrowed
+occurred
+offerers
+Palestine
+Peruvianizes
+pharmaceutic
+poisoning
+population
+Pygmalion
+rats
+realest
+recording
+regimented
+retransmitting
+reviver
+rouses
+scars
+sicker
+sleepwalk
+stopped
+sugars
+translatable
+uncles
+unexpected
+uprisings
+versatility
+vest
+select distinct fld3 from t2 limit 10;
+fld3
+abates
+abiding
+Abraham
+abrogating
+absentee
+abut
+accessed
+accruing
+accumulating
+accuracies
+select distinct fld3 from t2 having fld3 like "A%" limit 10;
+fld3
+abates
+abiding
+Abraham
+abrogating
+absentee
+abut
+accessed
+accruing
+accumulating
+accuracies
+select distinct substring(fld3,1,3) from t2 where fld3 like "A%";
+substring(fld3,1,3)
+aba
+abi
+Abr
+abs
+abu
+acc
+acq
+acu
+Ade
+adj
+Adl
+adm
+Ado
+ads
+adv
+aer
+aff
+afi
+afl
+afo
+agi
+ahe
+aim
+air
+Ald
+alg
+ali
+all
+alp
+alr
+ama
+ame
+amm
+ana
+and
+ane
+Ang
+ani
+Ann
+Ant
+api
+app
+aqu
+Ara
+arc
+Arm
+arr
+Art
+Asi
+ask
+asp
+ass
+ast
+att
+aud
+Aug
+aut
+ave
+avo
+awe
+aye
+Azt
+select distinct substring(fld3,1,3) as a from t2 having a like "A%" order by a limit 10;
+a
+aba
+abi
+Abr
+abs
+abu
+acc
+acq
+acu
+Ade
+adj
+select distinct substring(fld3,1,3) from t2 where fld3 like "A%" limit 10;
+substring(fld3,1,3)
+aba
+abi
+Abr
+abs
+abu
+acc
+acq
+acu
+Ade
+adj
+select distinct substring(fld3,1,3) as a from t2 having a like "A%" limit 10;
+a
+aba
+abi
+Abr
+abs
+abu
+acc
+acq
+acu
+Ade
+adj
+create table t3 (
+period int not null,
+name char(32) not null,
+companynr int not null,
+price double(11,0),
+price2 double(11,0),
+key (period),
+key (name)
+);
+create temporary table tmp engine = myisam select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+insert into tmp select * from t3;
+insert into t3 select * from tmp;
+alter table t3 add t2nr int not null auto_increment primary key first;
+drop table tmp;
+SET SQL_BIG_TABLES=1;
+select distinct concat(fld3," ",fld3) as namn from t2,t3 where t2.fld1=t3.t2nr order by namn limit 10;
+namn
+Abraham Abraham
+abrogating abrogating
+admonishing admonishing
+Adolph Adolph
+afield afield
+aging aging
+ammonium ammonium
+analyzable analyzable
+animals animals
+animized animized
+SET SQL_BIG_TABLES=0;
+select distinct concat(fld3," ",fld3) from t2,t3 where t2.fld1=t3.t2nr order by fld3 limit 10;
+concat(fld3," ",fld3)
+Abraham Abraham
+abrogating abrogating
+admonishing admonishing
+Adolph Adolph
+afield afield
+aging aging
+ammonium ammonium
+analyzable analyzable
+animals animals
+animized animized
+select distinct fld5 from t2 limit 10;
+fld5
+neat
+Steinberg
+jarring
+tinily
+balled
+persist
+attainments
+fanatic
+measures
+rightfulness
+select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10;
+fld3 count(*)
+affixed 1
+and 1
+annoyers 1
+Anthony 1
+assayed 1
+assurers 1
+attendants 1
+bedlam 1
+bedpost 1
+boasted 1
+SET SQL_BIG_TABLES=1;
+select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10;
+fld3 count(*)
+affixed 1
+and 1
+annoyers 1
+Anthony 1
+assayed 1
+assurers 1
+attendants 1
+bedlam 1
+bedpost 1
+boasted 1
+SET SQL_BIG_TABLES=0;
+select distinct fld3,repeat("a",length(fld3)),count(*) from t2 group by companynr,fld3 limit 100,10;
+fld3 repeat("a",length(fld3)) count(*)
+circus aaaaaa 1
+cited aaaaa 1
+Colombo aaaaaaa 1
+congresswoman aaaaaaaaaaaaa 1
+contrition aaaaaaaaaa 1
+corny aaaaa 1
+cultivation aaaaaaaaaaa 1
+definiteness aaaaaaaaaaaa 1
+demultiplex aaaaaaaaaaa 1
+disappointing aaaaaaaaaaaaa 1
+select distinct companynr,rtrim(space(512+companynr)) from t3 order by 1,2;
+companynr rtrim(space(512+companynr))
+37
+78
+101
+154
+311
+447
+512
+select distinct fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by fld3;
+fld3
+explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by t3.t2nr,fld3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort
+1 SIMPLE t3 ref period period 4 test.t1.period 4181
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 index period period 4 NULL 41810
+1 SIMPLE t1 ref period period 4 test.t3.period 4181
+explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index period period 4 NULL 41810
+1 SIMPLE t3 ref period period 4 test.t1.period 4181
+select period from t1;
+period
+9410
+select period from t1 where period=1900;
+period
+select fld3,period from t1,t2 where fld1 = 011401 order by period;
+fld3 period
+breaking 9410
+select fld3,period from t2,t3 where t2.fld1 = 011401 and t2.fld1=t3.t2nr and t3.period=1001;
+fld3 period
+breaking 1001
+explain select fld3,period from t2,t3 where t2.fld1 = 011401 and t3.t2nr=t2.fld1 and 1001 = t3.period;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 const fld1 fld1 4 const 1
+1 SIMPLE t3 const PRIMARY,period PRIMARY 4 const 1
+select fld3,period from t2,t1 where companynr*10 = 37*10;
+fld3 period
+breaking 9410
+Romans 9410
+intercepted 9410
+bewilderingly 9410
+astound 9410
+admonishing 9410
+sumac 9410
+flanking 9410
+combed 9410
+subjective 9410
+scatterbrain 9410
+Eulerian 9410
+Kane 9410
+overlay 9410
+perturb 9410
+goblins 9410
+annihilates 9410
+Wotan 9410
+snatching 9410
+concludes 9410
+laterally 9410
+yelped 9410
+grazing 9410
+Baird 9410
+celery 9410
+misunderstander 9410
+handgun 9410
+foldout 9410
+mystic 9410
+succumbed 9410
+Nabisco 9410
+fingerings 9410
+aging 9410
+afield 9410
+ammonium 9410
+boat 9410
+intelligibility 9410
+Augustine 9410
+teethe 9410
+dreaded 9410
+scholastics 9410
+audiology 9410
+wallet 9410
+parters 9410
+eschew 9410
+quitter 9410
+neat 9410
+Steinberg 9410
+jarring 9410
+tinily 9410
+balled 9410
+persist 9410
+attainments 9410
+fanatic 9410
+measures 9410
+rightfulness 9410
+capably 9410
+impulsive 9410
+starlet 9410
+terminators 9410
+untying 9410
+announces 9410
+featherweight 9410
+pessimist 9410
+daughter 9410
+decliner 9410
+lawgiver 9410
+stated 9410
+readable 9410
+attrition 9410
+cascade 9410
+motors 9410
+interrogate 9410
+pests 9410
+stairway 9410
+dopers 9410
+testicle 9410
+Parsifal 9410
+leavings 9410
+postulation 9410
+squeaking 9410
+contrasted 9410
+leftover 9410
+whiteners 9410
+erases 9410
+Punjab 9410
+Merritt 9410
+Quixotism 9410
+sweetish 9410
+dogging 9410
+scornfully 9410
+bellow 9410
+bills 9410
+cupboard 9410
+sureties 9410
+puddings 9410
+fetters 9410
+bivalves 9410
+incurring 9410
+Adolph 9410
+pithed 9410
+Miles 9410
+trimmings 9410
+tragedies 9410
+skulking 9410
+flint 9410
+flopping 9410
+relaxing 9410
+offload 9410
+suites 9410
+lists 9410
+animized 9410
+multilayer 9410
+standardizes 9410
+Judas 9410
+vacuuming 9410
+dentally 9410
+humanness 9410
+inch 9410
+Weissmuller 9410
+irresponsibly 9410
+luckily 9410
+culled 9410
+medical 9410
+bloodbath 9410
+subschema 9410
+animals 9410
+Micronesia 9410
+repetitions 9410
+Antares 9410
+ventilate 9410
+pityingly 9410
+interdependent 9410
+Graves 9410
+neonatal 9410
+chafe 9410
+honoring 9410
+realtor 9410
+elite 9410
+funereal 9410
+abrogating 9410
+sorters 9410
+Conley 9410
+lectured 9410
+Abraham 9410
+Hawaii 9410
+cage 9410
+hushes 9410
+Simla 9410
+reporters 9410
+Dutchman 9410
+descendants 9410
+groupings 9410
+dissociate 9410
+coexist 9410
+Beebe 9410
+Taoism 9410
+Connally 9410
+fetched 9410
+checkpoints 9410
+rusting 9410
+galling 9410
+obliterates 9410
+traitor 9410
+resumes 9410
+analyzable 9410
+terminator 9410
+gritty 9410
+firearm 9410
+minima 9410
+Selfridge 9410
+disable 9410
+witchcraft 9410
+betroth 9410
+Manhattanize 9410
+imprint 9410
+peeked 9410
+swelling 9410
+interrelationships 9410
+riser 9410
+Gandhian 9410
+peacock 9410
+bee 9410
+kanji 9410
+dental 9410
+scarf 9410
+chasm 9410
+insolence 9410
+syndicate 9410
+alike 9410
+imperial 9410
+convulsion 9410
+railway 9410
+validate 9410
+normalizes 9410
+comprehensive 9410
+chewing 9410
+denizen 9410
+schemer 9410
+chronicle 9410
+Kline 9410
+Anatole 9410
+partridges 9410
+brunch 9410
+recruited 9410
+dimensions 9410
+Chicana 9410
+announced 9410
+praised 9410
+employing 9410
+linear 9410
+quagmire 9410
+western 9410
+relishing 9410
+serving 9410
+scheduling 9410
+lore 9410
+eventful 9410
+arteriole 9410
+disentangle 9410
+cured 9410
+Fenton 9410
+avoidable 9410
+drains 9410
+detectably 9410
+husky 9410
+impelling 9410
+undoes 9410
+evened 9410
+squeezes 9410
+destroyer 9410
+rudeness 9410
+beaner 9410
+boorish 9410
+Everhart 9410
+encompass 9410
+mushrooms 9410
+Alison 9410
+externally 9410
+pellagra 9410
+cult 9410
+creek 9410
+Huffman 9410
+Majorca 9410
+governing 9410
+gadfly 9410
+reassigned 9410
+intentness 9410
+craziness 9410
+psychic 9410
+squabbled 9410
+burlesque 9410
+capped 9410
+extracted 9410
+DiMaggio 9410
+exclamation 9410
+subdirectory 9410
+Gothicism 9410
+feminine 9410
+metaphysically 9410
+sanding 9410
+Miltonism 9410
+freakish 9410
+index 9410
+straight 9410
+flurried 9410
+denotative 9410
+coming 9410
+commencements 9410
+gentleman 9410
+gifted 9410
+Shanghais 9410
+sportswriting 9410
+sloping 9410
+navies 9410
+leaflet 9410
+shooter 9410
+Joplin 9410
+babies 9410
+assails 9410
+admiring 9410
+swaying 9410
+Goldstine 9410
+fitting 9410
+Norwalk 9410
+analogy 9410
+deludes 9410
+cokes 9410
+Clayton 9410
+exhausts 9410
+causality 9410
+sating 9410
+icon 9410
+throttles 9410
+communicants 9410
+dehydrate 9410
+priceless 9410
+publicly 9410
+incidentals 9410
+commonplace 9410
+mumbles 9410
+furthermore 9410
+cautioned 9410
+parametrized 9410
+registration 9410
+sadly 9410
+positioning 9410
+babysitting 9410
+eternal 9410
+hoarder 9410
+congregates 9410
+rains 9410
+workers 9410
+sags 9410
+unplug 9410
+garage 9410
+boulder 9410
+specifics 9410
+Teresa 9410
+Winsett 9410
+convenient 9410
+buckboards 9410
+amenities 9410
+resplendent 9410
+sews 9410
+participated 9410
+Simon 9410
+certificates 9410
+Fitzpatrick 9410
+Evanston 9410
+misted 9410
+textures 9410
+save 9410
+count 9410
+rightful 9410
+chaperone 9410
+Lizzy 9410
+clenched 9410
+effortlessly 9410
+accessed 9410
+beaters 9410
+Hornblower 9410
+vests 9410
+indulgences 9410
+infallibly 9410
+unwilling 9410
+excrete 9410
+spools 9410
+crunches 9410
+overestimating 9410
+ineffective 9410
+humiliation 9410
+sophomore 9410
+star 9410
+rifles 9410
+dialysis 9410
+arriving 9410
+indulge 9410
+clockers 9410
+languages 9410
+Antarctica 9410
+percentage 9410
+ceiling 9410
+specification 9410
+regimented 9410
+ciphers 9410
+pictures 9410
+serpents 9410
+allot 9410
+realized 9410
+mayoral 9410
+opaquely 9410
+hostess 9410
+fiftieth 9410
+incorrectly 9410
+decomposition 9410
+stranglings 9410
+mixture 9410
+electroencephalography 9410
+similarities 9410
+charges 9410
+freest 9410
+Greenberg 9410
+tinting 9410
+expelled 9410
+warm 9410
+smoothed 9410
+deductions 9410
+Romano 9410
+bitterroot 9410
+corset 9410
+securing 9410
+environing 9410
+cute 9410
+Crays 9410
+heiress 9410
+inform 9410
+avenge 9410
+universals 9410
+Kinsey 9410
+ravines 9410
+bestseller 9410
+equilibrium 9410
+extents 9410
+relatively 9410
+pressure 9410
+critiques 9410
+befouled 9410
+rightfully 9410
+mechanizing 9410
+Latinizes 9410
+timesharing 9410
+Aden 9410
+embassies 9410
+males 9410
+shapelessly 9410
+mastering 9410
+Newtonian 9410
+finishers 9410
+abates 9410
+teem 9410
+kiting 9410
+stodgy 9410
+feed 9410
+guitars 9410
+airships 9410
+store 9410
+denounces 9410
+Pyle 9410
+Saxony 9410
+serializations 9410
+Peruvian 9410
+taxonomically 9410
+kingdom 9410
+stint 9410
+Sault 9410
+faithful 9410
+Ganymede 9410
+tidiness 9410
+gainful 9410
+contrary 9410
+Tipperary 9410
+tropics 9410
+theorizers 9410
+renew 9410
+already 9410
+terminal 9410
+Hegelian 9410
+hypothesizer 9410
+warningly 9410
+journalizing 9410
+nested 9410
+Lars 9410
+saplings 9410
+foothill 9410
+labeled 9410
+imperiously 9410
+reporters 9410
+furnishings 9410
+precipitable 9410
+discounts 9410
+excises 9410
+Stalin 9410
+despot 9410
+ripeness 9410
+Arabia 9410
+unruly 9410
+mournfulness 9410
+boom 9410
+slaughter 9410
+Sabine 9410
+handy 9410
+rural 9410
+organizer 9410
+shipyard 9410
+civics 9410
+inaccuracy 9410
+rules 9410
+juveniles 9410
+comprised 9410
+investigations 9410
+stabilizes 9410
+seminaries 9410
+Hunter 9410
+sporty 9410
+test 9410
+weasels 9410
+CERN 9410
+tempering 9410
+afore 9410
+Galatean 9410
+techniques 9410
+error 9410
+veranda 9410
+severely 9410
+Cassites 9410
+forthcoming 9410
+guides 9410
+vanish 9410
+lied 9410
+sawtooth 9410
+fated 9410
+gradually 9410
+widens 9410
+preclude 9410
+evenhandedly 9410
+percentage 9410
+disobedience 9410
+humility 9410
+gleaning 9410
+petted 9410
+bloater 9410
+minion 9410
+marginal 9410
+apiary 9410
+measures 9410
+precaution 9410
+repelled 9410
+primary 9410
+coverings 9410
+Artemia 9410
+navigate 9410
+spatial 9410
+Gurkha 9410
+meanwhile 9410
+Melinda 9410
+Butterfield 9410
+Aldrich 9410
+previewing 9410
+glut 9410
+unaffected 9410
+inmate 9410
+mineral 9410
+impending 9410
+meditation 9410
+ideas 9410
+miniaturizes 9410
+lewdly 9410
+title 9410
+youthfulness 9410
+creak 9410
+Chippewa 9410
+clamored 9410
+freezes 9410
+forgivably 9410
+reduce 9410
+McGovern 9410
+Nazis 9410
+epistle 9410
+socializes 9410
+conceptions 9410
+Kevin 9410
+uncovering 9410
+chews 9410
+appendixes 9410
+appendixes 9410
+appendixes 9410
+appendixes 9410
+appendixes 9410
+appendixes 9410
+raining 9410
+infest 9410
+compartment 9410
+minting 9410
+ducks 9410
+roped 9410
+waltz 9410
+Lillian 9410
+repressions 9410
+chillingly 9410
+noncritical 9410
+lithograph 9410
+spongers 9410
+parenthood 9410
+posed 9410
+instruments 9410
+filial 9410
+fixedly 9410
+relives 9410
+Pandora 9410
+watering 9410
+ungrateful 9410
+secures 9410
+poison 9410
+dusted 9410
+encompasses 9410
+presentation 9410
+Kantian 9410
+select fld3,period,price,price2 from t2,t3 where t2.fld1=t3.t2nr and period >= 1001 and period <= 1002 and t2.companynr = 37 order by fld3,period, price;
+fld3 period price price2
+admonishing 1002 28357832 8723648
+analyzable 1002 28357832 8723648
+annihilates 1001 5987435 234724
+Antares 1002 28357832 8723648
+astound 1001 5987435 234724
+audiology 1001 5987435 234724
+Augustine 1002 28357832 8723648
+Baird 1002 28357832 8723648
+bewilderingly 1001 5987435 234724
+breaking 1001 5987435 234724
+Conley 1001 5987435 234724
+dentally 1002 28357832 8723648
+dissociate 1002 28357832 8723648
+elite 1001 5987435 234724
+eschew 1001 5987435 234724
+Eulerian 1001 5987435 234724
+flanking 1001 5987435 234724
+foldout 1002 28357832 8723648
+funereal 1002 28357832 8723648
+galling 1002 28357832 8723648
+Graves 1001 5987435 234724
+grazing 1001 5987435 234724
+groupings 1001 5987435 234724
+handgun 1001 5987435 234724
+humility 1002 28357832 8723648
+impulsive 1002 28357832 8723648
+inch 1001 5987435 234724
+intelligibility 1001 5987435 234724
+jarring 1001 5987435 234724
+lawgiver 1001 5987435 234724
+lectured 1002 28357832 8723648
+Merritt 1002 28357832 8723648
+neonatal 1001 5987435 234724
+offload 1002 28357832 8723648
+parters 1002 28357832 8723648
+pityingly 1002 28357832 8723648
+puddings 1002 28357832 8723648
+Punjab 1001 5987435 234724
+quitter 1002 28357832 8723648
+realtor 1001 5987435 234724
+relaxing 1001 5987435 234724
+repetitions 1001 5987435 234724
+resumes 1001 5987435 234724
+Romans 1002 28357832 8723648
+rusting 1001 5987435 234724
+scholastics 1001 5987435 234724
+skulking 1002 28357832 8723648
+stated 1002 28357832 8723648
+suites 1002 28357832 8723648
+sureties 1001 5987435 234724
+testicle 1002 28357832 8723648
+tinily 1002 28357832 8723648
+tragedies 1001 5987435 234724
+trimmings 1001 5987435 234724
+vacuuming 1001 5987435 234724
+ventilate 1001 5987435 234724
+wallet 1001 5987435 234724
+Weissmuller 1002 28357832 8723648
+Wotan 1002 28357832 8723648
+select t2.fld1,fld3,period,price,price2 from t2,t3 where t2.fld1>= 18201 and t2.fld1 <= 18811 and t2.fld1=t3.t2nr and period = 1001 and t2.companynr = 37;
+fld1 fld3 period price price2
+018201 relaxing 1001 5987435 234724
+018601 vacuuming 1001 5987435 234724
+018801 inch 1001 5987435 234724
+018811 repetitions 1001 5987435 234724
+create table t4 (
+companynr tinyint(2) unsigned zerofill NOT NULL default '00',
+companyname char(30) NOT NULL default '',
+PRIMARY KEY (companynr),
+UNIQUE KEY companyname(companyname)
+) ENGINE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames';
+select STRAIGHT_JOIN t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr;
+companynr companyname
+00 Unknown
+29 company 1
+34 company 2
+36 company 3
+37 company 4
+40 company 5
+41 company 6
+50 company 11
+53 company 7
+58 company 8
+65 company 9
+68 company 10
+select SQL_SMALL_RESULT t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr;
+companynr companyname
+00 Unknown
+29 company 1
+34 company 2
+36 company 3
+37 company 4
+40 company 5
+41 company 6
+50 company 11
+53 company 7
+58 company 8
+65 company 9
+68 company 10
+select * from t1,t1 t12;
+Period Varor_period Period Varor_period
+9410 9412 9410 9412
+select t2.fld1,t22.fld1 from t2,t2 t22 where t2.fld1 >= 250501 and t2.fld1 <= 250505 and t22.fld1 >= 250501 and t22.fld1 <= 250505;
+fld1 fld1
+250501 250501
+250502 250501
+250503 250501
+250504 250501
+250505 250501
+250501 250502
+250502 250502
+250503 250502
+250504 250502
+250505 250502
+250501 250503
+250502 250503
+250503 250503
+250504 250503
+250505 250503
+250501 250504
+250502 250504
+250503 250504
+250504 250504
+250505 250504
+250501 250505
+250502 250505
+250503 250505
+250504 250505
+250505 250505
+insert into t2 (fld1, companynr) values (999999,99);
+select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null;
+companynr companyname
+99 NULL
+select count(*) from t2 left join t4 using (companynr) where t4.companynr is not null;
+count(*)
+1199
+explain select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1200
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where; Not exists
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where; Not exists
+select companynr,companyname from t2 left join t4 using (companynr) where companynr is null;
+companynr companyname
+select count(*) from t2 left join t4 using (companynr) where companynr is not null;
+count(*)
+1200
+explain select companynr,companyname from t2 left join t4 using (companynr) where companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+delete from t2 where fld1=999999;
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
+companynr companynr
+37 36
+41 40
+explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
+fld1 companynr fld3 period
+038008 37 reporters 1008
+038208 37 Selfridge 1008
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t2.fld1 = 38208 or t2.fld1 = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009;
+fld1 companynr fld3 period
+038008 37 reporters 1008
+038208 37 Selfridge 1008
+select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t3.t2nr = 38208 or t3.t2nr = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009;
+fld1 companynr fld3 period
+038008 37 reporters 1008
+038208 37 Selfridge 1008
+select period from t1 where (((period > 0) or period < 10000 or (period = 1900)) and (period=1900 and period <= 1901) or (period=1903 and (period=1903)) and period>=1902) or ((period=1904 or period=1905) or (period=1906 or period>1907)) or (period=1908 and period = 1909);
+period
+9410
+select period from t1 where ((period > 0 and period < 1) or (((period > 0 and period < 100) and (period > 10)) or (period > 10)) or (period > 0 and (period > 5 or period > 6)));
+period
+9410
+select a.fld1 from t2 as a,t2 b where ((a.fld1 = 250501 and a.fld1=b.fld1) or a.fld1=250502 or a.fld1=250503 or (a.fld1=250505 and a.fld1<=b.fld1 and b.fld1>=a.fld1)) and a.fld1=b.fld1;
+fld1
+250501
+250502
+250503
+250505
+select fld1 from t2 where fld1 in (250502,98005,98006,250503,250605,250606) and fld1 >=250502 and fld1 not in (250605,250606);
+fld1
+250502
+250503
+select fld1 from t2 where fld1 between 250502 and 250504;
+fld1
+250502
+250503
+250504
+select fld3 from t2 where (((fld3 like "_%L%" ) or (fld3 like "%ok%")) and ( fld3 like "L%" or fld3 like "G%")) and fld3 like "L%" ;
+fld3
+label
+labeled
+labeled
+landslide
+laterally
+leaflet
+lewdly
+Lillian
+luckily
+select count(*) from t1;
+count(*)
+1
+select companynr,count(*),sum(fld1) from t2 group by companynr;
+companynr count(*) sum(fld1)
+00 82 10355753
+29 95 14473298
+34 70 17788966
+36 215 22786296
+37 588 83602098
+40 37 6618386
+41 52 12816335
+50 11 1595438
+53 4 793210
+58 23 2254293
+65 10 2284055
+68 12 3097288
+select companynr,count(*) from t2 group by companynr order by companynr desc limit 5;
+companynr count(*)
+68 12
+65 10
+58 23
+53 4
+50 11
+select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>"";
+count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
+70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069
+explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>"";
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+Warnings:
+Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> _latin1''))
+select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3;
+companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
+00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087
+29 95 abut wetness 14473298 152350.5053 8368.5480 70032594.9026
+34 70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069
+select companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10;
+companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
+37 1 1 5987435 5987435 5987435 5987435.0000
+37 2 1 28357832 28357832 28357832 28357832.0000
+37 3 1 39654943 39654943 39654943 39654943.0000
+37 11 1 5987435 5987435 5987435 5987435.0000
+37 12 1 28357832 28357832 28357832 28357832.0000
+37 13 1 39654943 39654943 39654943 39654943.0000
+37 21 1 5987435 5987435 5987435 5987435.0000
+37 22 1 28357832 28357832 28357832 28357832.0000
+37 23 1 39654943 39654943 39654943 39654943.0000
+37 31 1 5987435 5987435 5987435 5987435.0000
+select /*! SQL_SMALL_RESULT */ companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10;
+companynr t2nr count(price) sum(price) min(price) max(price) avg(price)
+37 1 1 5987435 5987435 5987435 5987435.0000
+37 2 1 28357832 28357832 28357832 28357832.0000
+37 3 1 39654943 39654943 39654943 39654943.0000
+37 11 1 5987435 5987435 5987435 5987435.0000
+37 12 1 28357832 28357832 28357832 28357832.0000
+37 13 1 39654943 39654943 39654943 39654943.0000
+37 21 1 5987435 5987435 5987435 5987435.0000
+37 22 1 28357832 28357832 28357832 28357832.0000
+37 23 1 39654943 39654943 39654943 39654943.0000
+37 31 1 5987435 5987435 5987435 5987435.0000
+select companynr,count(price),sum(price),min(price),max(price),avg(price) from t3 group by companynr ;
+companynr count(price) sum(price) min(price) max(price) avg(price)
+37 12543 309394878010 5987435 39654943 24666736.6667
+78 8362 414611089292 726498 98439034 49582766.0000
+101 4181 3489454238 834598 834598 834598.0000
+154 4181 4112197254950 983543950 983543950 983543950.0000
+311 4181 979599938 234298 234298 234298.0000
+447 4181 9929180954 2374834 2374834 2374834.0000
+512 4181 3288532102 786542 786542 786542.0000
+select distinct mod(companynr,10) from t4 group by companynr;
+mod(companynr,10)
+0
+9
+4
+6
+7
+1
+3
+8
+5
+select distinct 1 from t4 group by companynr;
+1
+1
+select count(distinct fld1) from t2;
+count(distinct fld1)
+1199
+select companynr,count(distinct fld1) from t2 group by companynr;
+companynr count(distinct fld1)
+00 82
+29 95
+34 70
+36 215
+37 588
+40 37
+41 52
+50 11
+53 4
+58 23
+65 10
+68 12
+select companynr,count(*) from t2 group by companynr;
+companynr count(*)
+00 82
+29 95
+34 70
+36 215
+37 588
+40 37
+41 52
+50 11
+53 4
+58 23
+65 10
+68 12
+select companynr,count(distinct concat(fld1,repeat(65,1000))) from t2 group by companynr;
+companynr count(distinct concat(fld1,repeat(65,1000)))
+00 82
+29 95
+34 70
+36 215
+37 588
+40 37
+41 52
+50 11
+53 4
+58 23
+65 10
+68 12
+select companynr,count(distinct concat(fld1,repeat(65,200))) from t2 group by companynr;
+companynr count(distinct concat(fld1,repeat(65,200)))
+00 82
+29 95
+34 70
+36 215
+37 588
+40 37
+41 52
+50 11
+53 4
+58 23
+65 10
+68 12
+select companynr,count(distinct floor(fld1/100)) from t2 group by companynr;
+companynr count(distinct floor(fld1/100))
+00 47
+29 35
+34 14
+36 69
+37 108
+40 16
+41 11
+50 9
+53 1
+58 1
+65 1
+68 1
+select companynr,count(distinct concat(repeat(65,1000),floor(fld1/100))) from t2 group by companynr;
+companynr count(distinct concat(repeat(65,1000),floor(fld1/100)))
+00 47
+29 35
+34 14
+36 69
+37 108
+40 16
+41 11
+50 9
+53 1
+58 1
+65 1
+68 1
+select sum(fld1),fld3 from t2 where fld3="Romans" group by fld1 limit 10;
+sum(fld1) fld3
+11402 Romans
+select name,count(*) from t3 where name='cloakroom' group by name;
+name count(*)
+cloakroom 4181
+select name,count(*) from t3 where name='cloakroom' and price>10 group by name;
+name count(*)
+cloakroom 4181
+select count(*) from t3 where name='cloakroom' and price2=823742;
+count(*)
+4181
+select name,count(*) from t3 where name='cloakroom' and price2=823742 group by name;
+name count(*)
+cloakroom 4181
+select name,count(*) from t3 where name >= "extramarital" and price <= 39654943 group by name;
+name count(*)
+extramarital 4181
+gazer 4181
+gems 4181
+Iranizes 4181
+spates 4181
+tucked 4181
+violinist 4181
+select t2.fld3,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name;
+fld3 count(*)
+spates 4181
+select companynr|0,companyname from t4 group by 1;
+companynr|0 companyname
+0 Unknown
+29 company 1
+34 company 2
+36 company 3
+37 company 4
+40 company 5
+41 company 6
+50 company 11
+53 company 7
+58 company 8
+65 company 9
+68 company 10
+select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by t2.companynr order by companyname;
+companynr companyname count(*)
+29 company 1 95
+68 company 10 12
+50 company 11 11
+34 company 2 70
+36 company 3 215
+37 company 4 588
+40 company 5 37
+41 company 6 52
+53 company 7 4
+58 company 8 23
+65 company 9 10
+00 Unknown 82
+select t2.fld1,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name;
+fld1 count(*)
+158402 4181
+select sum(Period)/count(*) from t1;
+sum(Period)/count(*)
+9410.0000
+select companynr,count(price) as "count",sum(price) as "sum" ,abs(sum(price)/count(price)-avg(price)) as "diff",(0+count(price))*companynr as func from t3 group by companynr;
+companynr count sum diff func
+37 12543 309394878010 0.0000 464091
+78 8362 414611089292 0.0000 652236
+101 4181 3489454238 0.0000 422281
+154 4181 4112197254950 0.0000 643874
+311 4181 979599938 0.0000 1300291
+447 4181 9929180954 0.0000 1868907
+512 4181 3288532102 0.0000 2140672
+select companynr,sum(price)/count(price) as avg from t3 group by companynr having avg > 70000000 order by avg;
+companynr avg
+154 983543950.0000
+select companynr,count(*) from t2 group by companynr order by 2 desc;
+companynr count(*)
+37 588
+36 215
+29 95
+00 82
+34 70
+41 52
+40 37
+58 23
+68 12
+50 11
+65 10
+53 4
+select companynr,count(*) from t2 where companynr > 40 group by companynr order by 2 desc;
+companynr count(*)
+41 52
+58 23
+68 12
+50 11
+65 10
+53 4
+select t2.fld4,t2.fld1,count(price),sum(price),min(price),max(price),avg(price) from t3,t2 where t3.companynr = 37 and t2.fld1 = t3.t2nr group by fld1,t2.fld4;
+fld4 fld1 count(price) sum(price) min(price) max(price) avg(price)
+teethe 000001 1 5987435 5987435 5987435 5987435.0000
+dreaded 011401 1 5987435 5987435 5987435 5987435.0000
+scholastics 011402 1 28357832 28357832 28357832 28357832.0000
+audiology 011403 1 39654943 39654943 39654943 39654943.0000
+wallet 011501 1 5987435 5987435 5987435 5987435.0000
+parters 011701 1 5987435 5987435 5987435 5987435.0000
+eschew 011702 1 28357832 28357832 28357832 28357832.0000
+quitter 011703 1 39654943 39654943 39654943 39654943.0000
+neat 012001 1 5987435 5987435 5987435 5987435.0000
+Steinberg 012003 1 39654943 39654943 39654943 39654943.0000
+balled 012301 1 5987435 5987435 5987435 5987435.0000
+persist 012302 1 28357832 28357832 28357832 28357832.0000
+attainments 012303 1 39654943 39654943 39654943 39654943.0000
+capably 012501 1 5987435 5987435 5987435 5987435.0000
+impulsive 012602 1 28357832 28357832 28357832 28357832.0000
+starlet 012603 1 39654943 39654943 39654943 39654943.0000
+featherweight 012701 1 5987435 5987435 5987435 5987435.0000
+pessimist 012702 1 28357832 28357832 28357832 28357832.0000
+daughter 012703 1 39654943 39654943 39654943 39654943.0000
+lawgiver 013601 1 5987435 5987435 5987435 5987435.0000
+stated 013602 1 28357832 28357832 28357832 28357832.0000
+readable 013603 1 39654943 39654943 39654943 39654943.0000
+testicle 013801 1 5987435 5987435 5987435 5987435.0000
+Parsifal 013802 1 28357832 28357832 28357832 28357832.0000
+leavings 013803 1 39654943 39654943 39654943 39654943.0000
+squeaking 013901 1 5987435 5987435 5987435 5987435.0000
+contrasted 016001 1 5987435 5987435 5987435 5987435.0000
+leftover 016201 1 5987435 5987435 5987435 5987435.0000
+whiteners 016202 1 28357832 28357832 28357832 28357832.0000
+erases 016301 1 5987435 5987435 5987435 5987435.0000
+Punjab 016302 1 28357832 28357832 28357832 28357832.0000
+Merritt 016303 1 39654943 39654943 39654943 39654943.0000
+sweetish 018001 1 5987435 5987435 5987435 5987435.0000
+dogging 018002 1 28357832 28357832 28357832 28357832.0000
+scornfully 018003 1 39654943 39654943 39654943 39654943.0000
+fetters 018012 1 28357832 28357832 28357832 28357832.0000
+bivalves 018013 1 39654943 39654943 39654943 39654943.0000
+skulking 018021 1 5987435 5987435 5987435 5987435.0000
+flint 018022 1 28357832 28357832 28357832 28357832.0000
+flopping 018023 1 39654943 39654943 39654943 39654943.0000
+Judas 018032 1 28357832 28357832 28357832 28357832.0000
+vacuuming 018033 1 39654943 39654943 39654943 39654943.0000
+medical 018041 1 5987435 5987435 5987435 5987435.0000
+bloodbath 018042 1 28357832 28357832 28357832 28357832.0000
+subschema 018043 1 39654943 39654943 39654943 39654943.0000
+interdependent 018051 1 5987435 5987435 5987435 5987435.0000
+Graves 018052 1 28357832 28357832 28357832 28357832.0000
+neonatal 018053 1 39654943 39654943 39654943 39654943.0000
+sorters 018061 1 5987435 5987435 5987435 5987435.0000
+epistle 018062 1 28357832 28357832 28357832 28357832.0000
+Conley 018101 1 5987435 5987435 5987435 5987435.0000
+lectured 018102 1 28357832 28357832 28357832 28357832.0000
+Abraham 018103 1 39654943 39654943 39654943 39654943.0000
+cage 018201 1 5987435 5987435 5987435 5987435.0000
+hushes 018202 1 28357832 28357832 28357832 28357832.0000
+Simla 018402 1 28357832 28357832 28357832 28357832.0000
+reporters 018403 1 39654943 39654943 39654943 39654943.0000
+coexist 018601 1 5987435 5987435 5987435 5987435.0000
+Beebe 018602 1 28357832 28357832 28357832 28357832.0000
+Taoism 018603 1 39654943 39654943 39654943 39654943.0000
+Connally 018801 1 5987435 5987435 5987435 5987435.0000
+fetched 018802 1 28357832 28357832 28357832 28357832.0000
+checkpoints 018803 1 39654943 39654943 39654943 39654943.0000
+gritty 018811 1 5987435 5987435 5987435 5987435.0000
+firearm 018812 1 28357832 28357832 28357832 28357832.0000
+minima 019101 1 5987435 5987435 5987435 5987435.0000
+Selfridge 019102 1 28357832 28357832 28357832 28357832.0000
+disable 019103 1 39654943 39654943 39654943 39654943.0000
+witchcraft 019201 1 5987435 5987435 5987435 5987435.0000
+betroth 030501 1 5987435 5987435 5987435 5987435.0000
+Manhattanize 030502 1 28357832 28357832 28357832 28357832.0000
+imprint 030503 1 39654943 39654943 39654943 39654943.0000
+swelling 031901 1 5987435 5987435 5987435 5987435.0000
+interrelationships 036001 1 5987435 5987435 5987435 5987435.0000
+riser 036002 1 28357832 28357832 28357832 28357832.0000
+bee 038001 1 5987435 5987435 5987435 5987435.0000
+kanji 038002 1 28357832 28357832 28357832 28357832.0000
+dental 038003 1 39654943 39654943 39654943 39654943.0000
+railway 038011 1 5987435 5987435 5987435 5987435.0000
+validate 038012 1 28357832 28357832 28357832 28357832.0000
+normalizes 038013 1 39654943 39654943 39654943 39654943.0000
+Kline 038101 1 5987435 5987435 5987435 5987435.0000
+Anatole 038102 1 28357832 28357832 28357832 28357832.0000
+partridges 038103 1 39654943 39654943 39654943 39654943.0000
+recruited 038201 1 5987435 5987435 5987435 5987435.0000
+dimensions 038202 1 28357832 28357832 28357832 28357832.0000
+Chicana 038203 1 39654943 39654943 39654943 39654943.0000
+select t3.companynr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 group by companynr,fld3;
+companynr fld3 sum(price)
+512 boat 786542
+512 capably 786542
+512 cupboard 786542
+512 decliner 786542
+512 descendants 786542
+512 dopers 786542
+512 erases 786542
+512 Micronesia 786542
+512 Miles 786542
+512 skies 786542
+select t2.companynr,count(*),min(fld3),max(fld3),sum(price),avg(price) from t2,t3 where t3.companynr >= 30 and t3.companynr <= 58 and t3.t2nr = t2.fld1 and 1+1=2 group by t2.companynr;
+companynr count(*) min(fld3) max(fld3) sum(price) avg(price)
+00 1 Omaha Omaha 5987435 5987435.0000
+36 1 dubbed dubbed 28357832 28357832.0000
+37 83 Abraham Wotan 1908978016 22999735.1325
+50 2 scribbled tapestry 68012775 34006387.5000
+select t3.companynr+0,t3.t2nr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 37 group by 1,t3.t2nr,fld3,fld3,fld3,fld3,fld3 order by fld1;
+t3.companynr+0 t2nr fld3 sum(price)
+37 1 Omaha 5987435
+37 11401 breaking 5987435
+37 11402 Romans 28357832
+37 11403 intercepted 39654943
+37 11501 bewilderingly 5987435
+37 11701 astound 5987435
+37 11702 admonishing 28357832
+37 11703 sumac 39654943
+37 12001 flanking 5987435
+37 12003 combed 39654943
+37 12301 Eulerian 5987435
+37 12302 dubbed 28357832
+37 12303 Kane 39654943
+37 12501 annihilates 5987435
+37 12602 Wotan 28357832
+37 12603 snatching 39654943
+37 12701 grazing 5987435
+37 12702 Baird 28357832
+37 12703 celery 39654943
+37 13601 handgun 5987435
+37 13602 foldout 28357832
+37 13603 mystic 39654943
+37 13801 intelligibility 5987435
+37 13802 Augustine 28357832
+37 13803 teethe 39654943
+37 13901 scholastics 5987435
+37 16001 audiology 5987435
+37 16201 wallet 5987435
+37 16202 parters 28357832
+37 16301 eschew 5987435
+37 16302 quitter 28357832
+37 16303 neat 39654943
+37 18001 jarring 5987435
+37 18002 tinily 28357832
+37 18003 balled 39654943
+37 18012 impulsive 28357832
+37 18013 starlet 39654943
+37 18021 lawgiver 5987435
+37 18022 stated 28357832
+37 18023 readable 39654943
+37 18032 testicle 28357832
+37 18033 Parsifal 39654943
+37 18041 Punjab 5987435
+37 18042 Merritt 28357832
+37 18043 Quixotism 39654943
+37 18051 sureties 5987435
+37 18052 puddings 28357832
+37 18053 tapestry 39654943
+37 18061 trimmings 5987435
+37 18062 humility 28357832
+37 18101 tragedies 5987435
+37 18102 skulking 28357832
+37 18103 flint 39654943
+37 18201 relaxing 5987435
+37 18202 offload 28357832
+37 18402 suites 28357832
+37 18403 lists 39654943
+37 18601 vacuuming 5987435
+37 18602 dentally 28357832
+37 18603 humanness 39654943
+37 18801 inch 5987435
+37 18802 Weissmuller 28357832
+37 18803 irresponsibly 39654943
+37 18811 repetitions 5987435
+37 18812 Antares 28357832
+37 19101 ventilate 5987435
+37 19102 pityingly 28357832
+37 19103 interdependent 39654943
+37 19201 Graves 5987435
+37 30501 neonatal 5987435
+37 30502 scribbled 28357832
+37 30503 chafe 39654943
+37 31901 realtor 5987435
+37 36001 elite 5987435
+37 36002 funereal 28357832
+37 38001 Conley 5987435
+37 38002 lectured 28357832
+37 38003 Abraham 39654943
+37 38011 groupings 5987435
+37 38012 dissociate 28357832
+37 38013 coexist 39654943
+37 38101 rusting 5987435
+37 38102 galling 28357832
+37 38103 obliterates 39654943
+37 38201 resumes 5987435
+37 38202 analyzable 28357832
+37 38203 terminator 39654943
+select sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1= t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008;
+sum(price)
+234298
+select t2.fld1,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1 = t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008 or t3.t2nr = t2.fld1 and t2.fld1 = 38008 group by t2.fld1;
+fld1 sum(price)
+038008 234298
+explain select fld3 from t2 where 1>2 or 2>3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+explain select fld3 from t2 where fld1=fld1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1199
+select companynr,fld1 from t2 HAVING fld1=250501 or fld1=250502;
+companynr fld1
+34 250501
+34 250502
+select companynr,fld1 from t2 WHERE fld1>=250501 HAVING fld1<=250502;
+companynr fld1
+34 250501
+34 250502
+select companynr,count(*) as count,sum(fld1) as sum from t2 group by companynr having count > 40 and sum/count >= 120000;
+companynr count sum
+00 82 10355753
+29 95 14473298
+34 70 17788966
+37 588 83602098
+41 52 12816335
+select companynr from t2 group by companynr having count(*) > 40 and sum(fld1)/count(*) >= 120000 ;
+companynr
+00
+29
+34
+37
+41
+select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by companyname having t2.companynr >= 40;
+companynr companyname count(*)
+68 company 10 12
+50 company 11 11
+40 company 5 37
+41 company 6 52
+53 company 7 4
+58 company 8 23
+65 company 9 10
+select count(*) from t2;
+count(*)
+1199
+select count(*) from t2 where fld1 < 098024;
+count(*)
+387
+select min(fld1) from t2 where fld1>= 098024;
+min(fld1)
+98024
+select max(fld1) from t2 where fld1>= 098024;
+max(fld1)
+1232609
+select count(*) from t3 where price2=76234234;
+count(*)
+4181
+select count(*) from t3 where companynr=512 and price2=76234234;
+count(*)
+4181
+explain select min(fld1),max(fld1),count(*) from t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+select min(fld1),max(fld1),count(*) from t2;
+min(fld1) max(fld1) count(*)
+0 1232609 1199
+select min(t2nr),max(t2nr) from t3 where t2nr=2115 and price2=823742;
+min(t2nr) max(t2nr)
+2115 2115
+select count(*),min(t2nr),max(t2nr) from t3 where name='spates' and companynr=78;
+count(*) min(t2nr) max(t2nr)
+4181 4 41804
+select t2nr,count(*) from t3 where name='gems' group by t2nr limit 20;
+t2nr count(*)
+9 1
+19 1
+29 1
+39 1
+49 1
+59 1
+69 1
+79 1
+89 1
+99 1
+109 1
+119 1
+129 1
+139 1
+149 1
+159 1
+169 1
+179 1
+189 1
+199 1
+select max(t2nr) from t3 where price=983543950;
+max(t2nr)
+41807
+select t1.period from t3 = t1 limit 1;
+period
+1001
+select t1.period from t1 as t1 limit 1;
+period
+9410
+select t1.period as "Nuvarande period" from t1 as t1 limit 1;
+Nuvarande period
+9410
+select period as ok_period from t1 limit 1;
+ok_period
+9410
+select period as ok_period from t1 group by ok_period limit 1;
+ok_period
+9410
+select 1+1 as summa from t1 group by summa limit 1;
+summa
+2
+select period as "Nuvarande period" from t1 group by "Nuvarande period" limit 1;
+Nuvarande period
+9410
+show tables;
+Tables_in_test
+t1
+t2
+t3
+t4
+show tables from test like "s%";
+Tables_in_test (s%)
+show tables from test like "t?";
+Tables_in_test (t?)
+show full columns from t2;
+Field Type Collation Null Key Default Extra Privileges Comment
+auto int(11) NULL NO PRI NULL auto_increment #
+fld1 int(6) unsigned zerofill NULL NO UNI 000000 #
+companynr tinyint(2) unsigned zerofill NULL NO 00 #
+fld3 char(30) latin1_swedish_ci NO MUL #
+fld4 char(35) latin1_swedish_ci NO #
+fld5 char(35) latin1_swedish_ci NO #
+fld6 char(4) latin1_swedish_ci NO #
+show full columns from t2 from test like 'f%';
+Field Type Collation Null Key Default Extra Privileges Comment
+fld1 int(6) unsigned zerofill NULL NO UNI 000000 #
+fld3 char(30) latin1_swedish_ci NO MUL #
+fld4 char(35) latin1_swedish_ci NO #
+fld5 char(35) latin1_swedish_ci NO #
+fld6 char(4) latin1_swedish_ci NO #
+show full columns from t2 from test like 's%';
+Field Type Collation Null Key Default Extra Privileges Comment
+show keys from t2;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t2 0 PRIMARY 1 auto A 1199 NULL NULL BTREE
+t2 0 fld1 1 fld1 A 1199 NULL NULL BTREE
+t2 1 fld3 1 fld3 A NULL NULL NULL BTREE
+drop table t4, t3, t2, t1;
+CREATE TABLE t1 (
+cont_nr int(11) NOT NULL auto_increment,
+ver_nr int(11) NOT NULL default '0',
+aufnr int(11) NOT NULL default '0',
+username varchar(50) NOT NULL default '',
+hdl_nr int(11) NOT NULL default '0',
+eintrag date NOT NULL default '0000-00-00',
+st_klasse varchar(40) NOT NULL default '',
+st_wert varchar(40) NOT NULL default '',
+st_zusatz varchar(40) NOT NULL default '',
+st_bemerkung varchar(255) NOT NULL default '',
+kunden_art varchar(40) NOT NULL default '',
+mcbs_knr int(11) default NULL,
+mcbs_aufnr int(11) NOT NULL default '0',
+schufa_status char(1) default '?',
+bemerkung text,
+wirknetz text,
+wf_igz int(11) NOT NULL default '0',
+tarifcode varchar(80) default NULL,
+recycle char(1) default NULL,
+sim varchar(30) default NULL,
+mcbs_tpl varchar(30) default NULL,
+emp_nr int(11) NOT NULL default '0',
+laufzeit int(11) default NULL,
+hdl_name varchar(30) default NULL,
+prov_hdl_nr int(11) NOT NULL default '0',
+auto_wirknetz varchar(50) default NULL,
+auto_billing varchar(50) default NULL,
+touch timestamp NOT NULL,
+kategorie varchar(50) default NULL,
+kundentyp varchar(20) NOT NULL default '',
+sammel_rech_msisdn varchar(30) NOT NULL default '',
+p_nr varchar(9) NOT NULL default '',
+suffix char(3) NOT NULL default '',
+PRIMARY KEY (cont_nr),
+KEY idx_aufnr(aufnr),
+KEY idx_hdl_nr(hdl_nr),
+KEY idx_st_klasse(st_klasse),
+KEY ver_nr(ver_nr),
+KEY eintrag_idx(eintrag),
+KEY emp_nr_idx(emp_nr),
+KEY wf_igz(wf_igz),
+KEY touch(touch),
+KEY hdl_tag(eintrag,hdl_nr),
+KEY prov_hdl_nr(prov_hdl_nr),
+KEY mcbs_aufnr(mcbs_aufnr),
+KEY kundentyp(kundentyp),
+KEY p_nr(p_nr,suffix)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (3359356,405,3359356,'Mustermann Musterfrau',52500,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1485525,2122316,'+','','N',1909160,'MobilComSuper92000D2',NULL,NULL,'MS9ND2',3,24,'MobilCom Shop Koeln',52500,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359357,468,3359357,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1503580,2139699,'+','','P',1909171,'MobilComSuper9D1T10SFreisprech(Akquise)',NULL,NULL,'MS9NS1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359358,407,3359358,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1501358,2137473,'N','','N',1909159,'MobilComSuper92000D2',NULL,NULL,'MS9ND2',325,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359359,468,3359359,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1507831,2143894,'+','','P',1909162,'MobilComSuper9D1T10SFreisprech(Akquise)',NULL,NULL,'MS9NS1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359360,0,0,'Mustermann Musterfrau',29674907,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1900169997,2414578,'+',NULL,'N',1909148,'',NULL,NULL,'RV99066_2',20,NULL,'POS',29674907,NULL,NULL,20010202105916,'Mobilfunk','','','97317481','007');
+INSERT INTO t1 VALUES (3359361,406,3359361,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag storniert','','(7001-84):Storno, Kd. möchte nicht mehr','privat',NULL,0,'+','','P',1909150,'MobilComSuper92000D1(Akquise)',NULL,NULL,'MS9ND1',325,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+INSERT INTO t1 VALUES (3359362,406,3359362,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1509984,2145874,'+','','P',1909154,'MobilComSuper92000D1(Akquise)',NULL,NULL,'MS9ND1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
+SELECT ELT(FIELD(kundentyp,'PP','PPA','PG','PGA','FK','FKA','FP','FPA','K','KA','V','VA',''), 'Privat (Private Nutzung)','Privat (Private Nutzung) Sitz im Ausland','Privat (geschaeftliche Nutzung)','Privat (geschaeftliche Nutzung) Sitz im Ausland','Firma (Kapitalgesellschaft)','Firma (Kapitalgesellschaft) Sitz im Ausland','Firma (Personengesellschaft)','Firma (Personengesellschaft) Sitz im Ausland','oeff. rechtl. Koerperschaft','oeff. rechtl. Koerperschaft Sitz im Ausland','Eingetragener Verein','Eingetragener Verein Sitz im Ausland','Typ unbekannt') AS Kundentyp ,kategorie FROM t1 WHERE hdl_nr < 2000000 AND kategorie IN ('Prepaid','Mobilfunk') AND st_klasse = 'Workflow' GROUP BY kundentyp ORDER BY kategorie;
+Kundentyp kategorie
+Privat (Private Nutzung) Mobilfunk
+Warnings:
+Warning 1052 Column 'kundentyp' in group statement is ambiguous
+drop table t1;
+SHOW STATUS LIKE 'Ssl_cipher';
+Variable_name Value
+Ssl_cipher DHE-RSA-AES256-SHA
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index e57cc44ddd4..ecd9762dd24 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -2717,8 +2717,7 @@ select (1,2,3) = (select * from t1);
ERROR 21000: Operand should contain 3 column(s)
select (select * from t1) = (1,2,3);
ERROR 21000: Operand should contain 2 column(s)
-drop table t1
-#;
+drop table t1;
CREATE TABLE `t1` (
`itemid` bigint(20) unsigned NOT NULL auto_increment,
`sessionid` bigint(20) unsigned default NULL,
diff --git a/mysql-test/r/synchronization.result b/mysql-test/r/synchronization.result
index 697eb064998..4543a829494 100644
--- a/mysql-test/r/synchronization.result
+++ b/mysql-test/r/synchronization.result
@@ -1,6 +1,6 @@
drop table if exists t1;
CREATE TABLE t1 (x1 int);
- ALTER TABLE t1 CHANGE x1 x2 int;
+ALTER TABLE t1 CHANGE x1 x2 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -8,7 +8,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x2 x1 int;
+ALTER TABLE t1 CHANGE x2 x1 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -16,7 +16,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x1 x2 int;
+ALTER TABLE t1 CHANGE x1 x2 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -24,7 +24,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x2 x1 int;
+ALTER TABLE t1 CHANGE x2 x1 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -32,7 +32,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x1 x2 int;
+ALTER TABLE t1 CHANGE x1 x2 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -40,7 +40,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x2 x1 int;
+ALTER TABLE t1 CHANGE x2 x1 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -48,7 +48,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x1 x2 int;
+ALTER TABLE t1 CHANGE x1 x2 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -56,7 +56,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x2 x1 int;
+ALTER TABLE t1 CHANGE x2 x1 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -64,7 +64,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x1 x2 int;
+ALTER TABLE t1 CHANGE x1 x2 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -72,7 +72,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x2 x1 int;
+ALTER TABLE t1 CHANGE x2 x1 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -80,7 +80,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x1 x2 int;
+ALTER TABLE t1 CHANGE x1 x2 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -88,7 +88,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x2 x1 int;
+ALTER TABLE t1 CHANGE x2 x1 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -96,7 +96,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x1 x2 int;
+ALTER TABLE t1 CHANGE x1 x2 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -104,7 +104,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x2 x1 int;
+ALTER TABLE t1 CHANGE x2 x1 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -112,7 +112,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x1 x2 int;
+ALTER TABLE t1 CHANGE x1 x2 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -120,7 +120,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x2 x1 int;
+ALTER TABLE t1 CHANGE x2 x1 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -128,7 +128,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x1 x2 int;
+ALTER TABLE t1 CHANGE x1 x2 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -136,7 +136,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x2 x1 int;
+ALTER TABLE t1 CHANGE x2 x1 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -144,7 +144,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x1 x2 int;
+ALTER TABLE t1 CHANGE x1 x2 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
@@ -152,7 +152,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
- ALTER TABLE t1 CHANGE x2 x1 int;
+ALTER TABLE t1 CHANGE x2 x1 int;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
diff --git a/mysql-test/r/timezone.result b/mysql-test/r/timezone.result
index 10944c3706e..1223fff36c6 100644
--- a/mysql-test/r/timezone.result
+++ b/mysql-test/r/timezone.result
@@ -41,7 +41,7 @@ Warning 1299 Invalid TIMESTAMP value in column 'ts' at row 2
DROP TABLE t1;
select unix_timestamp('1970-01-01 01:00:00'),
unix_timestamp('1970-01-01 01:00:01'),
-unix_timestamp('2038-01-01 00:59:59'),
-unix_timestamp('2038-01-01 01:00:00');
-unix_timestamp('1970-01-01 01:00:00') unix_timestamp('1970-01-01 01:00:01') unix_timestamp('2038-01-01 00:59:59') unix_timestamp('2038-01-01 01:00:00')
-0 1 2145916799 0
+unix_timestamp('2038-01-19 04:14:07'),
+unix_timestamp('2038-01-19 04:14:08');
+unix_timestamp('1970-01-01 01:00:00') unix_timestamp('1970-01-01 01:00:01') unix_timestamp('2038-01-19 04:14:07') unix_timestamp('2038-01-19 04:14:08')
+0 1 2147483647 0
diff --git a/mysql-test/r/timezone2.result b/mysql-test/r/timezone2.result
index af8d52a017d..6fd67d00259 100644
--- a/mysql-test/r/timezone2.result
+++ b/mysql-test/r/timezone2.result
@@ -116,7 +116,7 @@ create table t1 (ts timestamp);
set time_zone='UTC';
insert into t1 values ('0000-00-00 00:00:00'),('1969-12-31 23:59:59'),
('1970-01-01 00:00:00'),('1970-01-01 00:00:01'),
-('2037-12-31 23:59:59'),('2038-01-01 00:00:00');
+('2038-01-19 03:14:07'),('2038-01-19 03:14:08');
Warnings:
Warning 1264 Out of range value for column 'ts' at row 2
Warning 1264 Out of range value for column 'ts' at row 3
@@ -127,13 +127,13 @@ ts
0000-00-00 00:00:00
0000-00-00 00:00:00
1970-01-01 00:00:01
-2037-12-31 23:59:59
+2038-01-19 03:14:07
0000-00-00 00:00:00
truncate table t1;
set time_zone='MET';
insert into t1 values ('0000-00-00 00:00:00'),('1970-01-01 00:30:00'),
('1970-01-01 01:00:00'),('1970-01-01 01:00:01'),
-('2038-01-01 00:59:59'),('2038-01-01 01:00:00');
+('2038-01-19 04:14:07'),('2038-01-19 04:14:08');
Warnings:
Warning 1264 Out of range value for column 'ts' at row 2
Warning 1264 Out of range value for column 'ts' at row 3
@@ -144,13 +144,13 @@ ts
0000-00-00 00:00:00
0000-00-00 00:00:00
1970-01-01 01:00:01
-2038-01-01 00:59:59
+2038-01-19 04:14:07
0000-00-00 00:00:00
truncate table t1;
set time_zone='+01:30';
insert into t1 values ('0000-00-00 00:00:00'),('1970-01-01 01:00:00'),
('1970-01-01 01:30:00'),('1970-01-01 01:30:01'),
-('2038-01-01 01:29:59'),('2038-01-01 01:30:00');
+('2038-01-19 04:44:07'),('2038-01-19 04:44:08');
Warnings:
Warning 1264 Out of range value for column 'ts' at row 2
Warning 1264 Out of range value for column 'ts' at row 3
@@ -161,7 +161,7 @@ ts
0000-00-00 00:00:00
0000-00-00 00:00:00
1970-01-01 01:30:01
-2038-01-01 01:29:59
+2038-01-19 04:44:07
0000-00-00 00:00:00
drop table t1;
show variables like 'time_zone';
@@ -223,12 +223,12 @@ convert_tz('2003-10-26 02:59:59', 'MET', 'UTC')
select convert_tz('2003-10-26 04:00:00', 'MET', 'UTC');
convert_tz('2003-10-26 04:00:00', 'MET', 'UTC')
2003-10-26 03:00:00
-select convert_tz('2038-01-01 00:59:59', 'MET', 'UTC');
-convert_tz('2038-01-01 00:59:59', 'MET', 'UTC')
-2037-12-31 23:59:59
-select convert_tz('2038-01-01 01:00:00', 'MET', 'UTC');
-convert_tz('2038-01-01 01:00:00', 'MET', 'UTC')
-2038-01-01 01:00:00
+select convert_tz('2038-01-19 04:14:07', 'MET', 'UTC');
+convert_tz('2038-01-19 04:14:07', 'MET', 'UTC')
+2038-01-19 03:14:07
+select convert_tz('2038-01-19 04:14:08', 'MET', 'UTC');
+convert_tz('2038-01-19 04:14:08', 'MET', 'UTC')
+2038-01-19 04:14:08
select convert_tz('2103-01-01 04:00:00', 'MET', 'UTC');
convert_tz('2103-01-01 04:00:00', 'MET', 'UTC')
2103-01-01 04:00:00
diff --git a/mysql-test/r/timezone4.result b/mysql-test/r/timezone4.result
new file mode 100644
index 00000000000..28028bea657
--- /dev/null
+++ b/mysql-test/r/timezone4.result
@@ -0,0 +1,6 @@
+select from_unixtime(0);
+from_unixtime(0)
+1969-12-31 14:00:00
+select unix_timestamp('1969-12-31 14:00:01');
+unix_timestamp('1969-12-31 14:00:01')
+1
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 5f027195e2e..52123885772 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -1073,10 +1073,11 @@ SELECT @x;
NULL
SET @x=2;
UPDATE t1 SET i1 = @x;
-ERROR 22012: Division by 0
+Warnings:
+Error 1365 Division by 0
SELECT @x;
@x
-2
+NULL
SET SQL_MODE='';
SET @x=3;
INSERT INTO t1 VALUES (@x);
@@ -1085,10 +1086,12 @@ SELECT @x;
NULL
SET @x=4;
UPDATE t1 SET i1 = @x;
-ERROR 22012: Division by 0
+Warnings:
+Error 1365 Division by 0
+Error 1365 Division by 0
SELECT @x;
@x
-4
+NULL
SET @@sql_mode=@save_sql_mode;
DROP TRIGGER t1_ai;
DROP TRIGGER t1_au;
@@ -1174,6 +1177,59 @@ ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghi
DROP TABLE t1;
DROP TABLE t2;
drop table if exists t1;
+drop table if exists t2;
+drop table if exists t3;
+drop table if exists t4;
+SET @save_sql_mode=@@sql_mode;
+SET sql_mode='TRADITIONAL'|
+create table t1 (id int(10) not null primary key, v int(10) )|
+create table t2 (id int(10) not null primary key, v int(10) )|
+create table t3 (id int(10) not null primary key, v int(10) )|
+create table t4 (c int)|
+create trigger t4_bi before insert on t4 for each row set @t4_bi_called:=1|
+create trigger t4_bu before update on t4 for each row set @t4_bu_called:=1|
+insert into t1 values(10, 10)|
+set @a:=1/0|
+Warnings:
+Error 1365 Division by 0
+select 1/0 from t1|
+1/0
+NULL
+Warnings:
+Error 1365 Division by 0
+create trigger t1_bi before insert on t1 for each row set @a:=1/0|
+insert into t1 values(20, 20)|
+Warnings:
+Error 1365 Division by 0
+drop trigger t1_bi|
+create trigger t1_bi before insert on t1 for each row
+begin
+insert into t2 values (new.id, new.v);
+update t2 set v=v+1 where id= new.id;
+replace t3 values (new.id, 0);
+update t2, t3 set t2.v=new.v, t3.v=new.v where t2.id=t3.id;
+create temporary table t5 select * from t1;
+delete from t5;
+insert into t5 select * from t1;
+insert into t4 values (0);
+set @check= (select count(*) from t5);
+update t4 set c= @check;
+drop temporary table t5;
+set @a:=1/0;
+end|
+set @check=0, @t4_bi_called=0, @t4_bu_called=0|
+insert into t1 values(30, 30)|
+Warnings:
+Error 1365 Division by 0
+select @check, @t4_bi_called, @t4_bu_called|
+@check @t4_bi_called @t4_bu_called
+2 1 1
+SET @@sql_mode=@save_sql_mode;
+drop table t1;
+drop table t2;
+drop table t3;
+drop table t4;
+drop table if exists t1;
create table t1 (i int, j int key);
insert into t1 values (1,1), (2,2), (3,3);
create trigger t1_bu before update on t1 for each row
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index 0b6bdfda6bc..595c15afcc2 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -978,8 +978,6 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
drop procedure if exists wg2;
-Warnings:
-Note 1305 PROCEDURE wg2 does not exist
create procedure wg2()
begin
declare v int default 1;
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index 53497fd528b..8382f521b84 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -215,6 +215,7 @@ select @@version;
select @@global.version;
@@global.version
#
+End of 4.1 tests
set @first_var= NULL;
create table t1 select @first_var;
show create table t1;
@@ -301,3 +302,11 @@ select @var;
@var
3
drop table t1;
+insert into city 'blah';
+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 ''blah'' at line 1
+SHOW COUNT(*) WARNINGS;
+@@session.warning_count
+1
+SHOW COUNT(*) ERRORS;
+@@session.error_count
+1
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index ed31ade9d33..501d15efa82 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -12,6 +12,9 @@ create table t1 (a int, b int);
insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
create view v1 (c,d) as select a,b+@@global.max_user_connections from t1;
ERROR HY000: View's SELECT contains a variable or parameter
+create view v1 (c,d) as select a,b from t1
+where a = @@global.max_user_connections;
+ERROR HY000: View's SELECT contains a variable or parameter
create view v1 (c) as select b+1 from t1;
select c from v1;
c
@@ -596,11 +599,6 @@ ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function
drop view v1;
create view v1 (a,a) as select 'a','a';
ERROR 42S21: Duplicate column name 'a'
-drop procedure if exists p1;
-create procedure p1 () begin declare v int; create view v1 as select v; end;//
-call p1();
-ERROR HY000: View's SELECT contains a variable or parameter
-drop procedure p1;
create table t1 (col1 int,col2 char(22));
insert into t1 values(5,'Hello, world of views');
create view v1 as select * from t1;
@@ -793,13 +791,13 @@ test.`f``1` ()
5
drop view v1;
drop function `f``1`;
-create function x () returns int return 5;
-create view v1 as select x ();
+create function a() returns int return 5;
+create view v1 as select a();
select * from v1;
-x ()
+a()
5
drop view v1;
-drop function x;
+drop function a;
create table t2 (col1 char collate latin1_german2_ci);
create view v2 as select col1 collate latin1_german1_ci from t2;
show create view v2;
@@ -886,6 +884,8 @@ ERROR HY000: View's SELECT contains a 'INTO' clause
create table t1 (a int);
create view v1 as select a from t1 procedure analyse();
ERROR HY000: View's SELECT contains a 'PROCEDURE' clause
+create view v1 as select 1 from (select 1) as d1;
+ERROR HY000: View's SELECT contains a subquery in the FROM clause
drop table t1;
create table t1 (s1 int, primary key (s1));
create view v1 as select * from t1;
@@ -1980,7 +1980,7 @@ v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VI
drop view v1;
drop table t1;
set sql_mode='strict_all_tables';
-CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL) ENGINE = INNODB;
+CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL);
CREATE VIEW v1 (vcol1) AS SELECT col1 FROM t1;
CREATE VIEW v2 (vcol1) AS SELECT col1 FROM t1 WHERE col2 > 2;
INSERT INTO t1 (col1) VALUES(12);
@@ -2032,7 +2032,7 @@ f3 f1
1 3
drop view v1;
drop table t1;
-CREATE TABLE t1 (f1 char) ENGINE = innodb;
+CREATE TABLE t1 (f1 char);
INSERT INTO t1 VALUES ('A');
CREATE VIEW v1 AS SELECT * FROM t1;
INSERT INTO t1 VALUES('B');
@@ -2956,6 +2956,20 @@ View Create View
v1 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`pk` AS `pk` from (`t1` join `t2` on(((`t2`.`fk` = `t1`.`pk`) and (`t2`.`ver` = (select max(`t`.`ver`) AS `MAX(t.ver)` from `t2` `t` where (`t`.`org` = `t2`.`org`))))))
DROP VIEW v1;
DROP TABLE t1, t2;
+DROP FUNCTION IF EXISTS f1;
+DROP VIEW IF EXISTS v1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1);
+CREATE VIEW v1 AS SELECT MAX(i) FROM t1;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+SET NEW.i = (SELECT * FROM v1) + 1;
+INSERT INTO t1 VALUES (1);
+CREATE FUNCTION f1() RETURNS INT RETURN (SELECT * FROM v1);
+UPDATE t1 SET i= f1();
+DROP FUNCTION f1;
+DROP VIEW v1;
+DROP TABLE t1;
CREATE TABLE t1(id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, val INT UNSIGNED NOT NULL);
CREATE VIEW v1 AS SELECT id, val FROM t1 WHERE val >= 1 AND val <= 5 WITH CHECK OPTION;
INSERT INTO v1 (val) VALUES (2);
@@ -2966,4 +2980,38 @@ UPDATE v1 SET val=6 WHERE id=2;
ERROR HY000: CHECK OPTION failed 'test.v1'
DROP VIEW v1;
DROP TABLE t1;
+DROP VIEW IF EXISTS v1, v2;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (i INT AUTO_INCREMENT PRIMARY KEY, j INT);
+CREATE VIEW v1 AS SELECT j FROM t1;
+CREATE VIEW v2 AS SELECT * FROM t1;
+INSERT INTO t1 (j) VALUES (1);
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+1
+INSERT INTO v1 (j) VALUES (2);
+# LAST_INSERT_ID() should not change.
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+1
+INSERT INTO v2 (j) VALUES (3);
+# LAST_INSERT_ID() should be updated.
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+3
+INSERT INTO v1 (j) SELECT j FROM t1;
+# LAST_INSERT_ID() should not change.
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+3
+SELECT * FROM t1;
+i j
+1 1
+2 2
+3 3
+4 1
+5 2
+6 3
+DROP VIEW v1, v2;
+DROP TABLE t1;
End of 5.0 tests.
diff --git a/mysql-test/std_data/server-cert-des.pem b/mysql-test/std_data/server-cert-des.pem
new file mode 100644
index 00000000000..3b93d865d5b
--- /dev/null
+++ b/mysql-test/std_data/server-cert-des.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICljCCAX4CAQEwDQYJKoZIhvcNAQEEBQAwUTELMAkGA1UEBhMCU0UxEDAOBgNV
+BAgTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMRAwDgYDVQQLEwdTdXBwb3J0
+MQswCQYDVQQDEwJDQTAeFw0wNjA4MjgxMTA4NTlaFw0wOTA1MjQxMTA4NTlaMFUx
+CzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBB
+QjEQMA4GA1UECxMHU3VwcG9ydDEPMA0GA1UEAxMGc2VydmVyMIGfMA0GCSqGSIb3
+DQEBAQUAA4GNADCBiQKBgQDEiOVZcWYzZe7I8xhhUwCzvmkZifAXeMTH+8XKGLHX
+NWF3FLduAmeAad9oOZgBKb+oWTdRDWXqwu6nYYUBfrUpaY27/wLkgWRgewL3LZnw
+W2FjhNsjx3gI2NK+Pix47q9d+a+5T4AW5+lK499l0K0k2cvyFdIerhDW8R0t8Uru
+twIDAQABMA0GCSqGSIb3DQEBBAUAA4IBAQC2LQcqLg52RbelWrKutlJ5E6rzugnJ
+ZAlbN9sM98O2xFiIGDA3tb5j9LAEjE0E+RqdptEYnvy9b3szhLYXtIILZTkClf9r
+Uwu1nUYPTyp+9ZYCa4fovOU5h1Ogv+9UZPds/LPDwWEn8K+lvscB4X57wJyuoEck
+1Mu41OA6h77181MydSdgZo0oquJDWhdCsYHXVFVs0F6naMm2uPMCTDiQVlhHJuTO
+VQMNIwxRFtvsv2tpsXsaP/8sT32d5CFebfxxSVnqQvJ4ZdIrphl6L43XU01rsEcE
+K8KYujZQ6SKws+HVcGqsr7TPgJfJE6D+5RazvvIQISPvx4eduebqzqdC
+-----END CERTIFICATE-----
diff --git a/mysql-test/std_data/server-key-des.pem b/mysql-test/std_data/server-key-des.pem
new file mode 100644
index 00000000000..b35d4ab223b
--- /dev/null
+++ b/mysql-test/std_data/server-key-des.pem
@@ -0,0 +1,18 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,D2BE7598C7E3BDA5
+
+1W3qPgw5ut80OhaAGVZZe/tfFiBAlwpX1SohdApWj+QYP+dK/mdEBhgI3BXTFNLW
+pJqDTzGlKtft7hHN6QDFEdZMKxej5+2iLu14V62o+5yQgUoqswoXcmmqJCJ7AvyJ
+yMBmGAzxRFlQsT8lf6o5TS1/efBvjvWhh3NG2Zq2LpyhWRRqA3kNhzktzt2WjDZe
+ZkKmZJJnArr/Aw7jEBC4sH+nmgxoR18GzDddRG12hv1AWyHc3+VisTBpyNzeBy17
+rxuQtqLzkAJmId723ddw83RVNSvBUUS3G0rx5O3HPobvZK89UqVxcXtIgc11WTVU
+N3DbcJq5it43Loo0W3gAngtESDm2E3rTadrmdUSDGv2wQ5dNFl6cQ1f397Sdd/WC
+A0grn1tKjJ6COp80Ymdyvn+stjv/+Rl1/KHSeG0lNeZxqjPPOJ7NHaKv7qjYsJ6W
+LT35/Xc3oCo5qk9FOlq/0tGjHxf6RcFr5U7k5ILKZs+RmvJ4Sv/VYShLfLTcfGbJ
+wBNfRKvcHZBQJQBb1+s/kRrjFFtvhrUwLz4+c9kskp+t4qRVYywUAnGGGsMs/GPm
+wYsLQZO6Bs5/taaVUyaJQW015J7FGGv+/7/A1dIhu73S/Xl/YcFbX/CMEVq2Lxxd
+hZdFIuaZ7LE+0MDQWsvYMYPDPLDH11diczb/jeKBdLPOzk/FUqVx3Fin1PpcaBxY
+b+7oZJhYdg/rAWDeQ/nji9qnEG8waK6x1hdkYPOrqqWQPfgM/LPsSrgWeuTSdx2B
+Ixi01UlBb5UP4K7UrjyddPobmcVjXaQLNe7zaq0+OS3UnIG85GtHrQ==
+-----END RSA PRIVATE KEY-----
diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test
index 5ee3d64e56f..2e66c24d877 100644
--- a/mysql-test/t/connect.test
+++ b/mysql-test/t/connect.test
@@ -59,6 +59,7 @@ flush privileges;
connect (con10,localhost,test,gambling2,);
connect (con5,localhost,test,gambling2,mysql);
+connection con5;
set password="";
--error 1372
set password='gambling3';
diff --git a/mysql-test/t/crash_commit_before.test b/mysql-test/t/crash_commit_before.test
index a10cf254a83..757817915dd 100644
--- a/mysql-test/t/crash_commit_before.test
+++ b/mysql-test/t/crash_commit_before.test
@@ -20,6 +20,9 @@ SET SESSION debug="d,crash_commit_before";
--error 2013
COMMIT;
+# Turn on reconnect
+--enable_reconnect
+
# Call script that will poll the server waiting for it to be back online again
--source include/wait_until_connected_again.inc
diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test
index f70b5b40766..82102a6078e 100644
--- a/mysql-test/t/csv.test
+++ b/mysql-test/t/csv.test
@@ -1295,7 +1295,7 @@ SELECT fld3 FROM t2;
#
DROP TABLE t1;
-ALTER TABLE t2 RENAME t1
+ALTER TABLE t2 RENAME t1;
#
# Drop and recreate
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 7ee7c9d00cb..65ee82fff23 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -1233,17 +1233,21 @@ drop table if exists t1;
# Bug#19960: Inconsistent results when joining
# InnoDB tables using partial UTF8 indexes
#
+--disable_warnings
CREATE TABLE t1 (
colA int(11) NOT NULL,
colB varchar(255) character set utf8 NOT NULL,
PRIMARY KEY (colA)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+--enable_warnings
INSERT INTO t1 (colA, colB) VALUES (1, 'foo'), (2, 'foo bar');
+--disable_warnings
CREATE TABLE t2 (
colA int(11) NOT NULL,
colB varchar(255) character set utf8 NOT NULL,
KEY bad (colA,colB(3))
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+--enable_warnings
INSERT INTO t2 (colA, colB) VALUES (1, 'foo'),(2, 'foo bar');
SELECT * FROM t1 JOIN t2 ON t1.colA=t2.colA AND t1.colB=t2.colB
WHERE t1.colA < 3;
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 1dd1778d68e..0d3b7cdfdeb 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -9,28 +9,20 @@
# Do not use any TAB characters for whitespace.
#
##############################################################################
-#events_bugs : BUG#17619 2006-02-21 andrey Race conditions
-#events_stress : BUG#17619 2006-02-21 andrey Race conditions
-#events : BUG#17619 2006-02-21 andrey Race conditions
-#events_scheduling : BUG#19170 2006-04-26 andrey Test case of 19170 fails on some platforms. Has to be checked.
+user_limits : Bug#23921 random failure of user_limits.test
+
im_options : Bug#20294 2006-07-24 stewart Instance manager test im_options fails randomly
-#im_life_cycle : Bug#20368 2006-06-10 alik im_life_cycle test fails
-im_daemon_life_cycle : BUG#22379 2006-09-15 ingo im_daemon_life_cycle.test fails on merge of 5.1 -> 5.1-engines
-im_instance_conf : BUG#20294 2006-09-16 ingo Instance manager test im_instance_conf fails randomly
concurrent_innodb : BUG#21579 2006-08-11 mleich innodb_concurrent random failures with varying differences
ndb_autodiscover : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t binlog
ndb_autodiscover2 : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t binlog
-#ndb_binlog_ignore_db : BUG#21279 2006-07-25 ingo Randomly throws a warning
ndb_load : BUG#17233 2006-05-04 tomas failed load data from infile causes mysqld dbug_assert, binlog not flushed
partition_03ndb : BUG#16385 2006-03-24 mikael Partitions: crash when updating a range partitioned NDB table
ps_7ndb : BUG#18950 2006-02-16 jmiller create table like does not obtain LOCK_open
rpl_ndb_2innodb : BUG#19227 2006-04-20 pekka pk delete apparently not replicated
rpl_ndb_2myisam : BUG#19227 Seems to pass currently
-#rpl_ndb_commit_afterflush : BUG#19328 2006-05-04 tomas Slave timeout with COM_REGISTER_SLAVE error causing stop
rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s/AMD
rpl_ndb_ddl : BUG#18946 result file needs update + test needs to checked
rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement
-#rpl_ndb_log : BUG#18947 2006-03-21 tomas CRBR: order in binlog of create table and insert (on different table) not determ
rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement
rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly
rpl_sp : BUG#16456 2006-02-16 jmiller
@@ -38,8 +30,5 @@ rpl_multi_engine : BUG#22583 2006-09-23 lars
# 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
-#rpl_ndb_idempotent : BUG#21298 2006-07-27 msvensson
-#rpl_row_basic_7ndb : BUG#21298 2006-07-27 msvensson
-#rpl_truncate_7ndb : BUG#21298 2006-07-27 msvensson
ndb_binlog_discover : bug#21806 2006-08-24
ndb_autodiscover3 : bug#21806
diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test
index 60e8c78d8bb..6223395bfd9 100644
--- a/mysql-test/t/events_bugs.test
+++ b/mysql-test/t/events_bugs.test
@@ -222,13 +222,13 @@ drop database mysqltest_db1;
#
# START - BUG#16394: Events: Crash if schedule contains SELECT
#
---error ER_PARSE_ERROR
+--error ER_NOT_SUPPORTED_YET
create event e_53 on schedule at (select s1 from ttx) do drop table t;
---error ER_PARSE_ERROR
+--error ER_NOT_SUPPORTED_YET
create event e_53 on schedule every (select s1 from ttx) second do drop table t;
---error ER_PARSE_ERROR
+--error ER_NOT_SUPPORTED_YET
create event e_53 on schedule every 5 second starts (select s1 from ttx) do drop table t;
---error ER_PARSE_ERROR
+--error ER_NOT_SUPPORTED_YET
create event e_53 on schedule every 5 second ends (select s1 from ttx) do drop table t;
#
# END - BUG#16394: Events: Crash if schedule contains SELECT
@@ -253,4 +253,47 @@ call p_16();
drop procedure p_16;
drop event e_16;
+
+#
+# START - BUG#22830 Events: crash with procedure which alters events with function
+#
+--disable_warnings
+drop function if exists f22830;
+drop event if exists e22830;
+drop event if exists e22830_1;
+drop event if exists e22830_2;
+drop event if exists e22830_3;
+drop event if exists e22830_4;
+drop table if exists t1;
+drop table if exists t2;
+--enable_warnings
+create table t1 (a int);
+insert into t1 values (2);
+create table t2 (a char(20));
+insert into t2 values ("e22830_1");
+create function f22830 () returns int return 5;
+--error ER_NOT_SUPPORTED_YET
+create event e22830 on schedule every f22830() second do select 123;
+create event e22830_1 on schedule every 1 hour do alter event e22830_1 on schedule every (select 8 from dual) hour;
+create event e22830_2 on schedule every 1 hour do alter event e22830_2 on schedule every (select 8 from t1) hour;
+create event e22830_3 on schedule every 1 hour do alter event e22830_3 on schedule every f22830() hour;
+create event e22830_4 on schedule every 1 hour do alter event e22830_4 on schedule every (select f22830() from dual) hour;
+select event_name, event_definition, interval_value, interval_field from information_schema.events order by event_name;
+set global event_scheduler=on;
+--sleep 0.7
+set global event_scheduler=off;
+select event_name, event_definition, interval_value, interval_field from information_schema.events order by event_name;
+drop function f22830;
+--error ER_PARSE_ERROR
+drop event (select a from t2);
+drop event e22830_1;
+drop event e22830_2;
+drop event e22830_3;
+drop event e22830_4;
+drop table t1;
+drop table t2;
+
+#
+# End of tests
+#
drop database events_test;
diff --git a/mysql-test/t/events_grant.test b/mysql-test/t/events_grant.test
index 3ead141c27c..44288fc1ac6 100644
--- a/mysql-test/t/events_grant.test
+++ b/mysql-test/t/events_grant.test
@@ -9,7 +9,7 @@ use events_test;
CREATE EVENT one_event ON SCHEDULE EVERY 10 SECOND DO SELECT 123;
--replace_column 8 # 9 #
SHOW EVENTS;
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from information_schema.events;
+SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME;
CREATE DATABASE events_test2;
CREATE USER ev_test@localhost;
GRANT ALL ON events_test.* to ev_test@localhost;
@@ -55,10 +55,10 @@ CREATE EVENT four_event ON SCHEDULE EVERY 20 SECOND DO SELECT 42;
connection default;
USE events_test;
--echo "We should see 4 events : one_event, two_event, three_event & four_event"
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS;
+SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME;
DROP DATABASE events_test2;
--echo "We should see 3 events : one_event, two_event, three_event"
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS;
+SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME;
connection default;
CREATE DATABASE events_test2;
@@ -67,13 +67,13 @@ CREATE EVENT five_event ON SCHEDULE EVERY 20 SECOND DO SELECT 42;
connection ev_con1;
--echo "Should see 4 events - one, two, three & five"
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS;
+SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME;
connection default;
REVOKE EVENT ON events_test2.* FROM ev_test@localhost;
connection ev_con1;
USE test;
--echo "Should see 3 events - one, two & three"
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS;
+SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME;
--echo "Let's test ALTER EVENT which changes the definer"
USE events_test;
ALTER EVENT one_event ON SCHEDULE EVERY 10 SECOND;
@@ -96,7 +96,7 @@ connection ev_con1;
DROP EVENT one_event;
connection default;
--echo "One event should not be there"
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS;
+SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME;
disconnect ev_con1;
connection default;
DROP USER ev_test@localhost;
diff --git a/mysql-test/t/func_compress.test b/mysql-test/t/func_compress.test
index eeb5d509b94..68f07f258bf 100644
--- a/mysql-test/t/func_compress.test
+++ b/mysql-test/t/func_compress.test
@@ -56,7 +56,19 @@ insert into t1 values(NULL), (compress('a'));
select uncompress(a), uncompressed_length(a) from t1;
drop table t1;
-# End of 4.1 tests
+#
+# Bug #23254: problem with compress(NULL)
+#
+
+create table t1(a blob);
+insert into t1 values ('0'), (NULL), ('0');
+--disable_result_log
+select compress(a), compress(a) from t1;
+--enable_result_log
+select compress(a) is null from t1;
+drop table t1;
+
+--echo End of 4.1 tests
#
# Bug #18539: uncompress(d) is null: impossible?
diff --git a/mysql-test/t/func_date_add.test b/mysql-test/t/func_date_add.test
index e01fce30577..b575eeececa 100644
--- a/mysql-test/t/func_date_add.test
+++ b/mysql-test/t/func_date_add.test
@@ -64,4 +64,17 @@ insert into t1 values (date_add('2000-01-04', INTERVAL NULL DAY));
select * from t1;
drop table t1;
-# End of 4.1 tests
+--echo End of 4.1 tests
+
+#
+# Bug#21811
+#
+# Make sure we end up with an appropriate
+# date format (DATE) after addition operation
+#
+SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 DAY;
+SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 MONTH;
+SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR;
+SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test
index c2035132d06..db3536c6d36 100644
--- a/mysql-test/t/func_gconcat.test
+++ b/mysql-test/t/func_gconcat.test
@@ -98,7 +98,7 @@ select ifnull(group_concat(concat(t1.id, ':', t1.name)), 'shortname') as 'withou
select distinct ifnull(group_concat(concat(t1.id, ':', t1.name)), 'shortname') as 'with distinct: cutoff at length of shortname' from t1;
drop table t1;
-# check zero rows
+# check zero rows (bug#836)
create table t1(id int);
create table t2(id int);
insert into t1 values(0),(1);
diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test
index 4041c267134..09aa5751301 100644
--- a/mysql-test/t/func_math.test
+++ b/mysql-test/t/func_math.test
@@ -34,6 +34,11 @@ select pi(),format(sin(pi()/2),6),format(cos(pi()/2),6),format(abs(tan(pi())),6)
explain extended select pi(),format(sin(pi()/2),6),format(cos(pi()/2),6),format(abs(tan(pi())),6),format(cot(1),6),format(asin(1),6),format(acos(0),6),format(atan(1),6);
select degrees(pi()),radians(360);
+select format(atan(-2, 2), 6);
+select format(atan(pi(), 0), 6);
+select format(atan2(-2, 2), 6);
+select format(atan2(pi(), 0), 6);
+
#
# Bug #2338 Trignometric arithmatic problems
#
diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test
index 0ea89cd0913..77bf3be5e72 100644
--- a/mysql-test/t/func_test.test
+++ b/mysql-test/t/func_test.test
@@ -108,6 +108,40 @@ select 5.1 mod 3, 5.1 mod -3, -5.1 mod 3, -5.1 mod -3;
select 5 mod 3, 5 mod -3, -5 mod 3, -5 mod -3;
+#
+# Bug#23411: The "%" (MOD) operator is not documented; MOD-ing zero returns strange result
+# Manual: "Division by zero produces a NULL result"
+#
+select (12%0) <=> null as '1';
+select (12%0) is null as '1';
+select 12%0 as 'NULL';
+select 12%2 as '0';
+select 12%NULL as 'NULL';
+select 12 % null as 'NULL';
+select null % 12 as 'NULL';
+select null % 0 as 'NULL';
+select 0 % null as 'NULL';
+select null % null as 'NULL';
+
+select (12 mod 0) <=> null as '1';
+select (12 mod 0) is null as '1';
+select 12 mod 0 as 'NULL';
+select 12 mod 2 as '0';
+select 12 mod null as 'NULL';
+select null mod 12 as 'NULL';
+select null mod 0 as 'NULL';
+select 0 mod null as 'NULL';
+select null mod null as 'NULL';
+
+select mod(12.0, 0) as 'NULL';
+select mod(12, 0.0) as 'NULL';
+select mod(12, NULL) as 'NULL';
+select mod(12.0, NULL) as 'NULL';
+select mod(NULL, 2) as 'NULL';
+select mod(NULL, 2.0) as 'NULL';
+
+
+#
# Bug#6726: NOT BETWEEN parse failure
#
create table t1 (a int, b int);
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index d49a4fed9d2..a6cbca61b84 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -255,17 +255,57 @@ select unix_timestamp(@a);
select unix_timestamp('1969-12-01 19:00:01');
#
-# Test for bug #6439 "unix_timestamp() function returns wrong datetime
-# values for too big argument" and bug #7515 "from_unixtime(0) now
-# returns NULL instead of the epoch". unix_timestamp() should return error
-# for too big or negative argument. It should return Epoch value for zero
-# argument since it seems that many user's rely on this fact.
+# Tests for bug #6439 "unix_timestamp() function returns wrong datetime
+# values for too big argument", bug #7515 "from_unixtime(0) now
+# returns NULL instead of the epoch" and bug #9191
+# "TIMESTAMP/from_unixtime() no longer accepts 2^31-1."
+# unix_timestamp() should return error for too big or negative argument.
+# It should return Epoch value for zero argument since it seems that many
+# users rely on this fact, from_unixtime() should work with values
+# up to INT_MAX32 because of the same reason.
#
select from_unixtime(-1);
-select from_unixtime(2145916800);
+# check for from_unixtime(2^31-1) and from_unixtime(2^31)
+select from_unixtime(2147483647);
+select from_unixtime(2147483648);
select from_unixtime(0);
#
+# Some more tests for bug #9191 "TIMESTAMP/from_unixtime() no
+# longer accepts 2^31-1". Here we test that from_unixtime and
+# unix_timestamp are consistent, when working with boundary dates.
+#
+select unix_timestamp(from_unixtime(2147483647));
+select unix_timestamp(from_unixtime(2147483648));
+
+# check for invalid dates
+
+# bad year
+select unix_timestamp('2039-01-20 01:00:00');
+select unix_timestamp('1968-01-20 01:00:00');
+# bad month
+select unix_timestamp('2038-02-10 01:00:00');
+select unix_timestamp('1969-11-20 01:00:00');
+# bad day
+select unix_timestamp('2038-01-20 01:00:00');
+select unix_timestamp('1969-12-30 01:00:00');
+
+#
+# Check negative shift (we subtract several days for boundary dates during
+# conversion).
+select unix_timestamp('2038-01-17 12:00:00');
+
+#
+# Check positive shift. (it happens only on
+# platfroms with unsigned time_t, such as QNX)
+#
+select unix_timestamp('1970-01-01 03:00:01');
+
+# check bad date, close to the boundary (we cut them off in the very end)
+select unix_timestamp('2038-01-19 07:14:07');
+
+
+#
# Test types from + INTERVAL
#
@@ -447,6 +487,49 @@ show create table t1;
drop table t1;
#
+# Bug #11655: Wrong time is returning from nested selects - maximum time exists
+#
+# check if SEC_TO_TIME() handles out-of-range values correctly
+SELECT SEC_TO_TIME(3300000);
+SELECT SEC_TO_TIME(3300000)+0;
+SELECT SEC_TO_TIME(3600 * 4294967296);
+
+# check if TIME_TO_SEC() handles out-of-range values correctly
+SELECT TIME_TO_SEC('916:40:00');
+
+# check if ADDTIME() handles out-of-range values correctly
+SELECT ADDTIME('500:00:00', '416:40:00');
+SELECT ADDTIME('916:40:00', '416:40:00');
+
+# check if SUBTIME() handles out-of-range values correctly
+SELECT SUBTIME('916:40:00', '416:40:00');
+SELECT SUBTIME('-916:40:00', '416:40:00');
+
+# check if MAKETIME() handles out-of-range values correctly
+SELECT MAKETIME(916,0,0);
+SELECT MAKETIME(4294967296, 0, 0);
+SELECT MAKETIME(-4294967296, 0, 0);
+SELECT MAKETIME(0, 4294967296, 0);
+SELECT MAKETIME(0, 0, 4294967296);
+SELECT MAKETIME(CAST(-1 AS UNSIGNED), 0, 0);
+
+# check if EXTRACT() handles out-of-range values correctly
+SELECT EXTRACT(HOUR FROM '100000:02:03');
+
+# check if we get proper warnings if both input string truncation
+# and out-of-range value occur
+CREATE TABLE t1(f1 TIME);
+INSERT INTO t1 VALUES('916:00:00 a');
+SELECT * FROM t1;
+DROP TABLE t1;
+
+#
+# Bug #20927: sec_to_time treats big unsigned as signed
+#
+# check if SEC_TO_TIME() handles BIGINT UNSIGNED values correctly
+SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED));
+
+#
# 21913: DATE_FORMAT() Crashes mysql server if I use it through
# mysql-connector-j driver.
#
@@ -464,7 +547,6 @@ DROP TABLE testBug8868;
SET NAMES DEFAULT;
-
#
# Bug #19844 time_format in Union truncates values
#
@@ -483,24 +565,6 @@ union
union
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%k') As H);
-#
-# 21913: DATE_FORMAT() Crashes mysql server if I use it through
-# mysql-connector-j driver.
-#
-
-SET NAMES latin1;
-SET character_set_results = NULL;
-SHOW VARIABLES LIKE 'character_set_results';
-
-CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY);
-INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd');
-
-SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868;
-
-DROP TABLE testBug8868;
-
-SET NAMES DEFAULT;
-
--echo End of 4.1 tests
explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1,
diff --git a/mysql-test/t/im_daemon_life_cycle.imtest b/mysql-test/t/im_daemon_life_cycle.imtest
index 55e52f4e464..fd19b6f8527 100644
--- a/mysql-test/t/im_daemon_life_cycle.imtest
+++ b/mysql-test/t/im_daemon_life_cycle.imtest
@@ -8,6 +8,9 @@
--source include/im_check_env.inc
+# Turn on reconnect, not on by default anymore
+--enable_reconnect
+
###########################################################################
# Kill the IM main process and check that the IM Angel will restart the main
@@ -17,6 +20,12 @@
###########################################################################
+# Wait for IM to start accepting connections.
+
+--exec $MYSQL_TEST_DIR/t/wait_for_socket.sh $EXE_MYSQL $IM_PATH_SOCK $IM_USERNAME $IM_PASSWORD '' 30
+
+###########################################################################
+
#
# BUG#12751: Instance Manager: client hangs
#
@@ -37,10 +46,13 @@ START INSTANCE mysqld2;
# FIXME: START INSTANCE should be synchronous.
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 started
-# 2. Restart IM-main: kill it and IM-angel will restart it.
+# 2. Restart IM-main: kill it and IM-angel will restart it; wait for IM to
+# start accepting connections again.
--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted 30
+--exec $MYSQL_TEST_DIR/t/wait_for_socket.sh $EXE_MYSQL $IM_PATH_SOCK $IM_USERNAME $IM_PASSWORD '' 30
+
# 3. Issue some statement -- connection should be re-established.
# Give some time to begin accepting connections after restart.
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index 222b9652fca..4ae88736b98 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -934,7 +934,46 @@ SELECT MAX(table_name) FROM information_schema.tables;
SELECT table_name from information_schema.tables
WHERE table_name=(SELECT MAX(table_name)
FROM information_schema.tables);
+#
+# Bug #23037: Bug in field "Default" of query "SHOW COLUMNS FROM table"
+#
+# Note, MyISAM/InnoDB can't take more that 65532 chars, because the row
+# size is limited to 65535 bytes (BLOBs not counted)
+#
+--disable_warnings
+DROP TABLE IF EXISTS bug23037;
+DROP FUNCTION IF EXISTS get_value;
+--enable_warnings
+--disable_query_log
+DELIMITER |;
+CREATE FUNCTION get_value()
+ RETURNS TEXT
+ DETERMINISTIC
+BEGIN
+ DECLARE col1, col2, col3, col4, col6 CHAR(255);
+ DECLARE default_val VARCHAR(65532);
+ DECLARE done INT DEFAULT 0;
+ DECLARE cur1 CURSOR FOR SHOW COLUMNS FROM bug23037;
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
+ OPEN cur1;
+ FETCH cur1 INTO col1, col2, col3, col4, default_val, col6;
+ CLOSE cur1;
+ RETURN default_val;
+end|
+DELIMITER ;|
+
+let $body=`SELECT REPEAT('A', 65532)`;
+eval CREATE TABLE bug23037(fld1 VARCHAR(65532) CHARACTER SET latin1 DEFAULT "$body");
+--enable_query_log
+
+SELECT COLUMN_NAME, MD5(COLUMN_DEFAULT), LENGTH(COLUMN_DEFAULT) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='bug23037';
+
+SELECT MD5(get_value());
+
+SELECT COLUMN_NAME, MD5(COLUMN_DEFAULT), LENGTH(COLUMN_DEFAULT), COLUMN_DEFAULT=get_value() FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='bug23037';
+DROP TABLE bug23037;
+DROP FUNCTION get_value;
--echo End of 5.0 tests.
#
# Show engines
diff --git a/mysql-test/t/init_file.test b/mysql-test/t/init_file.test
index 6b5e032fd99..31a6ef5a541 100644
--- a/mysql-test/t/init_file.test
+++ b/mysql-test/t/init_file.test
@@ -4,7 +4,7 @@
#
# See mysql-test/std_data/init_file.dat and
# mysql-test/t/init_file-master.opt for the actual test
-#
+#
--echo ok
--echo end of 4.1 tests
diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test
index f8ba649b3eb..53a88df7bd9 100644
--- a/mysql-test/t/kill.test
+++ b/mysql-test/t/kill.test
@@ -48,7 +48,7 @@ select 4;
drop table t1;
connection default;
---error 1064
+--error ER_NOT_SUPPORTED_YET
kill (select count(*) from mysql.user);
#
diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test
index 9c9e68f931f..765da1ee18d 100644
--- a/mysql-test/t/lock_multi.test
+++ b/mysql-test/t/lock_multi.test
@@ -244,7 +244,10 @@ DROP DATABASE mysqltest_1;
# Bug #17264: MySQL Server freeze
#
connection locker;
+# Disable warnings to allow test to run also without InnoDB
+--disable_warnings
create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)) engine=innodb;
+--enable_warnings
lock tables t1 write;
connection writer;
--sleep 2
diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test
index d9e17129799..f1ff91a6d1d 100644
--- a/mysql-test/t/log_tables.test
+++ b/mysql-test/t/log_tables.test
@@ -314,6 +314,89 @@ use mysql;
lock tables general_log read local, help_category read local;
unlock tables;
+#
+# Bug #17544 Cannot do atomic log rotate and
+# Bug #21785 Server crashes after rename of the log table
+#
+
+use mysql;
+# Should result in error
+--error ER_CANT_RENAME_LOG_TABLE
+RENAME TABLE general_log TO renamed_general_log;
+--error ER_CANT_RENAME_LOG_TABLE
+RENAME TABLE slow_log TO renamed_slow_log;
+
+#check rotate logs
+truncate table general_log;
+--replace_column 1 TIMESTAMP 2 USER_HOST 3 THREAD_ID
+select * from general_log;
+
+truncate table slow_log;
+--replace_column 1 TIMESTAMP 2 USER_HOST
+select * from slow_log;
+
+create table general_log_new like general_log;
+rename table general_log TO renamed_general_log, general_log_new TO general_log;
+
+create table slow_log_new like slow_log;
+rename table slow_log TO renamed_slow_log, slow_log_new TO slow_log;
+
+# check that rename checks more then first table in the list
+--error ER_CANT_RENAME_LOG_TABLE
+rename table general_log TO general_log_new, renamed_general_log TO general_log, slow_log to renamed_slow_log;
+
+# now check the content of tables
+--replace_column 1 TIMESTAMP 2 USER_HOST 3 THREAD_ID
+select * from general_log;
+--replace_column 1 TIMESTAMP 2 USER_HOST 3 THREAD_ID
+select * from renamed_general_log;
+
+# the content of the slow log is empty, but we will try a select anyway
+--replace_column 1 TIMESTAMP 2 USER_HOST
+select * from slow_log;
+--replace_column 1 TIMESTAMP 2 USER_HOST
+select * from renamed_slow_log;
+
+# check that we can do whatever we want with disabled log
+set global general_log='OFF';
+RENAME TABLE general_log TO general_log2;
+
+set global slow_query_log='OFF';
+RENAME TABLE slow_log TO slow_log2;
+
+# this should fail
+--error ER_CANT_ACTIVATE_LOG
+set global general_log='ON';
+--error ER_CANT_ACTIVATE_LOG
+set global slow_query_log='ON';
+
+RENAME TABLE general_log2 TO general_log;
+RENAME TABLE slow_log2 TO slow_log;
+
+# this should work
+set global general_log='ON';
+set global slow_query_log='ON';
+# now check flush logs
+flush logs;
+flush logs;
+drop table renamed_general_log, renamed_slow_log;
+use test;
+
+#
+# Bug #21966 Strange warnings on repair of the log tables
+#
+
+use mysql;
+# check that no warning occurs on repair of the log tables
+repair table general_log;
+repair table slow_log;
+# check that no warning occurs on "create like" for the log tables
+create table general_log_new like general_log;
+create table slow_log_new like slow_log;
+show tables like "%log%";
+drop table slow_log_new, general_log_new;
+use test;
+
# kill all connections
disconnect con1;
disconnect con2;
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index f3296e6f706..c06e52e2d78 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -153,4 +153,74 @@ drop table t1;
--exec echo "SELECT '\';';" >> $MYSQLTEST_VARDIR/tmp/bug20103.sql
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20103.sql 2>&1
+#
+# Bug#17583: mysql drops connection when stdout is not writable
+#
+create table t17583 (a int);
+insert into t17583 (a) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+# Close to the minimal data needed to exercise bug.
+select count(*) from t17583;
+--exec echo "select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; " |$MYSQL test >&-
+drop table t17583;
+
+#
+# Bug#20984: Reproducible MySQL client segmentation fault
+# + additional tests for the "com_connect" function in mysql
+#
+#
+--echo Test connect without db- or host-name => reconnect
+--exec $MYSQL test -e "\r" 2>&1
+--exec $MYSQL test -e "connect" 2>&1
+
+--echo Test connect with dbname only => new dbname, old hostname
+--exec $MYSQL test -e "\r test" 2>&1
+--exec $MYSQL test -e "connect test" 2>&1
+--exec $MYSQL test -e "\rtest" 2>&1
+--error 1
+--exec $MYSQL test -e "connecttest" 2>&1
+
+--echo Test connect with _invalid_ dbname only => new invalid dbname, old hostname
+--error 1
+--exec $MYSQL test -e "\r invalid" 2>&1
+--error 1
+--exec $MYSQL test -e "connect invalid" 2>&1
+
+--echo Test connect with dbname + hostname
+--exec $MYSQL test -e "\r test localhost" 2>&1
+--exec $MYSQL test -e "connect test localhost" 2>&1
+
+--echo Test connect with dbname + _invalid_ hostname
+# Mask the errno of the error message
+--replace_regex /\([0-9]*\)/(errno)/
+--error 1
+--exec $MYSQL test -e "\r test invalid_hostname" 2>&1
+--replace_regex /\([0-9]*\)/(errno)/
+--error 1
+--exec $MYSQL test -e "connect test invalid_hostname" 2>&1
+
+--echo The commands reported in the bug report
+--replace_regex /\([0-9]*\)/(errno)/
+--error 1
+--exec $MYSQL test -e "\r\r\n\r\n cyril\ has\ found\ a\ bug\ :)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 2>&1
+
+#--replace_regex /\([0-9]*\)/(errno)/
+#--error 1
+#--exec echo '\r\r\n\r\n cyril\ has\ found\ a\ bug\ :)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' | $MYSQL 2>&1
+
+--echo Too long dbname
+--error 1
+--exec $MYSQL test -e "\r test_really_long_dbnamexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx localhost" 2>&1
+
+--echo Too long hostname
+--replace_regex /\([0-9]*\)/(errno)/
+--error 1
+--exec $MYSQL test -e "\r test cyrils_superlonghostnameXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 2>&1
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/mysqldump-max.test b/mysql-test/t/mysqldump-max.test
index fbea84808b4..359c4ea5793 100644
--- a/mysql-test/t/mysqldump-max.test
+++ b/mysql-test/t/mysqldump-max.test
@@ -3,14 +3,9 @@
--source include/have_innodb.inc
--source include/have_archive.inc
---disable-warnings
-drop table if exists t1;
-drop table if exists t2;
-drop table if exists t3;
-drop table if exists t4;
-drop table if exists t5;
-drop table if exists t6;
---enable-warnings
+--disable_warnings
+drop table if exists t1, t2, t3, t4, t5, t6;
+--enable_warnings
create table t1 (id int(8), name varchar(32));
create table t2 (id int(8), name varchar(32)) ENGINE="MyISAM";
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 327b071afeb..1f1c8a44dbe 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -1415,6 +1415,21 @@ DROP TABLE `t1`;
--enable_warnings
--echo #
+--echo # Bug #19745: mysqldump --xml produces invalid xml
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (f1 int(10), data MEDIUMBLOB);
+INSERT INTO t1 VALUES(1,0xff00fef0);
+
+--exec $MYSQL_DUMP --xml --hex-blob --skip-create-options test t1
+
+DROP TABLE t1;
+
+--echo #
--echo # End of 5.0 tests
--echo #
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index 25f8d63d0b2..3c20b38722f 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -317,7 +317,6 @@ select 3 from t1 ;
#
#select 3 from t1 ;
-# End of 4.1 tests
--error 1
--exec echo "disable_abort_on_error; enable_abort_on_error; error 1064; select 3 from t1; select 3 from t1;" | $MYSQL_TEST 2>&1
@@ -360,18 +359,80 @@ select 3 from t1 ;
# Missing delimiter
# The comment will be "sucked into" the sleep command since
# delimiter is missing until after "show status"
---system echo "sleep 4" > $MYSQLTEST_VARDIR/tmp/mysqltest.sql
---system echo "# A comment" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql
---system echo "show status;" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql
+--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql
+sleep 4
+# A comment
+show status;
+EOF
--error 1
--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
#
# Missing delimiter until eof
# The comment will be "sucked into" the sleep command since
-# delimiter is missing
---system echo "sleep 7" > $MYSQLTEST_VARDIR/tmp/mysqltest.sql
---system echo "# Another comment" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql
+# delimiter is missing
+--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql
+sleep 7
+# Another comment
+EOF
+--error 1
+--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
+
+#
+# Missing delimiter until "disable_query_log"
+#
+--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql
+disconnect default
+
+#
+# comment
+# comment 3
+disable_query_log;
+EOF
+--error 1
+--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
+
+#
+# Missing delimiter until "disable_query_log"
+#
+--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql
+disconnect default
+
+#
+# comment
+
+# comment 3
+disable_query_log;
+EOF
+--error 1
+--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
+
+#
+# Missing delimiter until eof
+#
+--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql
+disconnect default
+
+#
+# comment
+# comment2
+
+# comment 3
+--disable_query_log
+EOF
+--error 1
+--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
+
+#
+# Missing delimiter until eof
+#
+--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql
+disconnect default # comment
+# comment part2
+
+# comment 3
+--disable_query_log
+EOF
--error 1
--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
@@ -388,6 +449,67 @@ select 3 from t1 ;
--sleep 1 # Wait for insert delayed to be executed.
--sleep 1 # Wait for insert delayed to be executed.
+# ----------------------------------------------------------------------------
+# Test error
+# ----------------------------------------------------------------------------
+
+# Missing argument
+--error 1
+--exec echo "error;" | $MYSQL_TEST 2>&1
+--error 1
+--exec echo "--error" | $MYSQL_TEST 2>&1
+
+# First char must be uppercase 'S' or 'E' or [0-9]
+--error 1
+--exec echo "--error s99999" | $MYSQL_TEST 2>&1
+--error 1
+--exec echo "--error e99999" | $MYSQL_TEST 2>&1
+--error 1
+--exec echo "--error 9eeeee" | $MYSQL_TEST 2>&1
+--error 1
+--exec echo "--error 1sssss" | $MYSQL_TEST 2>&1
+
+# First char 'S' but too long
+--error 1
+--exec echo "--error S999999" | $MYSQL_TEST 2>&1
+
+# First char 'S' but lowercase char found
+--error 1
+--exec echo "--error S99a99" | $MYSQL_TEST 2>&1
+
+# First char 'S' but too short
+--error 1
+--exec echo "--error S9999" | $MYSQL_TEST 2>&1
+
+# First char 'E' but not found in error array
+--error 1
+--exec echo "--error E9999" | $MYSQL_TEST 2>&1
+
+# First char [0-9] but contains chars
+--error 1
+--exec echo "--error 999e9" | $MYSQL_TEST 2>&1
+--error 1
+--exec echo "--error 9b" | $MYSQL_TEST 2>&1
+
+# Multiple errorcodes separated by ','
+--error 1,1,1,1
+#--error 9,ER_PARSE_ERROR
+#--error ER_PARSE_ERROR
+#--error 9,ER_PARSE_ERROR,9,ER_PARSE_ERROR
+#--error 9, ER_PARSE_ERROR, 9, ER_PARSE_ERROR
+#--error 9,S00000,9,ER_PARSE_ERROR
+#--error 9,S00000,9,ER_PARSE_ERROR,ER_PARSE_ERROR,ER_PARSE_ERROR,9,10,11,12
+--error 9,S00000,9
+--error 9,S00000,9,9,10,11,12
+--error 9 ,10
+--error 9 , 10
+--error 9 , 10
+--error 9 , 10
+
+# Too many errorcodes specified
+--error 1
+--exec echo "--error 1,2,3,4,5,6,7,8,9,10,11" | $MYSQL_TEST 2>&1
+
# ----------------------------------------------------------------------------
# Test echo command
@@ -610,6 +732,7 @@ echo $var3_var3;
# Fix win paths
--replace_result \\ /
+# Source a nonexisting file
--error 1
--exec echo "source non_existingFile;" | $MYSQL_TEST 2>&1
@@ -627,13 +750,16 @@ echo $var3_var3;
# Test execution of source in a while loop
+--write_file $MYSQLTEST_VARDIR/tmp/sourced.inc
+echo here is the sourced script;
+EOF
--disable_query_log
let $outer= 2; # Number of outer loops
while ($outer)
{
eval SELECT '$outer = outer loop variable after while' AS "";
- --source include/sourced.inc
+ --source $MYSQLTEST_VARDIR/tmp/sourced.inc
eval SELECT '$outer = outer loop variable before dec' AS "";
dec $outer;
@@ -661,11 +787,12 @@ let $num= 9;
while ($num)
{
SELECT 'In loop' AS "";
- --source include/sourced1.inc
+ --source $MYSQLTEST_VARDIR/tmp/sourced.inc
dec $num;
}
--enable_abort_on_error
--enable_query_log
+--remove_file $MYSQLTEST_VARDIR/tmp/sourced.inc
# ----------------------------------------------------------------------------
# Test sleep command
@@ -817,10 +944,150 @@ while (!$i)
}
# Exceed max nesting level
+--write_file $MYSQLTEST_VARDIR/tmp/mysqltest_while.inc
+let $1 = 10;
+while ($1)
+{
+while ($1)
+{
+while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ while ($1)
+{
+ echo $1;
+ dec $1;
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+}
+EOF
# Fix win path
---replace_result \\ /
+--replace_result \\ / $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--error 1
---exec echo "source include/mysqltest_while.inc;" | $MYSQL_TEST 2>&1
+--exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest_while.inc;" | $MYSQL_TEST 2>&1
+--remove_file $MYSQLTEST_VARDIR/tmp/mysqltest_while.inc
--error 1
--exec echo "while \$i;" | $MYSQL_TEST 2>&1
--error 1
@@ -925,12 +1192,6 @@ select "a" as col1, "c" as col2;
--error 1
--exec echo "connect (con2,);" | $MYSQL_TEST 2>&1
--error 1
---exec echo "connect (con2,localhost);" | $MYSQL_TEST 2>&1
---error 1
---exec echo "connect (con2, localhost, root);" | $MYSQL_TEST 2>&1
---error 1
---exec echo "connect (con2, localhost, root,);" | $MYSQL_TEST 2>&1
---error 1
--exec echo "connect (con2,localhost,root,,illegal_db);" | $MYSQL_TEST 2>&1
--error 1
--exec echo "connect (con1,localhost,root,,,illegal_port,);" | $MYSQL_TEST 2>&1
@@ -938,13 +1199,15 @@ select "a" as col1, "c" as col2;
--exec echo "connect (con1,localhost,root,,,,,SMTP POP);" | $MYSQL_TEST 2>&1
# Repeat connect/disconnect
---system echo "let \$i=100;" > $MYSQLTEST_VARDIR/tmp/mysqltest.sql
---system echo "while (\$i)" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql
---system echo "{" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql
---system echo " connect (test_con1,localhost,root,,); " >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql
---system echo " disconnect test_con1; " >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql
---system echo " dec \$i; " >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql
---system echo "}" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql
+--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql
+let $i=100;
+while ($i)
+{
+ connect (test_con1,localhost,root,,);
+ disconnect test_con1;
+ dec $i;
+}
+EOF
--exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql; echo OK;" | $MYSQL_TEST 2>&1
# Repeat connect/disconnect, exceed max number of connections
@@ -1149,8 +1412,6 @@ query sleep;
--error 1065
query ;
---echo End of 5.0 tests
-
# test for replace_regex
--replace_regex /at/b/
select "at" as col1, "c" as col2;
@@ -1189,4 +1450,117 @@ insert into t1 values (2,4);
select * from t1;
drop table t1;
---echo End of 5.1 tests
+# ----------------------------------------------------------------------------
+# test for remove_file
+# ----------------------------------------------------------------------------
+
+--error 1
+--exec echo "remove_file ;" | $MYSQL_TEST 2>&1
+
+--error 1
+remove_file non_existing_file;
+
+# ----------------------------------------------------------------------------
+# test for write_file
+# ----------------------------------------------------------------------------
+--error 1
+--exec echo "write_file ;" | $MYSQL_TEST 2>&1
+
+--error 1
+--exec echo "write_file filename ;" | $MYSQL_TEST 2>&1
+
+--error 1
+--exec echo "write_file filename \";" | $MYSQL_TEST 2>&1
+
+write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+Content for test_file1
+EOF
+file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+
+write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp END_DELIMITER;
+Content for test_file1 contains EOF
+END_DELIMITER
+file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+
+# ----------------------------------------------------------------------------
+# test for file_exist
+# ----------------------------------------------------------------------------
+--error 1
+--exec echo "file_exists ;" | $MYSQL_TEST 2>&1
+
+--error 0,1
+remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+--error 1
+file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+Content for test_file1
+EOF
+file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+--error 1
+file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+
+
+# ----------------------------------------------------------------------------
+# test for copy_file
+# ----------------------------------------------------------------------------
+--write_file $MYSQLTEST_VARDIR/tmp/file1.tmp
+file1
+EOF
+
+copy_file $MYSQLTEST_VARDIR/tmp/file1.tmp $MYSQLTEST_VARDIR/tmp/file2.tmp;
+file_exists $MYSQLTEST_VARDIR/tmp/file2.tmp;
+remove_file $MYSQLTEST_VARDIR/tmp/file1.tmp;
+remove_file $MYSQLTEST_VARDIR/tmp/file2.tmp;
+
+--error 1
+--exec echo "copy_file ;" | $MYSQL_TEST 2>&1
+
+--error 1
+--exec echo "copy_file from_file;" | $MYSQL_TEST 2>&1
+
+# ----------------------------------------------------------------------------
+# test for perl
+# ----------------------------------------------------------------------------
+--perl
+print "hello\n";
+EOF
+
+--perl EOF
+print "hello\n";
+EOF
+
+--perl DELIMITER
+print "hello\n";
+DELIMITER
+
+--error 1
+--exec echo "perl TOO_LONG_DELIMITER ;" | $MYSQL_TEST 2>&1
+
+perl;
+print "hello\n";
+EOF
+
+perl;
+ # Print "hello"
+ print "hello\n";
+EOF
+
+# ----------------------------------------------------------------------------
+# test for die
+# ----------------------------------------------------------------------------
+
+--error 1
+--exec echo "die test of die;" | $MYSQL_TEST 2>&1
+
+
+# ----------------------------------------------------------------------------
+# test for exit
+# ----------------------------------------------------------------------------
+
+--exec echo "echo Some output; exit; echo Not this;" | $MYSQL_TEST 2>&1
+
+
+--echo End of tests
diff --git a/mysql-test/t/ndb_index_unique.test b/mysql-test/t/ndb_index_unique.test
index 94bba98662c..a1fd432a29a 100644
--- a/mysql-test/t/ndb_index_unique.test
+++ b/mysql-test/t/ndb_index_unique.test
@@ -91,7 +91,6 @@ select * from t2 order by a;
drop table t2;
--- error 1121
CREATE TABLE t2 (
a int unsigned NOT NULL PRIMARY KEY,
b int unsigned not null,
@@ -99,6 +98,20 @@ CREATE TABLE t2 (
UNIQUE (b, c) USING HASH
) engine=ndbcluster;
+
+insert t2 values(1,1,NULL),(2,2,2),(3,3,NULL),(4,4,4),(5,5,NULL),(6,6,6),(7,7,NULL),(8,3,NULL),(9,3,NULL);
+
+select * from t2 where c IS NULL order by a;
+select * from t2 where b = 3 AND c IS NULL order by a;
+select * from t2 where (b = 3 OR b = 5) AND c IS NULL order by a;
+set @old_ecpd = @@session.engine_condition_pushdown;
+set engine_condition_pushdown = true;
+explain select * from t2 where (b = 3 OR b = 5) AND c IS NULL AND a < 9 order by a;
+select * from t2 where (b = 3 OR b = 5) AND c IS NULL AND a < 9 order by a;
+set engine_condition_pushdown = @old_ecpd;
+
+drop table t2;
+
#
# Show use of PRIMARY KEY USING HASH indexes
#
diff --git a/mysql-test/t/not_embedded_server-master.opt b/mysql-test/t/not_embedded_server-master.opt
index 35fcc5f30c6..cef79bc8585 100644
--- a/mysql-test/t/not_embedded_server-master.opt
+++ b/mysql-test/t/not_embedded_server-master.opt
@@ -1 +1 @@
---loose-to-force-a-restart
+--force-restart
diff --git a/mysql-test/t/not_partition.test b/mysql-test/t/not_partition.test
new file mode 100644
index 00000000000..992615c06f4
--- /dev/null
+++ b/mysql-test/t/not_partition.test
@@ -0,0 +1,62 @@
+--disable_abort_on_error
+# Run this tets only when mysqld don't has partitioning
+# the statements are not expected to work, just check that we
+# can't crash the server
+-- require r/not_partition.require
+disable_query_log;
+show variables like "have_partitioning";
+enable_query_log;
+
+
+--error ER_FEATURE_DISABLED
+CREATE TABLE t1 (
+ firstname VARCHAR(25) NOT NULL,
+ lastname VARCHAR(25) NOT NULL,
+ username VARCHAR(16) NOT NULL,
+ email VARCHAR(35),
+ joined DATE NOT NULL
+)
+PARTITION BY KEY(joined)
+PARTITIONS 6;
+
+--error ER_FEATURE_DISABLED
+ALTER TABLE t1 PARTITION BY KEY(joined) PARTITIONS 2;
+
+--error ER_BAD_TABLE_ERROR
+drop table t1;
+
+--error ER_FEATURE_DISABLED
+CREATE TABLE t1 (
+ firstname VARCHAR(25) NOT NULL,
+ lastname VARCHAR(25) NOT NULL,
+ username VARCHAR(16) NOT NULL,
+ email VARCHAR(35),
+ joined DATE NOT NULL
+)
+PARTITION BY RANGE( YEAR(joined) ) (
+ PARTITION p0 VALUES LESS THAN (1960),
+ PARTITION p1 VALUES LESS THAN (1970),
+ PARTITION p2 VALUES LESS THAN (1980),
+ PARTITION p3 VALUES LESS THAN (1990),
+ PARTITION p4 VALUES LESS THAN MAXVALUE
+);
+--error ER_BAD_TABLE_ERROR
+drop table t1;
+
+--error ER_FEATURE_DISABLED
+CREATE TABLE t1 (id INT, purchased DATE)
+ PARTITION BY RANGE( YEAR(purchased) )
+ SUBPARTITION BY HASH( TO_DAYS(purchased) )
+ SUBPARTITIONS 2 (
+ PARTITION p0 VALUES LESS THAN (1990),
+ PARTITION p1 VALUES LESS THAN (2000),
+ PARTITION p2 VALUES LESS THAN MAXVALUE
+ );
+--error ER_BAD_TABLE_ERROR
+drop table t1;
+
+# Create a table without partitions to test "EXPLAIN PARTITIONS"
+create table t1 (a varchar(10) charset latin1 collate latin1_bin);
+insert into t1 values (''),(' '),('a'),('a '),('a ');
+explain partitions select * from t1 where a='a ' OR a='a';
+drop table t1;
diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test
new file mode 100644
index 00000000000..11af7c691d8
--- /dev/null
+++ b/mysql-test/t/parser.test
@@ -0,0 +1,510 @@
+#
+# This file contains tests covering the parser
+#
+
+#=============================================================================
+# LEXICAL PARSER (lex)
+#=============================================================================
+
+SET @save_sql_mode=@@sql_mode;
+
+#
+# Documenting the current behavior, to detect incompatible changes.
+# In each cases:
+# - no error is the correct result
+# - an error is the expected result with the current implementation,
+# and is a limitation.
+
+set SQL_MODE='';
+
+create table ADDDATE(a int);
+drop table ADDDATE;
+create table ADDDATE (a int);
+drop table ADDDATE;
+
+--error ER_PARSE_ERROR
+create table BIT_AND(a int);
+create table BIT_AND (a int);
+drop table BIT_AND;
+
+--error ER_PARSE_ERROR
+create table BIT_OR(a int);
+create table BIT_OR (a int);
+drop table BIT_OR;
+
+--error ER_PARSE_ERROR
+create table BIT_XOR(a int);
+create table BIT_XOR (a int);
+drop table BIT_XOR;
+
+--error ER_PARSE_ERROR
+create table CAST(a int);
+create table CAST (a int);
+drop table CAST;
+
+--error ER_PARSE_ERROR
+create table COUNT(a int);
+create table COUNT (a int);
+drop table COUNT;
+
+--error ER_PARSE_ERROR
+create table CURDATE(a int);
+create table CURDATE (a int);
+drop table CURDATE;
+
+--error ER_PARSE_ERROR
+create table CURTIME(a int);
+create table CURTIME (a int);
+drop table CURTIME;
+
+--error ER_PARSE_ERROR
+create table DATE_ADD(a int);
+create table DATE_ADD (a int);
+drop table DATE_ADD;
+
+--error ER_PARSE_ERROR
+create table DATE_SUB(a int);
+create table DATE_SUB (a int);
+drop table DATE_SUB;
+
+--error ER_PARSE_ERROR
+create table EXTRACT(a int);
+create table EXTRACT (a int);
+drop table EXTRACT;
+
+--error ER_PARSE_ERROR
+create table GROUP_CONCAT(a int);
+create table GROUP_CONCAT (a int);
+drop table GROUP_CONCAT;
+
+--error ER_PARSE_ERROR
+create table GROUP_UNIQUE_USERS(a int);
+create table GROUP_UNIQUE_USERS (a int);
+drop table GROUP_UNIQUE_USERS;
+
+--error ER_PARSE_ERROR
+create table MAX(a int);
+create table MAX (a int);
+drop table MAX;
+
+--error ER_PARSE_ERROR
+create table MID(a int);
+create table MID (a int);
+drop table MID;
+
+--error ER_PARSE_ERROR
+create table MIN(a int);
+create table MIN (a int);
+drop table MIN;
+
+--error ER_PARSE_ERROR
+create table NOW(a int);
+create table NOW (a int);
+drop table NOW;
+
+--error ER_PARSE_ERROR
+create table POSITION(a int);
+create table POSITION (a int);
+drop table POSITION;
+
+create table SESSION_USER(a int);
+drop table SESSION_USER;
+create table SESSION_USER (a int);
+drop table SESSION_USER;
+
+--error ER_PARSE_ERROR
+create table STD(a int);
+create table STD (a int);
+drop table STD;
+
+--error ER_PARSE_ERROR
+create table STDDEV(a int);
+create table STDDEV (a int);
+drop table STDDEV;
+
+--error ER_PARSE_ERROR
+create table STDDEV_POP(a int);
+create table STDDEV_POP (a int);
+drop table STDDEV_POP;
+
+--error ER_PARSE_ERROR
+create table STDDEV_SAMP(a int);
+create table STDDEV_SAMP (a int);
+drop table STDDEV_SAMP;
+
+create table SUBDATE(a int);
+drop table SUBDATE;
+create table SUBDATE (a int);
+drop table SUBDATE;
+
+--error ER_PARSE_ERROR
+create table SUBSTR(a int);
+create table SUBSTR (a int);
+drop table SUBSTR;
+
+--error ER_PARSE_ERROR
+create table SUBSTRING(a int);
+create table SUBSTRING (a int);
+drop table SUBSTRING;
+
+--error ER_PARSE_ERROR
+create table SUM(a int);
+create table SUM (a int);
+drop table SUM;
+
+--error ER_PARSE_ERROR
+create table SYSDATE(a int);
+create table SYSDATE (a int);
+drop table SYSDATE;
+
+create table SYSTEM_USER(a int);
+drop table SYSTEM_USER;
+create table SYSTEM_USER (a int);
+drop table SYSTEM_USER;
+
+--error ER_PARSE_ERROR
+create table TRIM(a int);
+create table TRIM (a int);
+drop table TRIM;
+
+--error ER_PARSE_ERROR
+create table UNIQUE_USERS(a int);
+create table UNIQUE_USERS (a int);
+drop table UNIQUE_USERS;
+
+--error ER_PARSE_ERROR
+create table VARIANCE(a int);
+create table VARIANCE (a int);
+drop table VARIANCE;
+
+--error ER_PARSE_ERROR
+create table VAR_POP(a int);
+create table VAR_POP (a int);
+drop table VAR_POP;
+
+--error ER_PARSE_ERROR
+create table VAR_SAMP(a int);
+create table VAR_SAMP (a int);
+drop table VAR_SAMP;
+
+set SQL_MODE='IGNORE_SPACE';
+
+create table ADDDATE(a int);
+drop table ADDDATE;
+create table ADDDATE (a int);
+drop table ADDDATE;
+
+--error ER_PARSE_ERROR
+create table BIT_AND(a int);
+--error ER_PARSE_ERROR
+create table BIT_AND (a int);
+
+--error ER_PARSE_ERROR
+create table BIT_OR(a int);
+--error ER_PARSE_ERROR
+create table BIT_OR (a int);
+
+--error ER_PARSE_ERROR
+create table BIT_XOR(a int);
+--error ER_PARSE_ERROR
+create table BIT_XOR (a int);
+
+--error ER_PARSE_ERROR
+create table CAST(a int);
+--error ER_PARSE_ERROR
+create table CAST (a int);
+
+--error ER_PARSE_ERROR
+create table COUNT(a int);
+--error ER_PARSE_ERROR
+create table COUNT (a int);
+
+--error ER_PARSE_ERROR
+create table CURDATE(a int);
+--error ER_PARSE_ERROR
+create table CURDATE (a int);
+
+--error ER_PARSE_ERROR
+create table CURTIME(a int);
+--error ER_PARSE_ERROR
+create table CURTIME (a int);
+
+--error ER_PARSE_ERROR
+create table DATE_ADD(a int);
+--error ER_PARSE_ERROR
+create table DATE_ADD (a int);
+
+--error ER_PARSE_ERROR
+create table DATE_SUB(a int);
+--error ER_PARSE_ERROR
+create table DATE_SUB (a int);
+
+--error ER_PARSE_ERROR
+create table EXTRACT(a int);
+--error ER_PARSE_ERROR
+create table EXTRACT (a int);
+
+--error ER_PARSE_ERROR
+create table GROUP_CONCAT(a int);
+--error ER_PARSE_ERROR
+create table GROUP_CONCAT (a int);
+
+--error ER_PARSE_ERROR
+create table GROUP_UNIQUE_USERS(a int);
+--error ER_PARSE_ERROR
+create table GROUP_UNIQUE_USERS (a int);
+
+--error ER_PARSE_ERROR
+create table MAX(a int);
+--error ER_PARSE_ERROR
+create table MAX (a int);
+
+--error ER_PARSE_ERROR
+create table MID(a int);
+--error ER_PARSE_ERROR
+create table MID (a int);
+
+--error ER_PARSE_ERROR
+create table MIN(a int);
+--error ER_PARSE_ERROR
+create table MIN (a int);
+
+--error ER_PARSE_ERROR
+create table NOW(a int);
+--error ER_PARSE_ERROR
+create table NOW (a int);
+
+--error ER_PARSE_ERROR
+create table POSITION(a int);
+--error ER_PARSE_ERROR
+create table POSITION (a int);
+
+create table SESSION_USER(a int);
+drop table SESSION_USER;
+create table SESSION_USER (a int);
+drop table SESSION_USER;
+
+--error ER_PARSE_ERROR
+create table STD(a int);
+--error ER_PARSE_ERROR
+create table STD (a int);
+
+--error ER_PARSE_ERROR
+create table STDDEV(a int);
+--error ER_PARSE_ERROR
+create table STDDEV (a int);
+
+--error ER_PARSE_ERROR
+create table STDDEV_POP(a int);
+--error ER_PARSE_ERROR
+create table STDDEV_POP (a int);
+
+--error ER_PARSE_ERROR
+create table STDDEV_SAMP(a int);
+--error ER_PARSE_ERROR
+create table STDDEV_SAMP (a int);
+
+create table SUBDATE(a int);
+drop table SUBDATE;
+create table SUBDATE (a int);
+drop table SUBDATE;
+
+--error ER_PARSE_ERROR
+create table SUBSTR(a int);
+--error ER_PARSE_ERROR
+create table SUBSTR (a int);
+
+--error ER_PARSE_ERROR
+create table SUBSTRING(a int);
+--error ER_PARSE_ERROR
+create table SUBSTRING (a int);
+
+--error ER_PARSE_ERROR
+create table SUM(a int);
+--error ER_PARSE_ERROR
+create table SUM (a int);
+
+--error ER_PARSE_ERROR
+create table SYSDATE(a int);
+--error ER_PARSE_ERROR
+create table SYSDATE (a int);
+
+create table SYSTEM_USER(a int);
+drop table SYSTEM_USER;
+create table SYSTEM_USER (a int);
+drop table SYSTEM_USER;
+
+--error ER_PARSE_ERROR
+create table TRIM(a int);
+--error ER_PARSE_ERROR
+create table TRIM (a int);
+
+--error ER_PARSE_ERROR
+create table UNIQUE_USERS(a int);
+--error ER_PARSE_ERROR
+create table UNIQUE_USERS (a int);
+
+--error ER_PARSE_ERROR
+create table VARIANCE(a int);
+--error ER_PARSE_ERROR
+create table VARIANCE (a int);
+
+--error ER_PARSE_ERROR
+create table VAR_POP(a int);
+--error ER_PARSE_ERROR
+create table VAR_POP (a int);
+
+--error ER_PARSE_ERROR
+create table VAR_SAMP(a int);
+--error ER_PARSE_ERROR
+create table VAR_SAMP (a int);
+
+SET @@sql_mode=@save_sql_mode;
+
+#=============================================================================
+# SYNTACTIC PARSER (bison)
+#=============================================================================
+
+#
+#
+# Bug#21114 (Foreign key creation fails to table with name format)
+#
+
+# Test coverage with edge conditions
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select pi(3.14);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select tan();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select tan(1, 2);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select makedate(1);
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select makedate(1, 2, 3);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select maketime();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select maketime(1);
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select maketime(1, 2);
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select maketime(1, 2, 3, 4);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select atan();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select atan2(1, 2, 3);
+
+select benchmark(10, 1+1);
+
+-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT
+select benchmark(5+5, 2);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select concat();
+select concat("foo");
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select concat_ws();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select concat_ws("foo");
+
+set @pwd="my password";
+-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT
+select encode("secret", @pwd);
+-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT
+select decode("encoded-secret", @pwd);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select encrypt();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select encrypt(1, 2, 3);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select des_encrypt("p1", "p2", "not expected");
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select des_decrypt("p1", "p2", "not expected");
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select elt();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select elt(1);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select export_set();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select export_set("p1");
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select export_set("p1", "p2");
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select export_set("p1", "p2", "p3", "p4", "p5", "p6");
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select field();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select field("p1");
+
+set @dec=2;
+-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT
+select format(pi(), @dec);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select from_unixtime();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select from_unixtime(1, 2, 3);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select unix_timestamp(1, 2);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select greatest();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select greatest(12);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select last_insert_id(1, 2);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select least();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select least(12);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select locate();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select locate(1);
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select locate(1, 2, 3, 4);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select log();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select log(1, 2, 3);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select make_set();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select make_set(1);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select master_pos_wait();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select master_pos_wait(1);
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select master_pos_wait(1, 2, 3, 4);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select rand(1, 2, 3);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select round(1, 2, 3);
+
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select yearweek();
+-- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
+select yearweek(1, 2, 3);
+
diff --git a/mysql-test/t/parser_bug21114_innodb.test b/mysql-test/t/parser_bug21114_innodb.test
new file mode 100644
index 00000000000..969eea2da40
--- /dev/null
+++ b/mysql-test/t/parser_bug21114_innodb.test
@@ -0,0 +1,422 @@
+-- source include/have_innodb.inc
+
+let $engine_type=InnoDb;
+
+#
+# Bug#21114 (Foreign key creation fails to table with name format)
+#
+
+# Testing with the full log for only a few functions,
+# including FORMAT for witch the bug was reported.
+
+let $verbose=1;
+
+let $FCT=abs;
+-- source include/parser_bug21114.inc
+let $FCT=field;
+-- source include/parser_bug21114.inc
+let $FCT=format;
+-- source include/parser_bug21114.inc
+
+# Ignoring the result of SHOW CREATE (this generates too much noise)
+# Tests will fail if the create table statement can not be parsed
+
+let verbose=0;
+
+let $FCT=acos;
+-- source include/parser_bug21114.inc
+let $FCT=adddate;
+-- source include/parser_bug21114.inc
+let $FCT=addtime;
+-- source include/parser_bug21114.inc
+let $FCT=aes_decrypt;
+-- source include/parser_bug21114.inc
+let $FCT=aes_encrypt;
+-- source include/parser_bug21114.inc
+let $FCT=area;
+-- source include/parser_bug21114.inc
+let $FCT=asbinary;
+-- source include/parser_bug21114.inc
+let $FCT=asin;
+-- source include/parser_bug21114.inc
+let $FCT=astext;
+-- source include/parser_bug21114.inc
+let $FCT=aswkb;
+-- source include/parser_bug21114.inc
+let $FCT=aswkt;
+-- source include/parser_bug21114.inc
+let $FCT=atan;
+-- source include/parser_bug21114.inc
+let $FCT=atan2;
+-- source include/parser_bug21114.inc
+let $FCT=benchmark;
+-- source include/parser_bug21114.inc
+let $FCT=bin;
+-- source include/parser_bug21114.inc
+let $FCT=bit_count;
+-- source include/parser_bug21114.inc
+let $FCT=bit_length;
+-- source include/parser_bug21114.inc
+let $FCT=ceil;
+-- source include/parser_bug21114.inc
+let $FCT=ceiling;
+-- source include/parser_bug21114.inc
+let $FCT=centroid;
+-- source include/parser_bug21114.inc
+let $FCT=character_length;
+-- source include/parser_bug21114.inc
+let $FCT=char_length;
+-- source include/parser_bug21114.inc
+let $FCT=coercibility;
+-- source include/parser_bug21114.inc
+let $FCT=compress;
+-- source include/parser_bug21114.inc
+let $FCT=concat;
+-- source include/parser_bug21114.inc
+let $FCT=concat_ws;
+-- source include/parser_bug21114.inc
+let $FCT=connection_id;
+-- source include/parser_bug21114.inc
+let $FCT=conv;
+-- source include/parser_bug21114.inc
+let $FCT=convert_tz;
+-- source include/parser_bug21114.inc
+let $FCT=cos;
+-- source include/parser_bug21114.inc
+let $FCT=cot;
+-- source include/parser_bug21114.inc
+let $FCT=crc32;
+-- source include/parser_bug21114.inc
+let $FCT=crosses;
+-- source include/parser_bug21114.inc
+let $FCT=datediff;
+-- source include/parser_bug21114.inc
+let $FCT=date_format;
+-- source include/parser_bug21114.inc
+let $FCT=dayname;
+-- source include/parser_bug21114.inc
+let $FCT=dayofmonth;
+-- source include/parser_bug21114.inc
+let $FCT=dayofweek;
+-- source include/parser_bug21114.inc
+let $FCT=dayofyear;
+-- source include/parser_bug21114.inc
+let $FCT=decode;
+-- source include/parser_bug21114.inc
+let $FCT=degrees;
+-- source include/parser_bug21114.inc
+let $FCT=des_decrypt;
+-- source include/parser_bug21114.inc
+let $FCT=des_encrypt;
+-- source include/parser_bug21114.inc
+let $FCT=dimension;
+-- source include/parser_bug21114.inc
+let $FCT=disjoint;
+-- source include/parser_bug21114.inc
+let $FCT=elt;
+-- source include/parser_bug21114.inc
+let $FCT=encode;
+-- source include/parser_bug21114.inc
+let $FCT=encrypt;
+-- source include/parser_bug21114.inc
+let $FCT=endpoint;
+-- source include/parser_bug21114.inc
+let $FCT=envelope;
+-- source include/parser_bug21114.inc
+let $FCT=equals;
+-- source include/parser_bug21114.inc
+let $FCT=exp;
+-- source include/parser_bug21114.inc
+let $FCT=export_set;
+-- source include/parser_bug21114.inc
+let $FCT=exteriorring;
+-- source include/parser_bug21114.inc
+let $FCT=extractvalue;
+-- source include/parser_bug21114.inc
+let $FCT=find_in_set;
+-- source include/parser_bug21114.inc
+let $FCT=floor;
+-- source include/parser_bug21114.inc
+let $FCT=found_rows;
+-- source include/parser_bug21114.inc
+let $FCT=from_days;
+-- source include/parser_bug21114.inc
+let $FCT=from_unixtime;
+-- source include/parser_bug21114.inc
+let $FCT=geomcollfromtext;
+-- source include/parser_bug21114.inc
+let $FCT=geomcollfromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=geometrycollectionfromtext;
+-- source include/parser_bug21114.inc
+let $FCT=geometrycollectionfromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=geometryfromtext;
+-- source include/parser_bug21114.inc
+let $FCT=geometryfromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=geometryn;
+-- source include/parser_bug21114.inc
+let $FCT=geometrytype;
+-- source include/parser_bug21114.inc
+let $FCT=geomfromtext;
+-- source include/parser_bug21114.inc
+let $FCT=geomfromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=get_lock;
+-- source include/parser_bug21114.inc
+let $FCT=glength;
+-- source include/parser_bug21114.inc
+let $FCT=greatest;
+-- source include/parser_bug21114.inc
+let $FCT=hex;
+-- source include/parser_bug21114.inc
+let $FCT=ifnull;
+-- source include/parser_bug21114.inc
+let $FCT=inet_aton;
+-- source include/parser_bug21114.inc
+let $FCT=inet_ntoa;
+-- source include/parser_bug21114.inc
+let $FCT=instr;
+-- source include/parser_bug21114.inc
+let $FCT=interiorringn;
+-- source include/parser_bug21114.inc
+let $FCT=intersects;
+-- source include/parser_bug21114.inc
+let $FCT=isclosed;
+-- source include/parser_bug21114.inc
+let $FCT=isempty;
+-- source include/parser_bug21114.inc
+let $FCT=isnull;
+-- source include/parser_bug21114.inc
+let $FCT=issimple;
+-- source include/parser_bug21114.inc
+let $FCT=is_free_lock;
+-- source include/parser_bug21114.inc
+let $FCT=is_used_lock;
+-- source include/parser_bug21114.inc
+let $FCT=last_day;
+-- source include/parser_bug21114.inc
+let $FCT=last_insert_id;
+-- source include/parser_bug21114.inc
+let $FCT=lcase;
+-- source include/parser_bug21114.inc
+let $FCT=least;
+-- source include/parser_bug21114.inc
+let $FCT=length;
+-- source include/parser_bug21114.inc
+let $FCT=linefromtext;
+-- source include/parser_bug21114.inc
+let $FCT=linefromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=linestringfromtext;
+-- source include/parser_bug21114.inc
+let $FCT=linestringfromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=ln;
+-- source include/parser_bug21114.inc
+let $FCT=load_file;
+-- source include/parser_bug21114.inc
+let $FCT=locate;
+-- source include/parser_bug21114.inc
+let $FCT=log;
+-- source include/parser_bug21114.inc
+let $FCT=log10;
+-- source include/parser_bug21114.inc
+let $FCT=log2;
+-- source include/parser_bug21114.inc
+let $FCT=lower;
+-- source include/parser_bug21114.inc
+let $FCT=lpad;
+-- source include/parser_bug21114.inc
+let $FCT=ltrim;
+-- source include/parser_bug21114.inc
+let $FCT=makedate;
+-- source include/parser_bug21114.inc
+let $FCT=maketime;
+-- source include/parser_bug21114.inc
+let $FCT=make_set;
+-- source include/parser_bug21114.inc
+let $FCT=master_pos_wait;
+-- source include/parser_bug21114.inc
+let $FCT=mbrcontains;
+-- source include/parser_bug21114.inc
+let $FCT=mbrdisjoint;
+-- source include/parser_bug21114.inc
+let $FCT=mbrequal;
+-- source include/parser_bug21114.inc
+let $FCT=mbrintersects;
+-- source include/parser_bug21114.inc
+let $FCT=mbroverlaps;
+-- source include/parser_bug21114.inc
+let $FCT=mbrtouches;
+-- source include/parser_bug21114.inc
+let $FCT=mbrwithin;
+-- source include/parser_bug21114.inc
+let $FCT=md5;
+-- source include/parser_bug21114.inc
+let $FCT=mlinefromtext;
+-- source include/parser_bug21114.inc
+let $FCT=mlinefromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=monthname;
+-- source include/parser_bug21114.inc
+let $FCT=mpointfromtext;
+-- source include/parser_bug21114.inc
+let $FCT=mpointfromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=mpolyfromtext;
+-- source include/parser_bug21114.inc
+let $FCT=mpolyfromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=multilinestringfromtext;
+-- source include/parser_bug21114.inc
+let $FCT=multilinestringfromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=multipointfromtext;
+-- source include/parser_bug21114.inc
+let $FCT=multipointfromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=multipolygonfromtext;
+-- source include/parser_bug21114.inc
+let $FCT=multipolygonfromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=name_const;
+-- source include/parser_bug21114.inc
+let $FCT=nullif;
+-- source include/parser_bug21114.inc
+let $FCT=numgeometries;
+-- source include/parser_bug21114.inc
+let $FCT=numinteriorrings;
+-- source include/parser_bug21114.inc
+let $FCT=numpoints;
+-- source include/parser_bug21114.inc
+let $FCT=oct;
+-- source include/parser_bug21114.inc
+let $FCT=octet_length;
+-- source include/parser_bug21114.inc
+let $FCT=ord;
+-- source include/parser_bug21114.inc
+let $FCT=overlaps;
+-- source include/parser_bug21114.inc
+let $FCT=period_add;
+-- source include/parser_bug21114.inc
+let $FCT=period_diff;
+-- source include/parser_bug21114.inc
+let $FCT=pi;
+-- source include/parser_bug21114.inc
+let $FCT=pointfromtext;
+-- source include/parser_bug21114.inc
+let $FCT=pointfromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=pointn;
+-- source include/parser_bug21114.inc
+let $FCT=polyfromtext;
+-- source include/parser_bug21114.inc
+let $FCT=polyfromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=polygonfromtext;
+-- source include/parser_bug21114.inc
+let $FCT=polygonfromwkb;
+-- source include/parser_bug21114.inc
+let $FCT=pow;
+-- source include/parser_bug21114.inc
+let $FCT=power;
+-- source include/parser_bug21114.inc
+let $FCT=quote;
+-- source include/parser_bug21114.inc
+let $FCT=radians;
+-- source include/parser_bug21114.inc
+let $FCT=rand;
+-- source include/parser_bug21114.inc
+let $FCT=release_lock;
+-- source include/parser_bug21114.inc
+let $FCT=reverse;
+-- source include/parser_bug21114.inc
+let $FCT=round;
+-- source include/parser_bug21114.inc
+let $FCT=row_count;
+-- source include/parser_bug21114.inc
+let $FCT=rpad;
+-- source include/parser_bug21114.inc
+let $FCT=rtrim;
+-- source include/parser_bug21114.inc
+let $FCT=sec_to_time;
+-- source include/parser_bug21114.inc
+let $FCT=session_user;
+-- source include/parser_bug21114.inc
+let $FCT=sha;
+-- source include/parser_bug21114.inc
+let $FCT=sha1;
+-- source include/parser_bug21114.inc
+let $FCT=sign;
+-- source include/parser_bug21114.inc
+let $FCT=sin;
+-- source include/parser_bug21114.inc
+let $FCT=sleep;
+-- source include/parser_bug21114.inc
+let $FCT=soundex;
+-- source include/parser_bug21114.inc
+let $FCT=space;
+-- source include/parser_bug21114.inc
+let $FCT=sqrt;
+-- source include/parser_bug21114.inc
+let $FCT=srid;
+-- source include/parser_bug21114.inc
+let $FCT=startpoint;
+-- source include/parser_bug21114.inc
+let $FCT=strcmp;
+-- source include/parser_bug21114.inc
+let $FCT=str_to_date;
+-- source include/parser_bug21114.inc
+let $FCT=subdate;
+-- source include/parser_bug21114.inc
+let $FCT=substring_index;
+-- source include/parser_bug21114.inc
+let $FCT=subtime;
+-- source include/parser_bug21114.inc
+let $FCT=system_user;
+-- source include/parser_bug21114.inc
+let $FCT=tan;
+-- source include/parser_bug21114.inc
+let $FCT=timediff;
+-- source include/parser_bug21114.inc
+let $FCT=time_format;
+-- source include/parser_bug21114.inc
+let $FCT=time_to_sec;
+-- source include/parser_bug21114.inc
+let $FCT=touches;
+-- source include/parser_bug21114.inc
+let $FCT=to_days;
+-- source include/parser_bug21114.inc
+let $FCT=ucase;
+-- source include/parser_bug21114.inc
+let $FCT=uncompress;
+-- source include/parser_bug21114.inc
+let $FCT=uncompressed_length;
+-- source include/parser_bug21114.inc
+let $FCT=unhex;
+-- source include/parser_bug21114.inc
+let $FCT=unix_timestamp;
+-- source include/parser_bug21114.inc
+let $FCT=updatexml;
+-- source include/parser_bug21114.inc
+let $FCT=upper;
+-- source include/parser_bug21114.inc
+let $FCT=uuid;
+-- source include/parser_bug21114.inc
+let $FCT=version;
+-- source include/parser_bug21114.inc
+let $FCT=weekday;
+-- source include/parser_bug21114.inc
+let $FCT=weekofyear;
+-- source include/parser_bug21114.inc
+let $FCT=within;
+-- source include/parser_bug21114.inc
+let $FCT=x;
+-- source include/parser_bug21114.inc
+let $FCT=y;
+-- source include/parser_bug21114.inc
+let $FCT=yearweek;
+-- source include/parser_bug21114.inc
+
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index 42fd0426d01..8cb5e76d85b 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -4,6 +4,7 @@
# Taken fromm the select test
#
-- source include/have_partition.inc
+
#
# This test is disabled on Windows due to BUG#19107
#
@@ -1286,37 +1287,51 @@ eval SET @inx_dir = 'INDEX DIRECTORY = ''$MYSQLTEST_VARDIR/master-data/tmpinx'''
let $inx_directory = `select @inx_dir`;
--enable_query_log
---replace_result $MYSQLTEST_VARDIR "hello"
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval create table t1 (a int) engine myisam
partition by range (a)
subpartition by hash (a)
(partition p0 VALUES LESS THAN (1) $data_directory $inx_directory
(SUBPARTITION subpart00, SUBPARTITION subpart01));
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/test/t1.* || true
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/test/t1#* || true
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/tmpdata/t1#* || true
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/tmpinx/t1#* || true
---replace_result $MYSQLTEST_VARDIR "hello"
-
+--echo Checking if file exists before alter
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1.frm
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1.par
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart00.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart00.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart01.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart01.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p0#SP#subpart00.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p0#SP#subpart01.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p0#SP#subpart00.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p0#SP#subpart01.MYI
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval ALTER TABLE t1 REORGANIZE PARTITION p0 INTO
(partition p1 VALUES LESS THAN (1) $data_directory $inx_directory
(SUBPARTITION subpart10, SUBPARTITION subpart11),
partition p2 VALUES LESS THAN (2) $data_directory $inx_directory
(SUBPARTITION subpart20, SUBPARTITION subpart21));
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/test/t1.* || true
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/test/t1#* || true
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/tmpdata/t1#* || true
---replace_result $MYSQLTEST_VARDIR "hello"
---exec ls $MYSQLTEST_VARDIR/master-data/tmpinx/t1#* || true
+--echo Checking if file exists after alter
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1.frm
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1.par
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p1#SP#subpart10.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p1#SP#subpart10.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p1#SP#subpart11.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p1#SP#subpart11.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart20.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart20.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart21.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart21.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p1#SP#subpart10.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p1#SP#subpart11.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p2#SP#subpart20.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p2#SP#subpart21.MYD
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p1#SP#subpart10.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p1#SP#subpart11.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p2#SP#subpart20.MYI
+--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p2#SP#subpart21.MYI
drop table t1;
--exec rmdir $MYSQLTEST_VARDIR/master-data/tmpdata || true
diff --git a/mysql-test/t/ps-master.opt b/mysql-test/t/ps-master.opt
new file mode 100644
index 00000000000..3eb98fc3d6b
--- /dev/null
+++ b/mysql-test/t/ps-master.opt
@@ -0,0 +1 @@
+--log-slow-queries --log-long-format --log-queries-not-using-indexes
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 902d8fcd9d8..1a19355406a 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -523,8 +523,9 @@ deallocate prepare stmt;
#
create table t1 (a varchar(20));
insert into t1 values ('foo');
---error 1305
prepare stmt FROM 'SELECT char_length (a) FROM t1';
+-- error ER_SP_DOES_NOT_EXIST
+prepare stmt2 FROM 'SELECT not_a_function (a) FROM t1';
drop table t1;
#
@@ -988,6 +989,7 @@ execute stmt;
drop temporary table t1;
deallocate prepare stmt;
+
#
# BUG#22085: Crash on the execution of a prepared statement that
# uses an IN subquery with aggregate functions in HAVING
@@ -1040,7 +1042,81 @@ EXECUTE STMT USING @id,@id;
DEALLOCATE PREPARE STMT;
DROP TABLE t1;
---echo End of 4.1 tests
+#
+# BUG#21354: (COUNT(*) = 1) not working in SELECT inside prepared
+# statement
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (i INT, INDEX(i));
+INSERT INTO t1 VALUES (1);
+
+PREPARE stmt FROM "SELECT (COUNT(i) = 1), COUNT(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+SET @a = 1;
+EXECUTE stmt USING @a;
+SET @a = 0;
+EXECUTE stmt USING @a;
+
+PREPARE stmt FROM "SELECT (AVG(i) = 1), AVG(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+SET @a = 1;
+EXECUTE stmt USING @a;
+SET @a = 0;
+EXECUTE stmt USING @a;
+
+PREPARE stmt FROM "SELECT (VARIANCE(i) = 1), VARIANCE(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+SET @a = 1;
+EXECUTE stmt USING @a;
+SET @a = 0;
+EXECUTE stmt USING @a;
+
+PREPARE stmt FROM "SELECT (STDDEV(i) = 1), STDDEV(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+SET @a = 1;
+EXECUTE stmt USING @a;
+SET @a = 0;
+EXECUTE stmt USING @a;
+
+PREPARE stmt FROM "SELECT (BIT_OR(i) = 1), BIT_OR(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+SET @a = 1;
+EXECUTE stmt USING @a;
+SET @a = 0;
+EXECUTE stmt USING @a;
+
+PREPARE stmt FROM "SELECT (BIT_AND(i) = 1), BIT_AND(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+SET @a = 1;
+EXECUTE stmt USING @a;
+SET @a = 0;
+EXECUTE stmt USING @a;
+
+PREPARE stmt FROM "SELECT (BIT_XOR(i) = 1), BIT_XOR(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+SET @a = 1;
+EXECUTE stmt USING @a;
+SET @a = 0;
+EXECUTE stmt USING @a;
+
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+
+
+--echo End of 4.1 tests.
+
+
+
############################# 5.0 tests start ################################
#
#
@@ -1051,8 +1127,9 @@ DROP TABLE t1;
#
create table t1 (a varchar(20));
insert into t1 values ('foo');
---error 1305
prepare stmt FROM 'SELECT char_length (a) FROM t1';
+-- error ER_SP_DOES_NOT_EXIST
+prepare stmt2 FROM 'SELECT not_a_function (a) FROM t1';
drop table t1;
#
@@ -1437,6 +1514,39 @@ DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2;
+#
+# BUG#21856: Prepared Statments: crash if bad create
+#
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1;
+--enable_warnings
+
+let $iterations= 100;
+--disable_query_log
+--disable_result_log
+while ($iterations > 0)
+{
+ --error ER_PARSE_ERROR
+ PREPARE stmt FROM "CREATE PROCEDURE p1()";
+ dec $iterations;
+}
+--enable_query_log
+--enable_result_log
+
+#
+# Bug 19764: SHOW commands end up in the slow log as table scans
+#
+
+flush status;
+prepare sq from 'show status like "slow_queries"';
+execute sq;
+prepare no_index from 'select 1 from information_schema.tables limit 1';
+execute sq;
+execute no_index;
+execute sq;
+deallocate prepare no_index;
+deallocate prepare sq;
+
--echo End of 5.0 tests.
#
diff --git a/mysql-test/t/ps_11bugs.test b/mysql-test/t/ps_11bugs.test
index ff1c87f3bd8..515bcc03c1a 100644
--- a/mysql-test/t/ps_11bugs.test
+++ b/mysql-test/t/ps_11bugs.test
@@ -144,3 +144,37 @@ prepare st_18492 from 'select * from t1 where 3 in (select (1+1) union select 1)
execute st_18492;
drop table t1;
+
+#
+# Bug#19356: Assertion failure with undefined @uservar in prepared statement execution
+#
+create table t1 (a int, b varchar(4));
+create table t2 (a int, b varchar(4), primary key(a));
+
+prepare stmt1 from 'insert into t1 (a, b) values (?, ?)';
+prepare stmt2 from 'insert into t2 (a, b) values (?, ?)';
+
+set @intarg= 11;
+set @varchararg= '2222';
+execute stmt1 using @intarg, @varchararg;
+execute stmt2 using @intarg, @varchararg;
+set @intarg= 12;
+execute stmt1 using @intarg, @UNDEFINED;
+execute stmt2 using @intarg, @UNDEFINED;
+set @intarg= 13;
+execute stmt1 using @UNDEFINED, @varchararg;
+--error 1048
+execute stmt2 using @UNDEFINED, @varchararg;
+set @intarg= 14;
+set @nullarg= Null;
+execute stmt1 using @UNDEFINED, @nullarg;
+--error 1048
+execute stmt2 using @nullarg, @varchararg;
+
+select * from t1;
+select * from t2;
+
+drop table t1;
+drop table t2;
+
+--echo End of 5.0 tests.
diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test
index c0b81796731..4c0f411c758 100644
--- a/mysql-test/t/ps_1general.test
+++ b/mysql-test/t/ps_1general.test
@@ -316,8 +316,8 @@ prepare stmt4 from ' show table status from test like ''t9%'' ';
--replace_column 8 # 12 # 13 # 14 #
# Bug#4288
execute stmt4;
---replace_column 2 #
prepare stmt4 from ' show status like ''Threads_running'' ';
+--replace_column 2 #
execute stmt4;
prepare stmt4 from ' show variables like ''sql_mode'' ';
execute stmt4;
diff --git a/mysql-test/t/ps_grant.test b/mysql-test/t/ps_grant.test
index 4c48b4d151f..b25facdb418 100644
--- a/mysql-test/t/ps_grant.test
+++ b/mysql-test/t/ps_grant.test
@@ -35,7 +35,7 @@ use mysqltest;
--source include/ps_create.inc
--source include/ps_renew.inc
--enable_query_log
-eval use $DB;
+use test;
grant usage on mysqltest.* to second_user@localhost
identified by 'looser' ;
grant select on mysqltest.t9 to second_user@localhost
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index 2c94fe63c04..67c4c4cb20b 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -699,7 +699,7 @@ select a from t1;
flush query cache;
drop table t1, t2;
-set GLOBAL query_cache_size=1355776
+set GLOBAL query_cache_size=1355776;
#
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index 1a80234e485..400e28c3e28 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -515,7 +515,17 @@ OR ((pk4 =1) AND (((pk1 IN ( 7, 2, 1 ))) OR (pk1 =522)) AND ((pk2 IN ( 0, 2635))
) AND (pk3 >=1000000);
drop table t1, t2;
-# End of 4.1 tests
+#
+# Bug #20732: Partial index and long sjis search with '>' fails sometimes
+#
+
+create table t1(a char(2), key(a(1)));
+insert into t1 values ('x'), ('xx');
+explain select a from t1 where a > 'x';
+select a from t1 where a > 'x';
+drop table t1;
+
+--echo End of 4.1 tests
#
# Test for optimization request #10561: to use keys for
diff --git a/mysql-test/t/rename.test b/mysql-test/t/rename.test
index 054b1bd3403..09a02344203 100644
--- a/mysql-test/t/rename.test
+++ b/mysql-test/t/rename.test
@@ -43,8 +43,8 @@ select * from t3;
drop table if exists t1,t2,t3,t4;
#
-# Test-case for Bug #2397 RENAME TABLES is not blocked by
-# FLUSH TABLES WITH READ LOCK
+# Bug #2397 RENAME TABLES is not blocked by
+# FLUSH TABLES WITH READ LOCK
#
connect (con1,localhost,root,,);
@@ -58,12 +58,17 @@ FLUSH TABLES WITH READ LOCK;
connection con1;
send RENAME TABLE t1 TO t2, t3 to t4;
connection con2;
-sleep 1;
show tables;
UNLOCK TABLES;
connection con1;
reap;
connection con2;
+
+# Wait for the the tables to be renamed
+# i.e the query below succeds
+let $query= select * from t2, t4;
+source include/wait_for_query_to_suceed.inc;
+
show tables;
drop table t2, t4;
@@ -72,6 +77,10 @@ disconnect con2;
disconnect con1;
connection default;
+
+--echo End of 4.1 tests
+
+
#
# Bug#14959: ALTER TABLE isn't able to rename a view
#
@@ -85,4 +94,6 @@ rename table v2 to v1;
rename table v2 to v1;
drop view v1;
drop table t1;
-# End of 4.1 tests
+
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/rpl_dual_pos_advance-master.opt b/mysql-test/t/rpl_dual_pos_advance-master.opt
index 35fcc5f30c6..cef79bc8585 100644
--- a/mysql-test/t/rpl_dual_pos_advance-master.opt
+++ b/mysql-test/t/rpl_dual_pos_advance-master.opt
@@ -1 +1 @@
---loose-to-force-a-restart
+--force-restart
diff --git a/mysql-test/t/rpl_empty_master_crash-master.opt b/mysql-test/t/rpl_empty_master_crash-master.opt
new file mode 100644
index 00000000000..cef79bc8585
--- /dev/null
+++ b/mysql-test/t/rpl_empty_master_crash-master.opt
@@ -0,0 +1 @@
+--force-restart
diff --git a/mysql-test/t/rpl_ndb_auto_inc.test b/mysql-test/t/rpl_ndb_auto_inc.test
index 0fc31de9b3a..53bb7e764f1 100644
--- a/mysql-test/t/rpl_ndb_auto_inc.test
+++ b/mysql-test/t/rpl_ndb_auto_inc.test
@@ -6,6 +6,7 @@
# Date: 2006-02-10
# Change: Augmented test to use with cluster
#####################################
+--source include/have_ndb.inc
--source include/master-slave.inc
--source include/have_binlog_format_mixed_or_row.inc
diff --git a/mysql-test/t/rpl_slave_status.test b/mysql-test/t/rpl_slave_status.test
index a4a276b63d6..f98cc7a7d14 100644
--- a/mysql-test/t/rpl_slave_status.test
+++ b/mysql-test/t/rpl_slave_status.test
@@ -19,7 +19,7 @@ start slave;
connection master;
--disable_warnings
drop table if exists t1;
---enable_warning
+--enable_warnings
create table t1 (n int);
insert into t1 values (1);
save_master_pos;
diff --git a/mysql-test/t/rpl_stm_log-master.opt b/mysql-test/t/rpl_stm_log-master.opt
index e0d075c3fbd..cef79bc8585 100644
--- a/mysql-test/t/rpl_stm_log-master.opt
+++ b/mysql-test/t/rpl_stm_log-master.opt
@@ -1 +1 @@
---skip-external-locking
+--force-restart
diff --git a/mysql-test/t/rpl_trigger.test b/mysql-test/t/rpl_trigger.test
index 279574a8aaa..6ec0021635a 100644
--- a/mysql-test/t/rpl_trigger.test
+++ b/mysql-test/t/rpl_trigger.test
@@ -70,7 +70,7 @@ select get_lock("bug12480",2);
connection default;
create table t1 (a datetime,b datetime, c datetime);
---ignore_warnings
+--disable_warnings
drop function if exists bug12480;
--enable_warnings
diff --git a/mysql-test/t/rpl_truncate_7ndb.test b/mysql-test/t/rpl_truncate_7ndb.test
index b0d4bdfc763..1d69eee5dd0 100644
--- a/mysql-test/t/rpl_truncate_7ndb.test
+++ b/mysql-test/t/rpl_truncate_7ndb.test
@@ -39,6 +39,7 @@ SELECT * FROM t1 ORDER BY a,b;
--echo **** On Master ****
connection master;
DROP TABLE t1;
+let SERVER_VERSION=`select version()`;
--replace_regex /\/\* xid=[0-9]+ \*\//\/* xid= *\// /table_id: [0-9]+/table_id: #/
--replace_result $SERVER_VERSION SERVER_VERSION
SHOW BINLOG EVENTS;
diff --git a/mysql-test/t/show_check-master.opt b/mysql-test/t/show_check-master.opt
new file mode 100644
index 00000000000..3eb98fc3d6b
--- /dev/null
+++ b/mysql-test/t/show_check-master.opt
@@ -0,0 +1 @@
+--log-slow-queries --log-long-format --log-queries-not-using-indexes
diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test
index 553b3d9059b..7d4ad099e6f 100644
--- a/mysql-test/t/show_check.test
+++ b/mysql-test/t/show_check.test
@@ -501,7 +501,19 @@ SHOW TABLES FROM no_such_database;
--error ER_NO_SUCH_TABLE
SHOW COLUMNS FROM no_such_table;
-# End of 5.0 tests.
+
+#
+# Bug #19764: SHOW commands end up in the slow log as table scans
+#
+flush status;
+show status like 'slow_queries';
+show tables;
+show status like 'slow_queries';
+# Table scan query, to ensure that slow_queries does still get incremented
+# (mysqld is started with --log-queries-not-using-indexes)
+select 1 from information_schema.tables limit 1;
+show status like 'slow_queries';
+
--echo End of 5.0 tests.
--disable_result_log
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index e829a71c45a..456a23123d3 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -319,7 +319,7 @@ begin
declare x int;
end|
---error 1332
+--error 1332
create procedure p()
begin
declare c condition for 1064;
@@ -1748,6 +1748,8 @@ drop function if exists bug16896;
--error ER_SP_NO_AGGREGATE
create aggregate function bug16896() returns int return 1;
+#
+#
# BUG#14702: misleading error message when syntax error in CREATE
# PROCEDURE
#
@@ -1770,6 +1772,47 @@ END;
#
+# BUG#20953: create proc with a create view that uses local
+# vars/params should fail to create
+#
+# See test case for what syntax is forbidden in a view.
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (i INT);
+
+# We do not have to drop this procedure and view because they won't be
+# created.
+--error ER_VIEW_SELECT_CLAUSE
+CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO @a;
+--error ER_VIEW_SELECT_CLAUSE
+CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO DUMPFILE "file";
+--error ER_VIEW_SELECT_CLAUSE
+CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO OUTFILE "file";
+--error ER_VIEW_SELECT_CLAUSE
+CREATE PROCEDURE bug20953()
+ CREATE VIEW v AS SELECT i FROM t1 PROCEDURE ANALYSE();
+--error ER_VIEW_SELECT_DERIVED
+CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 FROM (SELECT 1) AS d1;
+--error ER_VIEW_SELECT_VARIABLE
+CREATE PROCEDURE bug20953(i INT) CREATE VIEW v AS SELECT i;
+delimiter |;
+--error ER_VIEW_SELECT_VARIABLE
+CREATE PROCEDURE bug20953()
+BEGIN
+ DECLARE i INT;
+ CREATE VIEW v AS SELECT i;
+END |
+delimiter ;|
+--error ER_VIEW_SELECT_VARIABLE
+PREPARE stmt FROM "CREATE VIEW v AS SELECT ?";
+
+DROP TABLE t1;
+
+
+#
# End of 5.0 tests
#
--echo End of 5.0 tests
@@ -1788,12 +1831,14 @@ begin
show authors;
return 42;
end|
+delimiter ;|
+
#
# BUG#20701: BINARY keyword should be forbidden in stored routines
#
--disable_warnings
-drop function if exists bug20701|
+drop function if exists bug20701;
--enable_warnings
#
# This was disabled in 5.1.12. See bug #20701
@@ -1801,17 +1846,19 @@ drop function if exists bug20701|
# be removed.
#
--error ER_NOT_SUPPORTED_YET
-create function bug20701() returns varchar(25) binary return "test"|
-create function bug20701() returns varchar(25) return "test"|
-drop function bug20701|
+create function bug20701() returns varchar(25) binary return "test";
+create function bug20701() returns varchar(25) return "test";
+drop function bug20701;
+
+
--echo End of 5.1 tests
#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
-#drop procedure if exists bugNNNN|
-#drop function if exists bugNNNN|
+#drop procedure if exists bugNNNN;
+#drop function if exists bugNNNN;
#--enable_warnings
#create procedure bugNNNN...
#create function bugNNNN...
diff --git a/mysql-test/t/sp-vars.test b/mysql-test/t/sp-vars.test
index 48dbd4de7aa..7cf92dc5d0d 100644
--- a/mysql-test/t/sp-vars.test
+++ b/mysql-test/t/sp-vars.test
@@ -15,6 +15,7 @@ DROP FUNCTION IF EXISTS sp_vars_check_ret1;
DROP FUNCTION IF EXISTS sp_vars_check_ret2;
DROP FUNCTION IF EXISTS sp_vars_check_ret3;
DROP FUNCTION IF EXISTS sp_vars_check_ret4;
+DROP FUNCTION IF EXISTS sp_vars_div_zero;
--enable_warnings
@@ -49,6 +50,8 @@ SELECT sp_vars_check_ret3();
SELECT sp_vars_check_ret4();
+SELECT sp_vars_div_zero();
+
# Check that changing sql_mode after creating a store procedure does not
# matter.
@@ -72,6 +75,8 @@ SELECT sp_vars_check_ret3();
SELECT sp_vars_check_ret4();
+SELECT sp_vars_div_zero();
+
# Create the procedure in TRADITIONAL mode. Check that error will be thrown on
# execution.
@@ -81,6 +86,7 @@ DROP FUNCTION sp_vars_check_ret1;
DROP FUNCTION sp_vars_check_ret2;
DROP FUNCTION sp_vars_check_ret3;
DROP FUNCTION sp_vars_check_ret4;
+DROP FUNCTION sp_vars_div_zero;
--source include/sp-vars.inc
@@ -110,6 +116,9 @@ SELECT sp_vars_check_ret3();
SELECT sp_vars_check_ret4();
+--error ER_DIVISION_BY_ZERO
+SELECT sp_vars_div_zero();
+
SET @@sql_mode = 'ansi';
#
@@ -122,6 +131,7 @@ DROP FUNCTION sp_vars_check_ret1;
DROP FUNCTION sp_vars_check_ret2;
DROP FUNCTION sp_vars_check_ret3;
DROP FUNCTION sp_vars_check_ret4;
+DROP FUNCTION sp_vars_div_zero;
###########################################################################
#
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index b3563e21bdd..bb18c0e5858 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -2940,11 +2940,11 @@ begin
end|
--disable_parsing
--replace_regex /table_id: [0-9]+/table_id: #/
-show binlog events;
-show storage engines;
-show master status;
-show slave hosts;
-show slave status;
+show binlog events|
+show storage engines|
+show master status|
+show slave hosts|
+show slave status|
--enable_parsing
call bug4902()|
@@ -6419,6 +6419,170 @@ SELECT bug21493(Member_ID) FROM t3|
DROP FUNCTION bug21493|
DROP TABLE t3,t4|
+#
+# Bug#20028 Function with select return no data
+#
+
+--disable_warnings
+drop function if exists func_20028_a|
+drop function if exists func_20028_b|
+drop function if exists func_20028_c|
+drop procedure if exists proc_20028_a|
+drop procedure if exists proc_20028_b|
+drop procedure if exists proc_20028_c|
+drop table if exists table_20028|
+--enable_warnings
+
+create table table_20028 (i int)|
+
+SET @save_sql_mode=@@sql_mode|
+
+SET sql_mode=''|
+
+create function func_20028_a() returns integer
+begin
+ declare temp integer;
+ select i into temp from table_20028 limit 1;
+ return ifnull(temp, 0);
+end|
+
+create function func_20028_b() returns integer
+begin
+ return func_20028_a();
+end|
+
+create function func_20028_c() returns integer
+begin
+ declare div_zero integer;
+ set SQL_MODE='TRADITIONAL';
+ select 1/0 into div_zero;
+ return div_zero;
+end|
+
+create procedure proc_20028_a()
+begin
+ declare temp integer;
+ select i into temp from table_20028 limit 1;
+end|
+
+create procedure proc_20028_b()
+begin
+ call proc_20028_a();
+end|
+
+create procedure proc_20028_c()
+begin
+ declare div_zero integer;
+ set SQL_MODE='TRADITIONAL';
+ select 1/0 into div_zero;
+end|
+
+select func_20028_a()|
+select func_20028_b()|
+--error ER_DIVISION_BY_ZERO
+select func_20028_c()|
+call proc_20028_a()|
+call proc_20028_b()|
+--error ER_DIVISION_BY_ZERO
+call proc_20028_c()|
+
+SET sql_mode='TRADITIONAL'|
+
+drop function func_20028_a|
+drop function func_20028_b|
+drop function func_20028_c|
+drop procedure proc_20028_a|
+drop procedure proc_20028_b|
+drop procedure proc_20028_c|
+
+create function func_20028_a() returns integer
+begin
+ declare temp integer;
+ select i into temp from table_20028 limit 1;
+ return ifnull(temp, 0);
+end|
+
+create function func_20028_b() returns integer
+begin
+ return func_20028_a();
+end|
+
+create function func_20028_c() returns integer
+begin
+ declare div_zero integer;
+ set SQL_MODE='';
+ select 1/0 into div_zero;
+ return div_zero;
+end|
+
+create procedure proc_20028_a()
+begin
+ declare temp integer;
+ select i into temp from table_20028 limit 1;
+end|
+
+create procedure proc_20028_b()
+begin
+ call proc_20028_a();
+end|
+
+create procedure proc_20028_c()
+begin
+ declare div_zero integer;
+ set SQL_MODE='';
+ select 1/0 into div_zero;
+end|
+
+select func_20028_a()|
+select func_20028_b()|
+select func_20028_c()|
+call proc_20028_a()|
+call proc_20028_b()|
+call proc_20028_c()|
+
+SET @@sql_mode=@save_sql_mode|
+
+drop function func_20028_a|
+drop function func_20028_b|
+drop function func_20028_c|
+drop procedure proc_20028_a|
+drop procedure proc_20028_b|
+drop procedure proc_20028_c|
+drop table table_20028|
+
+#
+# Bug#21462 Stored procedures with no arguments require parenthesis
+#
+
+--disable_warnings
+drop procedure if exists proc_21462_a|
+drop procedure if exists proc_21462_b|
+--enable_warnings
+
+create procedure proc_21462_a()
+begin
+ select "Called A";
+end|
+
+create procedure proc_21462_b(x int)
+begin
+ select "Called B";
+end|
+
+call proc_21462_a|
+call proc_21462_a()|
+-- error ER_SP_WRONG_NO_OF_ARGS
+call proc_21462_a(1)|
+
+-- error ER_SP_WRONG_NO_OF_ARGS
+call proc_21462_b|
+-- error ER_SP_WRONG_NO_OF_ARGS
+call proc_21462_b()|
+call proc_21462_b(1)|
+
+drop procedure proc_21462_a|
+drop procedure proc_21462_b|
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/sp_notembedded.test b/mysql-test/t/sp_notembedded.test
index 28abf448089..6335ad55606 100644
--- a/mysql-test/t/sp_notembedded.test
+++ b/mysql-test/t/sp_notembedded.test
@@ -19,11 +19,11 @@ begin
show grants for 'root'@'localhost';
end|
--disable_parsing
-show binlog events;
-show storage engines;
-show master status;
-show slave hosts;
-show slave status;
+show binlog events|
+show storage engines|
+show master status|
+show slave hosts|
+show slave status|
--enable_parsing
call bug4902()|
@@ -110,7 +110,7 @@ flush status|
flush query cache|
delete from t1|
drop procedure bug3583|
-drop table t1;
+drop table t1|
#
# BUG#6807: Stored procedure crash if CREATE PROCEDURE ... KILL QUERY
diff --git a/mysql-test/t/ssl_des-master.opt b/mysql-test/t/ssl_des-master.opt
new file mode 100644
index 00000000000..0b2b8cb85ac
--- /dev/null
+++ b/mysql-test/t/ssl_des-master.opt
@@ -0,0 +1 @@
+--loose_ssl-cert=std_data/server-cert-des.pem --loose_ssl-key=std_data/server-key-des.pem
diff --git a/mysql-test/t/ssl_des.test b/mysql-test/t/ssl_des.test
new file mode 100644
index 00000000000..7cf2c920ab5
--- /dev/null
+++ b/mysql-test/t/ssl_des.test
@@ -0,0 +1,19 @@
+# Tell the server to use a DES-encrypted cert
+# then turn on ssl between the client and server
+# and run a number of standard tests
+
+-- source include/have_openssl.inc
+
+# Connect by ip to avoid turning on "ssl-verify-server-cert"
+connect (ssl_con,127.0.0.1,root,,,,$MASTER_MYPORT,SSL);
+
+# Check ssl turned on
+SHOW STATUS LIKE 'Ssl_cipher';
+
+# Source select test case
+-- source include/common-tests.inc
+
+# Check ssl turned on
+SHOW STATUS LIKE 'Ssl_cipher';
+
+
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 6d5082c360b..dee5b1e4fb0 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -1728,7 +1728,7 @@ select (select a from t1) = (1,2);
select (1,2,3) = (select * from t1);
-- error 1241
select (select * from t1) = (1,2,3);
-drop table t1
+drop table t1;
#
# Item_int_with_ref check (BUG#10020)
diff --git a/mysql-test/t/system_mysql_db_fix.test b/mysql-test/t/system_mysql_db_fix.test
index daba3b6ff86..3956e26e9cc 100644
--- a/mysql-test/t/system_mysql_db_fix.test
+++ b/mysql-test/t/system_mysql_db_fix.test
@@ -42,7 +42,7 @@ CREATE TABLE db (
KEY User (User)
)
engine=MyISAM;
---enable-warnings
+--enable_warnings
INSERT INTO db VALUES ('%','test', '','Y','Y','Y','Y','Y','Y');
INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y');
@@ -60,7 +60,7 @@ CREATE TABLE host (
PRIMARY KEY Host (Host,Db)
)
engine=MyISAM;
---enable-warnings
+--enable_warnings
--disable_warnings
CREATE TABLE user (
@@ -79,7 +79,7 @@ CREATE TABLE user (
PRIMARY KEY Host (Host,User)
)
engine=MyISAM;
---enable-warnings
+--enable_warnings
INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y');
INSERT INTO user VALUES ('localhost','', '','N','N','N','N','N','N','N','N','N');
diff --git a/mysql-test/t/timezone.test b/mysql-test/t/timezone.test
index 34bbb365c70..157b18f57fa 100644
--- a/mysql-test/t/timezone.test
+++ b/mysql-test/t/timezone.test
@@ -52,11 +52,12 @@ INSERT INTO t1 (ts) VALUES ('2003-03-30 01:59:59'),
DROP TABLE t1;
#
-# Test for fix for Bug#2523
+# Test for fix for Bug#2523 Check that boundary dates are processed
+# correctly.
#
select unix_timestamp('1970-01-01 01:00:00'),
unix_timestamp('1970-01-01 01:00:01'),
- unix_timestamp('2038-01-01 00:59:59'),
- unix_timestamp('2038-01-01 01:00:00');
+ unix_timestamp('2038-01-19 04:14:07'),
+ unix_timestamp('2038-01-19 04:14:08');
# End of 4.1 tests
diff --git a/mysql-test/t/timezone2.test b/mysql-test/t/timezone2.test
index bad1df554d9..862b9cc58d1 100644
--- a/mysql-test/t/timezone2.test
+++ b/mysql-test/t/timezone2.test
@@ -113,21 +113,21 @@ create table t1 (ts timestamp);
set time_zone='UTC';
insert into t1 values ('0000-00-00 00:00:00'),('1969-12-31 23:59:59'),
('1970-01-01 00:00:00'),('1970-01-01 00:00:01'),
- ('2037-12-31 23:59:59'),('2038-01-01 00:00:00');
+ ('2038-01-19 03:14:07'),('2038-01-19 03:14:08');
select * from t1;
truncate table t1;
# MET time zone has range shifted by one hour
set time_zone='MET';
insert into t1 values ('0000-00-00 00:00:00'),('1970-01-01 00:30:00'),
('1970-01-01 01:00:00'),('1970-01-01 01:00:01'),
- ('2038-01-01 00:59:59'),('2038-01-01 01:00:00');
+ ('2038-01-19 04:14:07'),('2038-01-19 04:14:08');
select * from t1;
truncate table t1;
# same for +01:30 time zone
set time_zone='+01:30';
insert into t1 values ('0000-00-00 00:00:00'),('1970-01-01 01:00:00'),
('1970-01-01 01:30:00'),('1970-01-01 01:30:01'),
- ('2038-01-01 01:29:59'),('2038-01-01 01:30:00');
+ ('2038-01-19 04:44:07'),('2038-01-19 04:44:08');
select * from t1;
drop table t1;
@@ -177,8 +177,8 @@ select convert_tz('2003-10-26 01:00:00', 'MET', 'UTC');
select convert_tz('2003-10-26 02:00:00', 'MET', 'UTC');
select convert_tz('2003-10-26 02:59:59', 'MET', 'UTC');
select convert_tz('2003-10-26 04:00:00', 'MET', 'UTC');
-select convert_tz('2038-01-01 00:59:59', 'MET', 'UTC');
-select convert_tz('2038-01-01 01:00:00', 'MET', 'UTC');
+select convert_tz('2038-01-19 04:14:07', 'MET', 'UTC');
+select convert_tz('2038-01-19 04:14:08', 'MET', 'UTC');
select convert_tz('2103-01-01 04:00:00', 'MET', 'UTC');
# Let us test variable time zone argument
diff --git a/mysql-test/t/timezone4-master.opt b/mysql-test/t/timezone4-master.opt
new file mode 100644
index 00000000000..d1ab6207933
--- /dev/null
+++ b/mysql-test/t/timezone4-master.opt
@@ -0,0 +1 @@
+--timezone=GMT+10
diff --git a/mysql-test/t/timezone4.test b/mysql-test/t/timezone4.test
new file mode 100644
index 00000000000..d7372c75d5a
--- /dev/null
+++ b/mysql-test/t/timezone4.test
@@ -0,0 +1,13 @@
+#
+# Tests for time functions. The difference from func_time test is the
+# timezone. In func_time it's GMT-3. In our case it's GMT+10
+#
+
+#
+# Test for bug bug #9191 "TIMESTAMP/from_unixtime() no longer accepts 2^31-1"
+#
+
+select from_unixtime(0);
+# check 0 boundary
+select unix_timestamp('1969-12-31 14:00:01');
+
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index ccc17e55dc8..8242c614d0a 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -1274,7 +1274,6 @@ INSERT INTO t1 VALUES (@x);
SELECT @x;
SET @x=2;
---error ER_DIVISION_BY_ZERO
UPDATE t1 SET i1 = @x;
SELECT @x;
@@ -1285,7 +1284,6 @@ INSERT INTO t1 VALUES (@x);
SELECT @x;
SET @x=4;
---error ER_DIVISION_BY_ZERO
UPDATE t1 SET i1 = @x;
SELECT @x;
@@ -1420,6 +1418,67 @@ CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890
DROP TABLE t1;
DROP TABLE t2;
+#
+# Bug#20028 Function with select return no data
+#
+
+--disable_warnings
+drop table if exists t1;
+drop table if exists t2;
+drop table if exists t3;
+drop table if exists t4;
+--enable_warnings
+
+SET @save_sql_mode=@@sql_mode;
+
+delimiter |;
+SET sql_mode='TRADITIONAL'|
+create table t1 (id int(10) not null primary key, v int(10) )|
+create table t2 (id int(10) not null primary key, v int(10) )|
+create table t3 (id int(10) not null primary key, v int(10) )|
+create table t4 (c int)|
+
+create trigger t4_bi before insert on t4 for each row set @t4_bi_called:=1|
+create trigger t4_bu before update on t4 for each row set @t4_bu_called:=1|
+
+insert into t1 values(10, 10)|
+set @a:=1/0|
+select 1/0 from t1|
+
+create trigger t1_bi before insert on t1 for each row set @a:=1/0|
+
+insert into t1 values(20, 20)|
+
+drop trigger t1_bi|
+create trigger t1_bi before insert on t1 for each row
+begin
+ insert into t2 values (new.id, new.v);
+ update t2 set v=v+1 where id= new.id;
+ replace t3 values (new.id, 0);
+ update t2, t3 set t2.v=new.v, t3.v=new.v where t2.id=t3.id;
+ create temporary table t5 select * from t1;
+ delete from t5;
+ insert into t5 select * from t1;
+ insert into t4 values (0);
+ set @check= (select count(*) from t5);
+ update t4 set c= @check;
+ drop temporary table t5;
+
+ set @a:=1/0;
+end|
+
+set @check=0, @t4_bi_called=0, @t4_bu_called=0|
+insert into t1 values(30, 30)|
+select @check, @t4_bi_called, @t4_bu_called|
+
+delimiter ;|
+
+SET @@sql_mode=@save_sql_mode;
+
+drop table t1;
+drop table t2;
+drop table t3;
+drop table t4;
#
# Bug#20670 "UPDATE using key and invoking trigger that modifies
diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test
index 6bf18b30c41..1b80a15e4ff 100644
--- a/mysql-test/t/type_newdecimal.test
+++ b/mysql-test/t/type_newdecimal.test
@@ -1000,9 +1000,9 @@ drop table t1;
#
# Bug 12938 (arithmetic loop's zero)
#
---disable-warnings
+--disable_warnings
drop procedure if exists wg2;
---enable-warnings
+--enable_warnings
delimiter //;
create procedure wg2()
begin
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index 644ca506eba..65ca1b2c1b7 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -144,6 +144,8 @@ select @@version;
--replace_column 1 #
select @@global.version;
+--echo End of 4.1 tests
+
# Bug #6598: problem with cast(NULL as signed integer);
#
@@ -210,4 +212,10 @@ select @var:=f2 from t1 group by f1 order by f2 desc limit 1;
select @var;
drop table t1;
-# End of 4.1 tests
+#
+# Bug#19024 - SHOW COUNT(*) WARNINGS not return Errors
+#
+--error 1064
+insert into city 'blah';
+SHOW COUNT(*) WARNINGS;
+SHOW COUNT(*) ERRORS;
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index f86e32e6a82..fa3ddd28489 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -23,8 +23,11 @@ create table t1 (a int, b int);
insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
# view with variable
--- error 1351
+-- error ER_VIEW_SELECT_VARIABLE
create view v1 (c,d) as select a,b+@@global.max_user_connections from t1;
+-- error ER_VIEW_SELECT_VARIABLE
+create view v1 (c,d) as select a,b from t1
+ where a = @@global.max_user_connections;
# simple view
create view v1 (c) as select b+1 from t1;
@@ -487,19 +490,6 @@ drop view v1;
create view v1 (a,a) as select 'a','a';
#
-# SP variables inside view test
-#
---disable_warnings
-drop procedure if exists p1;
---enable_warnings
-delimiter //;
-create procedure p1 () begin declare v int; create view v1 as select v; end;//
-delimiter ;//
--- error 1351
-call p1();
-drop procedure p1;
-
-#
# updatablity should be transitive
#
create table t1 (col1 int,col2 char(22));
@@ -708,11 +698,11 @@ drop function `f``1`;
#
# tested problem when function name length close to ALIGN_SIZE
#
-create function x () returns int return 5;
-create view v1 as select x ();
+create function a() returns int return 5;
+create view v1 as select a();
select * from v1;
drop view v1;
-drop function x;
+drop function a;
#
# VIEW with collation
@@ -820,6 +810,8 @@ create view v1 as select 5 into outfile 'ttt';
create table t1 (a int);
-- error 1350
create view v1 as select a from t1 procedure analyse();
+-- error ER_VIEW_SELECT_DERIVED
+create view v1 as select 1 from (select 1) as d1;
drop table t1;
#
@@ -1801,9 +1793,7 @@ drop table t1;
# underlying tables (BUG#6443)
#
set sql_mode='strict_all_tables';
---disable_warnings
-CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL) ENGINE = INNODB;
---enable_warnings
+CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL);
CREATE VIEW v1 (vcol1) AS SELECT col1 FROM t1;
CREATE VIEW v2 (vcol1) AS SELECT col1 FROM t1 WHERE col2 > 2;
-- error 1364
@@ -1859,9 +1849,7 @@ drop table t1;
#
# Test for bug #11771: wrong query_id in SELECT * FROM <view>
#
---disable_warnings
-CREATE TABLE t1 (f1 char) ENGINE = innodb;
---enable_warnings
+CREATE TABLE t1 (f1 char);
INSERT INTO t1 VALUES ('A');
CREATE VIEW v1 AS SELECT * FROM t1;
@@ -2886,6 +2874,38 @@ DROP VIEW v1;
DROP TABLE t1, t2;
#
+# Bug#19111: TRIGGERs selecting from a VIEW on the firing base table
+# fail
+#
+# Allow to select from a view on a table being modified in a trigger
+# and stored function, since plain select is allowed there.
+#
+--disable_warnings
+DROP FUNCTION IF EXISTS f1;
+DROP VIEW IF EXISTS v1;
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1);
+
+CREATE VIEW v1 AS SELECT MAX(i) FROM t1;
+
+# Plain 'SET NEW.i = (SELECT MAX(i) FROM t1) + 1' works, so select
+# from a view should work too.
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+ SET NEW.i = (SELECT * FROM v1) + 1;
+INSERT INTO t1 VALUES (1);
+
+# Plain 'RETURN (SELECT MAX(i) FROM t1)' works in INSERT, so select
+# from a view should work too.
+CREATE FUNCTION f1() RETURNS INT RETURN (SELECT * FROM v1);
+UPDATE t1 SET i= f1();
+
+DROP FUNCTION f1;
+DROP VIEW v1;
+DROP TABLE t1;
+
# Bug #16813 (WITH CHECK OPTION doesn't work with UPDATE)
#
CREATE TABLE t1(id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, val INT UNSIGNED NOT NULL);
@@ -2899,4 +2919,43 @@ UPDATE v1 SET val=6 WHERE id=2;
DROP VIEW v1;
DROP TABLE t1;
+
+#
+# BUG#22584: last_insert_id not updated after inserting a record
+# through a updatable view
+#
+# We still do not update LAST_INSERT_ID if AUTO_INCREMENT column is
+# not accessible through a view. However, we do not reset the value
+# of LAST_INSERT_ID, but keep it unchanged.
+#
+--disable_warnings
+DROP VIEW IF EXISTS v1, v2;
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (i INT AUTO_INCREMENT PRIMARY KEY, j INT);
+CREATE VIEW v1 AS SELECT j FROM t1;
+CREATE VIEW v2 AS SELECT * FROM t1;
+
+INSERT INTO t1 (j) VALUES (1);
+SELECT LAST_INSERT_ID();
+
+INSERT INTO v1 (j) VALUES (2);
+--echo # LAST_INSERT_ID() should not change.
+SELECT LAST_INSERT_ID();
+
+INSERT INTO v2 (j) VALUES (3);
+--echo # LAST_INSERT_ID() should be updated.
+SELECT LAST_INSERT_ID();
+
+INSERT INTO v1 (j) SELECT j FROM t1;
+--echo # LAST_INSERT_ID() should not change.
+SELECT LAST_INSERT_ID();
+
+SELECT * FROM t1;
+
+DROP VIEW v1, v2;
+DROP TABLE t1;
+
+
--echo End of 5.0 tests.
diff --git a/mysql-test/t/wait_for_socket.sh b/mysql-test/t/wait_for_socket.sh
new file mode 100755
index 00000000000..3b900fa2208
--- /dev/null
+++ b/mysql-test/t/wait_for_socket.sh
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+###########################################################################
+
+if [ $# -ne 6 ]; then
+ echo "Usage: wait_for_socket.sh <executable path> <socket path> <username> <password> <db> <timeout>"
+ exit 0
+fi
+
+client_exe="$1"
+socket_path="$2"
+username="$3"
+password="$4"
+db="$5"
+total_timeout="$6"
+
+###########################################################################
+
+if [ -z "$client_exe" ]; then
+ echo "Error: invalid path to client executable ($client_exe)."
+ exit 0;
+fi
+
+if [ ! -x "$client_exe" ]; then
+ echo "Error: client by path '$client_exe' is not available."
+ exit 0;
+fi
+
+if [ -z "$socket_path" ]; then
+ echo "Error: invalid socket patch."
+ exit 0
+fi
+
+###########################################################################
+
+client_args="--silent --socket=$socket_path "
+
+[ -n "$username" ] && client_args="$client_args --user=$username "
+[ -n "$password" ] && client_args="$client_args --password=$password "
+[ -n "$db" ] && client_args="$client_args $db"
+
+###########################################################################
+
+cur_attempt=1
+
+while true; do
+
+ if ( echo 'quit' | "$client_exe" $client_args >/dev/null 2>&1 ); then
+ echo "Success: server is ready to accept connection on socket."
+ exit 0
+ fi
+
+ [ $cur_attempt -ge $total_timeout ] && break
+
+ sleep 1
+
+ cur_attempt=`expr $cur_attempt + 1`
+
+done
+
+echo "Error: server does not accept connections after $total_timeout seconds."
+exit 0
diff --git a/mysql-test/t/wait_timeout.test b/mysql-test/t/wait_timeout.test
index dbd792e48d8..bdff72cdc76 100644
--- a/mysql-test/t/wait_timeout.test
+++ b/mysql-test/t/wait_timeout.test
@@ -55,7 +55,7 @@ select 2;
select 3;
# Disconnect so that we will not be confused by a future abort from this
# connection.
-disconnect default
+disconnect default;
#
# Do the same test as above on a TCP connection
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index 4aa99a70121..7b362b4c1f9 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -20,7 +20,7 @@ ADD_LIBRARY(mysys array.c charset-def.c charset.c checksum.c default.c default_m
my_clock.c my_compress.c my_conio.c my_copy.c my_crc32.c my_create.c my_delete.c
my_div.c my_error.c my_file.c my_fopen.c my_fstream.c my_gethostbyname.c
my_gethwaddr.c my_getopt.c my_getsystime.c my_getwd.c my_handler.c my_init.c
- my_lib.c my_lock.c my_lockmem.c my_lread.c my_lwrite.c my_malloc.c my_messnc.c
+ my_lib.c my_lock.c my_lockmem.c my_malloc.c my_messnc.c
my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c
my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c
my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index b209d64e78f..79d79d41c34 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -43,7 +43,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
tree.c trie.c list.c hash.c array.c string.c typelib.c \
my_copy.c my_append.c my_lib.c \
my_delete.c my_rename.c my_redel.c \
- my_chsize.c my_lread.c my_lwrite.c my_clock.c \
+ my_chsize.c my_clock.c \
my_quick.c my_lockmem.c my_static.c \
my_sync.c my_getopt.c my_mkdir.c \
default_modify.c default.c \
diff --git a/mysys/charset.c b/mysys/charset.c
index 64b15fab0c2..d10a580ae4e 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -312,7 +312,7 @@ static my_bool my_read_charset_file(const char *filename, myf myflags)
{
char *buf;
int fd;
- uint len;
+ uint len, tmp_len;
MY_STAT stat_info;
if (!my_stat(filename, &stat_info, MYF(myflags)) ||
@@ -321,12 +321,11 @@ static my_bool my_read_charset_file(const char *filename, myf myflags)
return TRUE;
if ((fd=my_open(filename,O_RDONLY,myflags)) < 0)
- {
- my_free(buf,myflags);
- return TRUE;
- }
- len=read(fd,buf,len);
+ goto error;
+ tmp_len=my_read(fd, buf, len, myflags);
my_close(fd,myflags);
+ if (tmp_len != len)
+ goto error;
if (my_parse_charset_xml(buf,len,add_collation))
{
@@ -340,6 +339,10 @@ static my_bool my_read_charset_file(const char *filename, myf myflags)
my_free(buf, myflags);
return FALSE;
+
+error:
+ my_free(buf, myflags);
+ return TRUE;
}
diff --git a/mysys/make-ccc b/mysys/make-ccc
index 9c54185682a..b34bd80e1d1 100755
--- a/mysys/make-ccc
+++ b/mysys/make-ccc
@@ -1,4 +1,4 @@
rm -f .deps/* raid.o mf_iocache.o libmysys.a
-ccc -DDEFAULT_BASEDIR="\"/usr/local/mysql\"" -DDATADIR="\"/usr/local/mysql/var\"" -DHAVE_CONFIG_H -I./../include -I../include -I.. -DDBUG_OFF -fast -O3 -fomit-frame-pointer -c array.c checksum.c default.c errors.c getopt.c getopt1.c getvar.c hash.c list.c mf_brkhant.c mf_cache.c mf_casecnv.c mf_dirname.c mf_fn_ext.c mf_format.c mf_getdate.c mf_keycache.c mf_loadpath.c mf_pack.c mf_pack2.c mf_path.c mf_qsort.c mf_qsort2.c mf_radix.c mf_reccache.c mf_same.c mf_sort.c mf_soundex.c mf_stripp.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_alarm.c my_alloc.c my_append.c my_chsize.c my_clock.c my_compress.c my_copy.c my_create.c my_delete.c my_div.c my_error.c my_fopen.c my_fstream.c my_getwd.c my_init.c my_lib.c my_lockmem.c my_lread.c my_lwrite.c my_malloc.c my_messnc.c my_mkdir.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_static.c my_tempnam.c my_thr_init.c my_write.c ptr_cmp.c queues.c safemalloc.c string.c thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c tree.c typelib.c
+ccc -DDEFAULT_BASEDIR="\"/usr/local/mysql\"" -DDATADIR="\"/usr/local/mysql/var\"" -DHAVE_CONFIG_H -I./../include -I../include -I.. -DDBUG_OFF -fast -O3 -fomit-frame-pointer -c array.c checksum.c default.c errors.c getopt.c getopt1.c getvar.c hash.c list.c mf_brkhant.c mf_cache.c mf_casecnv.c mf_dirname.c mf_fn_ext.c mf_format.c mf_getdate.c mf_keycache.c mf_loadpath.c mf_pack.c mf_pack2.c mf_path.c mf_qsort.c mf_qsort2.c mf_radix.c mf_reccache.c mf_same.c mf_sort.c mf_soundex.c mf_stripp.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_alarm.c my_alloc.c my_append.c my_chsize.c my_clock.c my_compress.c my_copy.c my_create.c my_delete.c my_div.c my_error.c my_fopen.c my_fstream.c my_getwd.c my_init.c my_lib.c my_lockmem.c my_malloc.c my_messnc.c my_mkdir.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_static.c my_tempnam.c my_thr_init.c my_write.c ptr_cmp.c queues.c safemalloc.c string.c thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c tree.c typelib.c
make raid.o mf_iocache.o my_lock.o
ar -cr libmysys.a array.o raid.o mf_iocache.o my_lock.o
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index b1cf940d70d..249eaf48ad2 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -332,7 +332,11 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
{
info->read_end=info->write_pos;
info->end_of_file=my_b_tell(info);
- info->seek_not_done=1;
+ /*
+ Trigger a new seek only if we have a valid
+ file handle.
+ */
+ info->seek_not_done= (info->file != -1);
}
else if (type == WRITE_CACHE)
{
@@ -441,11 +445,24 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
/* pos_in_file always point on where info->buffer was read */
pos_in_file=info->pos_in_file+(uint) (info->read_end - info->buffer);
+
+ /*
+ Whenever a function which operates on IO_CACHE flushes/writes
+ some part of the IO_CACHE to disk it will set the property
+ "seek_not_done" to indicate this to other functions operating
+ on the IO_CACHE.
+ */
if (info->seek_not_done)
- { /* File touched, do seek */
- VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
+ {
+ if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0))
+ == MY_FILEPOS_ERROR)
+ {
+ info->error= -1;
+ DBUG_RETURN(1);
+ }
info->seek_not_done=0;
}
+
diff_length=(uint) (pos_in_file & (IO_SIZE-1));
if (Count >= (uint) (IO_SIZE+(IO_SIZE-diff_length)))
{ /* Fill first intern buffer */
@@ -946,8 +963,22 @@ int _my_b_read_r(register IO_CACHE *cache, byte *Buffer, uint Count)
len= 0;
else
{
- if (cache->seek_not_done) /* File touched, do seek */
- VOID(my_seek(cache->file, pos_in_file, MY_SEEK_SET, MYF(0)));
+ /*
+ Whenever a function which operates on IO_CACHE flushes/writes
+ some part of the IO_CACHE to disk it will set the property
+ "seek_not_done" to indicate this to other functions operating
+ on the IO_CACHE.
+ */
+ if (cache->seek_not_done)
+ {
+ if (my_seek(cache->file, pos_in_file, MY_SEEK_SET, MYF(0))
+ == MY_FILEPOS_ERROR)
+ {
+ cache->error= -1;
+ unlock_io_cache(cache);
+ DBUG_RETURN(1);
+ }
+ }
len= (int) my_read(cache->file, cache->buffer, length, cache->myflags);
}
DBUG_PRINT("io_cache_share", ("read %d bytes", len));
@@ -1049,11 +1080,16 @@ static void copy_to_read_buffer(IO_CACHE *write_cache,
/*
- Do sequential read from the SEQ_READ_APPEND cache
- we do this in three stages:
+ Do sequential read from the SEQ_READ_APPEND cache.
+
+ We do this in three stages:
- first read from info->buffer
- then if there are still data to read, try the file descriptor
- afterwards, if there are still data to read, try append buffer
+
+ RETURNS
+ 0 Success
+ 1 Failed to read
*/
int _my_b_seq_read(register IO_CACHE *info, byte *Buffer, uint Count)
@@ -1081,7 +1117,13 @@ int _my_b_seq_read(register IO_CACHE *info, byte *Buffer, uint Count)
With read-append cache we must always do a seek before we read,
because the write could have moved the file pointer astray
*/
- VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
+ if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0))
+ == MY_FILEPOS_ERROR)
+ {
+ info->error= -1;
+ unlock_append_buffer(info);
+ return (1);
+ }
info->seek_not_done=0;
diff_length=(uint) (pos_in_file & (IO_SIZE-1));
@@ -1197,6 +1239,21 @@ read_append_buffer:
#ifdef HAVE_AIOWAIT
+/*
+ Read from the IO_CACHE into a buffer and feed asynchronously
+ from disk when needed.
+
+ SYNOPSIS
+ _my_b_async_read()
+ info IO_CACHE pointer
+ Buffer Buffer to retrieve count bytes from file
+ Count Number of bytes to read into Buffer
+
+ RETURN VALUE
+ -1 An error has occurred; my_errno is set.
+ 0 Success
+ 1 An error has occurred; IO_CACHE to error state.
+*/
int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
{
uint length,read_length,diff_length,left_length,use_length,org_Count;
@@ -1287,13 +1344,20 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
info->error=(int) (read_length+left_length);
return 1;
}
- VOID(my_seek(info->file,next_pos_in_file,MY_SEEK_SET,MYF(0)));
+
+ if (my_seek(info->file,next_pos_in_file,MY_SEEK_SET,MYF(0))
+ == MY_FILEPOS_ERROR)
+ {
+ info->error= -1;
+ return (1);
+ }
+
read_length=IO_SIZE*2- (uint) (next_pos_in_file & (IO_SIZE-1));
if (Count < read_length)
{ /* Small block, read to cache */
if ((read_length=my_read(info->file,info->request_pos,
read_length, info->myflags)) == (uint) -1)
- return info->error= -1;
+ return info->error= -1;
use_length=min(Count,read_length);
memcpy(Buffer,info->request_pos,(size_t) use_length);
info->read_pos=info->request_pos+Count;
@@ -1380,7 +1444,15 @@ int _my_b_get(IO_CACHE *info)
return (int) (uchar) buff;
}
- /* Returns != 0 if error on write */
+/*
+ Write a byte buffer to IO_CACHE and flush to disk
+ if IO_CACHE is full.
+
+ RETURN VALUE
+ 1 On error on write
+ 0 On success
+ -1 On error; my_errno contains error code.
+*/
int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count)
{
@@ -1404,8 +1476,18 @@ int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count)
{ /* Fill first intern buffer */
length=Count & (uint) ~(IO_SIZE-1);
if (info->seek_not_done)
- { /* File touched, do seek */
- VOID(my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)));
+ {
+ /*
+ Whenever a function which operates on IO_CACHE flushes/writes
+ some part of the IO_CACHE to disk it will set the property
+ "seek_not_done" to indicate this to other functions operating
+ on the IO_CACHE.
+ */
+ if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)))
+ {
+ info->error= -1;
+ return (1);
+ }
info->seek_not_done=0;
}
if (my_write(info->file,Buffer,(uint) length,info->myflags | MY_NABP))
diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c
index fe0d0ffa607..4b26085c870 100644
--- a/mysys/my_chsize.c
+++ b/mysys/my_chsize.c
@@ -86,7 +86,11 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
Fill space between requested length and true length with 'filler'
We should never come here on any modern machine
*/
- VOID(my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE)));
+ if (my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE))
+ == MY_FILEPOS_ERROR)
+ {
+ goto err;
+ }
swap_variables(my_off_t, newlength, oldsize);
#endif
}
diff --git a/mysys/my_lock.c b/mysys/my_lock.c
index 919727e03d6..e32807004e8 100644
--- a/mysys/my_lock.c
+++ b/mysys/my_lock.c
@@ -30,7 +30,14 @@
#include <nks/fsio.h>
#endif
- /* Lock a part of a file */
+/*
+ Lock a part of a file
+
+ RETURN VALUE
+ 0 Success
+ -1 An error has occured and 'my_errno' is set
+ to indicate the actual error code.
+*/
int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
myf MyFlags)
@@ -94,10 +101,22 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
#elif defined(HAVE_LOCKING)
/* Windows */
{
- my_bool error;
+ my_bool error= FALSE;
pthread_mutex_lock(&my_file_info[fd].mutex);
- if (MyFlags & MY_SEEK_NOT_DONE)
- VOID(my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE)));
+ if (MyFlags & MY_SEEK_NOT_DONE)
+ {
+ if( my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE))
+ == MY_FILEPOS_ERROR )
+ {
+ /*
+ If my_seek fails my_errno will already contain an error code;
+ just unlock and return error code.
+ */
+ DBUG_PRINT("error",("my_errno: %d (%d)",my_errno,errno));
+ pthread_mutex_unlock(&my_file_info[fd].mutex);
+ DBUG_RETURN(-1);
+ }
+ }
error= locking(fd,locktype,(ulong) length) && errno != EINVAL;
pthread_mutex_unlock(&my_file_info[fd].mutex);
if (!error)
@@ -135,7 +154,17 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
}
#else
if (MyFlags & MY_SEEK_NOT_DONE)
- VOID(my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE)));
+ {
+ if (my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE))
+ == MY_FILEPOS_ERROR)
+ {
+ /*
+ If an error has occured in my_seek then we will already
+ have an error code in my_errno; Just return error code.
+ */
+ DBUG_RETURN(-1);
+ }
+ }
if (lockf(fd,locktype,length) != -1)
DBUG_RETURN(0);
#endif /* HAVE_FCNTL */
diff --git a/mysys/my_lread.c b/mysys/my_lread.c
deleted file mode 100644
index 601d772b844..00000000000
--- a/mysys/my_lread.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright (C) 2000 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 "mysys_priv.h"
-#include "mysys_err.h"
-
- /* Read a chunk of bytes from a file */
-
-uint32 my_lread(int Filedes, byte *Buffer, uint32 Count, myf MyFlags)
- /* File descriptor */
- /* Buffer must be at least count bytes */
- /* Max number of bytes returnd */
- /* Flags on what to do on error */
-{
- uint32 readbytes;
- DBUG_ENTER("my_lread");
- DBUG_PRINT("my",("Fd: %d Buffer: %ld Count: %ld MyFlags: %d",
- Filedes, Buffer, Count, MyFlags));
-
- /* Temp hack to get count to int32 while read wants int */
- if ((readbytes = (uint32) read(Filedes, Buffer, (uint) Count)) != Count)
- {
- my_errno=errno;
- if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
- {
- if (readbytes == MY_FILE_ERROR)
- my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
- my_filename(Filedes),errno);
- else
- if (MyFlags & (MY_NABP | MY_FNABP))
- my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
- my_filename(Filedes),errno);
- }
- if (readbytes == MY_FILE_ERROR || MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN((uint32) -1); /* Return med felkod */
- }
- if (MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN(0); /* Ok vid l{sning */
- DBUG_RETURN(readbytes);
-} /* my_lread */
diff --git a/mysys/my_lwrite.c b/mysys/my_lwrite.c
deleted file mode 100644
index 3b9afdbd71f..00000000000
--- a/mysys/my_lwrite.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (C) 2000 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 "mysys_priv.h"
-#include "mysys_err.h"
-
- /* Write a chunk of bytes to a file */
-
-uint32 my_lwrite(int Filedes, const byte *Buffer, uint32 Count, myf MyFlags)
-{
- uint32 writenbytes;
- DBUG_ENTER("my_lwrite");
- DBUG_PRINT("my",("Fd: %d Buffer: 0x%lx Count: %ld MyFlags: %d",
- Filedes, Buffer, Count, MyFlags));
-
- /* Temp hack to get count to int32 while write wants int */
- if ((writenbytes = (uint32) write(Filedes, Buffer, (uint) Count)) != Count)
- {
- my_errno=errno;
- if (writenbytes == (uint32) -1 || MyFlags & (MY_NABP | MY_FNABP))
- {
- if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
- {
- my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG),
- my_filename(Filedes),errno);
- }
- DBUG_RETURN((uint32) -1); /* Return med felkod */
- }
- }
- if (MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN(0); /* Ok vid l{sning */
- DBUG_RETURN(writenbytes);
-} /* my_lwrite */
diff --git a/mysys/my_pread.c b/mysys/my_pread.c
index 978366e57e5..45a4a363c0a 100644
--- a/mysys/my_pread.c
+++ b/mysys/my_pread.c
@@ -75,8 +75,12 @@ uint my_pread(File Filedes, byte *Buffer, uint Count, my_off_t offset,
DBUG_PRINT("warning",("Read only %ld bytes off %ld from %d, errno: %d",
readbytes,Count,Filedes,my_errno));
#ifdef THREAD
- if (readbytes == 0 && errno == EINTR)
- continue; /* Interrupted */
+ if ((readbytes == 0 || (int) readbytes == -1) && errno == EINTR)
+ {
+ DBUG_PRINT("debug", ("my_pread() was interrupted and returned %d",
+ (int) readbytes));
+ continue; /* Interrupted */
+ }
#endif
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
{
@@ -170,8 +174,8 @@ uint my_pwrite(int Filedes, const byte *Buffer, uint Count, my_off_t offset,
VOID(sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC));
continue;
}
- if ((writenbytes == 0 && my_errno == EINTR) ||
- (writenbytes > 0 && (uint) writenbytes != (uint) -1))
+ if ((writenbytes > 0 && (uint) writenbytes != (uint) -1) ||
+ my_errno == EINTR)
continue; /* Retry */
#endif
if (MyFlags & (MY_NABP | MY_FNABP))
diff --git a/mysys/my_quick.c b/mysys/my_quick.c
index 44ed3fc0b2c..ffc8160c371 100644
--- a/mysys/my_quick.c
+++ b/mysys/my_quick.c
@@ -26,6 +26,14 @@ uint my_quick_read(File Filedes,byte *Buffer,uint Count,myf MyFlags)
if ((readbytes = (uint) read(Filedes, Buffer, Count)) != Count)
{
+#ifndef DBUG_OFF
+ if ((readbytes == 0 || (int) readbytes == -1) && errno == EINTR)
+ {
+ DBUG_PRINT("error", ("my_quick_read() was interrupted and returned %d"
+ ". This function does not retry the read!",
+ (int) readbytes));
+ }
+#endif
my_errno=errno;
return readbytes;
}
@@ -35,8 +43,24 @@ uint my_quick_read(File Filedes,byte *Buffer,uint Count,myf MyFlags)
uint my_quick_write(File Filedes,const byte *Buffer,uint Count)
{
- if ((uint) write(Filedes,Buffer,Count) != Count)
+#ifndef DBUG_OFF
+ uint writtenbytes;
+#endif
+
+ if ((
+#ifndef DBUG_OFF
+ writtenbytes =
+#endif
+ (uint) write(Filedes,Buffer,Count)) != Count)
{
+#ifndef DBUG_OFF
+ if ((writtenbytes == 0 || (int) writtenbytes == -1) && errno == EINTR)
+ {
+ DBUG_PRINT("error", ("my_quick_write() was interrupted and returned %d"
+ ". This function does not retry the write!",
+ (int) writtenbytes));
+ }
+#endif
my_errno=errno;
return (uint) -1;
}
diff --git a/mysys/my_read.c b/mysys/my_read.c
index 2e23f2175f8..8b88e483fef 100644
--- a/mysys/my_read.c
+++ b/mysys/my_read.c
@@ -51,10 +51,11 @@ uint my_read(File Filedes, byte *Buffer, uint Count, myf MyFlags)
DBUG_PRINT("warning",("Read only %ld bytes off %ld from %d, errno: %d",
readbytes, Count, Filedes, my_errno));
#ifdef THREAD
- if ((int) readbytes <= 0 && errno == EINTR)
- {
- DBUG_PRINT("debug", ("my_read() was interrupted and returned %d", (int) readbytes));
- continue; /* Interrupted */
+ if ((readbytes == 0 || (int) readbytes == -1) && errno == EINTR)
+ {
+ DBUG_PRINT("debug", ("my_read() was interrupted and returned %d",
+ (int) readbytes));
+ continue; /* Interrupted */
}
#endif
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
diff --git a/mysys/my_seek.c b/mysys/my_seek.c
index e5b1905e551..269d1a65b31 100644
--- a/mysys/my_seek.c
+++ b/mysys/my_seek.c
@@ -16,8 +16,30 @@
#include "mysys_priv.h"
- /* Seek to position in file */
- /*ARGSUSED*/
+/*
+ Seek to a position in a file.
+
+ ARGUMENTS
+ File fd The file descriptor
+ my_off_t pos The expected position (absolute or relative)
+ int whence A direction parameter and one of
+ {SEEK_SET, SEEK_CUR, SEEK_END}
+ myf MyFlags Not used.
+
+ DESCRIPTION
+ The my_seek function is a wrapper around the system call lseek and
+ repositions the offset of the file descriptor fd to the argument
+ offset according to the directive whence as follows:
+ SEEK_SET The offset is set to offset bytes.
+ SEEK_CUR The offset is set to its current location plus offset bytes
+ SEEK_END The offset is set to the size of the file plus offset bytes
+
+ RETURN VALUE
+ my_off_t newpos The new position in the file.
+ MY_FILEPOS_ERROR An error was encountered while performing
+ the seek. my_errno is set to indicate the
+ actual error.
+*/
my_off_t my_seek(File fd, my_off_t pos, int whence,
myf MyFlags __attribute__((unused)))
@@ -29,8 +51,13 @@ my_off_t my_seek(File fd, my_off_t pos, int whence,
whence, MyFlags));
DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */
- if (-1 != fd)
- newpos=lseek(fd, pos, whence);
+ /*
+ Make sure we are using a valid file descriptor!
+ */
+ DBUG_ASSERT(fd != -1);
+
+ newpos= lseek(fd, pos, whence);
+
if (newpos == (os_off_t) -1)
{
my_errno=errno;
diff --git a/mysys/my_write.c b/mysys/my_write.c
index 4e8369480b3..ae8cb4ab02b 100644
--- a/mysys/my_write.c
+++ b/mysys/my_write.c
@@ -57,18 +57,24 @@ uint my_write(int Filedes, const byte *Buffer, uint Count, myf MyFlags)
VOID(sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC));
continue;
}
- if (!writenbytes)
+
+ if ((writenbytes == 0 || (int) writenbytes == -1))
{
- /* We may come here on an interrupt or if the file quote is exeeded */
if (my_errno == EINTR)
- continue;
- if (!errors++) /* Retry once */
{
- errno=EFBIG; /* Assume this is the error */
- continue;
+ DBUG_PRINT("debug", ("my_write() was interrupted and returned %d",
+ (int) writenbytes));
+ continue; /* Interrupted */
+ }
+
+ if (!writenbytes && !errors++) /* Retry once */
+ {
+ /* We may come here if the file quota is exeeded */
+ errno=EFBIG; /* Assume this is the error */
+ continue;
}
}
- else if ((uint) writenbytes != (uint) -1)
+ else
continue; /* Retry */
#endif
if (MyFlags & (MY_NABP | MY_FNABP))
diff --git a/netware/BUILD/compile-netware-END b/netware/BUILD/compile-netware-END
index c5c08cea908..6c531ab5c7c 100755
--- a/netware/BUILD/compile-netware-END
+++ b/netware/BUILD/compile-netware-END
@@ -15,11 +15,16 @@ if test -e "Makefile"; then make -k clean; fi
rm -f */.deps/*.P
rm -rf Makefile.in.bk
-# Metrowerks enviornment
+# Setup Metrowerks environment
. $path/mwenv
-# run auto tools
-. $path/compile-AUTOTOOLS
+# Temporary hack to allow building from source dist
+if [ ! "$USER"=pushbuild ]
+then
+ # Run autotools(use BUILD/autorun.sh)
+ echo "Running autotools again(BUILD/autorun.sh)"
+ . BUILD/autorun.sh
+fi
# configure
./configure $base_configs $extra_configs
diff --git a/netware/BUILD/compile-netware-max b/netware/BUILD/compile-netware-max
index ec737d4615c..d8278a4e915 100644..100755
--- a/netware/BUILD/compile-netware-max
+++ b/netware/BUILD/compile-netware-max
@@ -15,7 +15,7 @@ suffix="max"
extra_configs=" \
--with-innodb \
--with-embedded-server \
- --with-openssl \
+ --with-ssl \
"
. $path/compile-netware-END
diff --git a/netware/BUILD/compile-netware-max-debug b/netware/BUILD/compile-netware-max-debug
index ea3553ae6e1..de1b5dd17cc 100644..100755
--- a/netware/BUILD/compile-netware-max-debug
+++ b/netware/BUILD/compile-netware-max-debug
@@ -15,7 +15,7 @@ extra_configs=" \
--with-innodb \
--with-debug=full \
--with-embedded-server \
- --with-openssl \
+ --with-ssl \
"
. $path/compile-netware-END
diff --git a/netware/BUILD/compile-netware-src b/netware/BUILD/compile-netware-src
index f4e8a53ffea..f4e8a53ffea 100644..100755
--- a/netware/BUILD/compile-netware-src
+++ b/netware/BUILD/compile-netware-src
diff --git a/netware/BUILD/mwenv b/netware/BUILD/mwenv
index f43092492bb..44497c48917 100755
--- a/netware/BUILD/mwenv
+++ b/netware/BUILD/mwenv
@@ -26,8 +26,17 @@ WINE_BUILD_DIR=`echo "$BUILD_DIR" | sed 's_'$base_unix_part'/__'`
WINE_BUILD_DIR="$base/$WINE_BUILD_DIR"
echo "WINE_BUILD_DIR: $WINE_BUILD_DIR"
-export MWCNWx86Includes="$MYDEV/libc/include;$MYDEV/fs64/headers;$MYDEV/zlib-1.2.3;$WINE_BUILD_DIR/include;$MYDEV"
-export MWNWx86Libraries="$MYDEV/libc/imports;$MYDEV/mw/lib;$MYDEV/fs64/imports;$MYDEV/zlib-1.2.3;$MYDEV/openssl;$WINE_BUILD_DIR/netware/BUILD"
+# Look for libc, MySQL 5.1.x uses libc-2006 by default
+libc_dir="$MYDEV/libc-2006"
+if [ ! -d `winepath $libc_dir` ]
+then
+ # The libcdir didn't exist, set default
+ libc_dir="$MYDEV/libc"
+fi
+echo "Using libc in $libc_dir";
+
+export MWCNWx86Includes="$libc_dir/include;$MYDEV/fs64/headers;$MYDEV/zlib-1.2.3;$WINE_BUILD_DIR/include;$MYDEV"
+export MWNWx86Libraries="$libc_dir/imports;$MYDEV/mw/lib;$MYDEV/fs64/imports;$MYDEV/zlib-1.2.3;$MYDEV/openssl;$WINE_BUILD_DIR/netware/BUILD"
export MWNWx86LibraryFiles="libcpre.o;libc.imp;netware.imp;mwcrtl.lib;mwcpp.lib;libz.a;neb.imp;zPublics.imp;knetware.imp"
export WINEPATH="$MYDEV/mw/bin"
@@ -46,3 +55,21 @@ export LD='mwldnlm'
export LDFLAGS='-entry _LibCPrelude -exit _LibCPostlude -map -flags pseudopreemption'
export RANLIB=:
export STRIP=:
+
+#
+# Check that TERM has been set to avoid problem "Error opening
+# terminal: unknown" when the script is executed using non interactive ssh
+#
+if test -z "$TERM" -o "$TERM"=dumb
+then
+ export TERM=linux
+fi
+
+# Temporary hack to allow building from source dist
+if [ "$USER"=pushbuild ]
+then
+ export ARFLAGS=$AR_FLAGS
+fi
+
+# Print all env. variables
+export
diff --git a/netware/BUILD/mwldnlm b/netware/BUILD/mwldnlm
index cc8c9e63c6e..b1822827b59 100755
--- a/netware/BUILD/mwldnlm
+++ b/netware/BUILD/mwldnlm
@@ -3,6 +3,13 @@
# stop on errors
set -e
+# If libtool passes "x" as the first argument to this script
+# it's an indication that libtool is trying to unpack .la's
+# so they can be added to a new library
+# This step does not work on Netware and we avoid it by
+# replacing the .la library with the path to the .a library
+# in Makefile.in
+
args=" $*"
# NOTE: Option 'pipefail' is not standard sh
diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh
index 9302745ceee..68798e92725 100644
--- a/scripts/make_binary_distribution.sh
+++ b/scripts/make_binary_distribution.sh
@@ -123,7 +123,7 @@ copyfileto()
copyfileto $BASE/docs ChangeLog Docs/mysql.info
copyfileto $BASE COPYING COPYING.LIB README Docs/INSTALL-BINARY \
- EXCEPTIONS-CLIENT MySQLEULA.txt LICENSE.doc README.NW
+ EXCEPTIONS-CLIENT LICENSE.mysql
# Non platform-specific bin dir files:
BIN_FILES="extra/comp_err$BS extra/replace$BS extra/perror$BS \
@@ -308,10 +308,7 @@ if [ $BASE_SYSTEM = "netware" ] ; then
$BASE/support-files/build-tags \
$BASE/support-files/MySQL-shared-compat.spec \
$BASE/support-files/ndb-config-2-node.ini \
- $BASE/INSTALL-BINARY \
- $BASE/MySQLEULA.txt
-else
- rm -f $BASE/README.NW
+ $BASE/INSTALL-BINARY
fi
# Make safe_mysqld a symlink to mysqld_safe for backwards portability
diff --git a/server-tools/instance-manager/commands.cc b/server-tools/instance-manager/commands.cc
index f45b230171e..66140b8b049 100644
--- a/server-tools/instance-manager/commands.cc
+++ b/server-tools/instance-manager/commands.cc
@@ -1351,7 +1351,7 @@ Abstract_option_cmd::get_instance_options_list(const LEX_STRING *instance_name)
int Abstract_option_cmd::execute_impl(st_net *net, ulong connection_id)
{
- int err_code;
+ int err_code= 0;
/* Check that all the specified instances exist and are offline. */
diff --git a/server-tools/instance-manager/guardian.cc b/server-tools/instance-manager/guardian.cc
index 68d89a4b375..03bfadd8571 100644
--- a/server-tools/instance-manager/guardian.cc
+++ b/server-tools/instance-manager/guardian.cc
@@ -74,7 +74,7 @@ Guardian_thread::Guardian_thread(Thread_registry &thread_registry_arg,
uint monitoring_interval_arg) :
Guardian_thread_args(thread_registry_arg, instance_map_arg,
monitoring_interval_arg),
- thread_info(pthread_self()), guarded_instances(0)
+ thread_info(pthread_self(), TRUE), guarded_instances(0)
{
pthread_mutex_init(&LOCK_guardian, 0);
pthread_cond_init(&COND_guardian, 0);
@@ -95,11 +95,11 @@ Guardian_thread::~Guardian_thread()
}
-void Guardian_thread::request_shutdown(bool stop_instances_arg)
+void Guardian_thread::request_shutdown()
{
pthread_mutex_lock(&LOCK_guardian);
/* stop instances or just clean up Guardian repository */
- stop_instances(stop_instances_arg);
+ stop_instances();
shutdown_requested= TRUE;
pthread_mutex_unlock(&LOCK_guardian);
}
@@ -154,11 +154,11 @@ void Guardian_thread::process_instance(Instance *instance,
{
/* Pid file not created yet, don't go to STARTED state yet */
}
- else
+ else if (current_node->state != STARTED)
{
/* clear status fields */
- log_info("guardian: instance %s is running, set state to STARTED",
- instance->options.instance_name);
+ log_info("guardian: instance '%s' is running, set state to STARTED.",
+ (const char *) instance->options.instance_name.str);
current_node->restart_counter= 0;
current_node->crash_moment= 0;
current_node->state= STARTED;
@@ -168,8 +168,8 @@ void Guardian_thread::process_instance(Instance *instance,
{
switch (current_node->state) {
case NOT_STARTED:
- log_info("guardian: starting instance %s",
- instance->options.instance_name);
+ log_info("guardian: starting instance '%s'...",
+ (const char *) instance->options.instance_name.str);
/* NOTE, set state to STARTING _before_ start() is called */
current_node->state= STARTING;
@@ -193,8 +193,8 @@ void Guardian_thread::process_instance(Instance *instance,
if (instance->is_crashed())
{
instance->start();
- log_info("guardian: starting instance %s",
- instance->options.instance_name);
+ log_info("guardian: starting instance '%s'...",
+ (const char *) instance->options.instance_name.str);
}
}
else
@@ -211,14 +211,14 @@ void Guardian_thread::process_instance(Instance *instance,
instance->start();
current_node->last_checked= current_time;
current_node->restart_counter++;
- log_info("guardian: restarting instance %s",
- instance->options.instance_name);
+ log_info("guardian: restarting instance '%s'...",
+ (const char *) instance->options.instance_name.str);
}
}
else
{
log_info("guardian: cannot start instance %s. Abandoning attempts "
- "to (re)start it", instance->options.instance_name);
+ "to (re)start it", instance->options.instance_name.str);
current_node->state= CRASHED_AND_ABANDONED;
}
}
@@ -250,6 +250,8 @@ void Guardian_thread::run()
LIST *node;
struct timespec timeout;
+ log_info("Guardian: started.");
+
thread_registry.register_thread(&thread_info);
my_thread_init();
@@ -277,12 +279,16 @@ void Guardian_thread::run()
&LOCK_guardian, &timeout);
}
+ log_info("Guardian: stopped.");
+
stopped= TRUE;
pthread_mutex_unlock(&LOCK_guardian);
/* now, when the Guardian is stopped we can stop the IM */
thread_registry.unregister_thread(&thread_info);
thread_registry.request_shutdown();
my_thread_end();
+
+ log_info("Guardian: finished.");
}
@@ -414,12 +420,11 @@ int Guardian_thread::stop_guard(Instance *instance)
SYNOPSYS
stop_instances()
- stop_instances_arg whether we should stop instances at shutdown
DESCRIPTION
Loops through the guarded_instances list and prepares them for shutdown.
- If stop_instances was requested, we need to issue a stop command and change
- the state accordingly. Otherwise we simply delete an entry.
+ For each instance we issue a stop command and change the state
+ accordingly.
NOTE
Guardian object should be locked by the calling function.
@@ -429,42 +434,29 @@ int Guardian_thread::stop_guard(Instance *instance)
1 - error occured
*/
-int Guardian_thread::stop_instances(bool stop_instances_arg)
+int Guardian_thread::stop_instances()
{
LIST *node;
node= guarded_instances;
while (node != NULL)
{
- if (!stop_instances_arg)
+ GUARD_NODE *current_node= (GUARD_NODE *) node->data;
+ /*
+ If instance is running or was running (and now probably hanging),
+ request stop.
+ */
+ if (current_node->instance->is_running() ||
+ (current_node->state == STARTED))
{
- /* just forget about an instance */
- guarded_instances= list_delete(guarded_instances, node);
- /*
- This should still work fine, as we have only removed the
- node from the list. The pointer to the next one is still valid
- */
- node= node->next;
+ current_node->state= STOPPING;
+ current_node->last_checked= time(NULL);
}
else
- {
- GUARD_NODE *current_node= (GUARD_NODE *) node->data;
- /*
- If instance is running or was running (and now probably hanging),
- request stop.
- */
- if (current_node->instance->is_running() ||
- (current_node->state == STARTED))
- {
- current_node->state= STOPPING;
- current_node->last_checked= time(NULL);
- }
- else
- /* otherwise remove it from the list */
- guarded_instances= list_delete(guarded_instances, node);
- /* But try to kill it anyway. Just in case */
- current_node->instance->kill_instance(SIGTERM);
- node= node->next;
- }
+ /* otherwise remove it from the list */
+ guarded_instances= list_delete(guarded_instances, node);
+ /* But try to kill it anyway. Just in case */
+ current_node->instance->kill_instance(SIGTERM);
+ node= node->next;
}
return 0;
}
diff --git a/server-tools/instance-manager/guardian.h b/server-tools/instance-manager/guardian.h
index 6d3a2b222d7..27ca155fd67 100644
--- a/server-tools/instance-manager/guardian.h
+++ b/server-tools/instance-manager/guardian.h
@@ -91,7 +91,7 @@ public:
/* Initialize or refresh the list of guarded instances */
int init();
/* Request guardian shutdown. Stop instances if needed */
- void request_shutdown(bool stop_instances);
+ void request_shutdown();
/* Start instance protection */
int guard(Instance *instance, bool nolock= FALSE);
/* Stop instance protection */
@@ -123,7 +123,7 @@ public:
private:
/* Prepares Guardian shutdown. Stops instances is needed */
- int stop_instances(bool stop_instances_arg);
+ int stop_instances();
/* check instance state and act accordingly */
void process_instance(Instance *instance, GUARD_NODE *current_node,
LIST **guarded_instances, LIST *elem);
diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc
index dfe26397414..3927363a3e5 100644
--- a/server-tools/instance-manager/instance.cc
+++ b/server-tools/instance-manager/instance.cc
@@ -34,6 +34,7 @@
#include "mysql_manager_error.h"
#include "portability.h"
#include "priv.h"
+#include "thread_registry.h"
const LEX_STRING
@@ -44,7 +45,8 @@ static const int INSTANCE_NAME_PREFIX_LEN= Instance::DFLT_INSTANCE_NAME.length;
static void start_and_monitor_instance(Instance_options *old_instance_options,
- Instance_map *instance_map);
+ Instance_map *instance_map,
+ Thread_registry *thread_registry);
#ifndef __WIN__
typedef pid_t My_process_info;
@@ -63,7 +65,8 @@ pthread_handler_t proxy(void *arg)
{
Instance *instance= (Instance *) arg;
start_and_monitor_instance(&instance->options,
- instance->get_map());
+ instance->get_map(),
+ &instance->thread_registry);
return 0;
}
@@ -99,6 +102,7 @@ static int wait_process(My_process_info *pi)
thread, but we don't know this one). Or we could use waitpid(), but
couldn't use wait(), because it could return in any wait() in the program.
*/
+
if (linuxthreads)
wait(NULL); /* LinuxThreads were detected */
else
@@ -165,8 +169,8 @@ static int start_process(Instance_options *instance_options,
/* exec never returns */
exit(1);
case -1:
- log_info("cannot create a new process to start instance %s",
- instance_options->instance_name);
+ log_info("cannot create a new process to start instance '%s'.",
+ (const char *) instance_options->instance_name.str);
return 1;
}
return 0;
@@ -239,11 +243,28 @@ static int start_process(Instance_options *instance_options,
*/
static void start_and_monitor_instance(Instance_options *old_instance_options,
- Instance_map *instance_map)
+ Instance_map *instance_map,
+ Thread_registry *thread_registry)
{
Instance_name instance_name(&old_instance_options->instance_name);
Instance *current_instance;
My_process_info process_info;
+ Thread_info thread_info(pthread_self(), FALSE);
+
+ log_info("Monitoring thread (instance: '%s'): started.",
+ (const char *) instance_name.get_c_str());
+
+ if (!old_instance_options->nonguarded)
+ {
+ /*
+ Register thread in Thread_registry to wait for it to stop on shutdown
+ only if instance is nuarded. If instance is guarded, the thread will not
+ finish, because nonguarded instances are not stopped on shutdown.
+ */
+
+ thread_registry->register_thread(&thread_info);
+ my_thread_init();
+ }
/*
Lock instance map to guarantee that no instances are deleted during
@@ -256,7 +277,8 @@ static void start_and_monitor_instance(Instance_options *old_instance_options,
are using is destroyed. (E.g. by "FLUSH INSTANCES")
*/
- log_info("starting instance %s", (const char *) instance_name.get_c_str());
+ log_info("starting instance %s...",
+ (const char *) instance_name.get_c_str());
if (start_process(old_instance_options, &process_info))
{
@@ -279,7 +301,14 @@ static void start_and_monitor_instance(Instance_options *old_instance_options,
instance_map->unlock();
- return;
+ if (!old_instance_options->nonguarded)
+ {
+ thread_registry->unregister_thread(&thread_info);
+ my_thread_end();
+ }
+
+ log_info("Monitoring thread (instance: '%s'): finished.",
+ (const char *) instance_name.get_c_str());
}
@@ -311,9 +340,9 @@ void Instance::remove_pid()
int pid;
if ((pid= options.get_pid()) != 0) /* check the pidfile */
if (options.unlink_pidfile()) /* remove stalled pidfile */
- log_error("cannot remove pidfile for instance %i, this might be \
- since IM lacks permmissions or hasn't found the pidifle",
- options.instance_name);
+ log_error("cannot remove pidfile for instance '%s', this might be "
+ "since IM lacks permmissions or hasn't found the pidifle",
+ (const char *) options.instance_name.str);
}
@@ -342,10 +371,6 @@ int Instance::start()
{
remove_pid();
- /*
- No need to monitor this thread in the Thread_registry, as all
- instances are to be stopped during shutdown.
- */
pthread_t proxy_thd_id;
pthread_attr_t proxy_thd_attr;
int rc;
@@ -403,7 +428,8 @@ void Instance::set_crash_flag_n_wake_all()
-Instance::Instance(): crashed(FALSE), configured(FALSE)
+Instance::Instance(Thread_registry &thread_registry_arg):
+ crashed(FALSE), configured(FALSE), thread_registry(thread_registry_arg)
{
pthread_mutex_init(&LOCK_instance, 0);
pthread_cond_init(&COND_instance_stopped, 0);
@@ -467,9 +493,9 @@ bool Instance::is_running()
We have successfully connected to the server using fake
username/password. Write a warning to the logfile.
*/
- log_info("The Instance Manager was able to log into you server \
- with faked compiled-in password while checking server status. \
- Looks like something is wrong.");
+ log_info("The Instance Manager was able to log into you server "
+ "with faked compiled-in password while checking server status. "
+ "Looks like something is wrong.");
pthread_mutex_unlock(&LOCK_instance);
return_val= TRUE; /* server is alive */
}
@@ -616,10 +642,10 @@ void Instance::kill_instance(int signum)
/* Kill suceeded */
if (signum == SIGKILL) /* really killed instance with SIGKILL */
{
- log_error("The instance %s is being stopped forcibly. Normally" \
- "it should not happen. Probably the instance has been" \
+ log_error("The instance '%s' is being stopped forcibly. Normally"
+ "it should not happen. Probably the instance has been"
"hanging. You should also check your IM setup",
- options.instance_name);
+ (const char *) options.instance_name.str);
/* After sucessful hard kill the pidfile need to be removed */
options.unlink_pidfile();
}
diff --git a/server-tools/instance-manager/instance.h b/server-tools/instance-manager/instance.h
index 1f06cabebf7..329eaa68b1a 100644
--- a/server-tools/instance-manager/instance.h
+++ b/server-tools/instance-manager/instance.h
@@ -27,6 +27,7 @@
#endif
class Instance_map;
+class Thread_registry;
/*
@@ -87,7 +88,7 @@ public:
static bool is_mysqld_compatible_name(const LEX_STRING *name);
public:
- Instance();
+ Instance(Thread_registry &thread_registry_arg);
~Instance();
int init(const LEX_STRING *name_arg);
@@ -120,6 +121,7 @@ public:
public:
enum { DEFAULT_SHUTDOWN_DELAY= 35 };
Instance_options options;
+ Thread_registry &thread_registry;
private:
/* This attributes is a flag, specifies if the instance has been crashed. */
diff --git a/server-tools/instance-manager/instance_map.cc b/server-tools/instance-manager/instance_map.cc
index ec73fb7d73a..2f830e616c4 100644
--- a/server-tools/instance-manager/instance_map.cc
+++ b/server-tools/instance-manager/instance_map.cc
@@ -169,7 +169,7 @@ int Instance_map::process_one_option(const LEX_STRING *group,
if (!(instance= (Instance *) hash_search(&hash, (byte *) group->str,
group->length)))
{
- if (!(instance= new Instance()))
+ if (!(instance= new Instance(thread_registry)))
return 1;
if (instance->init(group) || add_instance(instance))
@@ -213,8 +213,10 @@ int Instance_map::process_one_option(const LEX_STRING *group,
}
-Instance_map::Instance_map(const char *default_mysqld_path_arg):
-mysqld_path(default_mysqld_path_arg)
+Instance_map::Instance_map(const char *default_mysqld_path_arg,
+ Thread_registry &thread_registry_arg):
+ mysqld_path(default_mysqld_path_arg),
+ thread_registry(thread_registry_arg)
{
pthread_mutex_init(&LOCK_instance_map, 0);
}
@@ -293,7 +295,9 @@ int Instance_map::flush_instances()
get_instance_key, delete_instance, 0);
rc= load();
- guardian->init(); // TODO: check error status.
+ /* don't init guardian if we failed to load instances */
+ if (!rc)
+ guardian->init(); // TODO: check error status.
return rc;
}
@@ -331,7 +335,7 @@ int Instance_map::remove_instance(Instance *instance)
int Instance_map::create_instance(const LEX_STRING *instance_name,
const Named_value_arr *options)
{
- Instance *instance= new Instance();
+ Instance *instance= new Instance(thread_registry);
if (!instance)
{
diff --git a/server-tools/instance-manager/instance_map.h b/server-tools/instance-manager/instance_map.h
index 8e6d2360652..9de40e35e0f 100644
--- a/server-tools/instance-manager/instance_map.h
+++ b/server-tools/instance-manager/instance_map.h
@@ -28,6 +28,7 @@
class Guardian_thread;
class Instance;
class Named_value_arr;
+class Thread_registry;
extern int load_all_groups(char ***groups, const char *filename);
extern void free_groups(char **groups);
@@ -104,7 +105,8 @@ public:
int create_instance(const LEX_STRING *instance_name,
const Named_value_arr *options);
- Instance_map(const char *default_mysqld_path_arg);
+ Instance_map(const char *default_mysqld_path_arg,
+ Thread_registry &thread_registry_arg);
~Instance_map();
/*
@@ -130,6 +132,8 @@ private:
enum { START_HASH_SIZE = 16 };
pthread_mutex_t LOCK_instance_map;
HASH hash;
+
+ Thread_registry &thread_registry;
};
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_MAP_H */
diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc
index f6ec751678f..00da6660703 100644
--- a/server-tools/instance-manager/instance_options.cc
+++ b/server-tools/instance-manager/instance_options.cc
@@ -182,7 +182,7 @@ int Instance_options::fill_instance_version()
err:
if (rc)
log_error("fill_instance_version: Failed to get version of '%s'",
- mysqld_path);
+ mysqld_path.str);
return rc;
}
diff --git a/server-tools/instance-manager/listener.cc b/server-tools/instance-manager/listener.cc
index 197c315dee8..62962c00957 100644
--- a/server-tools/instance-manager/listener.cc
+++ b/server-tools/instance-manager/listener.cc
@@ -87,7 +87,7 @@ private:
Listener_thread::Listener_thread(const Listener_thread_args &args) :
Listener_thread_args(args.thread_registry, args.user_map, args.instance_map)
,total_connection_count(0)
- ,thread_info(pthread_self())
+ ,thread_info(pthread_self(), TRUE)
,num_sockets(0)
{
}
@@ -112,6 +112,8 @@ void Listener_thread::run()
{
int i, n= 0;
+ log_info("Listener_thread: started.");
+
#ifndef __WIN__
/* we use this var to check whether we are running on LinuxThreads */
pid_t thread_pid;
@@ -164,7 +166,7 @@ void Listener_thread::run()
if (rc == 0 || rc == -1)
{
if (rc == -1 && errno != EINTR)
- log_error("Listener_thread::run(): select() failed, %s",
+ log_error("Listener_thread: select() failed, %s",
strerror(errno));
continue;
}
@@ -198,7 +200,7 @@ void Listener_thread::run()
/* III. Release all resources and exit */
- log_info("Listener_thread::run(): shutdown requested, exiting...");
+ log_info("Listener_thread: shutdown requested, exiting...");
for (i= 0; i < num_sockets; i++)
close(sockets[i]);
@@ -209,6 +211,8 @@ void Listener_thread::run()
thread_registry.unregister_thread(&thread_info);
my_thread_end();
+
+ log_info("Listener_thread: finished.");
return;
err:
@@ -230,7 +234,7 @@ int Listener_thread::create_tcp_socket()
int ip_socket= socket(AF_INET, SOCK_STREAM, 0);
if (ip_socket == INVALID_SOCKET)
{
- log_error("Listener_thead::run(): socket(AF_INET) failed, %s",
+ log_error("Listener_thead: socket(AF_INET) failed, %s",
strerror(errno));
return -1;
}
@@ -261,7 +265,7 @@ int Listener_thread::create_tcp_socket()
if (bind(ip_socket, (struct sockaddr *) &ip_socket_address,
sizeof(ip_socket_address)))
{
- log_error("Listener_thread::run(): bind(ip socket) failed, '%s'",
+ log_error("Listener_thread: bind(ip socket) failed, '%s'",
strerror(errno));
close(ip_socket);
return -1;
@@ -269,7 +273,7 @@ int Listener_thread::create_tcp_socket()
if (listen(ip_socket, LISTEN_BACK_LOG_SIZE))
{
- log_error("Listener_thread::run(): listen(ip socket) failed, %s",
+ log_error("Listener_thread: listen(ip socket) failed, %s",
strerror(errno));
close(ip_socket);
return -1;
@@ -283,7 +287,7 @@ int Listener_thread::create_tcp_socket()
FD_SET(ip_socket, &read_fds);
sockets[num_sockets++]= ip_socket;
- log_info("accepting connections on ip socket");
+ log_info("accepting connections on ip socket (port: %d)", (int) im_port);
return 0;
}
@@ -294,7 +298,7 @@ create_unix_socket(struct sockaddr_un &unix_socket_address)
int unix_socket= socket(AF_UNIX, SOCK_STREAM, 0);
if (unix_socket == INVALID_SOCKET)
{
- log_error("Listener_thead::run(): socket(AF_UNIX) failed, %s",
+ log_error("Listener_thead: socket(AF_UNIX) failed, %s",
strerror(errno));
return -1;
}
@@ -314,7 +318,7 @@ create_unix_socket(struct sockaddr_un &unix_socket_address)
if (bind(unix_socket, (struct sockaddr *) &unix_socket_address,
sizeof(unix_socket_address)))
{
- log_error("Listener_thread::run(): bind(unix socket) failed, "
+ log_error("Listener_thread: bind(unix socket) failed, "
"socket file name is '%s', error '%s'",
unix_socket_address.sun_path, strerror(errno));
close(unix_socket);
@@ -325,7 +329,7 @@ create_unix_socket(struct sockaddr_un &unix_socket_address)
if (listen(unix_socket, LISTEN_BACK_LOG_SIZE))
{
- log_error("Listener_thread::run(): listen(unix socket) failed, %s",
+ log_error("Listener_thread: listen(unix socket) failed, %s",
strerror(errno));
close(unix_socket);
return -1;
@@ -337,7 +341,7 @@ create_unix_socket(struct sockaddr_un &unix_socket_address)
/* make sure that instances won't be listening our sockets */
set_no_inherit(unix_socket);
- log_info("accepting connections on unix socket %s",
+ log_info("accepting connections on unix socket '%s'",
unix_socket_address.sun_path);
sockets[num_sockets++]= unix_socket;
FD_SET(unix_socket, &read_fds);
diff --git a/server-tools/instance-manager/log.cc b/server-tools/instance-manager/log.cc
index a88344f0b91..7214cde7193 100644
--- a/server-tools/instance-manager/log.cc
+++ b/server-tools/instance-manager/log.cc
@@ -52,14 +52,16 @@ static inline void log(FILE *file, const char *format, va_list args)
struct tm bd_time; // broken-down time
localtime_r(&now, &bd_time);
- char buff_date[32];
- sprintf(buff_date, "%02d%02d%02d %2d:%02d:%02d\t",
- bd_time.tm_year % 100,
- bd_time.tm_mon + 1,
- bd_time.tm_mday,
- bd_time.tm_hour,
- bd_time.tm_min,
- bd_time.tm_sec);
+ char buff_date[128];
+ sprintf(buff_date, "[%d/%lu] [%02d/%02d/%02d %02d:%02d:%02d] ",
+ (int) getpid(),
+ (unsigned long) pthread_self(),
+ bd_time.tm_year % 100,
+ bd_time.tm_mon + 1,
+ bd_time.tm_mday,
+ bd_time.tm_hour,
+ bd_time.tm_min,
+ bd_time.tm_sec);
/* Format the message */
char buff_stack[256];
diff --git a/server-tools/instance-manager/manager.cc b/server-tools/instance-manager/manager.cc
index d2d498eebf1..4bd298eedec 100644
--- a/server-tools/instance-manager/manager.cc
+++ b/server-tools/instance-manager/manager.cc
@@ -120,6 +120,19 @@ int my_sigwait(const sigset_t *set, int *sig)
#endif
+void stop_all(Guardian_thread *guardian, Thread_registry *registry)
+{
+ /*
+ Let guardian thread know that it should break it's processing cycle,
+ once it wakes up.
+ */
+ guardian->request_shutdown();
+ /* wake guardian */
+ pthread_cond_signal(&guardian->COND_guardian);
+ /* stop all threads */
+ registry->deliver_shutdown();
+}
+
/*
manager - entry point to the main instance manager process: start
listener thread, write pid file and enter into signal handling.
@@ -143,7 +156,8 @@ void manager()
*/
User_map user_map;
- Instance_map instance_map(Options::Main::default_mysqld_path);
+ Instance_map instance_map(Options::Main::default_mysqld_path,
+ thread_registry);
Guardian_thread guardian_thread(thread_registry,
&instance_map,
Options::Main::monitoring_interval);
@@ -251,7 +265,6 @@ void manager()
/* Load instances. */
-
{
instance_map.guardian->lock();
instance_map.lock();
@@ -266,7 +279,8 @@ void manager()
log_error("Cannot init instances repository. This might be caused by "
"the wrong config file options. For instance, missing mysqld "
"binary. Aborting.");
- return;
+ stop_all(&guardian_thread, &thread_registry);
+ goto err;
}
}
@@ -284,6 +298,7 @@ void manager()
if (rc)
{
log_error("manager(): set_stacksize_n_create_thread(listener) failed");
+ stop_all(&guardian_thread, &thread_registry);
goto err;
}
}
@@ -294,6 +309,8 @@ void manager()
*/
pthread_cond_signal(&guardian_thread.COND_guardian);
+ log_info("Main loop: started.");
+
while (!shutdown_complete)
{
int signo;
@@ -302,9 +319,24 @@ void manager()
if ((status= my_sigwait(&mask, &signo)) != 0)
{
log_error("sigwait() failed");
+ stop_all(&guardian_thread, &thread_registry);
goto err;
}
+ /*
+ The general idea in this loop is the following:
+ - we are waiting for SIGINT, SIGTERM -- signals that mean we should
+ shutdown;
+ - as shutdown signal is caught, we stop Guardian thread (by calling
+ Guardian_thread::request_shutdown());
+ - as Guardian_thread is stopped, it sends SIGTERM to this thread
+ (by calling Thread_registry::request_shutdown()), so that the
+ my_sigwait() above returns;
+ - as we catch the second SIGTERM, we send signals to all threads
+ registered in Thread_registry (by calling
+ Thread_registry::deliver_shutdown()) and waiting for threads to stop;
+ */
+
#ifndef __WIN__
/*
On some Darwin kernels SIGHUP is delivered along with most
@@ -321,10 +353,11 @@ void manager()
else
#endif
{
+ log_info("Main loop: got shutdown signal.");
+
if (!guardian_thread.is_stopped())
{
- bool stop_instances= TRUE;
- guardian_thread.request_shutdown(stop_instances);
+ guardian_thread.request_shutdown();
pthread_cond_signal(&guardian_thread.COND_guardian);
}
else
@@ -335,6 +368,8 @@ void manager()
}
}
+ log_info("Main loop: finished.");
+
err:
/* delete the pid file */
my_delete(Options::Main::pid_file_name, MYF(0));
diff --git a/server-tools/instance-manager/messages.cc b/server-tools/instance-manager/messages.cc
index 7b32b66fe52..236e33cc900 100644
--- a/server-tools/instance-manager/messages.cc
+++ b/server-tools/instance-manager/messages.cc
@@ -45,7 +45,7 @@ static const char *mysqld_error_message(unsigned sql_errno)
" corresponds to your MySQL Instance Manager version for the right"
" syntax to use";
case ER_BAD_INSTANCE_NAME:
- return "Bad instance name. Check that the instance with such a name exists";
+ return "Unknown instance name";
case ER_INSTANCE_IS_NOT_STARTED:
return "Cannot stop instance. Perhaps the instance is not started, or was"
" started manually, so IM cannot find the pidfile.";
diff --git a/server-tools/instance-manager/mysql_connection.cc b/server-tools/instance-manager/mysql_connection.cc
index 17cda3af704..82b24491903 100644
--- a/server-tools/instance-manager/mysql_connection.cc
+++ b/server-tools/instance-manager/mysql_connection.cc
@@ -97,7 +97,7 @@ Mysql_connection_thread::Mysql_connection_thread(
args.user_map,
args.connection_id,
args.instance_map)
- ,thread_info(pthread_self())
+ ,thread_info(pthread_self(), TRUE)
{
thread_registry.register_thread(&thread_info);
}
@@ -165,7 +165,7 @@ Mysql_connection_thread::~Mysql_connection_thread()
void Mysql_connection_thread::run()
{
- log_info("accepted mysql connection %d", connection_id);
+ log_info("accepted mysql connection %lu", (unsigned long) connection_id);
my_thread_init();
@@ -175,7 +175,8 @@ void Mysql_connection_thread::run()
return;
}
- log_info("connection %d is checked successfully", connection_id);
+ log_info("connection %lu is checked successfully",
+ (unsigned long) connection_id);
vio_keepalive(vio, TRUE);
@@ -314,8 +315,8 @@ int Mysql_connection_thread::do_command()
packet= (char*) net.read_pos;
enum enum_server_command command= (enum enum_server_command)
(uchar) *packet;
- log_info("connection %d: packet_length=%d, command=%d",
- connection_id, packet_length, command);
+ log_info("connection %lu: packet_length=%lu, command=%d",
+ (int) connection_id, (int) packet_length, (int) command);
return dispatch_command(command, packet + 1, packet_length - 1);
}
}
@@ -325,27 +326,33 @@ int Mysql_connection_thread::dispatch_command(enum enum_server_command command,
{
switch (command) {
case COM_QUIT: // client exit
- log_info("query for connection %d received quit command", connection_id);
+ log_info("query for connection %lu received quit command",
+ (unsigned long) connection_id);
return 1;
case COM_PING:
- log_info("query for connection %d received ping command", connection_id);
+ log_info("query for connection %lu received ping command",
+ (unsigned long) connection_id);
net_send_ok(&net, connection_id, NULL);
break;
case COM_QUERY:
{
- log_info("query for connection %d : ----\n%s\n-------------------------",
- connection_id,packet);
+ log_info("query for connection %lu : ----\n%s\n-------------------------",
+ (int) connection_id,
+ (const char *) packet);
if (Command *command= parse_command(&instance_map, packet))
{
int res= 0;
- log_info("query for connection %d successfully parsed",connection_id);
+ log_info("query for connection %lu successfully parsed",
+ (unsigned long) connection_id);
res= command->execute(&net, connection_id);
delete command;
if (!res)
- log_info("query for connection %d executed ok",connection_id);
+ log_info("query for connection %lu executed ok",
+ (unsigned long) connection_id);
else
{
- log_info("query for connection %d executed err=%d",connection_id,res);
+ log_info("query for connection %lu executed err=%d",
+ (unsigned long) connection_id, (int) res);
net_send_error(&net, res);
return 0;
}
@@ -358,7 +365,8 @@ int Mysql_connection_thread::dispatch_command(enum enum_server_command command,
break;
}
default:
- log_info("query for connection %d received unknown command",connection_id);
+ log_info("query for connection %lu received unknown command",
+ (unsigned long) connection_id);
net_send_error(&net, ER_UNKNOWN_COM_ERROR);
break;
}
diff --git a/server-tools/instance-manager/options.cc b/server-tools/instance-manager/options.cc
index 07a1fd3e932..0fff68fbd4f 100644
--- a/server-tools/instance-manager/options.cc
+++ b/server-tools/instance-manager/options.cc
@@ -41,7 +41,6 @@
static char win_dflt_config_file_name[FN_REFLEN];
static char win_dflt_password_file_name[FN_REFLEN];
static char win_dflt_pid_file_name[FN_REFLEN];
-static char win_dflt_socket_file_name[FN_REFLEN];
static char win_dflt_mysqld_path[FN_REFLEN];
@@ -54,7 +53,6 @@ my_bool Options::Service::stand_alone;
const char *Options::Main::config_file= win_dflt_config_file_name;
const char *Options::Main::password_file_name= win_dflt_password_file_name;
const char *Options::Main::pid_file_name= win_dflt_pid_file_name;
-const char *Options::Main::socket_file_name= win_dflt_socket_file_name;
const char *Options::Main::default_mysqld_path= win_dflt_mysqld_path;
@@ -262,10 +260,12 @@ static struct my_option my_long_options[] =
0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0 },
#endif
+#ifndef __WIN__
{ "socket", OPT_SOCKET, "Socket file to use for connection.",
(gptr *) &Options::Main::socket_file_name,
(gptr *) &Options::Main::socket_file_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+#endif
#ifdef __WIN__
{ "standalone", OPT_STAND_ALONE, "Run the application in stand alone mode.",
@@ -550,8 +550,6 @@ static int setup_windows_defaults()
strxmov(win_dflt_password_file_name, dir_name, im_name, DFLT_PASSWD_FILE_EXT,
NullS);
strxmov(win_dflt_pid_file_name, dir_name, im_name, DFLT_PID_FILE_EXT, NullS);
- strxmov(win_dflt_socket_file_name, dir_name, im_name, DFLT_SOCKET_FILE_EXT,
- NullS);
return 0;
}
diff --git a/server-tools/instance-manager/options.h b/server-tools/instance-manager/options.h
index 5c54ff201b2..ac4f6507892 100644
--- a/server-tools/instance-manager/options.h
+++ b/server-tools/instance-manager/options.h
@@ -50,7 +50,9 @@ struct Options
static bool is_forced_default_file;
static const char *pid_file_name;
+#ifndef __WIN__
static const char *socket_file_name;
+#endif
static const char *password_file_name;
static const char *default_mysqld_path;
static uint monitoring_interval;
diff --git a/server-tools/instance-manager/parse.cc b/server-tools/instance-manager/parse.cc
index d69fb1cecec..048f7983b32 100644
--- a/server-tools/instance-manager/parse.cc
+++ b/server-tools/instance-manager/parse.cc
@@ -273,7 +273,7 @@ Command *parse_command(Instance_map *map, const char *text)
{
uint word_len;
LEX_STRING instance_name;
- Command *command;
+ Command *command= 0;
const char *saved_text= text;
Token tok1= shift_token(&text, &word_len);
diff --git a/server-tools/instance-manager/thread_registry.cc b/server-tools/instance-manager/thread_registry.cc
index a424860548d..10370e0981e 100644
--- a/server-tools/instance-manager/thread_registry.cc
+++ b/server-tools/instance-manager/thread_registry.cc
@@ -43,8 +43,10 @@ static void handle_signal(int __attribute__((unused)) sig_no)
*/
Thread_info::Thread_info() {}
-Thread_info::Thread_info(pthread_t thread_id_arg) :
- thread_id(thread_id_arg) {}
+Thread_info::Thread_info(pthread_t thread_id_arg,
+ bool send_signal_on_shutdown_arg) :
+ thread_id(thread_id_arg),
+ send_signal_on_shutdown(send_signal_on_shutdown_arg) {}
/*
TODO: think about moving signal information (now it's shutdown_in_progress)
@@ -86,6 +88,9 @@ Thread_registry::~Thread_registry()
void Thread_registry::register_thread(Thread_info *info)
{
+ log_info("Thread_registry: registering thread %d...",
+ (int) info->thread_id);
+
#ifndef __WIN__
struct sigaction sa;
sa.sa_handler= handle_signal;
@@ -112,11 +117,19 @@ void Thread_registry::register_thread(Thread_info *info)
void Thread_registry::unregister_thread(Thread_info *info)
{
+ log_info("Thread_registry: unregistering thread %d...",
+ (int) info->thread_id);
+
pthread_mutex_lock(&LOCK_thread_registry);
info->prev->next= info->next;
info->next->prev= info->prev;
+
if (head.next == &head)
+ {
+ log_info("Thread_registry: thread registry is empty!");
pthread_cond_signal(&COND_thread_registry_is_empty);
+ }
+
pthread_mutex_unlock(&LOCK_thread_registry);
}
@@ -181,11 +194,6 @@ int Thread_registry::cond_timedwait(Thread_info *info, pthread_cond_t *cond,
void Thread_registry::deliver_shutdown()
{
- Thread_info *info;
- struct timespec shutdown_time;
- int error;
- set_timespec(shutdown_time, 1);
-
pthread_mutex_lock(&LOCK_thread_registry);
shutdown_in_progress= TRUE;
@@ -199,29 +207,14 @@ void Thread_registry::deliver_shutdown()
process_alarm(THR_SERVER_ALARM);
#endif
- for (info= head.next; info != &head; info= info->next)
- {
- pthread_kill(info->thread_id, THREAD_KICK_OFF_SIGNAL);
- /*
- sic: race condition here, the thread may not yet fall into
- pthread_cond_wait.
- */
- if (info->current_cond)
- pthread_cond_signal(info->current_cond);
- }
/*
- The common practice is to test predicate before pthread_cond_wait.
- I don't do that here because the predicate is practically always false
- before wait - is_shutdown's been just set, and the lock's still not
- released - the only case when the predicate is false is when no other
- threads exist.
+ sic: race condition here, the thread may not yet fall into
+ pthread_cond_wait.
*/
- while (((error= pthread_cond_timedwait(&COND_thread_registry_is_empty,
- &LOCK_thread_registry,
- &shutdown_time)) != ETIMEDOUT &&
- error != ETIME) &&
- head.next != &head)
- ;
+
+ interrupt_threads();
+
+ wait_for_threads_to_unregister();
/*
If previous signals did not reach some threads, they must be sleeping
@@ -230,11 +223,28 @@ void Thread_registry::deliver_shutdown()
so this time everybody should be informed (presumably each worker can
get CPU during shutdown_time.)
*/
- for (info= head.next; info != &head; info= info->next)
+
+ interrupt_threads();
+
+ /* Get the last chance to threads to stop. */
+
+ wait_for_threads_to_unregister();
+
+ /*
+ Print out threads, that didn't stopped. Thread_registry destructor will
+ probably abort the program if there is still any alive thread.
+ */
+
+ if (head.next != &head)
{
- pthread_kill(info->thread_id, THREAD_KICK_OFF_SIGNAL);
- if (info->current_cond)
- pthread_cond_signal(info->current_cond);
+ log_info("Thread_registry: non-stopped threads:");
+
+ for (Thread_info *info= head.next; info != &head; info= info->next)
+ log_info(" - %ld", (long int) info->thread_id);
+ }
+ else
+ {
+ log_info("Thread_registry: all threads stopped.");
}
pthread_mutex_unlock(&LOCK_thread_registry);
@@ -245,3 +255,46 @@ void Thread_registry::request_shutdown()
{
pthread_kill(sigwait_thread_pid, SIGTERM);
}
+
+
+void Thread_registry::interrupt_threads()
+{
+ for (Thread_info *info= head.next; info != &head; info= info->next)
+ {
+ if (!info->send_signal_on_shutdown)
+ continue;
+
+ pthread_kill(info->thread_id, THREAD_KICK_OFF_SIGNAL);
+ if (info->current_cond)
+ pthread_cond_signal(info->current_cond);
+ }
+}
+
+
+void Thread_registry::wait_for_threads_to_unregister()
+{
+ struct timespec shutdown_time;
+
+ set_timespec(shutdown_time, 1);
+
+ log_info("Thread_registry: joining threads...");
+
+ while (true)
+ {
+ if (head.next == &head)
+ {
+ log_info("Thread_registry: emptied.");
+ return;
+ }
+
+ int error= pthread_cond_timedwait(&COND_thread_registry_is_empty,
+ &LOCK_thread_registry,
+ &shutdown_time);
+
+ if (error == ETIMEDOUT || error == ETIME)
+ {
+ log_info("Thread_registry: threads shutdown timed out.");
+ return;
+ }
+ }
+}
diff --git a/server-tools/instance-manager/thread_registry.h b/server-tools/instance-manager/thread_registry.h
index 6dc320a8533..503d24e5fb0 100644
--- a/server-tools/instance-manager/thread_registry.h
+++ b/server-tools/instance-manager/thread_registry.h
@@ -67,13 +67,17 @@
class Thread_info
{
public:
- Thread_info();
- Thread_info(pthread_t thread_id_arg);
+ Thread_info(pthread_t thread_id_arg, bool send_signal_on_shutdown_arg);
friend class Thread_registry;
+
+private:
+ Thread_info();
+
private:
pthread_cond_t *current_cond;
Thread_info *prev, *next;
pthread_t thread_id;
+ bool send_signal_on_shutdown;
};
@@ -98,6 +102,10 @@ public:
int cond_timedwait(Thread_info *info, pthread_cond_t *cond,
pthread_mutex_t *mutex, struct timespec *wait_time);
private:
+ void interrupt_threads();
+ void wait_for_threads_to_unregister();
+
+private:
Thread_info head;
bool shutdown_in_progress;
pthread_mutex_t LOCK_thread_registry;
diff --git a/server-tools/instance-manager/user_map.cc b/server-tools/instance-manager/user_map.cc
index e8128cf015b..c1439e983d8 100644
--- a/server-tools/instance-manager/user_map.cc
+++ b/server-tools/instance-manager/user_map.cc
@@ -74,11 +74,10 @@ int User::init(const char *line)
password_length= strlen(password);
if (password_length > SCRAMBLED_PASSWORD_CHAR_LENGTH)
{
- log_info("Error: password is too long (%d). Max length: %d. ",
- "User line: '%s'.",
- (int) password_length,
- (int) SCRAMBLED_PASSWORD_CHAR_LENGTH,
- (const char *) line);
+ log_info("Error: password is too long (%d). Max length: %d. User line: '%s'.",
+ (int) password_length,
+ (int) SCRAMBLED_PASSWORD_CHAR_LENGTH,
+ line);
return 1;
}
diff --git a/sql-common/client.c b/sql-common/client.c
index 79a5be938b2..b6947028e74 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -2364,6 +2364,8 @@ my_bool mysql_reconnect(MYSQL *mysql)
{
MYSQL tmp_mysql;
DBUG_ENTER("mysql_reconnect");
+ DBUG_ASSERT(mysql);
+ DBUG_PRINT("enter", ("mysql->reconnect: %d", mysql->reconnect));
if (!mysql->reconnect ||
(mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info)
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index b4cfe041529..ab9a2c6d7c8 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -465,8 +465,10 @@ err:
There may be an optional [.second_part] after seconds
length Length of str
l_time Store result here
- was_cut Set to 1 if value was cut during conversion or to 0
- otherwise.
+ warning Set MYSQL_TIME_WARN_TRUNCATED flag if the input string
+ was cut during conversion, and/or
+ MYSQL_TIME_WARN_OUT_OF_RANGE flag, if the value is
+ out of range.
NOTES
Because of the extra days argument, this function can only
@@ -478,15 +480,16 @@ err:
*/
my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
- int *was_cut)
+ int *warning)
{
- long date[5],value;
+ ulong date[5];
+ ulonglong value;
const char *end=str+length, *end_of_days;
my_bool found_days,found_hours;
uint state;
l_time->neg=0;
- *was_cut= 0;
+ *warning= 0;
for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++)
length--;
if (str != end && *str == '-')
@@ -501,13 +504,16 @@ my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
/* Check first if this is a full TIMESTAMP */
if (length >= 12)
{ /* Probably full timestamp */
+ int was_cut;
enum enum_mysql_timestamp_type
res= str_to_datetime(str, length, l_time,
- (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), was_cut);
+ (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), &was_cut);
if ((int) res >= (int) MYSQL_TIMESTAMP_ERROR)
+ {
+ if (was_cut)
+ *warning|= MYSQL_TIME_WARN_TRUNCATED;
return res == MYSQL_TIMESTAMP_ERROR;
- /* We need to restore was_cut flag since str_to_datetime can modify it */
- *was_cut= 0;
+ }
}
/* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */
@@ -587,7 +593,7 @@ fractional:
if (field_length > 0)
value*= (long) log_10_int[field_length];
else if (field_length < 0)
- *was_cut= 1;
+ *warning|= MYSQL_TIME_WARN_TRUNCATED;
date[4]=value;
}
else
@@ -601,10 +607,7 @@ fractional:
((str[1] == '-' || str[1] == '+') &&
(end - str) > 2 &&
my_isdigit(&my_charset_latin1, str[2]))))
- {
- *was_cut= 1;
return 1;
- }
if (internal_format_positions[7] != 255)
{
@@ -623,12 +626,12 @@ fractional:
}
}
- /* Some simple checks */
- if (date[2] >= 60 || date[3] >= 60)
- {
- *was_cut= 1;
+ /* Integer overflow checks */
+ if (date[0] > UINT_MAX || date[1] > UINT_MAX ||
+ date[2] > UINT_MAX || date[3] > UINT_MAX ||
+ date[4] > UINT_MAX)
return 1;
- }
+
l_time->year= 0; /* For protocol::store_time */
l_time->month= 0;
l_time->day= date[0];
@@ -638,6 +641,10 @@ fractional:
l_time->second_part= date[4];
l_time->time_type= MYSQL_TIMESTAMP_TIME;
+ /* Check if the value is valid and fits into TIME range */
+ if (check_time_range(l_time, warning))
+ return 1;
+
/* Check if there is garbage at end of the TIME specification */
if (str != end)
{
@@ -645,7 +652,7 @@ fractional:
{
if (!my_isspace(&my_charset_latin1,*str))
{
- *was_cut= 1;
+ *warning|= MYSQL_TIME_WARN_TRUNCATED;
break;
}
} while (++str != end);
@@ -655,6 +662,47 @@ fractional:
/*
+ Check 'time' value to lie in the TIME range
+
+ SYNOPSIS:
+ check_time_range()
+ time pointer to TIME value
+ warning set MYSQL_TIME_WARN_OUT_OF_RANGE flag if the value is out of range
+
+ DESCRIPTION
+ If the time value lies outside of the range [-838:59:59, 838:59:59],
+ set it to the closest endpoint of the range and set
+ MYSQL_TIME_WARN_OUT_OF_RANGE flag in the 'warning' variable.
+
+ RETURN
+ 0 time value is valid, but was possibly truncated
+ 1 time value is invalid
+*/
+
+int check_time_range(struct st_mysql_time *time, int *warning)
+{
+ longlong hour;
+
+ if (time->minute >= 60 || time->second >= 60)
+ return 1;
+
+ hour= time->hour + (24*time->day);
+ if (hour <= TIME_MAX_HOUR &&
+ (hour != TIME_MAX_HOUR || time->minute != TIME_MAX_MINUTE ||
+ time->second != TIME_MAX_SECOND || !time->second_part))
+ return 0;
+
+ time->day= 0;
+ time->hour= TIME_MAX_HOUR;
+ time->minute= TIME_MAX_MINUTE;
+ time->second= TIME_MAX_SECOND;
+ time->second_part= 0;
+ *warning|= MYSQL_TIME_WARN_OUT_OF_RANGE;
+ return 0;
+}
+
+
+/*
Prepare offset of system time zone from UTC for my_system_gmt_sec() func.
SYNOPSIS
@@ -730,16 +778,28 @@ long calc_daynr(uint year,uint month,uint day)
RETURN VALUE
Time in UTC seconds since Unix Epoch representation.
*/
-my_time_t
-my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone,
- my_bool *in_dst_time_gap)
+my_time_t
+my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone,
+ bool *in_dst_time_gap)
{
uint loop;
- time_t tmp;
+ time_t tmp= 0;
+ int shift= 0;
+ MYSQL_TIME tmp_time;
+ MYSQL_TIME *t= &tmp_time;
struct tm *l_time,tm_tmp;
long diff, current_timezone;
/*
+ Use temp variable to avoid trashing input data, which could happen in
+ case of shift required for boundary dates processing.
+ */
+ memcpy(&tmp_time, t_src, sizeof(MYSQL_TIME));
+
+ if (!validate_timestamp_range(t))
+ return 0;
+
+ /*
Calculate the gmt time based on current time and timezone
The -1 on the end is to ensure that if have a date that exists twice
(like 2002-10-27 02:00:0 MET), we will find the initial date.
@@ -752,13 +812,89 @@ my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone,
Note: this code assumes that our time_t estimation is not too far away
from real value (we assume that localtime_r(tmp) will return something
within 24 hrs from t) which is probably true for all current time zones.
+
+ Note2: For the dates, which have time_t representation close to
+ MAX_INT32 (efficient time_t limit for supported platforms), we should
+ do a small trick to avoid overflow. That is, convert the date, which is
+ two days earlier, and then add these days to the final value.
+
+ The same trick is done for the values close to 0 in time_t
+ representation for platfroms with unsigned time_t (QNX).
+
+ To be more verbose, here is a sample (extracted from the code below):
+ (calc_daynr(2038, 1, 19) - (long) days_at_timestart)*86400L + 4*3600L
+ would return -2147480896 because of the long type overflow. In result
+ we would get 1901 year in localtime_r(), which is an obvious error.
+
+ Alike problem raises with the dates close to Epoch. E.g.
+ (calc_daynr(1969, 12, 31) - (long) days_at_timestart)*86400L + 23*3600L
+ will give -3600.
+
+ On some platforms, (E.g. on QNX) time_t is unsigned and localtime(-3600)
+ wil give us a date around 2106 year. Which is no good.
+
+ Theoreticaly, there could be problems with the latter conversion:
+ there are at least two timezones, which had time switches near 1 Jan
+ of 1970 (because of political reasons). These are America/Hermosillo and
+ America/Mazatlan time zones. They changed their offset on
+ 1970-01-01 08:00:00 UTC from UTC-8 to UTC-7. For these zones
+ the code below will give incorrect results for dates close to
+ 1970-01-01, in the case OS takes into account these historical switches.
+ Luckily, it seems that we support only one platform with unsigned
+ time_t. It's QNX. And QNX does not support historical timezone data at all.
+ E.g. there are no /usr/share/zoneinfo/ files or any other mean to supply
+ historical information for localtime_r() etc. That is, the problem is not
+ relevant to QNX.
+
+ We are safe with shifts close to MAX_INT32, as there are no known
+ time switches on Jan 2038 yet :)
*/
- tmp=(time_t) (((calc_daynr((uint) t->year,(uint) t->month,(uint) t->day) -
- (long) days_at_timestart)*86400L + (long) t->hour*3600L +
- (long) (t->minute*60 + t->second)) + (time_t) my_time_zone -
- 3600);
- current_timezone= my_time_zone;
+ if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && (t->day > 4))
+ {
+ /*
+ Below we will pass (uint) (t->day - shift) to calc_daynr.
+ As we don't want to get an overflow here, we will shift
+ only safe dates. That's why we have (t->day > 4) above.
+ */
+ t->day-= 2;
+ shift= 2;
+ }
+#ifdef TIME_T_UNSIGNED
+ else
+ {
+ /*
+ We can get 0 in time_t representaion only on 1969, 31 of Dec or on
+ 1970, 1 of Jan. For both dates we use shift, which is added
+ to t->day in order to step out a bit from the border.
+ This is required for platforms, where time_t is unsigned.
+ As far as I know, among the platforms we support it's only QNX.
+ Note: the order of below if-statements is significant.
+ */
+ if ((t->year == TIMESTAMP_MIN_YEAR + 1) && (t->month == 1)
+ && (t->day <= 10))
+ {
+ t->day+= 2;
+ shift= -2;
+ }
+
+ if ((t->year == TIMESTAMP_MIN_YEAR) && (t->month == 12)
+ && (t->day == 31))
+ {
+ t->year++;
+ t->month= 1;
+ t->day= 2;
+ shift= -2;
+ }
+ }
+#endif
+
+ tmp= (time_t) (((calc_daynr((uint) t->year, (uint) t->month, (uint) t->day) -
+ (long) days_at_timestart)*86400L + (long) t->hour*3600L +
+ (long) (t->minute*60 + t->second)) + (time_t) my_time_zone -
+ 3600);
+
+ current_timezone= my_time_zone;
localtime_r(&tmp,&tm_tmp);
l_time=&tm_tmp;
for (loop=0;
@@ -810,7 +946,24 @@ my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone,
*in_dst_time_gap= 1;
}
*my_timezone= current_timezone;
-
+
+
+ /* shift back, if we were dealing with boundary dates */
+ tmp+= shift*86400L;
+
+ /*
+ This is possible for dates, which slightly exceed boundaries.
+ Conversion will pass ok for them, but we don't allow them.
+ First check will pass for platforms with signed time_t.
+ instruction above (tmp+= shift*86400L) could exceed
+ MAX_INT32 (== TIMESTAMP_MAX_VALUE) and overflow will happen.
+ So, tmp < TIMESTAMP_MIN_VALUE will be triggered. On platfroms
+ with unsigned time_t tmp+= shift*86400L might result in a number,
+ larger then TIMESTAMP_MAX_VALUE, so another check will work.
+ */
+ if ((tmp < TIMESTAMP_MIN_VALUE) || (tmp > TIMESTAMP_MAX_VALUE))
+ tmp= 0;
+end:
return (my_time_t) tmp;
} /* my_system_gmt_sec */
@@ -840,7 +993,7 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type)
int my_time_to_str(const MYSQL_TIME *l_time, char *to)
{
uint extra_hours= 0;
- return my_sprintf(to, (to, "%s%02d:%02d:%02d",
+ return my_sprintf(to, (to, "%s%02u:%02u:%02u",
(l_time->neg ? "-" : ""),
extra_hours+ l_time->hour,
l_time->minute,
@@ -849,7 +1002,7 @@ int my_time_to_str(const MYSQL_TIME *l_time, char *to)
int my_date_to_str(const MYSQL_TIME *l_time, char *to)
{
- return my_sprintf(to, (to, "%04d-%02d-%02d",
+ return my_sprintf(to, (to, "%04u-%02u-%02u",
l_time->year,
l_time->month,
l_time->day));
@@ -857,7 +1010,7 @@ int my_date_to_str(const MYSQL_TIME *l_time, char *to)
int my_datetime_to_str(const MYSQL_TIME *l_time, char *to)
{
- return my_sprintf(to, (to, "%04d-%02d-%02d %02d:%02d:%02d",
+ return my_sprintf(to, (to, "%04u-%02u-%02u %02u:%02u:%02u",
l_time->year,
l_time->month,
l_time->day,
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 97e00471a6e..9a0303a433f 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -30,12 +30,13 @@ libexec_PROGRAMS = mysqld
noinst_PROGRAMS = gen_lex_hash
bin_PROGRAMS = mysql_tzinfo_to_sql
gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@
-LDADD = $(top_builddir)/vio/libvio.a \
+SUPPORTING_LIBS = $(top_builddir)/vio/libvio.a \
$(top_builddir)/mysys/libmysys.a \
$(top_builddir)/dbug/libdbug.a \
$(top_builddir)/regex/libregex.a \
- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
-mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(LDADD)
+ $(top_builddir)/strings/libmystrings.a
+mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(SUPPORTING_LIBS)
+LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@
mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \
@pstack_libs@ \
@mysql_plugin_libs@ \
@@ -151,9 +152,12 @@ mysql_tzinfo_to_sql.o: $(mysql_tzinfo_to_sql_SOURCES)
# things like different grammars for different pars of MySQL can
# happen if you are unlucky.
sql_yacc.cc: sql_yacc.yy
+
sql_yacc.h: sql_yacc.yy
sql_yacc.o: sql_yacc.cc sql_yacc.h $(HEADERS)
+ @SED@ -e 's/__attribute__ ((__unused__))//' sql_yacc.cc > sql_yacc.cc-new
+ @MV@ sql_yacc.cc-new sql_yacc.cc
@echo "Note: The following compile may take a long time."
@echo "If it fails, re-run configure with --with-low-memory"
$(CXXCOMPILE) $(LM_CFLAGS) -c $<
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index 4b9aa43b14b..afd10350bb5 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -886,14 +886,29 @@ Event_queue_element::load_from_row(TABLE *table)
goto error;
/*
- In DB the values start from 1 but enum interval_type starts
- from 0
+ We load the interval type from disk as string and then map it to
+ an integer. This decouples the values of enum interval_type
+ and values actually stored on disk. Therefore the type can be
+ reordered without risking incompatibilities of data between versions.
*/
if (!table->field[ET_FIELD_TRANSIENT_INTERVAL]->is_null())
- interval= (interval_type) ((ulonglong)
- table->field[ET_FIELD_TRANSIENT_INTERVAL]->val_int() - 1);
- else
- interval= (interval_type) 0;
+ {
+ int i;
+ char buff[MAX_FIELD_WIDTH];
+ String str(buff, sizeof(buff), &my_charset_bin);
+ LEX_STRING tmp;
+
+ table->field[ET_FIELD_TRANSIENT_INTERVAL]->val_str(&str);
+ if (!(tmp.length= str.length()))
+ goto error;
+
+ tmp.str= str.c_ptr_safe();
+
+ i= find_string_in_array(interval_type_to_name, &tmp, system_charset_info);
+ if (i < 0)
+ goto error;
+ interval= (interval_type) i;
+ }
table->field[ET_FIELD_LAST_EXECUTED]->get_date(&last_executed,
TIME_NO_ZERO_DATE);
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 464c26044c7..3d30aff669b 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -188,11 +188,11 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et,
fields[ET_FIELD_INTERVAL_EXPR]->store((longlong)et->expression, TRUE);
fields[ET_FIELD_TRANSIENT_INTERVAL]->set_notnull();
- /*
- In the enum (C) intervals start from 0 but in mysql enum valid values
- start from 1. Thus +1 offset is needed!
- */
- fields[ET_FIELD_TRANSIENT_INTERVAL]->store((longlong)et->interval+1, TRUE);
+
+ fields[ET_FIELD_TRANSIENT_INTERVAL]->
+ store(interval_type_to_name[et->interval].str,
+ interval_type_to_name[et->interval].length,
+ scs);
fields[ET_FIELD_EXECUTE_AT]->set_null();
diff --git a/sql/field.cc b/sql/field.cc
index 09e919d872a..122a44305f2 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4875,9 +4875,10 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
{
TIME ltime;
long tmp;
- int error;
+ int error= 0;
+ int warning;
- if (str_to_time(from, len, &ltime, &error))
+ if (str_to_time(from, len, &ltime, &warning))
{
tmp=0L;
error= 2;
@@ -4886,29 +4887,27 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
}
else
{
- if (error)
+ if (warning & MYSQL_TIME_WARN_TRUNCATED)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED,
from, len, MYSQL_TIMESTAMP_TIME, 1);
-
- if (ltime.month)
- ltime.day=0;
- tmp=(ltime.day*24L+ltime.hour)*10000L+(ltime.minute*100+ltime.second);
- if (tmp > 8385959)
+ if (warning & MYSQL_TIME_WARN_OUT_OF_RANGE)
{
- tmp=8385959;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
from, len, MYSQL_TIMESTAMP_TIME, !error);
error= 1;
}
+ if (ltime.month)
+ ltime.day=0;
+ tmp=(ltime.day*24L+ltime.hour)*10000L+(ltime.minute*100+ltime.second);
if (error > 1)
error= 2;
}
if (ltime.neg)
tmp= -tmp;
- error |= Field_time::store((longlong) tmp, FALSE);
+ int3store(ptr,tmp);
return error;
}
@@ -4928,16 +4927,16 @@ int Field_time::store(double nr)
ASSERT_COLUMN_MARKED_FOR_WRITE;
long tmp;
int error= 0;
- if (nr > 8385959.0)
+ if (nr > (double)TIME_MAX_VALUE)
{
- tmp=8385959L;
+ tmp= TIME_MAX_VALUE;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME);
error= 1;
}
- else if (nr < -8385959.0)
+ else if (nr < (double)-TIME_MAX_VALUE)
{
- tmp= -8385959L;
+ tmp= -TIME_MAX_VALUE;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME);
error= 1;
@@ -4966,17 +4965,17 @@ int Field_time::store(longlong nr, bool unsigned_val)
ASSERT_COLUMN_MARKED_FOR_WRITE;
long tmp;
int error= 0;
- if (nr < (longlong) -8385959L && !unsigned_val)
+ if (nr < (longlong) -TIME_MAX_VALUE && !unsigned_val)
{
- tmp= -8385959L;
+ tmp= -TIME_MAX_VALUE;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, nr,
MYSQL_TIMESTAMP_TIME, 1);
error= 1;
}
- else if (nr > (longlong) 8385959 || nr < 0 && unsigned_val)
+ else if (nr > (longlong) TIME_MAX_VALUE || nr < 0 && unsigned_val)
{
- tmp=8385959L;
+ tmp= TIME_MAX_VALUE;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE, nr,
MYSQL_TIMESTAMP_TIME, 1);
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 9554a6fdf93..cb5892e3481 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -6510,7 +6510,7 @@ static int ndbcluster_init(void *p)
}
{
char buf[128];
- my_snprintf(buf, sizeof(buf), "mysqld --server-id=%d", server_id);
+ my_snprintf(buf, sizeof(buf), "mysqld --server-id=%lu", server_id);
g_ndb_cluster_connection->set_name(buf);
}
g_ndb_cluster_connection->set_optimized_node_selection
@@ -7267,7 +7267,7 @@ int handle_trailing_share(NDB_SHARE *share)
share->key_length= min_key_length;
}
share->key_length=
- my_snprintf(share->key, min_key_length + 1, "#leak%d",
+ my_snprintf(share->key, min_key_length + 1, "#leak%lu",
trailing_share_id++);
}
/* Keep it for possible the future trailing free */
@@ -9804,12 +9804,12 @@ ndbcluster_show_status(handlerton *hton, THD* thd, stat_print_fn *stat_print,
update_status_variables(g_ndb_cluster_connection);
buflen=
my_snprintf(buf, sizeof(buf),
- "cluster_node_id=%u, "
+ "cluster_node_id=%ld, "
"connected_host=%s, "
- "connected_port=%u, "
- "number_of_data_nodes=%u, "
- "number_of_ready_data_nodes=%u, "
- "connect_count=%u",
+ "connected_port=%ld, "
+ "number_of_data_nodes=%ld, "
+ "number_of_ready_data_nodes=%ld, "
+ "connect_count=%ld",
ndb_cluster_node_id,
ndb_connected_host,
ndb_connected_port,
@@ -10695,7 +10695,8 @@ static int ndbcluster_fill_files_table(handlerton *hton,
table->field[IS_FILES_VERSION]->store(uf.getObjectVersion());
char extra[100];
- int len= my_snprintf(extra,sizeof(extra),"CLUSTER_NODE=%u;UNDO_BUFFER_SIZE=%lu",id,lfg.getUndoBufferSize());
+ int len= my_snprintf(extra,sizeof(extra),"CLUSTER_NODE=%u;UNDO_BUFFER_SIZE=%lu",
+ id, (ulong) lfg.getUndoBufferSize());
table->field[IS_FILES_EXTRA]->set_notnull();
table->field[IS_FILES_EXTRA]->store(extra, len, system_charset_info);
schema_table_store_record(thd, table);
@@ -10712,7 +10713,6 @@ static int ndbcluster_fill_files_table(handlerton *hton,
for (i= 0; i < lfglist.count; i++)
{
NdbDictionary::Dictionary::List::Element& elt= lfglist.elements[i];
- unsigned id;
NdbDictionary::LogfileGroup lfg= dict->getLogfileGroup(elt.name);
ndberr= dict->getNdbError();
@@ -10750,7 +10750,7 @@ static int ndbcluster_fill_files_table(handlerton *hton,
char extra[100];
int len= my_snprintf(extra,sizeof(extra),
"UNDO_BUFFER_SIZE=%lu",
- lfg.getUndoBufferSize());
+ (ulong) lfg.getUndoBufferSize());
table->field[IS_FILES_EXTRA]->set_notnull();
table->field[IS_FILES_EXTRA]->store(extra, len, system_charset_info);
schema_table_store_record(thd, table);
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index 5f5c8bcb221..3dfca5d1bb2 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -3907,7 +3907,7 @@ err:
close_thread_tables(thd);
pthread_mutex_lock(&injector_mutex);
/* don't mess with the injector_ndb anymore from other threads */
- int ndb_obj_cnt= 1; // g_ndb
+ uint ndb_obj_cnt= 1; // g_ndb
ndb_obj_cnt+= injector_ndb == 0 ? 0 : 1;
ndb_obj_cnt+= schema_ndb == 0 ? 0 : 1;
ndb_obj_cnt+= ndbcluster_util_inited ? 1 : 0;
@@ -3930,7 +3930,8 @@ err:
* otherwise user thread can have ongoing SUB_DATA
*/
int sleep_cnt= 0;
- while (sleep_cnt < 300 && g_ndb_cluster_connection->get_active_ndb_objects() > ndb_obj_cnt)
+ while (sleep_cnt < 300 &&
+ g_ndb_cluster_connection->get_active_ndb_objects() > ndb_obj_cnt)
{
my_sleep(10000); // 10ms
sleep_cnt++;
diff --git a/sql/handler.cc b/sql/handler.cc
index 280e518b3c5..451f974a066 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -376,11 +376,12 @@ int ha_finalize_handlerton(st_plugin_int *plugin)
case SHOW_OPTION_YES:
if (installed_htons[hton->db_type] == hton)
installed_htons[hton->db_type]= NULL;
- if (hton->panic && hton->panic(hton, HA_PANIC_CLOSE))
- DBUG_RETURN(1);
break;
};
+ if (hton->panic)
+ hton->panic(hton, HA_PANIC_CLOSE);
+
if (plugin->plugin->deinit)
{
/*
@@ -509,31 +510,22 @@ int ha_init()
DBUG_RETURN(error);
}
-/*
- close, flush or restart databases
- Ignore this for other databases than ours
-*/
-
-static my_bool panic_handlerton(THD *unused1, st_plugin_int *plugin, void *arg)
+int ha_end()
{
- handlerton *hton= (handlerton *)plugin->data;
- if (hton->state == SHOW_OPTION_YES && hton->panic)
- ((int*)arg)[0]|= hton->panic(hton, (enum ha_panic_function)((int*)arg)[1]);
- return FALSE;
-}
-
+ int error= 0;
+ DBUG_ENTER("ha_end");
-int ha_panic(enum ha_panic_function flag)
-{
- int error[2];
- error[0]= 0; error[1]= (int)flag;
- plugin_foreach(NULL, panic_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, error);
+ /*
+ This should be eventualy based on the graceful shutdown flag.
+ So if flag is equal to HA_PANIC_CLOSE, the deallocate
+ the errors.
+ */
+ if (ha_finish_errors())
+ error= 1;
- if (flag == HA_PANIC_CLOSE && ha_finish_errors())
- error[0]= 1;
- return error[0];
-} /* ha_panic */
+ DBUG_RETURN(error);
+}
static my_bool dropdb_handlerton(THD *unused1, st_plugin_int *plugin,
void *path)
@@ -1483,8 +1475,9 @@ bool handler::check_if_log_table_locking_is_allowed(uint sql_command,
{
/*
Deny locking of the log tables, which is incompatible with
- concurrent insert. Unless called from a logger THD:
- general_log_thd or slow_log_thd.
+ concurrent insert. The routine is not called if the table is
+ being locked from a logger THD (general_log_thd or slow_log_thd)
+ or from a privileged thread (see log.cc for details)
*/
if (table->s->log_table &&
sql_command != SQLCOM_TRUNCATE &&
@@ -2958,15 +2951,15 @@ static my_bool binlog_func_list(THD *thd, st_plugin_int *plugin, void *arg)
static my_bool binlog_func_foreach(THD *thd, binlog_func_st *bfn)
{
- handlerton *hton;
hton_list_st hton_list;
+ uint i, sz;
+
hton_list.sz= 0;
plugin_foreach(thd, binlog_func_list,
MYSQL_STORAGE_ENGINE_PLUGIN, &hton_list);
- uint i= 0, sz= hton_list.sz;
- while(i < sz)
- hton_list.hton[i++]->binlog_func(hton, thd, bfn->fn, bfn->arg);
+ for (i= 0, sz= hton_list.sz; i < sz ; i++)
+ hton_list.hton[i]->binlog_func(hton_list.hton[i], thd, bfn->fn, bfn->arg);
return FALSE;
}
diff --git a/sql/handler.h b/sql/handler.h
index 0cfd6da23d7..888f837d427 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -975,6 +975,10 @@ public:
thd Handler of the thread, trying to lock the table
table Table handler to check
count Number of locks already granted to the table
+ called_by_privileged_thread TRUE if called from a logger THD
+ (general_log_thd or slow_log_thd)
+ or by a privileged thread, which
+ has the right to lock log tables.
DESCRIPTION
Check whether a handler allows to lock the table. For instance,
@@ -990,7 +994,7 @@ public:
virtual bool check_if_locking_is_allowed(uint sql_command,
ulong type, TABLE *table,
uint count,
- bool called_by_logger_thread)
+ bool called_by_privileged_thread)
{
return TRUE;
}
@@ -1654,6 +1658,7 @@ static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
/* basic stuff */
int ha_init(void);
+int ha_end(void);
int ha_initialize_handlerton(st_plugin_int *plugin);
int ha_finalize_handlerton(st_plugin_int *plugin);
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 9435b3767a0..691715c3bff 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -275,6 +275,9 @@ static bool convert_constant_item(THD *thd, Field *field, Item **item)
my_bitmap_map *old_write_map;
my_bitmap_map *old_read_map;
+ LINT_INIT(old_write_map);
+ LINT_INIT(old_read_map);
+
if (table)
{
old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 3a93ec6e516..7722ce28d4a 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -14,728 +14,4926 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Functions to create an item. Used by lex.h */
+/* Functions to create an item. Used by sql_yacc.yy */
#include "mysql_priv.h"
+#include "item_create.h"
+#include "sp_head.h"
+#include "sp.h"
+
+/*
+=============================================================================
+ LOCAL DECLARATIONS
+=============================================================================
+*/
+
+/**
+ Adapter for functions that takes exactly zero arguments.
+*/
+
+class Create_func_arg0 : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ /**
+ Builder method, with no arguments.
+ @param thd The current thread
+ @return An item representing the function call
+ */
+ virtual Item* create(THD *thd) = 0;
+
+protected:
+ /** Constructor. */
+ Create_func_arg0() {}
+ /** Destructor. */
+ virtual ~Create_func_arg0() {}
+};
+
+
+/**
+ Adapter for functions that takes exactly one argument.
+*/
+
+class Create_func_arg1 : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ /**
+ Builder method, with one argument.
+ @param thd The current thread
+ @param arg1 The first argument of the function
+ @return An item representing the function call
+ */
+ virtual Item* create(THD *thd, Item *arg1) = 0;
+
+protected:
+ /** Constructor. */
+ Create_func_arg1() {}
+ /** Destructor. */
+ virtual ~Create_func_arg1() {}
+};
+
+
+/**
+ Adapter for functions that takes exactly two arguments.
+*/
+
+class Create_func_arg2 : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ /**
+ Builder method, with two arguments.
+ @param thd The current thread
+ @param arg1 The first argument of the function
+ @param arg2 The second argument of the function
+ @return An item representing the function call
+ */
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2) = 0;
+
+protected:
+ /** Constructor. */
+ Create_func_arg2() {}
+ /** Destructor. */
+ virtual ~Create_func_arg2() {}
+};
+
+
+/**
+ Adapter for functions that takes exactly three arguments.
+*/
+
+class Create_func_arg3 : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ /**
+ Builder method, with three arguments.
+ @param thd The current thread
+ @param arg1 The first argument of the function
+ @param arg2 The second argument of the function
+ @param arg3 The third argument of the function
+ @return An item representing the function call
+ */
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2, Item *arg3) = 0;
+
+protected:
+ /** Constructor. */
+ Create_func_arg3() {}
+ /** Destructor. */
+ virtual ~Create_func_arg3() {}
+};
+
+
+/**
+ Function builder for Stored Functions.
+*/
+
+class Create_sp_func : public Create_qfunc
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING db, LEX_STRING name,
+ List<Item> *item_list);
+
+ static Create_sp_func s_singleton;
+
+protected:
+ /** Constructor. */
+ Create_sp_func() {}
+ /** Destructor. */
+ virtual ~Create_sp_func() {}
+};
-Item *create_func_abs(Item* a)
+
+#ifndef HAVE_SPATIAL
+/**
+ Common (non) builder for geometry functions.
+ This builder is used in <code>--without-geometry</code> builds only,
+ to report an error.
+*/
+
+class Create_func_no_geom : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ /** Singleton. */
+ static Create_func_no_geom s_singleton;
+
+protected:
+ /** Constructor. */
+ Create_func_no_geom() {}
+ /** Destructor. */
+ virtual ~Create_func_no_geom() {}
+};
+#endif
+
+
+/*
+ Concrete functions builders (native functions).
+ Please keep this list sorted in alphabetical order,
+ it helps to compare code between versions, and helps with merges conflicts.
+*/
+
+class Create_func_abs : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_abs s_singleton;
+
+protected:
+ Create_func_abs() {}
+ virtual ~Create_func_abs() {}
+};
+
+
+class Create_func_acos : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_acos s_singleton;
+
+protected:
+ Create_func_acos() {}
+ virtual ~Create_func_acos() {}
+};
+
+
+class Create_func_addtime : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_addtime s_singleton;
+
+protected:
+ Create_func_addtime() {}
+ virtual ~Create_func_addtime() {}
+};
+
+
+class Create_func_aes_encrypt : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_aes_encrypt s_singleton;
+
+protected:
+ Create_func_aes_encrypt() {}
+ virtual ~Create_func_aes_encrypt() {}
+};
+
+
+class Create_func_aes_decrypt : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_aes_decrypt s_singleton;
+
+protected:
+ Create_func_aes_decrypt() {}
+ virtual ~Create_func_aes_decrypt() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_area : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_area s_singleton;
+
+protected:
+ Create_func_area() {}
+ virtual ~Create_func_area() {}
+};
+#endif
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_as_wkb : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_as_wkb s_singleton;
+
+protected:
+ Create_func_as_wkb() {}
+ virtual ~Create_func_as_wkb() {}
+};
+#endif
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_as_wkt : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_as_wkt s_singleton;
+
+protected:
+ Create_func_as_wkt() {}
+ virtual ~Create_func_as_wkt() {}
+};
+#endif
+
+
+class Create_func_asin : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_asin s_singleton;
+
+protected:
+ Create_func_asin() {}
+ virtual ~Create_func_asin() {}
+};
+
+
+class Create_func_atan : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_atan s_singleton;
+
+protected:
+ Create_func_atan() {}
+ virtual ~Create_func_atan() {}
+};
+
+
+class Create_func_benchmark : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_benchmark s_singleton;
+
+protected:
+ Create_func_benchmark() {}
+ virtual ~Create_func_benchmark() {}
+};
+
+
+class Create_func_bin : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_bin s_singleton;
+
+protected:
+ Create_func_bin() {}
+ virtual ~Create_func_bin() {}
+};
+
+
+class Create_func_bit_count : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_bit_count s_singleton;
+
+protected:
+ Create_func_bit_count() {}
+ virtual ~Create_func_bit_count() {}
+};
+
+
+class Create_func_bit_length : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_bit_length s_singleton;
+
+protected:
+ Create_func_bit_length() {}
+ virtual ~Create_func_bit_length() {}
+};
+
+
+class Create_func_ceiling : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg);
+
+ static Create_func_ceiling s_singleton;
+
+protected:
+ Create_func_ceiling() {}
+ virtual ~Create_func_ceiling() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_centroid : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_centroid s_singleton;
+
+protected:
+ Create_func_centroid() {}
+ virtual ~Create_func_centroid() {}
+};
+#endif
+
+
+class Create_func_char_length : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_char_length s_singleton;
+
+protected:
+ Create_func_char_length() {}
+ virtual ~Create_func_char_length() {}
+};
+
+
+class Create_func_coercibility : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_coercibility s_singleton;
+
+protected:
+ Create_func_coercibility() {}
+ virtual ~Create_func_coercibility() {}
+};
+
+
+class Create_func_compress : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_compress s_singleton;
+
+protected:
+ Create_func_compress() {}
+ virtual ~Create_func_compress() {}
+};
+
+
+class Create_func_concat : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_concat s_singleton;
+
+protected:
+ Create_func_concat() {}
+ virtual ~Create_func_concat() {}
+};
+
+
+class Create_func_concat_ws : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_concat_ws s_singleton;
+
+protected:
+ Create_func_concat_ws() {}
+ virtual ~Create_func_concat_ws() {}
+};
+
+
+class Create_func_connection_id : public Create_func_arg0
+{
+public:
+ virtual Item* create(THD *thd);
+
+ static Create_func_connection_id s_singleton;
+
+protected:
+ Create_func_connection_id() {}
+ virtual ~Create_func_connection_id() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_contains : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_contains s_singleton;
+
+protected:
+ Create_func_contains() {}
+ virtual ~Create_func_contains() {}
+};
+#endif
+
+
+class Create_func_conv : public Create_func_arg3
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+
+ static Create_func_conv s_singleton;
+
+protected:
+ Create_func_conv() {}
+ virtual ~Create_func_conv() {}
+};
+
+
+class Create_func_convert_tz : public Create_func_arg3
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+
+ static Create_func_convert_tz s_singleton;
+
+protected:
+ Create_func_convert_tz() {}
+ virtual ~Create_func_convert_tz() {}
+};
+
+
+class Create_func_cos : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_cos s_singleton;
+
+protected:
+ Create_func_cos() {}
+ virtual ~Create_func_cos() {}
+};
+
+
+class Create_func_cot : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_cot s_singleton;
+
+protected:
+ Create_func_cot() {}
+ virtual ~Create_func_cot() {}
+};
+
+
+class Create_func_crc32 : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_crc32 s_singleton;
+
+protected:
+ Create_func_crc32() {}
+ virtual ~Create_func_crc32() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_crosses : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_crosses s_singleton;
+
+protected:
+ Create_func_crosses() {}
+ virtual ~Create_func_crosses() {}
+};
+#endif
+
+
+class Create_func_date_format : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_date_format s_singleton;
+
+protected:
+ Create_func_date_format() {}
+ virtual ~Create_func_date_format() {}
+};
+
+
+class Create_func_datediff : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_datediff s_singleton;
+
+protected:
+ Create_func_datediff() {}
+ virtual ~Create_func_datediff() {}
+};
+
+
+class Create_func_dayname : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_dayname s_singleton;
+
+protected:
+ Create_func_dayname() {}
+ virtual ~Create_func_dayname() {}
+};
+
+
+class Create_func_dayofmonth : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_dayofmonth s_singleton;
+
+protected:
+ Create_func_dayofmonth() {}
+ virtual ~Create_func_dayofmonth() {}
+};
+
+
+class Create_func_dayofweek : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_dayofweek s_singleton;
+
+protected:
+ Create_func_dayofweek() {}
+ virtual ~Create_func_dayofweek() {}
+};
+
+
+class Create_func_dayofyear : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_dayofyear s_singleton;
+
+protected:
+ Create_func_dayofyear() {}
+ virtual ~Create_func_dayofyear() {}
+};
+
+
+class Create_func_decode : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_decode s_singleton;
+
+protected:
+ Create_func_decode() {}
+ virtual ~Create_func_decode() {}
+};
+
+
+class Create_func_degrees : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_degrees s_singleton;
+
+protected:
+ Create_func_degrees() {}
+ virtual ~Create_func_degrees() {}
+};
+
+
+class Create_func_des_decrypt : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_des_decrypt s_singleton;
+
+protected:
+ Create_func_des_decrypt() {}
+ virtual ~Create_func_des_decrypt() {}
+};
+
+
+class Create_func_des_encrypt : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_des_encrypt s_singleton;
+
+protected:
+ Create_func_des_encrypt() {}
+ virtual ~Create_func_des_encrypt() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_dimension : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_dimension s_singleton;
+
+protected:
+ Create_func_dimension() {}
+ virtual ~Create_func_dimension() {}
+};
+#endif
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_disjoint : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_disjoint s_singleton;
+
+protected:
+ Create_func_disjoint() {}
+ virtual ~Create_func_disjoint() {}
+};
+#endif
+
+
+class Create_func_elt : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_elt s_singleton;
+
+protected:
+ Create_func_elt() {}
+ virtual ~Create_func_elt() {}
+};
+
+
+class Create_func_encode : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_encode s_singleton;
+
+protected:
+ Create_func_encode() {}
+ virtual ~Create_func_encode() {}
+};
+
+
+class Create_func_encrypt : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_encrypt s_singleton;
+
+protected:
+ Create_func_encrypt() {}
+ virtual ~Create_func_encrypt() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_endpoint : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_endpoint s_singleton;
+
+protected:
+ Create_func_endpoint() {}
+ virtual ~Create_func_endpoint() {}
+};
+#endif
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_envelope : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_envelope s_singleton;
+
+protected:
+ Create_func_envelope() {}
+ virtual ~Create_func_envelope() {}
+};
+#endif
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_equals : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_equals s_singleton;
+
+protected:
+ Create_func_equals() {}
+ virtual ~Create_func_equals() {}
+};
+#endif
+
+
+class Create_func_exp : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_exp s_singleton;
+
+protected:
+ Create_func_exp() {}
+ virtual ~Create_func_exp() {}
+};
+
+
+class Create_func_export_set : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_export_set s_singleton;
+
+protected:
+ Create_func_export_set() {}
+ virtual ~Create_func_export_set() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_exteriorring : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_exteriorring s_singleton;
+
+protected:
+ Create_func_exteriorring() {}
+ virtual ~Create_func_exteriorring() {}
+};
+#endif
+
+
+class Create_func_field : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_field s_singleton;
+
+protected:
+ Create_func_field() {}
+ virtual ~Create_func_field() {}
+};
+
+
+class Create_func_find_in_set : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_find_in_set s_singleton;
+
+protected:
+ Create_func_find_in_set() {}
+ virtual ~Create_func_find_in_set() {}
+};
+
+
+class Create_func_floor : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_floor s_singleton;
+
+protected:
+ Create_func_floor() {}
+ virtual ~Create_func_floor() {}
+};
+
+
+class Create_func_format : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_format s_singleton;
+
+protected:
+ Create_func_format() {}
+ virtual ~Create_func_format() {}
+};
+
+
+class Create_func_found_rows : public Create_func_arg0
+{
+public:
+ virtual Item* create(THD *thd);
+
+ static Create_func_found_rows s_singleton;
+
+protected:
+ Create_func_found_rows() {}
+ virtual ~Create_func_found_rows() {}
+};
+
+
+class Create_func_from_days : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_from_days s_singleton;
+
+protected:
+ Create_func_from_days() {}
+ virtual ~Create_func_from_days() {}
+};
+
+
+class Create_func_from_unixtime : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_from_unixtime s_singleton;
+
+protected:
+ Create_func_from_unixtime() {}
+ virtual ~Create_func_from_unixtime() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_geometry_from_text : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_geometry_from_text s_singleton;
+
+protected:
+ Create_func_geometry_from_text() {}
+ virtual ~Create_func_geometry_from_text() {}
+};
+#endif
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_geometry_from_wkb : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_geometry_from_wkb s_singleton;
+
+protected:
+ Create_func_geometry_from_wkb() {}
+ virtual ~Create_func_geometry_from_wkb() {}
+};
+#endif
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_geometry_type : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_geometry_type s_singleton;
+
+protected:
+ Create_func_geometry_type() {}
+ virtual ~Create_func_geometry_type() {}
+};
+#endif
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_geometryn : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_geometryn s_singleton;
+
+protected:
+ Create_func_geometryn() {}
+ virtual ~Create_func_geometryn() {}
+};
+#endif
+
+
+class Create_func_get_lock : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_get_lock s_singleton;
+
+protected:
+ Create_func_get_lock() {}
+ virtual ~Create_func_get_lock() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_glength : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_glength s_singleton;
+
+protected:
+ Create_func_glength() {}
+ virtual ~Create_func_glength() {}
+};
+#endif
+
+
+class Create_func_greatest : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_greatest s_singleton;
+
+protected:
+ Create_func_greatest() {}
+ virtual ~Create_func_greatest() {}
+};
+
+
+class Create_func_hex : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_hex s_singleton;
+
+protected:
+ Create_func_hex() {}
+ virtual ~Create_func_hex() {}
+};
+
+
+class Create_func_ifnull : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_ifnull s_singleton;
+
+protected:
+ Create_func_ifnull() {}
+ virtual ~Create_func_ifnull() {}
+};
+
+
+class Create_func_inet_ntoa : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_inet_ntoa s_singleton;
+
+protected:
+ Create_func_inet_ntoa() {}
+ virtual ~Create_func_inet_ntoa() {}
+};
+
+
+class Create_func_inet_aton : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_inet_aton s_singleton;
+
+protected:
+ Create_func_inet_aton() {}
+ virtual ~Create_func_inet_aton() {}
+};
+
+
+class Create_func_instr : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_instr s_singleton;
+
+protected:
+ Create_func_instr() {}
+ virtual ~Create_func_instr() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_interiorringn : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_interiorringn s_singleton;
+
+protected:
+ Create_func_interiorringn() {}
+ virtual ~Create_func_interiorringn() {}
+};
+#endif
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_intersects : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_intersects s_singleton;
+
+protected:
+ Create_func_intersects() {}
+ virtual ~Create_func_intersects() {}
+};
+#endif
+
+
+class Create_func_is_free_lock : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_is_free_lock s_singleton;
+
+protected:
+ Create_func_is_free_lock() {}
+ virtual ~Create_func_is_free_lock() {}
+};
+
+
+class Create_func_is_used_lock : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_is_used_lock s_singleton;
+
+protected:
+ Create_func_is_used_lock() {}
+ virtual ~Create_func_is_used_lock() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_isclosed : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_isclosed s_singleton;
+
+protected:
+ Create_func_isclosed() {}
+ virtual ~Create_func_isclosed() {}
+};
+#endif
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_isempty : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_isempty s_singleton;
+
+protected:
+ Create_func_isempty() {}
+ virtual ~Create_func_isempty() {}
+};
+#endif
+
+
+class Create_func_isnull : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_isnull s_singleton;
+
+protected:
+ Create_func_isnull() {}
+ virtual ~Create_func_isnull() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_issimple : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_issimple s_singleton;
+
+protected:
+ Create_func_issimple() {}
+ virtual ~Create_func_issimple() {}
+};
+#endif
+
+
+class Create_func_last_day : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_last_day s_singleton;
+
+protected:
+ Create_func_last_day() {}
+ virtual ~Create_func_last_day() {}
+};
+
+
+class Create_func_last_insert_id : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_last_insert_id s_singleton;
+
+protected:
+ Create_func_last_insert_id() {}
+ virtual ~Create_func_last_insert_id() {}
+};
+
+
+class Create_func_lcase : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_lcase s_singleton;
+
+protected:
+ Create_func_lcase() {}
+ virtual ~Create_func_lcase() {}
+};
+
+
+class Create_func_least : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_least s_singleton;
+
+protected:
+ Create_func_least() {}
+ virtual ~Create_func_least() {}
+};
+
+
+class Create_func_length : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_length s_singleton;
+
+protected:
+ Create_func_length() {}
+ virtual ~Create_func_length() {}
+};
+
+
+class Create_func_ln : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_ln s_singleton;
+
+protected:
+ Create_func_ln() {}
+ virtual ~Create_func_ln() {}
+};
+
+
+class Create_func_load_file : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_load_file s_singleton;
+
+protected:
+ Create_func_load_file() {}
+ virtual ~Create_func_load_file() {}
+};
+
+
+class Create_func_locate : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_locate s_singleton;
+
+protected:
+ Create_func_locate() {}
+ virtual ~Create_func_locate() {}
+};
+
+
+class Create_func_log : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_log s_singleton;
+
+protected:
+ Create_func_log() {}
+ virtual ~Create_func_log() {}
+};
+
+
+class Create_func_log10 : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_log10 s_singleton;
+
+protected:
+ Create_func_log10() {}
+ virtual ~Create_func_log10() {}
+};
+
+
+class Create_func_log2 : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_log2 s_singleton;
+
+protected:
+ Create_func_log2() {}
+ virtual ~Create_func_log2() {}
+};
+
+
+class Create_func_lpad : public Create_func_arg3
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+
+ static Create_func_lpad s_singleton;
+
+protected:
+ Create_func_lpad() {}
+ virtual ~Create_func_lpad() {}
+};
+
+
+class Create_func_ltrim : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_ltrim s_singleton;
+
+protected:
+ Create_func_ltrim() {}
+ virtual ~Create_func_ltrim() {}
+};
+
+
+class Create_func_makedate : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_makedate s_singleton;
+
+protected:
+ Create_func_makedate() {}
+ virtual ~Create_func_makedate() {}
+};
+
+
+class Create_func_maketime : public Create_func_arg3
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+
+ static Create_func_maketime s_singleton;
+
+protected:
+ Create_func_maketime() {}
+ virtual ~Create_func_maketime() {}
+};
+
+
+class Create_func_make_set : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_make_set s_singleton;
+
+protected:
+ Create_func_make_set() {}
+ virtual ~Create_func_make_set() {}
+};
+
+
+class Create_func_master_pos_wait : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_master_pos_wait s_singleton;
+
+protected:
+ Create_func_master_pos_wait() {}
+ virtual ~Create_func_master_pos_wait() {}
+};
+
+
+class Create_func_md5 : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_md5 s_singleton;
+
+protected:
+ Create_func_md5() {}
+ virtual ~Create_func_md5() {}
+};
+
+
+class Create_func_monthname : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_monthname s_singleton;
+
+protected:
+ Create_func_monthname() {}
+ virtual ~Create_func_monthname() {}
+};
+
+
+class Create_func_name_const : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_name_const s_singleton;
+
+protected:
+ Create_func_name_const() {}
+ virtual ~Create_func_name_const() {}
+};
+
+
+class Create_func_nullif : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_nullif s_singleton;
+
+protected:
+ Create_func_nullif() {}
+ virtual ~Create_func_nullif() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_numgeometries : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_numgeometries s_singleton;
+
+protected:
+ Create_func_numgeometries() {}
+ virtual ~Create_func_numgeometries() {}
+};
+#endif
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_numinteriorring : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_numinteriorring s_singleton;
+
+protected:
+ Create_func_numinteriorring() {}
+ virtual ~Create_func_numinteriorring() {}
+};
+#endif
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_numpoints : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_numpoints s_singleton;
+
+protected:
+ Create_func_numpoints() {}
+ virtual ~Create_func_numpoints() {}
+};
+#endif
+
+
+class Create_func_oct : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_oct s_singleton;
+
+protected:
+ Create_func_oct() {}
+ virtual ~Create_func_oct() {}
+};
+
+
+class Create_func_ord : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_ord s_singleton;
+
+protected:
+ Create_func_ord() {}
+ virtual ~Create_func_ord() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_overlaps : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_overlaps s_singleton;
+
+protected:
+ Create_func_overlaps() {}
+ virtual ~Create_func_overlaps() {}
+};
+#endif
+
+
+class Create_func_period_add : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_period_add s_singleton;
+
+protected:
+ Create_func_period_add() {}
+ virtual ~Create_func_period_add() {}
+};
+
+
+class Create_func_period_diff : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_period_diff s_singleton;
+
+protected:
+ Create_func_period_diff() {}
+ virtual ~Create_func_period_diff() {}
+};
+
+
+class Create_func_pi : public Create_func_arg0
+{
+public:
+ virtual Item* create(THD *thd);
+
+ static Create_func_pi s_singleton;
+
+protected:
+ Create_func_pi() {}
+ virtual ~Create_func_pi() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_pointn : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_pointn s_singleton;
+
+protected:
+ Create_func_pointn() {}
+ virtual ~Create_func_pointn() {}
+};
+#endif
+
+
+class Create_func_pow : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_pow s_singleton;
+
+protected:
+ Create_func_pow() {}
+ virtual ~Create_func_pow() {}
+};
+
+
+class Create_func_quote : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_quote s_singleton;
+
+protected:
+ Create_func_quote() {}
+ virtual ~Create_func_quote() {}
+};
+
+
+class Create_func_radians : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_radians s_singleton;
+
+protected:
+ Create_func_radians() {}
+ virtual ~Create_func_radians() {}
+};
+
+
+class Create_func_rand : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_rand s_singleton;
+
+protected:
+ Create_func_rand() {}
+ virtual ~Create_func_rand() {}
+};
+
+
+class Create_func_release_lock : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_release_lock s_singleton;
+
+protected:
+ Create_func_release_lock() {}
+ virtual ~Create_func_release_lock() {}
+};
+
+
+class Create_func_reverse : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_reverse s_singleton;
+
+protected:
+ Create_func_reverse() {}
+ virtual ~Create_func_reverse() {}
+};
+
+
+class Create_func_round : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_round s_singleton;
+
+protected:
+ Create_func_round() {}
+ virtual ~Create_func_round() {}
+};
+
+
+class Create_func_row_count : public Create_func_arg0
+{
+public:
+ virtual Item* create(THD *thd);
+
+ static Create_func_row_count s_singleton;
+
+protected:
+ Create_func_row_count() {}
+ virtual ~Create_func_row_count() {}
+};
+
+
+class Create_func_rpad : public Create_func_arg3
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+
+ static Create_func_rpad s_singleton;
+
+protected:
+ Create_func_rpad() {}
+ virtual ~Create_func_rpad() {}
+};
+
+
+class Create_func_rtrim : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_rtrim s_singleton;
+
+protected:
+ Create_func_rtrim() {}
+ virtual ~Create_func_rtrim() {}
+};
+
+
+class Create_func_sec_to_time : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_sec_to_time s_singleton;
+
+protected:
+ Create_func_sec_to_time() {}
+ virtual ~Create_func_sec_to_time() {}
+};
+
+
+class Create_func_sha : public Create_func_arg1
{
- return new Item_func_abs(a);
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_sha s_singleton;
+
+protected:
+ Create_func_sha() {}
+ virtual ~Create_func_sha() {}
+};
+
+
+class Create_func_sign : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_sign s_singleton;
+
+protected:
+ Create_func_sign() {}
+ virtual ~Create_func_sign() {}
+};
+
+
+class Create_func_sin : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_sin s_singleton;
+
+protected:
+ Create_func_sin() {}
+ virtual ~Create_func_sin() {}
+};
+
+
+class Create_func_sleep : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_sleep s_singleton;
+
+protected:
+ Create_func_sleep() {}
+ virtual ~Create_func_sleep() {}
+};
+
+
+class Create_func_soundex : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_soundex s_singleton;
+
+protected:
+ Create_func_soundex() {}
+ virtual ~Create_func_soundex() {}
+};
+
+
+class Create_func_space : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_space s_singleton;
+
+protected:
+ Create_func_space() {}
+ virtual ~Create_func_space() {}
+};
+
+
+class Create_func_sqrt : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_sqrt s_singleton;
+
+protected:
+ Create_func_sqrt() {}
+ virtual ~Create_func_sqrt() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_srid : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_srid s_singleton;
+
+protected:
+ Create_func_srid() {}
+ virtual ~Create_func_srid() {}
+};
+#endif
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_startpoint : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_startpoint s_singleton;
+
+protected:
+ Create_func_startpoint() {}
+ virtual ~Create_func_startpoint() {}
+};
+#endif
+
+
+class Create_func_str_to_date : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_str_to_date s_singleton;
+
+protected:
+ Create_func_str_to_date() {}
+ virtual ~Create_func_str_to_date() {}
+};
+
+
+class Create_func_strcmp : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_strcmp s_singleton;
+
+protected:
+ Create_func_strcmp() {}
+ virtual ~Create_func_strcmp() {}
+};
+
+
+class Create_func_substr_index : public Create_func_arg3
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+
+ static Create_func_substr_index s_singleton;
+
+protected:
+ Create_func_substr_index() {}
+ virtual ~Create_func_substr_index() {}
+};
+
+
+class Create_func_subtime : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_subtime s_singleton;
+
+protected:
+ Create_func_subtime() {}
+ virtual ~Create_func_subtime() {}
+};
+
+
+class Create_func_tan : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_tan s_singleton;
+
+protected:
+ Create_func_tan() {}
+ virtual ~Create_func_tan() {}
+};
+
+
+class Create_func_time_format : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_time_format s_singleton;
+
+protected:
+ Create_func_time_format() {}
+ virtual ~Create_func_time_format() {}
+};
+
+
+class Create_func_time_to_sec : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_time_to_sec s_singleton;
+
+protected:
+ Create_func_time_to_sec() {}
+ virtual ~Create_func_time_to_sec() {}
+};
+
+
+class Create_func_timediff : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_timediff s_singleton;
+
+protected:
+ Create_func_timediff() {}
+ virtual ~Create_func_timediff() {}
+};
+
+
+class Create_func_to_days : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_to_days s_singleton;
+
+protected:
+ Create_func_to_days() {}
+ virtual ~Create_func_to_days() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_touches : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_touches s_singleton;
+
+protected:
+ Create_func_touches() {}
+ virtual ~Create_func_touches() {}
+};
+#endif
+
+
+class Create_func_ucase : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_ucase s_singleton;
+
+protected:
+ Create_func_ucase() {}
+ virtual ~Create_func_ucase() {}
+};
+
+
+class Create_func_uncompress : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_uncompress s_singleton;
+
+protected:
+ Create_func_uncompress() {}
+ virtual ~Create_func_uncompress() {}
+};
+
+
+class Create_func_uncompressed_length : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_uncompressed_length s_singleton;
+
+protected:
+ Create_func_uncompressed_length() {}
+ virtual ~Create_func_uncompressed_length() {}
+};
+
+
+class Create_func_unhex : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_unhex s_singleton;
+
+protected:
+ Create_func_unhex() {}
+ virtual ~Create_func_unhex() {}
+};
+
+
+class Create_func_unix_timestamp : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_unix_timestamp s_singleton;
+
+protected:
+ Create_func_unix_timestamp() {}
+ virtual ~Create_func_unix_timestamp() {}
+};
+
+
+class Create_func_uuid : public Create_func_arg0
+{
+public:
+ virtual Item* create(THD *thd);
+
+ static Create_func_uuid s_singleton;
+
+protected:
+ Create_func_uuid() {}
+ virtual ~Create_func_uuid() {}
+};
+
+
+class Create_func_version : public Create_func_arg0
+{
+public:
+ virtual Item* create(THD *thd);
+
+ static Create_func_version s_singleton;
+
+protected:
+ Create_func_version() {}
+ virtual ~Create_func_version() {}
+};
+
+
+class Create_func_weekday : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_weekday s_singleton;
+
+protected:
+ Create_func_weekday() {}
+ virtual ~Create_func_weekday() {}
+};
+
+
+class Create_func_weekofyear : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_weekofyear s_singleton;
+
+protected:
+ Create_func_weekofyear() {}
+ virtual ~Create_func_weekofyear() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_within : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_within s_singleton;
+
+protected:
+ Create_func_within() {}
+ virtual ~Create_func_within() {}
+};
+#endif
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_x : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_x s_singleton;
+
+protected:
+ Create_func_x() {}
+ virtual ~Create_func_x() {}
+};
+#endif
+
+
+class Create_func_xml_extractvalue : public Create_func_arg2
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_xml_extractvalue s_singleton;
+
+protected:
+ Create_func_xml_extractvalue() {}
+ virtual ~Create_func_xml_extractvalue() {}
+};
+
+
+class Create_func_xml_update : public Create_func_arg3
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+
+ static Create_func_xml_update s_singleton;
+
+protected:
+ Create_func_xml_update() {}
+ virtual ~Create_func_xml_update() {}
+};
+
+
+#ifdef HAVE_SPATIAL
+class Create_func_y : public Create_func_arg1
+{
+public:
+ virtual Item* create(THD *thd, Item *arg1);
+
+ static Create_func_y s_singleton;
+
+protected:
+ Create_func_y() {}
+ virtual ~Create_func_y() {}
+};
+#endif
+
+
+class Create_func_year_week : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ static Create_func_year_week s_singleton;
+
+protected:
+ Create_func_year_week() {}
+ virtual ~Create_func_year_week() {}
+};
+
+
+/*
+=============================================================================
+ IMPLEMENTATION
+=============================================================================
+*/
+
+#ifndef HAVE_SPATIAL
+Create_func_no_geom Create_func_no_geom::s_singleton;
+
+Item*
+Create_func_no_geom::create(THD * /* unused */,
+ LEX_STRING /* unused */,
+ List<Item> * /* unused */)
+{
+ /* FIXME: error message can't be translated. */
+ my_error(ER_FEATURE_DISABLED, MYF(0),
+ sym_group_geom.name, sym_group_geom.needed_define);
+ return NULL;
}
+#endif
-Item *create_func_acos(Item* a)
+
+Item*
+Create_qfunc::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- return new Item_func_acos(a);
+ LEX_STRING db;
+ if (thd->copy_db_to(&db.str, &db.length))
+ return NULL;
+
+ return create(thd, db, name, item_list);
}
-Item *create_func_aes_encrypt(Item* a, Item* b)
+
+#ifdef HAVE_DLOPEN
+Create_udf_func Create_udf_func::s_singleton;
+
+Item*
+Create_udf_func::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- return new Item_func_aes_encrypt(a, b);
+ udf_func *udf= find_udf(name.str, name.length);
+ DBUG_ASSERT(udf);
+ return create(thd, udf, item_list);
}
-Item *create_func_aes_decrypt(Item* a, Item* b)
+
+Item*
+Create_udf_func::create(THD *thd, udf_func *udf, List<Item> *item_list)
{
- return new Item_func_aes_decrypt(a, b);
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+#ifdef HAVE_ROW_BASED_REPLICATION
+ thd->lex->binlog_row_based_if_mixed= TRUE;
+#endif
+
+ DBUG_ASSERT( (udf->type == UDFTYPE_FUNCTION)
+ || (udf->type == UDFTYPE_AGGREGATE));
+
+ switch(udf->returns) {
+ case STRING_RESULT:
+ {
+ if (udf->type == UDFTYPE_FUNCTION)
+ {
+ if (arg_count)
+ func= new (thd->mem_root) Item_func_udf_str(udf, *item_list);
+ else
+ func= new (thd->mem_root) Item_func_udf_str(udf);
+ }
+ else
+ {
+ if (arg_count)
+ func= new (thd->mem_root) Item_sum_udf_str(udf, *item_list);
+ else
+ func= new (thd->mem_root) Item_sum_udf_str(udf);
+ }
+ break;
+ }
+ case REAL_RESULT:
+ {
+ if (udf->type == UDFTYPE_FUNCTION)
+ {
+ if (arg_count)
+ func= new (thd->mem_root) Item_func_udf_float(udf, *item_list);
+ else
+ func= new (thd->mem_root) Item_func_udf_float(udf);
+ }
+ else
+ {
+ if (arg_count)
+ func= new (thd->mem_root) Item_sum_udf_float(udf, *item_list);
+ else
+ func= new (thd->mem_root) Item_sum_udf_float(udf);
+ }
+ break;
+ }
+ case INT_RESULT:
+ {
+ if (udf->type == UDFTYPE_FUNCTION)
+ {
+ if (arg_count)
+ func= new (thd->mem_root) Item_func_udf_int(udf, *item_list);
+ else
+ func= new (thd->mem_root) Item_func_udf_int(udf);
+ }
+ else
+ {
+ if (arg_count)
+ func= new (thd->mem_root) Item_sum_udf_int(udf, *item_list);
+ else
+ func= new (thd->mem_root) Item_sum_udf_int(udf);
+ }
+ break;
+ }
+ case DECIMAL_RESULT:
+ {
+ if (udf->type == UDFTYPE_FUNCTION)
+ {
+ if (arg_count)
+ func= new (thd->mem_root) Item_func_udf_decimal(udf, *item_list);
+ else
+ func= new (thd->mem_root) Item_func_udf_decimal(udf);
+ }
+ else
+ {
+ if (arg_count)
+ func= new (thd->mem_root) Item_sum_udf_decimal(udf, *item_list);
+ else
+ func= new (thd->mem_root) Item_sum_udf_decimal(udf);
+ }
+ break;
+ }
+ default:
+ {
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "UDF return type");
+ }
+ }
+ return func;
}
+#endif
+
+
+Create_sp_func Create_sp_func::s_singleton;
-Item *create_func_ascii(Item* a)
+Item*
+Create_sp_func::create(THD *thd, LEX_STRING db, LEX_STRING name,
+ List<Item> *item_list)
{
- return new Item_func_ascii(a);
+ int arg_count= 0;
+ Item *func= NULL;
+ LEX *lex= thd->lex;
+ sp_name *qname= new (thd->mem_root) sp_name(db, name);
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ qname->init_qname(thd);
+ sp_add_used_routine(lex, thd, qname, TYPE_ENUM_FUNCTION);
+
+ if (arg_count > 0)
+ func= new (thd->mem_root) Item_func_sp(lex->current_context(), qname,
+ *item_list);
+ else
+ func= new (thd->mem_root) Item_func_sp(lex->current_context(), qname);
+
+ lex->safe_to_cache_query= 0;
+ return func;
}
-Item *create_func_ord(Item* a)
+
+Item*
+Create_func_arg0::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- return new Item_func_ord(a);
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ if (arg_count != 0)
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ return NULL;
+ }
+
+ return create(thd);
}
-Item *create_func_asin(Item* a)
+
+Item*
+Create_func_arg1::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- return new Item_func_asin(a);
+ int arg_count= 0;
+
+ if (item_list)
+ arg_count= item_list->elements;
+
+ if (arg_count != 1)
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ return NULL;
+ }
+
+ Item *param_1= item_list->pop();
+ return create(thd, param_1);
}
-Item *create_func_bin(Item* a)
+
+Item*
+Create_func_arg2::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- return new Item_func_conv(a,new Item_int((int32) 10,2),
- new Item_int((int32) 2,1));
+ int arg_count= 0;
+
+ if (item_list)
+ arg_count= item_list->elements;
+
+ if (arg_count != 2)
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ return NULL;
+ }
+
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ return create(thd, param_1, param_2);
}
-Item *create_func_bit_count(Item* a)
+
+Item*
+Create_func_arg3::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- return new Item_func_bit_count(a);
+ int arg_count= 0;
+
+ if (item_list)
+ arg_count= item_list->elements;
+
+ if (arg_count != 3)
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ return NULL;
+ }
+
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ Item *param_3= item_list->pop();
+ return create(thd, param_1, param_2, param_3);
}
-Item *create_func_ceiling(Item* a)
+
+Create_func_abs Create_func_abs::s_singleton;
+
+Item*
+Create_func_abs::create(THD *thd, Item *arg1)
{
- return new Item_func_ceiling(a);
+ return new (thd->mem_root) Item_func_abs(arg1);
}
-Item *create_func_connection_id(void)
+
+Create_func_acos Create_func_acos::s_singleton;
+
+Item*
+Create_func_acos::create(THD *thd, Item *arg1)
{
- current_thd->lex->safe_to_cache_query= 0;
- return new Item_func_connection_id();
+ return new (thd->mem_root) Item_func_acos(arg1);
}
-Item *create_func_conv(Item* a, Item *b, Item *c)
+
+Create_func_addtime Create_func_addtime::s_singleton;
+
+Item*
+Create_func_addtime::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_conv(a,b,c);
+ return new (thd->mem_root) Item_func_add_time(arg1, arg2, 0, 0);
}
-Item *create_func_cos(Item* a)
+
+Create_func_aes_encrypt Create_func_aes_encrypt::s_singleton;
+
+Item*
+Create_func_aes_encrypt::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_cos(a);
+ return new (thd->mem_root) Item_func_aes_encrypt(arg1, arg2);
}
-Item *create_func_cot(Item* a)
+
+Create_func_aes_decrypt Create_func_aes_decrypt::s_singleton;
+
+Item*
+Create_func_aes_decrypt::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_div(new Item_int((char*) "1",1,1),
- new Item_func_tan(a));
+ return new (thd->mem_root) Item_func_aes_decrypt(arg1, arg2);
}
-Item *create_func_date_format(Item* a,Item *b)
+
+#ifdef HAVE_SPATIAL
+Create_func_area Create_func_area::s_singleton;
+
+Item*
+Create_func_area::create(THD *thd, Item *arg1)
{
- return new Item_func_date_format(a,b,0);
+ return new (thd->mem_root) Item_func_area(arg1);
}
+#endif
-Item *create_func_dayofmonth(Item* a)
+
+#ifdef HAVE_SPATIAL
+Create_func_as_wkb Create_func_as_wkb::s_singleton;
+
+Item*
+Create_func_as_wkb::create(THD *thd, Item *arg1)
{
- return new Item_func_dayofmonth(a);
+ return new (thd->mem_root) Item_func_as_wkb(arg1);
}
+#endif
+
-Item *create_func_dayofweek(Item* a)
+#ifdef HAVE_SPATIAL
+Create_func_as_wkt Create_func_as_wkt::s_singleton;
+
+Item*
+Create_func_as_wkt::create(THD *thd, Item *arg1)
{
- return new Item_func_weekday(a, 1);
+ return new (thd->mem_root) Item_func_as_wkt(arg1);
+}
+#endif
+
+
+Create_func_asin Create_func_asin::s_singleton;
+
+Item*
+Create_func_asin::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_asin(arg1);
+}
+
+
+Create_func_atan Create_func_atan::s_singleton;
+
+Item*
+Create_func_atan::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+{
+ Item* func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 1:
+ {
+ Item *param_1= item_list->pop();
+ func= new (thd->mem_root) Item_func_atan(param_1);
+ break;
+ }
+ case 2:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ func= new (thd->mem_root) Item_func_atan(param_1, param_2);
+ break;
+ }
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
+ }
+
+ return func;
}
-Item *create_func_dayofyear(Item* a)
+
+Create_func_benchmark Create_func_benchmark::s_singleton;
+
+Item*
+Create_func_benchmark::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_dayofyear(a);
+ /* TODO: Known limitation, see Bug#22684 */
+ if ((arg1->type() != Item::INT_ITEM) || ! arg1->basic_const_item())
+ {
+ my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), "BENCHMARK");
+ return NULL;
+ }
+
+ thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
+ return new (thd->mem_root) Item_func_benchmark(arg1->val_int(), arg2);
}
-Item *create_func_dayname(Item* a)
+
+Create_func_bin Create_func_bin::s_singleton;
+
+Item*
+Create_func_bin::create(THD *thd, Item *arg1)
{
- return new Item_func_dayname(a);
+ Item *i10= new (thd->mem_root) Item_int((int32) 10,2);
+ Item *i2= new (thd->mem_root) Item_int((int32) 2,1);
+ return new (thd->mem_root) Item_func_conv(arg1, i10, i2);
}
-Item *create_func_degrees(Item *a)
+
+Create_func_bit_count Create_func_bit_count::s_singleton;
+
+Item*
+Create_func_bit_count::create(THD *thd, Item *arg1)
{
- return new Item_func_units((char*) "degrees",a,180/M_PI,0.0);
+ return new (thd->mem_root) Item_func_bit_count(arg1);
}
-Item *create_func_exp(Item* a)
+
+Create_func_bit_length Create_func_bit_length::s_singleton;
+
+Item*
+Create_func_bit_length::create(THD *thd, Item *arg1)
{
- return new Item_func_exp(a);
+ return new (thd->mem_root) Item_func_bit_length(arg1);
}
-Item *create_func_find_in_set(Item* a, Item *b)
+
+Create_func_ceiling Create_func_ceiling::s_singleton;
+
+Item*
+Create_func_ceiling::create(THD *thd, Item *arg1)
{
- return new Item_func_find_in_set(a, b);
+ return new (thd->mem_root) Item_func_ceiling(arg1);
}
-Item *create_func_floor(Item* a)
+
+#ifdef HAVE_SPATIAL
+Create_func_centroid Create_func_centroid::s_singleton;
+
+Item*
+Create_func_centroid::create(THD *thd, Item *arg1)
{
- return new Item_func_floor(a);
+ return new (thd->mem_root) Item_func_centroid(arg1);
}
+#endif
-Item *create_func_found_rows(void)
+
+Create_func_char_length Create_func_char_length::s_singleton;
+
+Item*
+Create_func_char_length::create(THD *thd, Item *arg1)
{
- THD *thd=current_thd;
- thd->lex->safe_to_cache_query= 0;
- return new Item_func_found_rows();
+ return new (thd->mem_root) Item_func_char_length(arg1);
}
-Item *create_func_from_days(Item* a)
+
+Create_func_coercibility Create_func_coercibility::s_singleton;
+
+Item*
+Create_func_coercibility::create(THD *thd, Item *arg1)
{
- return new Item_func_from_days(a);
+ return new (thd->mem_root) Item_func_coercibility(arg1);
}
-Item *create_func_get_lock(Item* a, Item *b)
+
+Create_func_concat Create_func_concat::s_singleton;
+
+Item*
+Create_func_concat::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
- return new Item_func_get_lock(a, b);
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ if (arg_count < 1)
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ return NULL;
+ }
+
+ return new (thd->mem_root) Item_func_concat(*item_list);
}
-Item *create_func_hex(Item *a)
+
+Create_func_concat_ws Create_func_concat_ws::s_singleton;
+
+Item*
+Create_func_concat_ws::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- return new Item_func_hex(a);
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ /* "WS" stands for "With Separator": this function takes 2+ arguments */
+ if (arg_count < 2)
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ return NULL;
+ }
+
+ return new (thd->mem_root) Item_func_concat_ws(*item_list);
}
-Item *create_func_inet_ntoa(Item* a)
+
+Create_func_compress Create_func_compress::s_singleton;
+
+Item*
+Create_func_compress::create(THD *thd, Item *arg1)
{
- return new Item_func_inet_ntoa(a);
+ return new (thd->mem_root) Item_func_compress(arg1);
}
-Item *create_func_inet_aton(Item* a)
+
+Create_func_connection_id Create_func_connection_id::s_singleton;
+
+Item*
+Create_func_connection_id::create(THD *thd)
{
- return new Item_func_inet_aton(a);
+ thd->lex->safe_to_cache_query= 0;
+ return new (thd->mem_root) Item_func_connection_id();
}
-Item *create_func_ifnull(Item* a, Item *b)
+#ifdef HAVE_SPATIAL
+Create_func_contains Create_func_contains::s_singleton;
+
+Item*
+Create_func_contains::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_ifnull(a,b);
+ return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
+ Item_func::SP_CONTAINS_FUNC);
}
+#endif
+
-Item *create_func_nullif(Item* a, Item *b)
+Create_func_conv Create_func_conv::s_singleton;
+
+Item*
+Create_func_conv::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
- return new Item_func_nullif(a,b);
+ return new (thd->mem_root) Item_func_conv(arg1, arg2, arg3);
}
-Item *create_func_locate(Item* a, Item *b)
+
+Create_func_convert_tz Create_func_convert_tz::s_singleton;
+
+Item*
+Create_func_convert_tz::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
- return new Item_func_locate(b,a);
+ if (thd->lex->add_time_zone_tables_to_query_tables(thd))
+ return NULL;
+
+ return new (thd->mem_root) Item_func_convert_tz(arg1, arg2, arg3);
}
-Item *create_func_instr(Item* a, Item *b)
+
+Create_func_cos Create_func_cos::s_singleton;
+
+Item*
+Create_func_cos::create(THD *thd, Item *arg1)
{
- return new Item_func_locate(a,b);
+ return new (thd->mem_root) Item_func_cos(arg1);
}
-Item *create_func_isnull(Item* a)
+
+Create_func_cot Create_func_cot::s_singleton;
+
+Item*
+Create_func_cot::create(THD *thd, Item *arg1)
{
- return new Item_func_isnull(a);
+ Item *i1= new (thd->mem_root) Item_int((char*) "1", 1, 1);
+ Item *i2= new (thd->mem_root) Item_func_tan(arg1);
+ return new (thd->mem_root) Item_func_div(i1, i2);
}
-Item *create_func_lcase(Item* a)
+
+Create_func_crc32 Create_func_crc32::s_singleton;
+
+Item*
+Create_func_crc32::create(THD *thd, Item *arg1)
{
- return new Item_func_lcase(a);
+ return new (thd->mem_root) Item_func_crc32(arg1);
}
-Item *create_func_length(Item* a)
+
+#ifdef HAVE_SPATIAL
+Create_func_crosses Create_func_crosses::s_singleton;
+
+Item*
+Create_func_crosses::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_length(a);
+ return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
+ Item_func::SP_CROSSES_FUNC);
}
+#endif
-Item *create_func_bit_length(Item* a)
+
+Create_func_date_format Create_func_date_format::s_singleton;
+
+Item*
+Create_func_date_format::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_bit_length(a);
+ return new (thd->mem_root) Item_func_date_format(arg1, arg2, 0);
}
-Item *create_func_coercibility(Item* a)
+
+Create_func_datediff Create_func_datediff::s_singleton;
+
+Item*
+Create_func_datediff::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_coercibility(a);
+ Item *i1= new (thd->mem_root) Item_func_to_days(arg1);
+ Item *i2= new (thd->mem_root) Item_func_to_days(arg2);
+
+ return new (thd->mem_root) Item_func_minus(i1, i2);
}
-Item *create_func_char_length(Item* a)
+
+Create_func_dayname Create_func_dayname::s_singleton;
+
+Item*
+Create_func_dayname::create(THD *thd, Item *arg1)
{
- return new Item_func_char_length(a);
+ return new (thd->mem_root) Item_func_dayname(arg1);
}
-Item *create_func_ln(Item* a)
+
+Create_func_dayofmonth Create_func_dayofmonth::s_singleton;
+
+Item*
+Create_func_dayofmonth::create(THD *thd, Item *arg1)
{
- return new Item_func_ln(a);
+ return new (thd->mem_root) Item_func_dayofmonth(arg1);
}
-Item *create_func_log2(Item* a)
+
+Create_func_dayofweek Create_func_dayofweek::s_singleton;
+
+Item*
+Create_func_dayofweek::create(THD *thd, Item *arg1)
{
- return new Item_func_log2(a);
+ return new (thd->mem_root) Item_func_weekday(arg1, 1);
}
-Item *create_func_log10(Item* a)
+
+Create_func_dayofyear Create_func_dayofyear::s_singleton;
+
+Item*
+Create_func_dayofyear::create(THD *thd, Item *arg1)
{
- return new Item_func_log10(a);
+ return new (thd->mem_root) Item_func_dayofyear(arg1);
}
-Item *create_func_lpad(Item* a, Item *b, Item *c)
+
+Create_func_decode Create_func_decode::s_singleton;
+
+Item*
+Create_func_decode::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_lpad(a,b,c);
+ /* TODO: Known limitation, see Bug#22684 */
+ if ((arg2->type() != Item::STRING_ITEM) || ! arg2->basic_const_item())
+ {
+ my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), "DECODE");
+ return NULL;
+ }
+
+ String dummy;
+ String *val = arg2->val_str(& dummy);
+ DBUG_ASSERT(val);
+ return new (thd->mem_root) Item_func_decode(arg1, val->c_ptr());
}
-Item *create_func_ltrim(Item* a)
+
+Create_func_degrees Create_func_degrees::s_singleton;
+
+Item*
+Create_func_degrees::create(THD *thd, Item *arg1)
{
- return new Item_func_ltrim(a);
+ return new (thd->mem_root) Item_func_units((char*) "degrees", arg1,
+ 180/M_PI, 0.0);
}
-Item *create_func_md5(Item* a)
+
+Create_func_des_decrypt Create_func_des_decrypt::s_singleton;
+
+Item*
+Create_func_des_decrypt::create(THD *thd, LEX_STRING name,
+ List<Item> *item_list)
{
- return new Item_func_md5(a);
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 1:
+ {
+ Item *param_1= item_list->pop();
+ func= new (thd->mem_root) Item_func_des_decrypt(param_1);
+ break;
+ }
+ case 2:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ func= new (thd->mem_root) Item_func_des_decrypt(param_1, param_2);
+ break;
+ }
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
+ }
+
+ return func;
}
-Item *create_func_mod(Item* a, Item *b)
+
+Create_func_des_encrypt Create_func_des_encrypt::s_singleton;
+
+Item*
+Create_func_des_encrypt::create(THD *thd, LEX_STRING name,
+ List<Item> *item_list)
{
- return new Item_func_mod(a,b);
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 1:
+ {
+ Item *param_1= item_list->pop();
+ func= new (thd->mem_root) Item_func_des_encrypt(param_1);
+ break;
+ }
+ case 2:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ func= new (thd->mem_root) Item_func_des_encrypt(param_1, param_2);
+ break;
+ }
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
+ }
+
+ return func;
}
-Item *create_func_name_const(Item *a, Item *b)
+
+#ifdef HAVE_SPATIAL
+Create_func_dimension Create_func_dimension::s_singleton;
+
+Item*
+Create_func_dimension::create(THD *thd, Item *arg1)
{
- return new Item_name_const(a,b);
+ return new (thd->mem_root) Item_func_dimension(arg1);
}
+#endif
+
-Item *create_func_monthname(Item* a)
+#ifdef HAVE_SPATIAL
+Create_func_disjoint Create_func_disjoint::s_singleton;
+
+Item*
+Create_func_disjoint::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_monthname(a);
+ return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
+ Item_func::SP_DISJOINT_FUNC);
}
+#endif
+
-Item *create_func_month(Item* a)
+Create_func_elt Create_func_elt::s_singleton;
+
+Item*
+Create_func_elt::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- return new Item_func_month(a);
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ if (arg_count < 2)
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ return NULL;
+ }
+
+ return new (thd->mem_root) Item_func_elt(*item_list);
}
-Item *create_func_oct(Item *a)
+
+Create_func_encode Create_func_encode::s_singleton;
+
+Item*
+Create_func_encode::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_conv(a,new Item_int((int32) 10,2),
- new Item_int((int32) 8,1));
+ /* TODO: Known limitation, see Bug#22684 */
+ if ((arg2->type() != Item::STRING_ITEM) || ! arg2->basic_const_item())
+ {
+ my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), "ENCODE");
+ return NULL;
+ }
+
+ String dummy;
+ String *val = arg2->val_str(& dummy);
+ DBUG_ASSERT(val);
+ return new (thd->mem_root) Item_func_encode(arg1, val->c_ptr());
}
-Item *create_func_period_add(Item* a, Item *b)
+
+Create_func_encrypt Create_func_encrypt::s_singleton;
+
+Item*
+Create_func_encrypt::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- return new Item_func_period_add(a,b);
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 1:
+ {
+ Item *param_1= item_list->pop();
+ func= new (thd->mem_root) Item_func_encrypt(param_1);
+ thd->lex->uncacheable(UNCACHEABLE_RAND);
+ break;
+ }
+ case 2:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ func= new (thd->mem_root) Item_func_encrypt(param_1, param_2);
+ break;
+ }
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
+ }
+
+ return func;
}
-Item *create_func_period_diff(Item* a, Item *b)
+
+#ifdef HAVE_SPATIAL
+Create_func_endpoint Create_func_endpoint::s_singleton;
+
+Item*
+Create_func_endpoint::create(THD *thd, Item *arg1)
{
- return new Item_func_period_diff(a,b);
+ return new (thd->mem_root) Item_func_spatial_decomp(arg1,
+ Item_func::SP_ENDPOINT);
}
+#endif
+
+
+#ifdef HAVE_SPATIAL
+Create_func_envelope Create_func_envelope::s_singleton;
-Item *create_func_pi(void)
+Item*
+Create_func_envelope::create(THD *thd, Item *arg1)
{
- return new Item_static_float_func("pi()", M_PI, 6, 8);
+ return new (thd->mem_root) Item_func_envelope(arg1);
}
+#endif
+
-Item *create_func_pow(Item* a, Item *b)
+#ifdef HAVE_SPATIAL
+Create_func_equals Create_func_equals::s_singleton;
+
+Item*
+Create_func_equals::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_pow(a,b);
+ return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
+ Item_func::SP_EQUALS_FUNC);
}
+#endif
+
+
+Create_func_exp Create_func_exp::s_singleton;
-Item *create_func_radians(Item *a)
+Item*
+Create_func_exp::create(THD *thd, Item *arg1)
{
- return new Item_func_units((char*) "radians",a,M_PI/180,0.0);
+ return new (thd->mem_root) Item_func_exp(arg1);
}
-Item *create_func_release_lock(Item* a)
+
+Create_func_export_set Create_func_export_set::s_singleton;
+
+Item*
+Create_func_export_set::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
- return new Item_func_release_lock(a);
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 3:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ Item *param_3= item_list->pop();
+ func= new (thd->mem_root) Item_func_export_set(param_1, param_2, param_3);
+ break;
+ }
+ case 4:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ Item *param_3= item_list->pop();
+ Item *param_4= item_list->pop();
+ func= new (thd->mem_root) Item_func_export_set(param_1, param_2, param_3,
+ param_4);
+ break;
+ }
+ case 5:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ Item *param_3= item_list->pop();
+ Item *param_4= item_list->pop();
+ Item *param_5= item_list->pop();
+ func= new (thd->mem_root) Item_func_export_set(param_1, param_2, param_3,
+ param_4, param_5);
+ break;
+ }
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
+ }
+
+ return func;
}
-Item *create_func_repeat(Item* a, Item *b)
+
+#ifdef HAVE_SPATIAL
+Create_func_exteriorring Create_func_exteriorring::s_singleton;
+
+Item*
+Create_func_exteriorring::create(THD *thd, Item *arg1)
{
- return new Item_func_repeat(a,b);
+ return new (thd->mem_root) Item_func_spatial_decomp(arg1,
+ Item_func::SP_EXTERIORRING);
}
+#endif
-Item *create_func_reverse(Item* a)
+
+Create_func_field Create_func_field::s_singleton;
+
+Item*
+Create_func_field::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- return new Item_func_reverse(a);
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ if (arg_count < 2)
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ return NULL;
+ }
+
+ return new (thd->mem_root) Item_func_field(*item_list);
}
-Item *create_func_rpad(Item* a, Item *b, Item *c)
+
+Create_func_find_in_set Create_func_find_in_set::s_singleton;
+
+Item*
+Create_func_find_in_set::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_rpad(a,b,c);
+ return new (thd->mem_root) Item_func_find_in_set(arg1, arg2);
}
-Item *create_func_rtrim(Item* a)
+
+Create_func_floor Create_func_floor::s_singleton;
+
+Item*
+Create_func_floor::create(THD *thd, Item *arg1)
{
- return new Item_func_rtrim(a);
+ return new (thd->mem_root) Item_func_floor(arg1);
}
-Item *create_func_sec_to_time(Item* a)
+
+Create_func_format Create_func_format::s_singleton;
+
+Item*
+Create_func_format::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_sec_to_time(a);
+ /* TODO: Known limitation, see Bug#22684 */
+ if ((arg2->type() != Item::INT_ITEM) || ! arg2->basic_const_item())
+ {
+ my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), "FORMAT");
+ return NULL;
+ }
+
+ return new (thd->mem_root) Item_func_format(arg1, arg2->val_int());
}
-Item *create_func_sign(Item* a)
+
+Create_func_found_rows Create_func_found_rows::s_singleton;
+
+Item*
+Create_func_found_rows::create(THD *thd)
{
- return new Item_func_sign(a);
+ thd->lex->safe_to_cache_query= 0;
+ return new (thd->mem_root) Item_func_found_rows();
}
-Item *create_func_sin(Item* a)
+
+Create_func_from_days Create_func_from_days::s_singleton;
+
+Item*
+Create_func_from_days::create(THD *thd, Item *arg1)
{
- return new Item_func_sin(a);
+ return new (thd->mem_root) Item_func_from_days(arg1);
}
-Item *create_func_sha(Item* a)
+
+Create_func_from_unixtime Create_func_from_unixtime::s_singleton;
+
+Item*
+Create_func_from_unixtime::create(THD *thd, LEX_STRING name,
+ List<Item> *item_list)
{
- return new Item_func_sha(a);
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 1:
+ {
+ Item *param_1= item_list->pop();
+ func= new (thd->mem_root) Item_func_from_unixtime(param_1);
+ break;
+ }
+ case 2:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ Item *ut= new (thd->mem_root) Item_func_from_unixtime(param_1);
+ func= new (thd->mem_root) Item_func_date_format(ut, param_2, 0);
+ break;
+ }
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
+ }
+
+ return func;
}
-Item *create_func_sleep(Item* a)
+
+#ifdef HAVE_SPATIAL
+Create_func_geometry_from_text Create_func_geometry_from_text::s_singleton;
+
+Item*
+Create_func_geometry_from_text::create(THD *thd, LEX_STRING name,
+ List<Item> *item_list)
{
- current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
- return new Item_func_sleep(a);
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 1:
+ {
+ Item *param_1= item_list->pop();
+ func= new (thd->mem_root) Item_func_geometry_from_text(param_1);
+ thd->lex->uncacheable(UNCACHEABLE_RAND);
+ break;
+ }
+ case 2:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ func= new (thd->mem_root) Item_func_geometry_from_text(param_1, param_2);
+ break;
+ }
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
+ }
+
+ return func;
}
+#endif
+
+
+#ifdef HAVE_SPATIAL
+Create_func_geometry_from_wkb Create_func_geometry_from_wkb::s_singleton;
-Item *create_func_space(Item *a)
+Item*
+Create_func_geometry_from_wkb::create(THD *thd, LEX_STRING name,
+ List<Item> *item_list)
{
- CHARSET_INFO *cs= current_thd->variables.collation_connection;
- Item *sp;
+ Item *func= NULL;
+ int arg_count= 0;
- if (cs->mbminlen > 1)
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 1:
{
- uint dummy_errors;
- sp= new Item_string("",0,cs);
- if (sp)
- sp->str_value.copy(" ", 1, &my_charset_latin1, cs, &dummy_errors);
+ Item *param_1= item_list->pop();
+ func= new (thd->mem_root) Item_func_geometry_from_wkb(param_1);
+ thd->lex->uncacheable(UNCACHEABLE_RAND);
+ break;
}
- else
+ case 2:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ func= new (thd->mem_root) Item_func_geometry_from_wkb(param_1, param_2);
+ break;
+ }
+ default:
{
- sp= new Item_string(" ",1,cs);
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
}
- return sp ? new Item_func_repeat(sp, a) : 0;
+
+ return func;
}
+#endif
+
+
+#ifdef HAVE_SPATIAL
+Create_func_geometry_type Create_func_geometry_type::s_singleton;
-Item *create_func_soundex(Item* a)
+Item*
+Create_func_geometry_type::create(THD *thd, Item *arg1)
{
- return new Item_func_soundex(a);
+ return new (thd->mem_root) Item_func_geometry_type(arg1);
}
+#endif
+
+
+#ifdef HAVE_SPATIAL
+Create_func_geometryn Create_func_geometryn::s_singleton;
-Item *create_func_sqrt(Item* a)
+Item*
+Create_func_geometryn::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_sqrt(a);
+ return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
+ Item_func::SP_GEOMETRYN);
}
+#endif
+
+
+Create_func_get_lock Create_func_get_lock::s_singleton;
-Item *create_func_strcmp(Item* a, Item *b)
+Item*
+Create_func_get_lock::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_strcmp(a,b);
+ thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
+ return new (thd->mem_root) Item_func_get_lock(arg1, arg2);
}
-Item *create_func_tan(Item* a)
+
+#ifdef HAVE_SPATIAL
+Create_func_glength Create_func_glength::s_singleton;
+
+Item*
+Create_func_glength::create(THD *thd, Item *arg1)
{
- return new Item_func_tan(a);
+ return new (thd->mem_root) Item_func_glength(arg1);
}
+#endif
-Item *create_func_time_format(Item *a, Item *b)
+
+Create_func_greatest Create_func_greatest::s_singleton;
+
+Item*
+Create_func_greatest::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- return new Item_func_date_format(a,b,1);
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ if (arg_count < 2)
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ return NULL;
+ }
+
+ return new (thd->mem_root) Item_func_max(*item_list);
}
-Item *create_func_time_to_sec(Item* a)
+
+Create_func_hex Create_func_hex::s_singleton;
+
+Item*
+Create_func_hex::create(THD *thd, Item *arg1)
{
- return new Item_func_time_to_sec(a);
+ return new (thd->mem_root) Item_func_hex(arg1);
}
-Item *create_func_to_days(Item* a)
+
+Create_func_ifnull Create_func_ifnull::s_singleton;
+
+Item*
+Create_func_ifnull::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_to_days(a);
+ return new (thd->mem_root) Item_func_ifnull(arg1, arg2);
}
-Item *create_func_ucase(Item* a)
+
+Create_func_inet_ntoa Create_func_inet_ntoa::s_singleton;
+
+Item*
+Create_func_inet_ntoa::create(THD *thd, Item *arg1)
{
- return new Item_func_ucase(a);
+ return new (thd->mem_root) Item_func_inet_ntoa(arg1);
}
-Item *create_func_unhex(Item* a)
+
+Create_func_inet_aton Create_func_inet_aton::s_singleton;
+
+Item*
+Create_func_inet_aton::create(THD *thd, Item *arg1)
{
- return new Item_func_unhex(a);
+ return new (thd->mem_root) Item_func_inet_aton(arg1);
}
-Item *create_func_uuid(void)
+
+Create_func_instr Create_func_instr::s_singleton;
+
+Item*
+Create_func_instr::create(THD *thd, Item *arg1, Item *arg2)
{
- THD *thd= current_thd;
-#ifdef HAVE_ROW_BASED_REPLICATION
- thd->lex->binlog_row_based_if_mixed= TRUE;
+ return new (thd->mem_root) Item_func_locate(arg1, arg2);
+}
+
+
+#ifdef HAVE_SPATIAL
+Create_func_interiorringn Create_func_interiorringn::s_singleton;
+
+Item*
+Create_func_interiorringn::create(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
+ Item_func::SP_INTERIORRINGN);
+}
#endif
- return new(thd->mem_root) Item_func_uuid();
+
+
+#ifdef HAVE_SPATIAL
+Create_func_intersects Create_func_intersects::s_singleton;
+
+Item*
+Create_func_intersects::create(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
+ Item_func::SP_INTERSECTS_FUNC);
}
+#endif
+
+
+Create_func_is_free_lock Create_func_is_free_lock::s_singleton;
-Item *create_func_version(void)
+Item*
+Create_func_is_free_lock::create(THD *thd, Item *arg1)
{
- return new Item_static_string_func("version()", server_version,
- (uint) strlen(server_version),
- system_charset_info, DERIVATION_SYSCONST);
+ thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
+ return new (thd->mem_root) Item_func_is_free_lock(arg1);
}
-Item *create_func_weekday(Item* a)
+
+Create_func_is_used_lock Create_func_is_used_lock::s_singleton;
+
+Item*
+Create_func_is_used_lock::create(THD *thd, Item *arg1)
{
- return new Item_func_weekday(a, 0);
+ thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
+ return new (thd->mem_root) Item_func_is_used_lock(arg1);
}
-Item *create_func_year(Item* a)
+
+#ifdef HAVE_SPATIAL
+Create_func_isclosed Create_func_isclosed::s_singleton;
+
+Item*
+Create_func_isclosed::create(THD *thd, Item *arg1)
{
- return new Item_func_year(a);
+ return new (thd->mem_root) Item_func_isclosed(arg1);
}
+#endif
+
-Item *create_load_file(Item* a)
+#ifdef HAVE_SPATIAL
+Create_func_isempty Create_func_isempty::s_singleton;
+
+Item*
+Create_func_isempty::create(THD *thd, Item *arg1)
{
- current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
- return new Item_load_file(a);
+ return new (thd->mem_root) Item_func_isempty(arg1);
}
+#endif
-Item *create_func_cast(Item *a, Cast_target cast_type, int len, int dec,
- CHARSET_INFO *cs)
+Create_func_isnull Create_func_isnull::s_singleton;
+
+Item*
+Create_func_isnull::create(THD *thd, Item *arg1)
{
- Item *res;
- int tmp_len;
- LINT_INIT(res);
+ return new (thd->mem_root) Item_func_isnull(arg1);
+}
- switch (cast_type) {
- case ITEM_CAST_BINARY: res= new Item_func_binary(a); break;
- case ITEM_CAST_SIGNED_INT: res= new Item_func_signed(a); break;
- case ITEM_CAST_UNSIGNED_INT: res= new Item_func_unsigned(a); break;
- case ITEM_CAST_DATE: res= new Item_date_typecast(a); break;
- case ITEM_CAST_TIME: res= new Item_time_typecast(a); break;
- case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break;
- case ITEM_CAST_DECIMAL:
- tmp_len= (len>0) ? len : 10;
- if (tmp_len < dec)
- {
- my_error(ER_M_BIGGER_THAN_D, MYF(0), "");
- return 0;
- }
- res= new Item_decimal_typecast(a, tmp_len, dec);
+
+#ifdef HAVE_SPATIAL
+Create_func_issimple Create_func_issimple::s_singleton;
+
+Item*
+Create_func_issimple::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_issimple(arg1);
+}
+#endif
+
+
+Create_func_last_day Create_func_last_day::s_singleton;
+
+Item*
+Create_func_last_day::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_last_day(arg1);
+}
+
+
+Create_func_last_insert_id Create_func_last_insert_id::s_singleton;
+
+Item*
+Create_func_last_insert_id::create(THD *thd, LEX_STRING name,
+ List<Item> *item_list)
+{
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 0:
+ {
+ func= new (thd->mem_root) Item_func_last_insert_id();
+ thd->lex->safe_to_cache_query= 0;
break;
- case ITEM_CAST_CHAR:
- res= new Item_char_typecast(a, len, cs ? cs :
- current_thd->variables.collation_connection);
+ }
+ case 1:
+ {
+ Item *param_1= item_list->pop();
+ func= new (thd->mem_root) Item_func_last_insert_id(param_1);
+ thd->lex->safe_to_cache_query= 0;
break;
+ }
default:
- DBUG_ASSERT(0);
- res= 0;
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
break;
}
- return res;
+ }
+
+ return func;
+}
+
+
+Create_func_lcase Create_func_lcase::s_singleton;
+
+Item*
+Create_func_lcase::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_lcase(arg1);
+}
+
+
+Create_func_least Create_func_least::s_singleton;
+
+Item*
+Create_func_least::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+{
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ if (arg_count < 2)
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ return NULL;
+ }
+
+ return new (thd->mem_root) Item_func_min(*item_list);
+}
+
+
+Create_func_length Create_func_length::s_singleton;
+
+Item*
+Create_func_length::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_length(arg1);
+}
+
+
+Create_func_ln Create_func_ln::s_singleton;
+
+Item*
+Create_func_ln::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_ln(arg1);
+}
+
+
+Create_func_load_file Create_func_load_file::s_singleton;
+
+Item*
+Create_func_load_file::create(THD *thd, Item *arg1)
+{
+ thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
+ return new (thd->mem_root) Item_load_file(arg1);
+}
+
+
+Create_func_locate Create_func_locate::s_singleton;
+
+Item*
+Create_func_locate::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+{
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 2:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ /* Yes, parameters in that order : 2, 1 */
+ func= new (thd->mem_root) Item_func_locate(param_2, param_1);
+ break;
+ }
+ case 3:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ Item *param_3= item_list->pop();
+ /* Yes, parameters in that order : 2, 1, 3 */
+ func= new (thd->mem_root) Item_func_locate(param_2, param_1, param_3);
+ break;
+ }
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
+ }
+
+ return func;
+}
+
+
+Create_func_log Create_func_log::s_singleton;
+
+Item*
+Create_func_log::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+{
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 1:
+ {
+ Item *param_1= item_list->pop();
+ func= new (thd->mem_root) Item_func_log(param_1);
+ break;
+ }
+ case 2:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ func= new (thd->mem_root) Item_func_log(param_1, param_2);
+ break;
+ }
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
+ }
+
+ return func;
+}
+
+
+Create_func_log10 Create_func_log10::s_singleton;
+
+Item*
+Create_func_log10::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_log10(arg1);
+}
+
+
+Create_func_log2 Create_func_log2::s_singleton;
+
+Item*
+Create_func_log2::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_log2(arg1);
+}
+
+
+Create_func_lpad Create_func_lpad::s_singleton;
+
+Item*
+Create_func_lpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+{
+ return new (thd->mem_root) Item_func_lpad(arg1, arg2, arg3);
+}
+
+
+Create_func_ltrim Create_func_ltrim::s_singleton;
+
+Item*
+Create_func_ltrim::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_ltrim(arg1);
+}
+
+
+Create_func_makedate Create_func_makedate::s_singleton;
+
+Item*
+Create_func_makedate::create(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_makedate(arg1, arg2);
+}
+
+
+Create_func_maketime Create_func_maketime::s_singleton;
+
+Item*
+Create_func_maketime::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+{
+ return new (thd->mem_root) Item_func_maketime(arg1, arg2, arg3);
+}
+
+
+Create_func_make_set Create_func_make_set::s_singleton;
+
+Item*
+Create_func_make_set::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+{
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ if (arg_count < 2)
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ return NULL;
+ }
+
+ Item *param_1= item_list->pop();
+ return new (thd->mem_root) Item_func_make_set(param_1, *item_list);
}
-Item *create_func_is_free_lock(Item* a)
+
+Create_func_master_pos_wait Create_func_master_pos_wait::s_singleton;
+
+Item*
+Create_func_master_pos_wait::create(THD *thd, LEX_STRING name,
+ List<Item> *item_list)
{
- current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
- return new Item_func_is_free_lock(a);
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 2:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ func= new (thd->mem_root) Item_master_pos_wait(param_1, param_2);
+ thd->lex->safe_to_cache_query= 0;
+ break;
+ }
+ case 3:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ Item *param_3= item_list->pop();
+ func= new (thd->mem_root) Item_master_pos_wait(param_1, param_2, param_3);
+ thd->lex->safe_to_cache_query= 0;
+ break;
+ }
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
+ }
+
+ return func;
}
-Item *create_func_is_used_lock(Item* a)
+
+Create_func_md5 Create_func_md5::s_singleton;
+
+Item*
+Create_func_md5::create(THD *thd, Item *arg1)
{
- current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
- return new Item_func_is_used_lock(a);
+ return new (thd->mem_root) Item_func_md5(arg1);
}
-Item *create_func_quote(Item* a)
+
+Create_func_monthname Create_func_monthname::s_singleton;
+
+Item*
+Create_func_monthname::create(THD *thd, Item *arg1)
{
- return new Item_func_quote(a);
+ return new (thd->mem_root) Item_func_monthname(arg1);
}
-Item *create_func_xml_extractvalue(Item *a, Item *b)
+
+Create_func_name_const Create_func_name_const::s_singleton;
+
+Item*
+Create_func_name_const::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_xml_extractvalue(a, b);
+ return new (thd->mem_root) Item_name_const(arg1, arg2);
}
-Item *create_func_xml_update(Item *a, Item *b, Item *c)
+
+Create_func_nullif Create_func_nullif::s_singleton;
+
+Item*
+Create_func_nullif::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_xml_update(a, b, c);
+ return new (thd->mem_root) Item_func_nullif(arg1, arg2);
}
+
#ifdef HAVE_SPATIAL
-Item *create_func_as_wkt(Item *a)
+Create_func_numgeometries Create_func_numgeometries::s_singleton;
+
+Item*
+Create_func_numgeometries::create(THD *thd, Item *arg1)
{
- return new Item_func_as_wkt(a);
+ return new (thd->mem_root) Item_func_numgeometries(arg1);
}
+#endif
+
+
+#ifdef HAVE_SPATIAL
+Create_func_numinteriorring Create_func_numinteriorring::s_singleton;
-Item *create_func_as_wkb(Item *a)
+Item*
+Create_func_numinteriorring::create(THD *thd, Item *arg1)
{
- return new Item_func_as_wkb(a);
+ return new (thd->mem_root) Item_func_numinteriorring(arg1);
}
+#endif
+
+
+#ifdef HAVE_SPATIAL
+Create_func_numpoints Create_func_numpoints::s_singleton;
-Item *create_func_srid(Item *a)
+Item*
+Create_func_numpoints::create(THD *thd, Item *arg1)
{
- return new Item_func_srid(a);
+ return new (thd->mem_root) Item_func_numpoints(arg1);
}
+#endif
+
+
+Create_func_oct Create_func_oct::s_singleton;
-Item *create_func_startpoint(Item *a)
+Item*
+Create_func_oct::create(THD *thd, Item *arg1)
{
- return new Item_func_spatial_decomp(a, Item_func::SP_STARTPOINT);
+ Item *i10= new (thd->mem_root) Item_int((int32) 10,2);
+ Item *i8= new (thd->mem_root) Item_int((int32) 8,1);
+ return new (thd->mem_root) Item_func_conv(arg1, i10, i8);
}
-Item *create_func_endpoint(Item *a)
+
+Create_func_ord Create_func_ord::s_singleton;
+
+Item*
+Create_func_ord::create(THD *thd, Item *arg1)
{
- return new Item_func_spatial_decomp(a, Item_func::SP_ENDPOINT);
+ return new (thd->mem_root) Item_func_ord(arg1);
}
-Item *create_func_exteriorring(Item *a)
+
+#ifdef HAVE_SPATIAL
+Create_func_overlaps Create_func_overlaps::s_singleton;
+
+Item*
+Create_func_overlaps::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_spatial_decomp(a, Item_func::SP_EXTERIORRING);
+ return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
+ Item_func::SP_OVERLAPS_FUNC);
}
+#endif
+
-Item *create_func_pointn(Item *a, Item *b)
+Create_func_period_add Create_func_period_add::s_singleton;
+
+Item*
+Create_func_period_add::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_spatial_decomp_n(a, b, Item_func::SP_POINTN);
+ return new (thd->mem_root) Item_func_period_add(arg1, arg2);
}
-Item *create_func_interiorringn(Item *a, Item *b)
+
+Create_func_period_diff Create_func_period_diff::s_singleton;
+
+Item*
+Create_func_period_diff::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_spatial_decomp_n(a, b, Item_func::SP_INTERIORRINGN);
+ return new (thd->mem_root) Item_func_period_diff(arg1, arg2);
}
-Item *create_func_geometryn(Item *a, Item *b)
+
+Create_func_pi Create_func_pi::s_singleton;
+
+Item*
+Create_func_pi::create(THD *thd)
{
- return new Item_func_spatial_decomp_n(a, b, Item_func::SP_GEOMETRYN);
+ return new (thd->mem_root) Item_static_float_func("pi()", M_PI, 6, 8);
}
-Item *create_func_centroid(Item *a)
+
+#ifdef HAVE_SPATIAL
+Create_func_pointn Create_func_pointn::s_singleton;
+
+Item*
+Create_func_pointn::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_centroid(a);
+ return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
+ Item_func::SP_POINTN);
}
+#endif
+
-Item *create_func_envelope(Item *a)
+Create_func_pow Create_func_pow::s_singleton;
+
+Item*
+Create_func_pow::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_envelope(a);
+ return new (thd->mem_root) Item_func_pow(arg1, arg2);
}
-Item *create_func_equals(Item *a, Item *b)
+
+Create_func_quote Create_func_quote::s_singleton;
+
+Item*
+Create_func_quote::create(THD *thd, Item *arg1)
{
- return new Item_func_spatial_rel(a, b, Item_func::SP_EQUALS_FUNC);
+ return new (thd->mem_root) Item_func_quote(arg1);
}
-Item *create_func_disjoint(Item *a, Item *b)
+
+Create_func_radians Create_func_radians::s_singleton;
+
+Item*
+Create_func_radians::create(THD *thd, Item *arg1)
{
- return new Item_func_spatial_rel(a, b, Item_func::SP_DISJOINT_FUNC);
+ return new (thd->mem_root) Item_func_units((char*) "radians", arg1,
+ M_PI/180, 0.0);
}
-Item *create_func_intersects(Item *a, Item *b)
+
+Create_func_rand Create_func_rand::s_singleton;
+
+Item*
+Create_func_rand::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- return new Item_func_spatial_rel(a, b, Item_func::SP_INTERSECTS_FUNC);
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 0:
+ {
+ func= new (thd->mem_root) Item_func_rand();
+ thd->lex->uncacheable(UNCACHEABLE_RAND);
+ break;
+ }
+ case 1:
+ {
+ Item *param_1= item_list->pop();
+ func= new (thd->mem_root) Item_func_rand(param_1);
+ thd->lex->uncacheable(UNCACHEABLE_RAND);
+ break;
+ }
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
+ }
+
+ return func;
}
-Item *create_func_touches(Item *a, Item *b)
+
+Create_func_release_lock Create_func_release_lock::s_singleton;
+
+Item*
+Create_func_release_lock::create(THD *thd, Item *arg1)
{
- return new Item_func_spatial_rel(a, b, Item_func::SP_TOUCHES_FUNC);
+ thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
+ return new (thd->mem_root) Item_func_release_lock(arg1);
}
-Item *create_func_crosses(Item *a, Item *b)
+
+Create_func_reverse Create_func_reverse::s_singleton;
+
+Item*
+Create_func_reverse::create(THD *thd, Item *arg1)
{
- return new Item_func_spatial_rel(a, b, Item_func::SP_CROSSES_FUNC);
+ return new (thd->mem_root) Item_func_reverse(arg1);
}
-Item *create_func_within(Item *a, Item *b)
+
+Create_func_round Create_func_round::s_singleton;
+
+Item*
+Create_func_round::create(THD *thd, LEX_STRING name, List<Item> *item_list)
{
- return new Item_func_spatial_rel(a, b, Item_func::SP_WITHIN_FUNC);
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 1:
+ {
+ Item *param_1= item_list->pop();
+ Item *i0 = new (thd->mem_root) Item_int((char*)"0", 0, 1);
+ func= new (thd->mem_root) Item_func_round(param_1, i0, 0);
+ break;
+ }
+ case 2:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ func= new (thd->mem_root) Item_func_round(param_1, param_2, 0);
+ break;
+ }
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
+ }
+
+ return func;
}
-Item *create_func_contains(Item *a, Item *b)
+
+Create_func_row_count Create_func_row_count::s_singleton;
+
+Item*
+Create_func_row_count::create(THD *thd)
{
- return new Item_func_spatial_rel(a, b, Item_func::SP_CONTAINS_FUNC);
+ thd->lex->safe_to_cache_query= 0;
+ return new (thd->mem_root) Item_func_row_count();
}
-Item *create_func_overlaps(Item *a, Item *b)
+
+Create_func_rpad Create_func_rpad::s_singleton;
+
+Item*
+Create_func_rpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
- return new Item_func_spatial_rel(a, b, Item_func::SP_OVERLAPS_FUNC);
+ return new (thd->mem_root) Item_func_rpad(arg1, arg2, arg3);
}
-Item *create_func_isempty(Item *a)
+
+Create_func_rtrim Create_func_rtrim::s_singleton;
+
+Item*
+Create_func_rtrim::create(THD *thd, Item *arg1)
{
- return new Item_func_isempty(a);
+ return new (thd->mem_root) Item_func_rtrim(arg1);
}
-Item *create_func_issimple(Item *a)
+
+Create_func_sec_to_time Create_func_sec_to_time::s_singleton;
+
+Item*
+Create_func_sec_to_time::create(THD *thd, Item *arg1)
{
- return new Item_func_issimple(a);
+ return new (thd->mem_root) Item_func_sec_to_time(arg1);
}
-Item *create_func_isclosed(Item *a)
+
+Create_func_sha Create_func_sha::s_singleton;
+
+Item*
+Create_func_sha::create(THD *thd, Item *arg1)
{
- return new Item_func_isclosed(a);
+ return new (thd->mem_root) Item_func_sha(arg1);
}
-Item *create_func_geometry_type(Item *a)
+
+Create_func_sign Create_func_sign::s_singleton;
+
+Item*
+Create_func_sign::create(THD *thd, Item *arg1)
{
- return new Item_func_geometry_type(a);
+ return new (thd->mem_root) Item_func_sign(arg1);
}
-Item *create_func_dimension(Item *a)
+
+Create_func_sin Create_func_sin::s_singleton;
+
+Item*
+Create_func_sin::create(THD *thd, Item *arg1)
{
- return new Item_func_dimension(a);
+ return new (thd->mem_root) Item_func_sin(arg1);
}
-Item *create_func_x(Item *a)
+
+Create_func_sleep Create_func_sleep::s_singleton;
+
+Item*
+Create_func_sleep::create(THD *thd, Item *arg1)
{
- return new Item_func_x(a);
+ thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
+ return new (thd->mem_root) Item_func_sleep(arg1);
}
-Item *create_func_y(Item *a)
+
+Create_func_soundex Create_func_soundex::s_singleton;
+
+Item*
+Create_func_soundex::create(THD *thd, Item *arg1)
{
- return new Item_func_y(a);
+ return new (thd->mem_root) Item_func_soundex(arg1);
}
-Item *create_func_numpoints(Item *a)
+
+Create_func_space Create_func_space::s_singleton;
+
+Item*
+Create_func_space::create(THD *thd, Item *arg1)
{
- return new Item_func_numpoints(a);
+ /**
+ TODO: Fix Bug#23637
+ The parsed item tree should not depend on
+ <code>thd->variables.collation_connection</code>.
+ */
+ CHARSET_INFO *cs= thd->variables.collation_connection;
+ Item *sp;
+
+ if (cs->mbminlen > 1)
+ {
+ uint dummy_errors;
+ sp= new (thd->mem_root) Item_string("", 0, cs);
+ sp->str_value.copy(" ", 1, &my_charset_latin1, cs, &dummy_errors);
+ }
+ else
+ {
+ sp= new (thd->mem_root) Item_string(" ", 1, cs);
+ }
+
+ return new (thd->mem_root) Item_func_repeat(sp, arg1);
}
-Item *create_func_numinteriorring(Item *a)
+
+Create_func_sqrt Create_func_sqrt::s_singleton;
+
+Item*
+Create_func_sqrt::create(THD *thd, Item *arg1)
{
- return new Item_func_numinteriorring(a);
+ return new (thd->mem_root) Item_func_sqrt(arg1);
}
-Item *create_func_numgeometries(Item *a)
+
+#ifdef HAVE_SPATIAL
+Create_func_srid Create_func_srid::s_singleton;
+
+Item*
+Create_func_srid::create(THD *thd, Item *arg1)
{
- return new Item_func_numgeometries(a);
+ return new (thd->mem_root) Item_func_srid(arg1);
}
+#endif
-Item *create_func_area(Item *a)
+
+#ifdef HAVE_SPATIAL
+Create_func_startpoint Create_func_startpoint::s_singleton;
+
+Item*
+Create_func_startpoint::create(THD *thd, Item *arg1)
{
- return new Item_func_area(a);
+ return new (thd->mem_root) Item_func_spatial_decomp(arg1,
+ Item_func::SP_STARTPOINT);
}
+#endif
-Item *create_func_glength(Item *a)
+
+Create_func_str_to_date Create_func_str_to_date::s_singleton;
+
+Item*
+Create_func_str_to_date::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_glength(a);
+ return new (thd->mem_root) Item_func_str_to_date(arg1, arg2);
}
-Item *create_func_point(Item *a, Item *b)
+
+Create_func_strcmp Create_func_strcmp::s_singleton;
+
+Item*
+Create_func_strcmp::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_point(a, b);
+ return new (thd->mem_root) Item_func_strcmp(arg1, arg2);
}
-#endif /*HAVE_SPATIAL*/
-Item *create_func_crc32(Item* a)
+
+Create_func_substr_index Create_func_substr_index::s_singleton;
+
+Item*
+Create_func_substr_index::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
- return new Item_func_crc32(a);
+ return new (thd->mem_root) Item_func_substr_index(arg1, arg2, arg3);
}
-Item *create_func_compress(Item* a)
+
+Create_func_subtime Create_func_subtime::s_singleton;
+
+Item*
+Create_func_subtime::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_compress(a);
+ return new (thd->mem_root) Item_func_add_time(arg1, arg2, 0, 1);
}
-Item *create_func_uncompress(Item* a)
+
+Create_func_tan Create_func_tan::s_singleton;
+
+Item*
+Create_func_tan::create(THD *thd, Item *arg1)
{
- return new Item_func_uncompress(a);
+ return new (thd->mem_root) Item_func_tan(arg1);
}
-Item *create_func_uncompressed_length(Item* a)
+
+Create_func_time_format Create_func_time_format::s_singleton;
+
+Item*
+Create_func_time_format::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_uncompressed_length(a);
+ return new (thd->mem_root) Item_func_date_format(arg1, arg2, 1);
}
-Item *create_func_datediff(Item *a, Item *b)
+
+Create_func_time_to_sec Create_func_time_to_sec::s_singleton;
+
+Item*
+Create_func_time_to_sec::create(THD *thd, Item *arg1)
{
- return new Item_func_minus(new Item_func_to_days(a),
- new Item_func_to_days(b));
+ return new (thd->mem_root) Item_func_time_to_sec(arg1);
}
-Item *create_func_weekofyear(Item *a)
+
+Create_func_timediff Create_func_timediff::s_singleton;
+
+Item*
+Create_func_timediff::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_week(a, new Item_int((char*) "0", 3, 1));
+ return new (thd->mem_root) Item_func_timediff(arg1, arg2);
}
-Item *create_func_makedate(Item* a,Item* b)
+
+Create_func_to_days Create_func_to_days::s_singleton;
+
+Item*
+Create_func_to_days::create(THD *thd, Item *arg1)
{
- return new Item_func_makedate(a, b);
+ return new (thd->mem_root) Item_func_to_days(arg1);
}
-Item *create_func_addtime(Item* a,Item* b)
+
+#ifdef HAVE_SPATIAL
+Create_func_touches Create_func_touches::s_singleton;
+
+Item*
+Create_func_touches::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_add_time(a, b, 0, 0);
+ return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
+ Item_func::SP_TOUCHES_FUNC);
}
+#endif
+
-Item *create_func_subtime(Item* a,Item* b)
+Create_func_ucase Create_func_ucase::s_singleton;
+
+Item*
+Create_func_ucase::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_ucase(arg1);
+}
+
+
+Create_func_uncompress Create_func_uncompress::s_singleton;
+
+Item*
+Create_func_uncompress::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_uncompress(arg1);
+}
+
+
+Create_func_uncompressed_length Create_func_uncompressed_length::s_singleton;
+
+Item*
+Create_func_uncompressed_length::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_uncompressed_length(arg1);
+}
+
+
+Create_func_unhex Create_func_unhex::s_singleton;
+
+Item*
+Create_func_unhex::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_unhex(arg1);
+}
+
+
+Create_func_unix_timestamp Create_func_unix_timestamp::s_singleton;
+
+Item*
+Create_func_unix_timestamp::create(THD *thd, LEX_STRING name,
+ List<Item> *item_list)
+{
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 0:
+ {
+ func= new (thd->mem_root) Item_func_unix_timestamp();
+ thd->lex->safe_to_cache_query= 0;
+ break;
+ }
+ case 1:
+ {
+ Item *param_1= item_list->pop();
+ func= new (thd->mem_root) Item_func_unix_timestamp(param_1);
+ break;
+ }
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
+ }
+
+ return func;
+}
+
+
+Create_func_uuid Create_func_uuid::s_singleton;
+
+Item*
+Create_func_uuid::create(THD *thd)
{
- return new Item_func_add_time(a, b, 0, 1);
+#ifdef HAVE_ROW_BASED_REPLICATION
+ thd->lex->binlog_row_based_if_mixed= TRUE;
+#endif
+ return new (thd->mem_root) Item_func_uuid();
}
-Item *create_func_timediff(Item* a,Item* b)
+
+Create_func_version Create_func_version::s_singleton;
+
+Item*
+Create_func_version::create(THD *thd)
{
- return new Item_func_timediff(a, b);
+ return new (thd->mem_root) Item_static_string_func("version()",
+ server_version,
+ (uint) strlen(server_version),
+ system_charset_info,
+ DERIVATION_SYSCONST);
}
-Item *create_func_maketime(Item* a,Item* b,Item* c)
+
+Create_func_weekday Create_func_weekday::s_singleton;
+
+Item*
+Create_func_weekday::create(THD *thd, Item *arg1)
{
- return new Item_func_maketime(a, b, c);
+ return new (thd->mem_root) Item_func_weekday(arg1, 0);
}
-Item *create_func_str_to_date(Item* a,Item* b)
+
+Create_func_weekofyear Create_func_weekofyear::s_singleton;
+
+Item*
+Create_func_weekofyear::create(THD *thd, Item *arg1)
{
- return new Item_func_str_to_date(a, b);
+ Item *i1= new (thd->mem_root) Item_int((char*) "0", 3, 1);
+ return new (thd->mem_root) Item_func_week(arg1, i1);
}
-Item *create_func_last_day(Item *a)
+
+#ifdef HAVE_SPATIAL
+Create_func_within Create_func_within::s_singleton;
+
+Item*
+Create_func_within::create(THD *thd, Item *arg1, Item *arg2)
{
- return new Item_func_last_day(a);
+ return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
+ Item_func::SP_WITHIN_FUNC);
}
+#endif
+
+
+#ifdef HAVE_SPATIAL
+Create_func_x Create_func_x::s_singleton;
+
+Item*
+Create_func_x::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_x(arg1);
+}
+#endif
+
+
+Create_func_xml_extractvalue Create_func_xml_extractvalue::s_singleton;
+
+Item*
+Create_func_xml_extractvalue::create(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_xml_extractvalue(arg1, arg2);
+}
+
+
+Create_func_xml_update Create_func_xml_update::s_singleton;
+
+Item*
+Create_func_xml_update::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+{
+ return new (thd->mem_root) Item_func_xml_update(arg1, arg2, arg3);
+}
+
+
+#ifdef HAVE_SPATIAL
+Create_func_y Create_func_y::s_singleton;
+
+Item*
+Create_func_y::create(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_y(arg1);
+}
+#endif
+
+
+Create_func_year_week Create_func_year_week::s_singleton;
+
+Item*
+Create_func_year_week::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+{
+ Item *func= NULL;
+ int arg_count= 0;
+
+ if (item_list != NULL)
+ arg_count= item_list->elements;
+
+ switch (arg_count) {
+ case 1:
+ {
+ Item *param_1= item_list->pop();
+ Item *i0= new (thd->mem_root) Item_int((char*) "0", 0, 1);
+ func= new (thd->mem_root) Item_func_yearweek(param_1, i0);
+ break;
+ }
+ case 2:
+ {
+ Item *param_1= item_list->pop();
+ Item *param_2= item_list->pop();
+ func= new (thd->mem_root) Item_func_yearweek(param_1, param_2);
+ break;
+ }
+ default:
+ {
+ my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
+ break;
+ }
+ }
+
+ return func;
+}
+
+
+struct Native_func_registry
+{
+ LEX_STRING name;
+ Create_func *builder;
+};
+
+#define BUILDER(F) & F::s_singleton
+
+#ifdef HAVE_SPATIAL
+ #define GEOM_BUILDER(F) & F::s_singleton
+#else
+ #define GEOM_BUILDER(F) & Create_func_no_geom::s_singleton
+#endif
+
+/*
+ MySQL native functions.
+ MAINTAINER:
+ - Keep sorted for human lookup. At runtime, a hash table is used.
+ - do **NOT** conditionally (#ifdef, #ifndef) define a function *NAME*:
+ doing so will cause user code that works against a --without-XYZ binary
+ to fail with name collisions against a --with-XYZ binary.
+ Use something similar to GEOM_BUILDER instead.
+ - keep 1 line per entry, it makes grep | sort easier
+*/
+
+static Native_func_registry func_array[] =
+{
+ { C_STRING_WITH_LEN("ABS"), BUILDER(Create_func_abs)},
+ { C_STRING_WITH_LEN("ACOS"), BUILDER(Create_func_acos)},
+ { C_STRING_WITH_LEN("ADDTIME"), BUILDER(Create_func_addtime)},
+ { C_STRING_WITH_LEN("AES_DECRYPT"), BUILDER(Create_func_aes_decrypt)},
+ { C_STRING_WITH_LEN("AES_ENCRYPT"), BUILDER(Create_func_aes_encrypt)},
+ { C_STRING_WITH_LEN("AREA"), GEOM_BUILDER(Create_func_area)},
+ { C_STRING_WITH_LEN("ASBINARY"), GEOM_BUILDER(Create_func_as_wkb)},
+ { C_STRING_WITH_LEN("ASIN"), BUILDER(Create_func_asin)},
+ { C_STRING_WITH_LEN("ASTEXT"), GEOM_BUILDER(Create_func_as_wkt)},
+ { C_STRING_WITH_LEN("ASWKB"), GEOM_BUILDER(Create_func_as_wkb)},
+ { C_STRING_WITH_LEN("ASWKT"), GEOM_BUILDER(Create_func_as_wkt)},
+ { C_STRING_WITH_LEN("ATAN"), BUILDER(Create_func_atan)},
+ { C_STRING_WITH_LEN("ATAN2"), BUILDER(Create_func_atan)},
+ { C_STRING_WITH_LEN("BENCHMARK"), BUILDER(Create_func_benchmark)},
+ { C_STRING_WITH_LEN("BIN"), BUILDER(Create_func_bin)},
+ { C_STRING_WITH_LEN("BIT_COUNT"), BUILDER(Create_func_bit_count)},
+ { C_STRING_WITH_LEN("BIT_LENGTH"), BUILDER(Create_func_bit_length)},
+ { C_STRING_WITH_LEN("CEIL"), BUILDER(Create_func_ceiling)},
+ { C_STRING_WITH_LEN("CEILING"), BUILDER(Create_func_ceiling)},
+ { C_STRING_WITH_LEN("CENTROID"), GEOM_BUILDER(Create_func_centroid)},
+ { C_STRING_WITH_LEN("CHARACTER_LENGTH"), BUILDER(Create_func_char_length)},
+ { C_STRING_WITH_LEN("CHAR_LENGTH"), BUILDER(Create_func_char_length)},
+ { C_STRING_WITH_LEN("COERCIBILITY"), BUILDER(Create_func_coercibility)},
+ { C_STRING_WITH_LEN("COMPRESS"), BUILDER(Create_func_compress)},
+ { C_STRING_WITH_LEN("CONCAT"), BUILDER(Create_func_concat)},
+ { C_STRING_WITH_LEN("CONCAT_WS"), BUILDER(Create_func_concat_ws)},
+ { C_STRING_WITH_LEN("CONNECTION_ID"), BUILDER(Create_func_connection_id)},
+ { C_STRING_WITH_LEN("CONV"), BUILDER(Create_func_conv)},
+ { C_STRING_WITH_LEN("CONVERT_TZ"), BUILDER(Create_func_convert_tz)},
+ { C_STRING_WITH_LEN("COS"), BUILDER(Create_func_cos)},
+ { C_STRING_WITH_LEN("COT"), BUILDER(Create_func_cot)},
+ { C_STRING_WITH_LEN("CRC32"), BUILDER(Create_func_crc32)},
+ { C_STRING_WITH_LEN("CROSSES"), GEOM_BUILDER(Create_func_crosses)},
+ { C_STRING_WITH_LEN("DATEDIFF"), BUILDER(Create_func_datediff)},
+ { C_STRING_WITH_LEN("DATE_FORMAT"), BUILDER(Create_func_date_format)},
+ { C_STRING_WITH_LEN("DAYNAME"), BUILDER(Create_func_dayname)},
+ { C_STRING_WITH_LEN("DAYOFMONTH"), BUILDER(Create_func_dayofmonth)},
+ { C_STRING_WITH_LEN("DAYOFWEEK"), BUILDER(Create_func_dayofweek)},
+ { C_STRING_WITH_LEN("DAYOFYEAR"), BUILDER(Create_func_dayofyear)},
+ { C_STRING_WITH_LEN("DECODE"), BUILDER(Create_func_decode)},
+ { C_STRING_WITH_LEN("DEGREES"), BUILDER(Create_func_degrees)},
+ { C_STRING_WITH_LEN("DES_DECRYPT"), BUILDER(Create_func_des_decrypt)},
+ { C_STRING_WITH_LEN("DES_ENCRYPT"), BUILDER(Create_func_des_encrypt)},
+ { C_STRING_WITH_LEN("DIMENSION"), GEOM_BUILDER(Create_func_dimension)},
+ { C_STRING_WITH_LEN("DISJOINT"), GEOM_BUILDER(Create_func_disjoint)},
+ { C_STRING_WITH_LEN("ELT"), BUILDER(Create_func_elt)},
+ { C_STRING_WITH_LEN("ENCODE"), BUILDER(Create_func_encode)},
+ { C_STRING_WITH_LEN("ENCRYPT"), BUILDER(Create_func_encrypt)},
+ { C_STRING_WITH_LEN("ENDPOINT"), GEOM_BUILDER(Create_func_endpoint)},
+ { C_STRING_WITH_LEN("ENVELOPE"), GEOM_BUILDER(Create_func_envelope)},
+ { C_STRING_WITH_LEN("EQUALS"), GEOM_BUILDER(Create_func_equals)},
+ { C_STRING_WITH_LEN("EXP"), BUILDER(Create_func_exp)},
+ { C_STRING_WITH_LEN("EXPORT_SET"), BUILDER(Create_func_export_set)},
+ { C_STRING_WITH_LEN("EXTERIORRING"), GEOM_BUILDER(Create_func_exteriorring)},
+ { C_STRING_WITH_LEN("EXTRACTVALUE"), BUILDER(Create_func_xml_extractvalue)},
+ { C_STRING_WITH_LEN("FIELD"), BUILDER(Create_func_field)},
+ { C_STRING_WITH_LEN("FIND_IN_SET"), BUILDER(Create_func_find_in_set)},
+ { C_STRING_WITH_LEN("FLOOR"), BUILDER(Create_func_floor)},
+ { C_STRING_WITH_LEN("FORMAT"), BUILDER(Create_func_format)},
+ { C_STRING_WITH_LEN("FOUND_ROWS"), BUILDER(Create_func_found_rows)},
+ { C_STRING_WITH_LEN("FROM_DAYS"), BUILDER(Create_func_from_days)},
+ { C_STRING_WITH_LEN("FROM_UNIXTIME"), BUILDER(Create_func_from_unixtime)},
+ { C_STRING_WITH_LEN("GEOMCOLLFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("GEOMCOLLFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("GEOMETRYCOLLECTIONFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("GEOMETRYCOLLECTIONFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("GEOMETRYFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("GEOMETRYFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("GEOMETRYN"), GEOM_BUILDER(Create_func_geometryn)},
+ { C_STRING_WITH_LEN("GEOMETRYTYPE"), GEOM_BUILDER(Create_func_geometry_type)},
+ { C_STRING_WITH_LEN("GEOMFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("GEOMFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("GET_LOCK"), BUILDER(Create_func_get_lock)},
+ { C_STRING_WITH_LEN("GLENGTH"), GEOM_BUILDER(Create_func_glength)},
+ { C_STRING_WITH_LEN("GREATEST"), BUILDER(Create_func_greatest)},
+ { C_STRING_WITH_LEN("HEX"), BUILDER(Create_func_hex)},
+ { C_STRING_WITH_LEN("IFNULL"), BUILDER(Create_func_ifnull)},
+ { C_STRING_WITH_LEN("INET_ATON"), BUILDER(Create_func_inet_aton)},
+ { C_STRING_WITH_LEN("INET_NTOA"), BUILDER(Create_func_inet_ntoa)},
+ { C_STRING_WITH_LEN("INSTR"), BUILDER(Create_func_instr)},
+ { C_STRING_WITH_LEN("INTERIORRINGN"), GEOM_BUILDER(Create_func_interiorringn)},
+ { C_STRING_WITH_LEN("INTERSECTS"), GEOM_BUILDER(Create_func_intersects)},
+ { C_STRING_WITH_LEN("ISCLOSED"), GEOM_BUILDER(Create_func_isclosed)},
+ { C_STRING_WITH_LEN("ISEMPTY"), GEOM_BUILDER(Create_func_isempty)},
+ { C_STRING_WITH_LEN("ISNULL"), BUILDER(Create_func_isnull)},
+ { C_STRING_WITH_LEN("ISSIMPLE"), GEOM_BUILDER(Create_func_issimple)},
+ { C_STRING_WITH_LEN("IS_FREE_LOCK"), BUILDER(Create_func_is_free_lock)},
+ { C_STRING_WITH_LEN("IS_USED_LOCK"), BUILDER(Create_func_is_used_lock)},
+ { C_STRING_WITH_LEN("LAST_DAY"), BUILDER(Create_func_last_day)},
+ { C_STRING_WITH_LEN("LAST_INSERT_ID"), BUILDER(Create_func_last_insert_id)},
+ { C_STRING_WITH_LEN("LCASE"), BUILDER(Create_func_lcase)},
+ { C_STRING_WITH_LEN("LEAST"), BUILDER(Create_func_least)},
+ { C_STRING_WITH_LEN("LENGTH"), BUILDER(Create_func_length)},
+ { C_STRING_WITH_LEN("LINEFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("LINEFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("LINESTRINGFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("LINESTRINGFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("LN"), BUILDER(Create_func_ln)},
+ { C_STRING_WITH_LEN("LOAD_FILE"), BUILDER(Create_func_load_file)},
+ { C_STRING_WITH_LEN("LOCATE"), BUILDER(Create_func_locate)},
+ { C_STRING_WITH_LEN("LOG"), BUILDER(Create_func_log)},
+ { C_STRING_WITH_LEN("LOG10"), BUILDER(Create_func_log10)},
+ { C_STRING_WITH_LEN("LOG2"), BUILDER(Create_func_log2)},
+ { C_STRING_WITH_LEN("LOWER"), BUILDER(Create_func_lcase)},
+ { C_STRING_WITH_LEN("LPAD"), BUILDER(Create_func_lpad)},
+ { C_STRING_WITH_LEN("LTRIM"), BUILDER(Create_func_ltrim)},
+ { C_STRING_WITH_LEN("MAKEDATE"), BUILDER(Create_func_makedate)},
+ { C_STRING_WITH_LEN("MAKETIME"), BUILDER(Create_func_maketime)},
+ { C_STRING_WITH_LEN("MAKE_SET"), BUILDER(Create_func_make_set)},
+ { C_STRING_WITH_LEN("MASTER_POS_WAIT"), BUILDER(Create_func_master_pos_wait)},
+ { C_STRING_WITH_LEN("MBRCONTAINS"), GEOM_BUILDER(Create_func_contains)},
+ { C_STRING_WITH_LEN("MD5"), BUILDER(Create_func_md5)},
+ { C_STRING_WITH_LEN("MLINEFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("MLINEFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("MONTHNAME"), BUILDER(Create_func_monthname)},
+ { C_STRING_WITH_LEN("MPOINTFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("MPOINTFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("MPOLYFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("MPOLYFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("MULTILINESTRINGFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("MULTILINESTRINGFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("MULTIPOINTFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("MULTIPOINTFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("MULTIPOLYGONFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("MULTIPOLYGONFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("NAME_CONST"), BUILDER(Create_func_name_const)},
+ { C_STRING_WITH_LEN("NULLIF"), BUILDER(Create_func_nullif)},
+ { C_STRING_WITH_LEN("NUMGEOMETRIES"), GEOM_BUILDER(Create_func_numgeometries)},
+ { C_STRING_WITH_LEN("NUMINTERIORRINGS"), GEOM_BUILDER(Create_func_numinteriorring)},
+ { C_STRING_WITH_LEN("NUMPOINTS"), GEOM_BUILDER(Create_func_numpoints)},
+ { C_STRING_WITH_LEN("OCT"), BUILDER(Create_func_oct)},
+ { C_STRING_WITH_LEN("OCTET_LENGTH"), BUILDER(Create_func_length)},
+ { C_STRING_WITH_LEN("ORD"), BUILDER(Create_func_ord)},
+ { C_STRING_WITH_LEN("OVERLAPS"), GEOM_BUILDER(Create_func_overlaps)},
+ { C_STRING_WITH_LEN("PERIOD_ADD"), BUILDER(Create_func_period_add)},
+ { C_STRING_WITH_LEN("PERIOD_DIFF"), BUILDER(Create_func_period_diff)},
+ { C_STRING_WITH_LEN("PI"), BUILDER(Create_func_pi)},
+ { C_STRING_WITH_LEN("POINTFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("POINTFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("POINTN"), GEOM_BUILDER(Create_func_pointn)},
+ { C_STRING_WITH_LEN("POLYFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("POLYFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("POLYGONFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
+ { C_STRING_WITH_LEN("POLYGONFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { C_STRING_WITH_LEN("POW"), BUILDER(Create_func_pow)},
+ { C_STRING_WITH_LEN("POWER"), BUILDER(Create_func_pow)},
+ { C_STRING_WITH_LEN("QUOTE"), BUILDER(Create_func_quote)},
+ { C_STRING_WITH_LEN("RADIANS"), BUILDER(Create_func_radians)},
+ { C_STRING_WITH_LEN("RAND"), BUILDER(Create_func_rand)},
+ { C_STRING_WITH_LEN("RELEASE_LOCK"), BUILDER(Create_func_release_lock)},
+ { C_STRING_WITH_LEN("REVERSE"), BUILDER(Create_func_reverse)},
+ { C_STRING_WITH_LEN("ROUND"), BUILDER(Create_func_round)},
+ { C_STRING_WITH_LEN("ROW_COUNT"), BUILDER(Create_func_row_count)},
+ { C_STRING_WITH_LEN("RPAD"), BUILDER(Create_func_rpad)},
+ { C_STRING_WITH_LEN("RTRIM"), BUILDER(Create_func_rtrim)},
+ { C_STRING_WITH_LEN("SEC_TO_TIME"), BUILDER(Create_func_sec_to_time)},
+ { C_STRING_WITH_LEN("SHA"), BUILDER(Create_func_sha)},
+ { C_STRING_WITH_LEN("SHA1"), BUILDER(Create_func_sha)},
+ { C_STRING_WITH_LEN("SIGN"), BUILDER(Create_func_sign)},
+ { C_STRING_WITH_LEN("SIN"), BUILDER(Create_func_sin)},
+ { C_STRING_WITH_LEN("SLEEP"), BUILDER(Create_func_sleep)},
+ { C_STRING_WITH_LEN("SOUNDEX"), BUILDER(Create_func_soundex)},
+ { C_STRING_WITH_LEN("SPACE"), BUILDER(Create_func_space)},
+ { C_STRING_WITH_LEN("SQRT"), BUILDER(Create_func_sqrt)},
+ { C_STRING_WITH_LEN("SRID"), GEOM_BUILDER(Create_func_srid)},
+ { C_STRING_WITH_LEN("STARTPOINT"), GEOM_BUILDER(Create_func_startpoint)},
+ { C_STRING_WITH_LEN("STRCMP"), BUILDER(Create_func_strcmp)},
+ { C_STRING_WITH_LEN("STR_TO_DATE"), BUILDER(Create_func_str_to_date)},
+ { C_STRING_WITH_LEN("SUBSTRING_INDEX"), BUILDER(Create_func_substr_index)},
+ { C_STRING_WITH_LEN("SUBTIME"), BUILDER(Create_func_subtime)},
+ { C_STRING_WITH_LEN("TAN"), BUILDER(Create_func_tan)},
+ { C_STRING_WITH_LEN("TIMEDIFF"), BUILDER(Create_func_timediff)},
+ { C_STRING_WITH_LEN("TIME_FORMAT"), BUILDER(Create_func_time_format)},
+ { C_STRING_WITH_LEN("TIME_TO_SEC"), BUILDER(Create_func_time_to_sec)},
+ { C_STRING_WITH_LEN("TOUCHES"), GEOM_BUILDER(Create_func_touches)},
+ { C_STRING_WITH_LEN("TO_DAYS"), BUILDER(Create_func_to_days)},
+ { C_STRING_WITH_LEN("UCASE"), BUILDER(Create_func_ucase)},
+ { C_STRING_WITH_LEN("UNCOMPRESS"), BUILDER(Create_func_uncompress)},
+ { C_STRING_WITH_LEN("UNCOMPRESSED_LENGTH"), BUILDER(Create_func_uncompressed_length)},
+ { C_STRING_WITH_LEN("UNHEX"), BUILDER(Create_func_unhex)},
+ { C_STRING_WITH_LEN("UNIX_TIMESTAMP"), BUILDER(Create_func_unix_timestamp)},
+ { C_STRING_WITH_LEN("UPDATEXML"), BUILDER(Create_func_xml_update)},
+ { C_STRING_WITH_LEN("UPPER"), BUILDER(Create_func_ucase)},
+ { C_STRING_WITH_LEN("UUID"), BUILDER(Create_func_uuid)},
+ { C_STRING_WITH_LEN("VERSION"), BUILDER(Create_func_version)},
+ { C_STRING_WITH_LEN("WEEKDAY"), BUILDER(Create_func_weekday)},
+ { C_STRING_WITH_LEN("WEEKOFYEAR"), BUILDER(Create_func_weekofyear)},
+ { C_STRING_WITH_LEN("WITHIN"), GEOM_BUILDER(Create_func_within)},
+ { C_STRING_WITH_LEN("X"), GEOM_BUILDER(Create_func_x)},
+ { C_STRING_WITH_LEN("Y"), GEOM_BUILDER(Create_func_y)},
+ { C_STRING_WITH_LEN("YEARWEEK"), BUILDER(Create_func_year_week)},
+
+ { {0, 0}, NULL}
+};
+
+static HASH native_functions_hash;
+
+extern "C" byte*
+get_native_fct_hash_key(const byte *buff, uint *length, my_bool /* unused */)
+{
+ Native_func_registry *func= (Native_func_registry*) buff;
+ *length= func->name.length;
+ return (byte*) func->name.str;
+}
+
+/*
+ Load the hash table for native functions.
+ Note: this code is not thread safe, and is intended to be used at server
+ startup only (before going multi-threaded)
+*/
+
+int item_create_init()
+{
+ Native_func_registry *func;
+
+ DBUG_ENTER("item_create_init");
+
+ if (hash_init(& native_functions_hash,
+ system_charset_info,
+ array_elements(func_array),
+ 0,
+ 0,
+ (hash_get_key) get_native_fct_hash_key,
+ NULL, /* Nothing to free */
+ MYF(0)))
+ DBUG_RETURN(1);
+
+ for (func= func_array; func->builder != NULL; func++)
+ {
+ if (my_hash_insert(& native_functions_hash, (byte*) func))
+ DBUG_RETURN(1);
+ }
+
+#ifndef DBUG_OFF
+ for (uint i=0 ; i < native_functions_hash.records ; i++)
+ {
+ func= (Native_func_registry*) hash_element(& native_functions_hash, i);
+ DBUG_PRINT("info", ("native function %s, length %d",
+ func->name.str, func->name.length));
+ }
+#endif
+
+ DBUG_RETURN(0);
+}
+
+/*
+ Empty the hash table for native functions.
+ Note: this code is not thread safe, and is intended to be used at server
+ shutdown only (after thread requests have been executed).
+*/
+
+void item_create_cleanup()
+{
+ DBUG_ENTER("item_create_cleanup");
+ hash_free(& native_functions_hash);
+ DBUG_VOID_RETURN;
+}
+
+Create_func *
+find_native_function_builder(THD *thd, LEX_STRING name)
+{
+ Native_func_registry *func;
+ Create_func *builder= NULL;
+
+ /* Thread safe */
+ func= (Native_func_registry*) hash_search(& native_functions_hash,
+ (byte*) name.str,
+ name.length);
+
+ if (func)
+ {
+ builder= func->builder;
+ }
+
+ return builder;
+}
+
+Create_qfunc *
+find_qualified_function_builder(THD *thd)
+{
+ return & Create_sp_func::s_singleton;
+}
+
+Item*
+create_func_cast(THD *thd, Item *a, Cast_target cast_type, int len, int dec,
+ CHARSET_INFO *cs)
+{
+ Item *res;
+ LINT_INIT(res);
+
+ switch (cast_type) {
+ case ITEM_CAST_BINARY:
+ res= new (thd->mem_root) Item_func_binary(a);
+ break;
+ case ITEM_CAST_SIGNED_INT:
+ res= new (thd->mem_root) Item_func_signed(a);
+ break;
+ case ITEM_CAST_UNSIGNED_INT:
+ res= new (thd->mem_root) Item_func_unsigned(a);
+ break;
+ case ITEM_CAST_DATE:
+ res= new (thd->mem_root) Item_date_typecast(a);
+ break;
+ case ITEM_CAST_TIME:
+ res= new (thd->mem_root) Item_time_typecast(a);
+ break;
+ case ITEM_CAST_DATETIME:
+ res= new (thd->mem_root) Item_datetime_typecast(a);
+ break;
+ case ITEM_CAST_DECIMAL:
+ {
+ int tmp_len= (len>0) ? len : 10;
+ if (tmp_len < dec)
+ {
+ my_error(ER_M_BIGGER_THAN_D, MYF(0), "");
+ return 0;
+ }
+ res= new (thd->mem_root) Item_decimal_typecast(a, tmp_len, dec);
+ break;
+ }
+ case ITEM_CAST_CHAR:
+ {
+ CHARSET_INFO *real_cs= (cs ? cs : thd->variables.collation_connection);
+ res= new (thd->mem_root) Item_char_typecast(a, len, real_cs);
+ break;
+ }
+ default:
+ {
+ DBUG_ASSERT(0);
+ res= 0;
+ break;
+ }
+ }
+ return res;
+}
+
diff --git a/sql/item_create.h b/sql/item_create.h
index 9b6a74b5bdd..c20e36af04f 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -14,148 +14,154 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Functions to create an item. Used by lex.h */
-
-Item *create_func_abs(Item* a);
-Item *create_func_acos(Item* a);
-Item *create_func_aes_encrypt(Item* a, Item* b);
-Item *create_func_aes_decrypt(Item* a, Item* b);
-Item *create_func_ascii(Item* a);
-Item *create_func_asin(Item* a);
-Item *create_func_bin(Item* a);
-Item *create_func_bit_count(Item* a);
-Item *create_func_bit_length(Item* a);
-Item *create_func_coercibility(Item* a);
-Item *create_func_ceiling(Item* a);
-Item *create_func_char_length(Item* a);
-Item *create_func_cast(Item *a, Cast_target cast_type, int len, int dec,
- CHARSET_INFO *cs);
-Item *create_func_connection_id(void);
-Item *create_func_conv(Item* a, Item *b, Item *c);
-Item *create_func_cos(Item* a);
-Item *create_func_cot(Item* a);
-Item *create_func_crc32(Item* a);
-Item *create_func_date_format(Item* a,Item *b);
-Item *create_func_dayname(Item* a);
-Item *create_func_dayofmonth(Item* a);
-Item *create_func_dayofweek(Item* a);
-Item *create_func_dayofyear(Item* a);
-Item *create_func_degrees(Item *);
-Item *create_func_exp(Item* a);
-Item *create_func_find_in_set(Item* a, Item *b);
-Item *create_func_floor(Item* a);
-Item *create_func_found_rows(void);
-Item *create_func_from_days(Item* a);
-Item *create_func_get_lock(Item* a, Item *b);
-Item *create_func_hex(Item *a);
-Item *create_func_inet_aton(Item* a);
-Item *create_func_inet_ntoa(Item* a);
-
-Item *create_func_ifnull(Item* a, Item *b);
-Item *create_func_instr(Item* a, Item *b);
-Item *create_func_isnull(Item* a);
-Item *create_func_lcase(Item* a);
-Item *create_func_length(Item* a);
-Item *create_func_ln(Item* a);
-Item *create_func_locate(Item* a, Item *b);
-Item *create_func_log2(Item* a);
-Item *create_func_log10(Item* a);
-Item *create_func_lpad(Item* a, Item *b, Item *c);
-Item *create_func_ltrim(Item* a);
-Item *create_func_md5(Item* a);
-Item *create_func_mod(Item* a, Item *b);
-Item *create_func_monthname(Item* a);
-Item *create_func_name_const(Item *a, Item *b);
-Item *create_func_nullif(Item* a, Item *b);
-Item *create_func_oct(Item *);
-Item *create_func_ord(Item* a);
-Item *create_func_period_add(Item* a, Item *b);
-Item *create_func_period_diff(Item* a, Item *b);
-Item *create_func_pi(void);
-Item *create_func_pow(Item* a, Item *b);
-Item *create_func_radians(Item *a);
-Item *create_func_release_lock(Item* a);
-Item *create_func_repeat(Item* a, Item *b);
-Item *create_func_reverse(Item* a);
-Item *create_func_rpad(Item* a, Item *b, Item *c);
-Item *create_func_rtrim(Item* a);
-Item *create_func_sec_to_time(Item* a);
-Item *create_func_sign(Item* a);
-Item *create_func_sin(Item* a);
-Item *create_func_sha(Item* a);
-Item *create_func_sleep(Item* a);
-Item *create_func_soundex(Item* a);
-Item *create_func_space(Item *);
-Item *create_func_sqrt(Item* a);
-Item *create_func_strcmp(Item* a, Item *b);
-Item *create_func_tan(Item* a);
-Item *create_func_time_format(Item *a, Item *b);
-Item *create_func_time_to_sec(Item* a);
-Item *create_func_to_days(Item* a);
-Item *create_func_ucase(Item* a);
-Item *create_func_unhex(Item* a);
-Item *create_func_uuid(void);
-Item *create_func_version(void);
-Item *create_func_weekday(Item* a);
-Item *create_load_file(Item* a);
-Item *create_func_is_free_lock(Item* a);
-Item *create_func_is_used_lock(Item* a);
-Item *create_func_quote(Item* a);
-Item *create_func_xml_extractvalue(Item *a, Item *b);
-Item *create_func_xml_update(Item *a, Item *b, Item *c);
-#ifdef HAVE_SPATIAL
-
-Item *create_func_geometry_from_text(Item *a);
-Item *create_func_as_wkt(Item *a);
-Item *create_func_as_wkb(Item *a);
-Item *create_func_srid(Item *a);
-Item *create_func_startpoint(Item *a);
-Item *create_func_endpoint(Item *a);
-Item *create_func_exteriorring(Item *a);
-Item *create_func_centroid(Item *a);
-Item *create_func_envelope(Item *a);
-Item *create_func_pointn(Item *a, Item *b);
-Item *create_func_interiorringn(Item *a, Item *b);
-Item *create_func_geometryn(Item *a, Item *b);
-
-Item *create_func_equals(Item *a, Item *b);
-Item *create_func_disjoint(Item *a, Item *b);
-Item *create_func_intersects(Item *a, Item *b);
-Item *create_func_touches(Item *a, Item *b);
-Item *create_func_crosses(Item *a, Item *b);
-Item *create_func_within(Item *a, Item *b);
-Item *create_func_contains(Item *a, Item *b);
-Item *create_func_overlaps(Item *a, Item *b);
-
-Item *create_func_isempty(Item *a);
-Item *create_func_issimple(Item *a);
-Item *create_func_isclosed(Item *a);
-
-Item *create_func_geometry_type(Item *a);
-Item *create_func_dimension(Item *a);
-Item *create_func_x(Item *a);
-Item *create_func_y(Item *a);
-Item *create_func_area(Item *a);
-Item *create_func_glength(Item *a);
-
-Item *create_func_numpoints(Item *a);
-Item *create_func_numinteriorring(Item *a);
-Item *create_func_numgeometries(Item *a);
-
-Item *create_func_point(Item *a, Item *b);
-
-#endif /*HAVE_SPATIAL*/
-
-Item *create_func_compress(Item *a);
-Item *create_func_uncompress(Item *a);
-Item *create_func_uncompressed_length(Item *a);
-
-Item *create_func_datediff(Item *a, Item *b);
-Item *create_func_weekofyear(Item *a);
-Item *create_func_makedate(Item* a,Item* b);
-Item *create_func_addtime(Item* a,Item* b);
-Item *create_func_subtime(Item* a,Item* b);
-Item *create_func_timediff(Item* a,Item* b);
-Item *create_func_maketime(Item* a,Item* b,Item* c);
-Item *create_func_str_to_date(Item* a,Item* b);
-Item *create_func_last_day(Item *a);
+/* Functions to create an item. Used by sql/sql_yacc.yy */
+
+#ifndef ITEM_CREATE_H
+#define ITEM_CREATE_H
+
+/**
+ Public function builder interface.
+ The parser (sql/sql_yacc.yy) uses a factory / builder pattern to
+ construct an <code>Item</code> object for each function call.
+ All the concrete function builders implements this interface,
+ either directly or indirectly with some adapter helpers.
+ Keeping the function creation separated from the bison grammar allows
+ to simplify the parser, and avoid the need to introduce a new token
+ for each function, which has undesirable side effects in the grammar.
+*/
+
+class Create_func
+{
+public:
+ /**
+ The builder create method.
+ Given the function name and list or arguments, this method creates
+ an <code>Item</code> that represents the function call.
+ In case or errors, a NULL item is returned, and an error is reported.
+ Note that the <code>thd</code> object may be modified by the builder.
+ In particular, the following members/methods can be set/called,
+ depending on the function called and the function possible side effects.
+ <ul>
+ <li><code>thd->lex->binlog_row_based_if_mixed</code></li>
+ <li><code>thd->lex->current_context()</code></li>
+ <li><code>thd->lex->safe_to_cache_query</code></li>
+ <li><code>thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT)</code></li>
+ <li><code>thd->lex->uncacheable(UNCACHEABLE_RAND)</code></li>
+ <li><code>thd->lex->add_time_zone_tables_to_query_tables(thd)</code></li>
+ </ul>
+ @param thd The current thread
+ @param name The function name
+ @param item_list The list of arguments to the function, can be NULL
+ @return An item representing the parsed function call, or NULL
+ */
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list) = 0;
+
+protected:
+ /** Constructor */
+ Create_func() {}
+ /** Destructor */
+ virtual ~Create_func() {}
+};
+
+
+/**
+ Function builder for qualified functions.
+ This builder is used with functions call using a qualified function name
+ syntax, as in <code>db.func(expr, expr, ...)</code>.
+*/
+
+class Create_qfunc : public Create_func
+{
+public:
+ /**
+ The builder create method, for unqualified functions.
+ This builder will use the current database for the database name.
+ @param thd The current thread
+ @param name The function name
+ @param item_list The list of arguments to the function, can be NULL
+ @return An item representing the parsed function call
+ */
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ /**
+ The builder create method, for qualified functions.
+ @param thd The current thread
+ @param db The database name
+ @param name The function name
+ @param item_list The list of arguments to the function, can be NULL
+ @return An item representing the parsed function call
+ */
+ virtual Item* create(THD *thd, LEX_STRING db, LEX_STRING name,
+ List<Item> *item_list) = 0;
+
+protected:
+ /** Constructor. */
+ Create_qfunc() {}
+ /** Destructor. */
+ virtual ~Create_qfunc() {}
+};
+
+
+/**
+ Find the native function builder associated with a given function name.
+ @param thd The current thread
+ @param name The native function name
+ @return The native function builder associated with the name, or NULL
+*/
+extern Create_func * find_native_function_builder(THD *thd, LEX_STRING name);
+
+
+/**
+ Find the function builder for qualified functions.
+ @param thd The current thread
+ @return A function builder for qualified functions
+*/
+extern Create_qfunc * find_qualified_function_builder(THD *thd);
+
+
+#ifdef HAVE_DLOPEN
+/**
+ Function builder for User Defined Functions.
+*/
+
+class Create_udf_func : public Create_func
+{
+public:
+ virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list);
+
+ /**
+ The builder create method, for User Defined Functions.
+ @param thd The current thread
+ @param fct The User Defined Function metadata
+ @param item_list The list of arguments to the function, can be NULL
+ @return An item representing the parsed function call
+ */
+ Item* create(THD *thd, udf_func *fct, List<Item> *item_list);
+
+ /** Singleton. */
+ static Create_udf_func s_singleton;
+
+protected:
+ /** Constructor. */
+ Create_udf_func() {}
+ /** Destructor. */
+ virtual ~Create_udf_func() {}
+};
+#endif
+
+
+/**
+ Builder for cast expressions.
+ @param thd The current thread
+ @param a The item to cast
+ @param cast_type the type casted into
+ @param len TODO
+ @param dec TODO
+ @param cs The character set
+*/
+Item*
+create_func_cast(THD *thd, Item *a, Cast_target cast_type, int len, int dec,
+ CHARSET_INFO *cs);
+
+#endif
+
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 4a069e662f9..fa17dee9605 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -105,7 +105,7 @@ Item_func::Item_func(THD *thd, Item_func *item)
/*
- Resolve references to table column for a function and it's argument
+ Resolve references to table column for a function and its argument
SYNOPSIS:
fix_fields()
@@ -1397,6 +1397,13 @@ void Item_func_mod::result_precision()
}
+void Item_func_mod::fix_length_and_dec()
+{
+ Item_num_op::fix_length_and_dec();
+ maybe_null= 1;
+}
+
+
double Item_func_neg::real_op()
{
double value= args[0]->val_real();
diff --git a/sql/item_func.h b/sql/item_func.h
index f820a89b5b6..dc4371ac967 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -434,6 +434,7 @@ public:
my_decimal *decimal_op(my_decimal *);
const char *func_name() const { return "%"; }
void result_precision();
+ void fix_length_and_dec();
};
diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h
index 4848f59301d..42f11820869 100644
--- a/sql/item_geofunc.h
+++ b/sql/item_geofunc.h
@@ -348,11 +348,11 @@ public:
void fix_length_and_dec() { max_length= 10; }
};
-#define GEOM_NEW(obj_constructor) new obj_constructor
+#define GEOM_NEW(thd, obj_constructor) new (thd->mem_root) obj_constructor
#else /*HAVE_SPATIAL*/
-#define GEOM_NEW(obj_constructor) NULL
+#define GEOM_NEW(thd, obj_constructor) NULL
#endif
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 7a82dd753b3..bf837f6720b 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2965,6 +2965,7 @@ String *Item_func_compress::val_str(String *str)
null_value= 1;
return 0;
}
+ null_value= 0;
if (res->is_empty()) return res;
/*
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index c656faa7c49..b2ff62028c1 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1065,6 +1065,7 @@ longlong Item_sum_count::val_int()
void Item_sum_count::cleanup()
{
DBUG_ENTER("Item_sum_count::cleanup");
+ count= 0;
Item_sum_int::cleanup();
used_table_cache= ~(table_map) 0;
DBUG_VOID_RETURN;
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 3679780db60..eb4c21bbe06 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -260,9 +260,30 @@ public:
Item_sum(THD *thd, Item_sum *item);
enum Type type() const { return SUM_FUNC_ITEM; }
virtual enum Sumfunctype sum_func () const=0;
+
+ /*
+ This method is similar to add(), but it is called when the current
+ aggregation group changes. Thus it performs a combination of
+ clear() and add().
+ */
inline bool reset() { clear(); return add(); };
+
+ /*
+ Prepare this item for evaluation of an aggregate value. This is
+ called by reset() when a group changes, or, for correlated
+ subqueries, between subquery executions. E.g. for COUNT(), this
+ method should set count= 0;
+ */
virtual void clear()= 0;
+
+ /*
+ This method is called for the next row in the same group. Its
+ purpose is to aggregate the new value to the previous values in
+ the group (i.e. since clear() was called last time). For example,
+ for COUNT(), do count++.
+ */
virtual bool add()=0;
+
/*
Called when new group is started and results are being saved in
a temporary table. Similar to reset(), but must also store value in
@@ -306,7 +327,17 @@ public:
void make_field(Send_field *field);
void print(String *str);
void fix_num_length_and_dec();
- void no_rows_in_result() { reset(); }
+
+ /*
+ This function is called by the execution engine to assign 'NO ROWS
+ FOUND' value to an aggregate item, when the underlying result set
+ has no rows. Such value, in a general case, may be different from
+ the default value of the item after 'clear()': e.g. a numeric item
+ may be initialized to 0 by clear() and to NULL by
+ no_rows_in_result().
+ */
+ void no_rows_in_result() { clear(); }
+
virtual bool setup(THD *thd) {return 0;}
virtual void make_unique() {}
Item *get_tmp_table_item(THD *thd);
@@ -610,6 +641,11 @@ public:
const char *func_name() const { return "avg("; }
Item *copy_or_same(THD* thd);
Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
+ void cleanup()
+ {
+ count= 0;
+ Item_sum_sum::cleanup();
+ }
};
class Item_sum_variance;
@@ -689,6 +725,12 @@ public:
Item *copy_or_same(THD* thd);
Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
enum Item_result result_type () const { return REAL_RESULT; }
+ void cleanup()
+ {
+ cur_dec= 0;
+ count= 0;
+ Item_sum_num::cleanup();
+ }
};
class Item_sum_std;
@@ -819,6 +861,11 @@ public:
void update_field();
void fix_length_and_dec()
{ decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; }
+ void cleanup()
+ {
+ bits= reset_bits;
+ Item_sum_int::cleanup();
+ }
};
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index d32adde5e64..3d49305cfd3 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -96,6 +96,125 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
/*
+ Wrapper over make_datetime() with validation of the input TIME value
+
+ NOTE
+ see make_datetime() for more information
+
+ RETURN
+ 1 if there was an error during converion
+ 0 otherwise
+*/
+
+static bool make_datetime_with_warn(date_time_format_types format, TIME *ltime,
+ String *str)
+{
+ int warning= 0;
+ bool rc;
+
+ if (make_datetime(format, ltime, str))
+ return 1;
+ if (check_time_range(ltime, &warning))
+ return 1;
+ if (!warning)
+ return 0;
+
+ make_truncated_value_warning(current_thd, str->ptr(), str->length(),
+ MYSQL_TIMESTAMP_TIME, NullS);
+ return make_datetime(format, ltime, str);
+}
+
+
+/*
+ Wrapper over make_time() with validation of the input TIME value
+
+ NOTE
+ see make_time() for more info
+
+ RETURN
+ 1 if there was an error during conversion
+ 0 otherwise
+*/
+
+static bool make_time_with_warn(const DATE_TIME_FORMAT *format,
+ TIME *l_time, String *str)
+{
+ int warning= 0;
+ make_time(format, l_time, str);
+ if (check_time_range(l_time, &warning))
+ return 1;
+ if (warning)
+ {
+ make_truncated_value_warning(current_thd, str->ptr(), str->length(),
+ MYSQL_TIMESTAMP_TIME, NullS);
+ make_time(format, l_time, str);
+ }
+
+ return 0;
+}
+
+
+/*
+ Convert seconds to TIME value with overflow checking
+
+ SYNOPSIS:
+ sec_to_time()
+ seconds number of seconds
+ unsigned_flag 1, if 'seconds' is unsigned, 0, otherwise
+ ltime output TIME value
+
+ DESCRIPTION
+ If the 'seconds' argument is inside TIME data range, convert it to a
+ corresponding value.
+ Otherwise, truncate the resulting value to the nearest endpoint, and
+ produce a warning message.
+
+ RETURN
+ 1 if the value was truncated during conversion
+ 0 otherwise
+*/
+
+static bool sec_to_time(longlong seconds, bool unsigned_flag, TIME *ltime)
+{
+ uint sec;
+
+ bzero((char *)ltime, sizeof(*ltime));
+
+ if (seconds < 0)
+ {
+ if (unsigned_flag)
+ goto overflow;
+ ltime->neg= 1;
+ if (seconds < -3020399)
+ goto overflow;
+ seconds= -seconds;
+ }
+ else if (seconds > 3020399)
+ goto overflow;
+
+ sec= (uint) ((ulonglong) seconds % 3600);
+ ltime->hour= (uint) (seconds/3600);
+ ltime->minute= sec/60;
+ ltime->second= sec % 60;
+
+ return 0;
+
+overflow:
+ ltime->hour= TIME_MAX_HOUR;
+ ltime->minute= TIME_MAX_MINUTE;
+ ltime->second= TIME_MAX_SECOND;
+
+ char buf[22];
+ int len= (int)(longlong10_to_str(seconds, buf, unsigned_flag ? 10 : -10)
+ - buf);
+ make_truncated_value_warning(current_thd, buf, len, MYSQL_TIMESTAMP_TIME,
+ NullS);
+
+ return 1;
+}
+
+
+/*
Date formats corresponding to compound %r and %T conversion specifiers
Note: We should init at least first element of "positions" array
@@ -1249,6 +1368,11 @@ bool get_interval_value(Item *args,interval_type int_type,
interval->second= array[0];
interval->second_part= array[1];
break;
+ /* purecov: begin deadcode */
+ case INTERVAL_LAST:
+ DBUG_ASSERT(0);
+ break;
+ /* purecov: end */
}
return 0;
}
@@ -1546,8 +1670,6 @@ int Item_func_sysdate_local::save_in_field(Field *to, bool no_conversions)
String *Item_func_sec_to_time::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- longlong seconds=(longlong) args[0]->val_int();
- uint sec;
TIME ltime;
if ((null_value=args[0]->null_value) || str->alloc(19))
@@ -1556,19 +1678,8 @@ String *Item_func_sec_to_time::val_str(String *str)
return (String*) 0;
}
- ltime.neg= 0;
- if (seconds < 0)
- {
- seconds= -seconds;
- ltime.neg= 1;
- }
-
- sec= (uint) ((ulonglong) seconds % 3600);
- ltime.day= 0;
- ltime.hour= (uint) (seconds/3600);
- ltime.minute= sec/60;
- ltime.second= sec % 60;
-
+ sec_to_time(args[0]->val_int(), args[0]->unsigned_flag, &ltime);
+
make_time((DATE_TIME_FORMAT *) 0, &ltime, str);
return str;
}
@@ -1577,16 +1688,15 @@ String *Item_func_sec_to_time::val_str(String *str)
longlong Item_func_sec_to_time::val_int()
{
DBUG_ASSERT(fixed == 1);
- longlong seconds=args[0]->val_int();
- longlong sign=1;
+ TIME ltime;
+
if ((null_value=args[0]->null_value))
return 0;
- if (seconds < 0)
- {
- seconds= -seconds;
- sign= -1;
- }
- return sign*((seconds / 3600)*10000+((seconds/60) % 60)*100+ (seconds % 60));
+
+ sec_to_time(args[0]->val_int(), args[0]->unsigned_flag, &ltime);
+
+ return (ltime.neg ? -1 : 1) *
+ ((ltime.hour)*10000 + ltime.minute*100 + ltime.second);
}
@@ -1906,17 +2016,14 @@ bool Item_func_convert_tz::get_date(TIME *ltime,
return 1;
}
- /* Check if we in range where we treat datetime values as non-UTC */
- if (ltime->year < TIMESTAMP_MAX_YEAR && ltime->year > TIMESTAMP_MIN_YEAR ||
- ltime->year==TIMESTAMP_MAX_YEAR && ltime->month==1 && ltime->day==1 ||
- ltime->year==TIMESTAMP_MIN_YEAR && ltime->month==12 && ltime->day==31)
{
my_bool not_used;
my_time_tmp= from_tz->TIME_to_gmt_sec(ltime, &not_used);
- if (my_time_tmp >= TIMESTAMP_MIN_VALUE && my_time_tmp <= TIMESTAMP_MAX_VALUE)
+ /* my_time_tmp is guranteed to be in the allowed range */
+ if (my_time_tmp)
to_tz->gmt_sec_to_TIME(ltime, my_time_tmp);
}
-
+
null_value= 0;
return 0;
}
@@ -2030,11 +2137,15 @@ bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const
(date_sub_interval == other->date_sub_interval));
}
+/*
+ 'interval_names' reflects the order of the enumeration interval_type.
+ See item_timefunc.h
+ */
static const char *interval_names[]=
{
- "year", "quarter", "month", "day", "hour",
- "minute", "week", "second", "microsecond",
+ "year", "quarter", "month", "week", "day",
+ "hour", "minute", "second", "microsecond",
"year_month", "day_hour", "day_minute",
"day_second", "hour_minute", "hour_second",
"minute_second", "day_microsecond",
@@ -2088,6 +2199,7 @@ void Item_extract::fix_length_and_dec()
case INTERVAL_HOUR_MICROSECOND: max_length=13; date_value=0; break;
case INTERVAL_MINUTE_MICROSECOND: max_length=11; date_value=0; break;
case INTERVAL_SECOND_MICROSECOND: max_length=9; date_value=0; break;
+ case INTERVAL_LAST: DBUG_ASSERT(0); break; /* purecov: deadcode */
}
}
@@ -2157,6 +2269,8 @@ longlong Item_extract::val_int()
ltime.second_part)*neg;
case INTERVAL_SECOND_MICROSECOND: return ((longlong)ltime.second*1000000L+
ltime.second_part)*neg;
+ case INTERVAL_LAST: DBUG_ASSERT(0); return(0); /* purecov: deadcode */
+ /* purecov: end */
}
return 0; // Impossible
}
@@ -2271,7 +2385,7 @@ String *Item_char_typecast::val_str(String *str)
{ // Safe even if const arg
char char_type[40];
my_snprintf(char_type, sizeof(char_type), "%s(%lu)",
- cast_cs == &my_charset_bin ? "BINARY" : "CHAR", length);
+ cast_cs == &my_charset_bin ? "BINARY" : "CHAR", (ulong) length);
if (!res->alloced_length())
{ // Don't change const str
@@ -2571,7 +2685,9 @@ String *Item_func_add_time::val_str(String *str)
}
if (l_time1.neg != l_time2.neg)
l_sign= -l_sign;
-
+
+ bzero((char *)&l_time3, sizeof(l_time3));
+
l_time3.neg= calc_time_diff(&l_time1, &l_time2, -l_sign,
&seconds, &microseconds);
@@ -2600,9 +2716,9 @@ String *Item_func_add_time::val_str(String *str)
}
l_time3.hour+= days*24;
- if (!make_datetime(l_time1.second_part || l_time2.second_part ?
- TIME_MICROSECOND : TIME_ONLY,
- &l_time3, str))
+ if (!make_datetime_with_warn(l_time1.second_part || l_time2.second_part ?
+ TIME_MICROSECOND : TIME_ONLY,
+ &l_time3, str))
return str;
null_date:
@@ -2657,6 +2773,8 @@ String *Item_func_timediff::val_str(String *str)
if (l_time1.neg != l_time2.neg)
l_sign= -l_sign;
+ bzero((char *)&l_time3, sizeof(l_time3));
+
l_time3.neg= calc_time_diff(&l_time1, &l_time2, l_sign,
&seconds, &microseconds);
@@ -2670,9 +2788,9 @@ String *Item_func_timediff::val_str(String *str)
calc_time_from_sec(&l_time3, (long) seconds, microseconds);
- if (!make_datetime(l_time1.second_part || l_time2.second_part ?
- TIME_MICROSECOND : TIME_ONLY,
- &l_time3, str))
+ if (!make_datetime_with_warn(l_time1.second_part || l_time2.second_part ?
+ TIME_MICROSECOND : TIME_ONLY,
+ &l_time3, str))
return str;
null_date:
@@ -2690,29 +2808,58 @@ String *Item_func_maketime::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
TIME ltime;
+ bool overflow= 0;
- long hour= (long) args[0]->val_int();
- long minute= (long) args[1]->val_int();
- long second= (long) args[2]->val_int();
+ longlong hour= args[0]->val_int();
+ longlong minute= args[1]->val_int();
+ longlong second= args[2]->val_int();
if ((null_value=(args[0]->null_value ||
- args[1]->null_value ||
- args[2]->null_value ||
- minute > 59 || minute < 0 ||
- second > 59 || second < 0 ||
- str->alloc(19))))
+ args[1]->null_value ||
+ args[2]->null_value ||
+ minute < 0 || minute > 59 ||
+ second < 0 || second > 59 ||
+ str->alloc(19))))
return 0;
+ bzero((char *)&ltime, sizeof(ltime));
ltime.neg= 0;
+
+ /* Check for integer overflows */
if (hour < 0)
{
- ltime.neg= 1;
- hour= -hour;
+ if (args[0]->unsigned_flag)
+ overflow= 1;
+ else
+ ltime.neg= 1;
+ }
+ if (-hour > UINT_MAX || hour > UINT_MAX)
+ overflow= 1;
+
+ if (!overflow)
+ {
+ ltime.hour= (uint) ((hour < 0 ? -hour : hour));
+ ltime.minute= (uint) minute;
+ ltime.second= (uint) second;
+ }
+ else
+ {
+ ltime.hour= TIME_MAX_HOUR;
+ ltime.minute= TIME_MAX_MINUTE;
+ ltime.second= TIME_MAX_SECOND;
+ char buf[28];
+ char *ptr= longlong10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10);
+ int len = (int)(ptr - buf) +
+ my_sprintf(ptr, (ptr, ":%02u:%02u", (uint)minute, (uint)second));
+ make_truncated_value_warning(current_thd, buf, len, MYSQL_TIMESTAMP_TIME,
+ NullS);
+ }
+
+ if (make_time_with_warn((DATE_TIME_FORMAT *) 0, &ltime, str))
+ {
+ null_value= 1;
+ return 0;
}
- ltime.hour= (ulong) hour;
- ltime.minute= (ulong) minute;
- ltime.second= (ulong) second;
- make_time((DATE_TIME_FORMAT *) 0, &ltime, str);
return str;
}
@@ -3056,7 +3203,7 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date)
goto null_date;
null_value= 0;
- bzero((char*) ltime, sizeof(ltime));
+ bzero((char*) ltime, sizeof(*ltime));
date_time_format.format.str= (char*) format->ptr();
date_time_format.format.length= format->length();
if (extract_date_time(&date_time_format, val->ptr(), val->length(),
diff --git a/sql/lex.h b/sql/lex.h
index f19c9413e0e..254d7f10fb7 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -30,21 +30,16 @@ SYM_GROUP sym_group_rtree= {"RTree keys", "HAVE_RTREE_KEYS"};
#define SYM_OR_NULL(A) A
#endif
-#define SYM(A) SYM_OR_NULL(A),0,0,&sym_group_common
-#define F_SYM(A) SYM_OR_NULL(A)
-
-#define CREATE_FUNC(A) (void *)(SYM_OR_NULL(A)), &sym_group_common
-
-#ifdef HAVE_SPATIAL
-#define CREATE_FUNC_GEOM(A) (void *)(SYM_OR_NULL(A)), &sym_group_geom
-#else
-#define CREATE_FUNC_GEOM(A) 0, &sym_group_geom
-#endif
+#define SYM(A) SYM_OR_NULL(A),0,&sym_group_common
/*
Symbols are broken into separated arrays to allow field names with
same name as functions.
These are kept sorted for human lookup (the symbols are hashed).
+
+ NOTE! The symbol tables should be the same regardless of what features
+ are compiled into the server. Don't add ifdef'ed symbols to the
+ lists
*/
static SYMBOL symbols[] = {
@@ -383,11 +378,9 @@ static SYMBOL symbols[] = {
{ "PACK_KEYS", SYM(PACK_KEYS_SYM)},
{ "PARSER", SYM(PARSER_SYM)},
{ "PARTIAL", SYM(PARTIAL)},
-#ifdef WITH_PARTITION_STORAGE_ENGINE
{ "PARTITION", SYM(PARTITION_SYM)},
{ "PARTITIONING", SYM(PARTITIONING_SYM)},
{ "PARTITIONS", SYM(PARTITIONS_SYM)},
-#endif
{ "PASSWORD", SYM(PASSWORD)},
{ "PHASE", SYM(PHASE_SYM)},
{ "PLUGIN", SYM(PLUGIN_SYM)},
@@ -588,235 +581,38 @@ static SYMBOL symbols[] = {
static SYMBOL sql_functions[] = {
- { "ABS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_abs)},
- { "ACOS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_acos)},
{ "ADDDATE", SYM(ADDDATE_SYM)},
- { "ADDTIME", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_addtime)},
- { "AES_ENCRYPT", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_aes_encrypt)},
- { "AES_DECRYPT", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_aes_decrypt)},
- { "AREA", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_area)},
- { "ASIN", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_asin)},
- { "ASBINARY", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_as_wkb)},
- { "ASTEXT", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_as_wkt)},
- { "ASWKB", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_as_wkb)},
- { "ASWKT", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_as_wkt)},
- { "ATAN", SYM(ATAN)},
- { "ATAN2", SYM(ATAN)},
- { "BENCHMARK", SYM(BENCHMARK_SYM)},
- { "BIN", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bin)},
- { "BIT_COUNT", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_count)},
- { "BIT_OR", SYM(BIT_OR)},
{ "BIT_AND", SYM(BIT_AND)},
+ { "BIT_OR", SYM(BIT_OR)},
{ "BIT_XOR", SYM(BIT_XOR)},
{ "CAST", SYM(CAST_SYM)},
- { "CEIL", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)},
- { "CEILING", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)},
- { "BIT_LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_length)},
- { "CENTROID", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_centroid)},
- { "CHAR_LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
- { "CHARACTER_LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
- { "COERCIBILITY", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_coercibility)},
- { "COMPRESS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_compress)},
- { "CONCAT", SYM(CONCAT)},
- { "CONCAT_WS", SYM(CONCAT_WS)},
- { "CONNECTION_ID", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_connection_id)},
- { "CONV", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_conv)},
- { "CONVERT_TZ", SYM(CONVERT_TZ_SYM)},
{ "COUNT", SYM(COUNT_SYM)},
- { "COS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cos)},
- { "COT", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cot)},
- { "CRC32", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_crc32)},
- { "CROSSES", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_crosses)},
{ "CURDATE", SYM(CURDATE)},
{ "CURTIME", SYM(CURTIME)},
{ "DATE_ADD", SYM(DATE_ADD_INTERVAL)},
- { "DATEDIFF", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_datediff)},
- { "DATE_FORMAT", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_date_format)},
{ "DATE_SUB", SYM(DATE_SUB_INTERVAL)},
- { "DAYNAME", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayname)},
- { "DAYOFMONTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofmonth)},
- { "DAYOFWEEK", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofweek)},
- { "DAYOFYEAR", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofyear)},
- { "DECODE", SYM(DECODE_SYM)},
- { "DEGREES", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_degrees)},
- { "DES_ENCRYPT", SYM(DES_ENCRYPT_SYM)},
- { "DES_DECRYPT", SYM(DES_DECRYPT_SYM)},
- { "DIMENSION", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_dimension)},
- { "DISJOINT", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_disjoint)},
- { "ELT", SYM(ELT_FUNC)},
- { "ENCODE", SYM(ENCODE_SYM)},
- { "ENCRYPT", SYM(ENCRYPT)},
- { "ENDPOINT", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_endpoint)},
- { "ENVELOPE", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_envelope)},
- { "EQUALS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_equals)},
- { "EXTERIORRING", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_exteriorring)},
{ "EXTRACT", SYM(EXTRACT_SYM)},
- { "EXTRACTVALUE", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_xml_extractvalue)},
- { "EXP", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_exp)},
- { "EXPORT_SET", SYM(EXPORT_SET)},
- { "FIELD", SYM(FIELD_FUNC)}, /* For compability */
- { "FIND_IN_SET", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_find_in_set)},
- { "FLOOR", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_floor)},
- { "FORMAT", SYM(FORMAT_SYM)},
- { "FOUND_ROWS", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_found_rows)},
- { "FROM_DAYS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_from_days)},
- { "FROM_UNIXTIME", SYM(FROM_UNIXTIME)},
- { "GET_LOCK", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_get_lock)},
- { "GEOMETRYN", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_geometryn)},
- { "GEOMETRYTYPE", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_geometry_type)},
- { "GEOMCOLLFROMTEXT", SYM(GEOMCOLLFROMTEXT)},
- { "GEOMCOLLFROMWKB", SYM(GEOMFROMWKB)},
- { "GEOMETRYCOLLECTIONFROMTEXT",SYM(GEOMCOLLFROMTEXT)},
- { "GEOMETRYCOLLECTIONFROMWKB",SYM(GEOMFROMWKB)},
- { "GEOMETRYFROMTEXT", SYM(GEOMFROMTEXT)},
- { "GEOMETRYFROMWKB", SYM(GEOMFROMWKB)},
- { "GEOMFROMTEXT", SYM(GEOMFROMTEXT)},
- { "GEOMFROMWKB", SYM(GEOMFROMWKB)},
- { "GLENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_glength)},
- { "GREATEST", SYM(GREATEST_SYM)},
{ "GROUP_CONCAT", SYM(GROUP_CONCAT_SYM)},
{ "GROUP_UNIQUE_USERS", SYM(GROUP_UNIQUE_USERS)},
- { "HEX", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_hex)},
- { "IFNULL", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_ifnull)},
- { "INET_ATON", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_inet_aton)},
- { "INET_NTOA", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_inet_ntoa)},
- { "INSTR", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_instr)},
- { "INTERIORRINGN", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_interiorringn)},
- { "INTERSECTS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_intersects)},
- { "ISCLOSED", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_isclosed)},
- { "ISEMPTY", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_isempty)},
- { "ISNULL", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isnull)},
- { "IS_FREE_LOCK", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_free_lock)},
- { "IS_USED_LOCK", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_used_lock)},
- { "LAST_INSERT_ID", SYM(LAST_INSERT_ID)},
- { "ISSIMPLE", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_issimple)},
- { "LAST_DAY", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_last_day)},
- { "LCASE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)},
- { "LEAST", SYM(LEAST_SYM)},
- { "LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)},
- { "LN", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ln)},
- { "LINEFROMTEXT", SYM(LINEFROMTEXT)},
- { "LINEFROMWKB", SYM(GEOMFROMWKB)},
- { "LINESTRINGFROMTEXT",SYM(LINEFROMTEXT)},
- { "LINESTRINGFROMWKB",SYM(GEOMFROMWKB)},
- { "LOAD_FILE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_load_file)},
- { "LOCATE", SYM(LOCATE)},
- { "LOG", SYM(LOG_SYM)},
- { "LOG2", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log2)},
- { "LOG10", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log10)},
- { "LOWER", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)},
- { "LPAD", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_lpad)},
- { "LTRIM", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ltrim)},
- { "MAKE_SET", SYM(MAKE_SET_SYM)},
- { "MAKEDATE", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_makedate)},
- { "MAKETIME", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_maketime)},
- { "MASTER_POS_WAIT", SYM(MASTER_POS_WAIT)},
{ "MAX", SYM(MAX_SYM)},
- { "MBRCONTAINS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_contains)},
- { "MBRDISJOINT", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_disjoint)},
- { "MBREQUAL", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_equals)},
- { "MBRINTERSECTS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_intersects)},
- { "MBROVERLAPS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_overlaps)},
- { "MBRTOUCHES", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_touches)},
- { "MBRWITHIN", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_within)},
- { "MD5", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_md5)},
{ "MID", SYM(SUBSTRING)}, /* unireg function */
{ "MIN", SYM(MIN_SYM)},
- { "MLINEFROMTEXT", SYM(MLINEFROMTEXT)},
- { "MLINEFROMWKB", SYM(GEOMFROMWKB)},
- { "MPOINTFROMTEXT", SYM(MPOINTFROMTEXT)},
- { "MPOINTFROMWKB", SYM(GEOMFROMWKB)},
- { "MPOLYFROMTEXT", SYM(MPOLYFROMTEXT)},
- { "MPOLYFROMWKB", SYM(GEOMFROMWKB)},
- { "MONTHNAME", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_monthname)},
- { "MULTILINESTRINGFROMTEXT",SYM(MLINEFROMTEXT)},
- { "MULTILINESTRINGFROMWKB",SYM(GEOMFROMWKB)},
- { "MULTIPOINTFROMTEXT",SYM(MPOINTFROMTEXT)},
- { "MULTIPOINTFROMWKB",SYM(GEOMFROMWKB)},
- { "MULTIPOLYGONFROMTEXT",SYM(MPOLYFROMTEXT)},
- { "MULTIPOLYGONFROMWKB",SYM(GEOMFROMWKB)},
- { "NAME_CONST", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_name_const)},
{ "NOW", SYM(NOW_SYM)},
- { "NULLIF", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_nullif)},
- { "NUMGEOMETRIES", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_numgeometries)},
- { "NUMINTERIORRINGS", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_numinteriorring)},
- { "NUMPOINTS", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_numpoints)},
- { "OCTET_LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)},
- { "OCT", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_oct)},
- { "ORD", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ord)},
- { "OVERLAPS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_overlaps)},
- { "PERIOD_ADD", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_add)},
- { "PERIOD_DIFF", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_diff)},
- { "PI", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_pi)},
- { "POINTFROMTEXT", SYM(POINTFROMTEXT)},
- { "POINTFROMWKB", SYM(GEOMFROMWKB)},
- { "POINTN", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_pointn)},
- { "POLYFROMTEXT", SYM(POLYFROMTEXT)},
- { "POLYFROMWKB", SYM(GEOMFROMWKB)},
- { "POLYGONFROMTEXT", SYM(POLYFROMTEXT)},
- { "POLYGONFROMWKB", SYM(GEOMFROMWKB)},
{ "POSITION", SYM(POSITION_SYM)},
- { "POW", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)},
- { "POWER", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)},
- { "QUOTE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_quote)},
- { "RADIANS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_radians)},
- { "RAND", SYM(RAND)},
- { "RELEASE_LOCK", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)},
- { "REVERSE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_reverse)},
- { "ROUND", SYM(ROUND)},
- { "ROW_COUNT", SYM(ROW_COUNT_SYM)},
- { "RPAD", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_rpad)},
- { "RTRIM", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_rtrim)},
- { "SEC_TO_TIME", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sec_to_time)},
- { "SESSION_USER", SYM(USER)},
- { "SUBDATE", SYM(SUBDATE_SYM)},
- { "SIGN", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sign)},
- { "SIN", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sin)},
- { "SHA", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sha)},
- { "SHA1", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sha)},
- { "SLEEP", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sleep)},
- { "SOUNDEX", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_soundex)},
- { "SPACE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_space)},
- { "SQRT", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sqrt)},
- { "SRID", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_srid)},
- { "STARTPOINT", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_startpoint)},
+ { "SESSION_USER", SYM(USER)},
{ "STD", SYM(STD_SYM)},
{ "STDDEV", SYM(STD_SYM)},
{ "STDDEV_POP", SYM(STD_SYM)},
{ "STDDEV_SAMP", SYM(STDDEV_SAMP_SYM)},
- { "STR_TO_DATE", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_str_to_date)},
- { "STRCMP", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_strcmp)},
+ { "SUBDATE", SYM(SUBDATE_SYM)},
{ "SUBSTR", SYM(SUBSTRING)},
{ "SUBSTRING", SYM(SUBSTRING)},
- { "SUBSTRING_INDEX", SYM(SUBSTRING_INDEX)},
- { "SUBTIME", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_subtime)},
{ "SUM", SYM(SUM_SYM)},
{ "SYSDATE", SYM(SYSDATE)},
- { "SYSTEM_USER", SYM(USER)},
- { "TAN", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_tan)},
- { "TIME_FORMAT", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_time_format)},
- { "TIME_TO_SEC", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_time_to_sec)},
- { "TIMEDIFF", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_timediff)},
- { "TO_DAYS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_to_days)},
- { "TOUCHES", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_touches)},
+ { "SYSTEM_USER", SYM(USER)},
{ "TRIM", SYM(TRIM)},
- { "UCASE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
- { "UNCOMPRESS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_uncompress)},
- { "UNCOMPRESSED_LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_uncompressed_length)},
- { "UNHEX", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_unhex)},
{ "UNIQUE_USERS", SYM(UNIQUE_USERS)},
- { "UNIX_TIMESTAMP", SYM(UNIX_TIMESTAMP)},
- { "UPDATEXML", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_xml_update)},
- { "UPPER", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
- { "UUID", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_uuid)},
{ "VARIANCE", SYM(VARIANCE_SYM)},
{ "VAR_POP", SYM(VARIANCE_SYM)},
{ "VAR_SAMP", SYM(VAR_SAMP_SYM)},
- { "VERSION", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_version)},
- { "WEEKDAY", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekday)},
- { "WEEKOFYEAR", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekofyear)},
- { "WITHIN", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_within)},
- { "X", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_x)},
- { "Y", F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_y)},
- { "YEARWEEK", SYM(YEARWEEK)}
};
diff --git a/sql/lex_symbol.h b/sql/lex_symbol.h
index 3074a489b6a..5ba785d16f3 100644
--- a/sql/lex_symbol.h
+++ b/sql/lex_symbol.h
@@ -26,7 +26,6 @@ typedef struct st_symbol {
const char *name;
uint tok;
uint length;
- void *create_func;
struct st_sym_group *group;
} SYMBOL;
diff --git a/sql/lock.cc b/sql/lock.cc
index 06f538a2a03..f36ecf58620 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -691,7 +691,8 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
check_if_locking_is_allowed(thd->lex->sql_command, thd->lex->type,
table_ptr[i], count,
(thd == logger.get_general_log_thd()) ||
- (thd == logger.get_slow_log_thd())))
+ (thd == logger.get_slow_log_thd()) ||
+ (thd == logger.get_privileged_thread())))
DBUG_RETURN(0);
}
diff --git a/sql/log.cc b/sql/log.cc
index a1ed9bd6df3..83e190a5c01 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -173,6 +173,33 @@ public:
handlerton *binlog_hton;
+
+/* Check if a given table is opened log table */
+int check_if_log_table(uint db_len, const char *db, uint table_name_len,
+ const char *table_name, uint check_if_opened)
+{
+ if (db_len == 5 &&
+ !(lower_case_table_names ?
+ my_strcasecmp(system_charset_info, db, "mysql") :
+ strcmp(db, "mysql")))
+ {
+ if (table_name_len == 11 && !(lower_case_table_names ?
+ my_strcasecmp(system_charset_info,
+ table_name, "general_log") :
+ strcmp(table_name, "general_log")) &&
+ (!check_if_opened || logger.is_log_table_enabled(QUERY_LOG_GENERAL)))
+ return QUERY_LOG_GENERAL;
+ else
+ if (table_name_len == 8 && !(lower_case_table_names ?
+ my_strcasecmp(system_charset_info, table_name, "slow_log") :
+ strcmp(table_name, "slow_log")) &&
+ (!check_if_opened ||logger.is_log_table_enabled(QUERY_LOG_SLOW)))
+ return QUERY_LOG_SLOW;
+ }
+ return 0;
+}
+
+
/*
Open log table of a given type (general or slow log)
@@ -273,6 +300,12 @@ bool Log_to_csv_event_handler::open_log_table(uint log_table_type)
my_pthread_setspecific_ptr(THR_MALLOC, 0);
}
+ /*
+ After a log table was opened, we should clear privileged thread
+ flag (which allows locking of a log table by a special thread, usually
+ the one who closed log tables temporarily).
+ */
+ privileged_thread= 0;
DBUG_RETURN(error);
}
@@ -284,11 +317,15 @@ Log_to_csv_event_handler::Log_to_csv_event_handler()
/* logger thread always works with mysql database */
general_log_thd->db= my_strdup("mysql", MYF(0));
general_log_thd->db_length= 5;
+ general_log.table= 0;
slow_log_thd= new THD;
/* logger thread always works with mysql database */
slow_log_thd->db= my_strdup("mysql", MYF(0));;
slow_log_thd->db_length= 5;
+ slow_log.table= 0;
+ /* no privileged thread exists at the moment */
+ privileged_thread= 0;
}
@@ -341,6 +378,7 @@ bool Log_to_csv_event_handler::reopen_log_table(uint log_table_type)
return open_log_table(log_table_type);
}
+
void Log_to_csv_event_handler::cleanup()
{
if (opt_log)
@@ -395,9 +433,6 @@ bool Log_to_csv_event_handler::
filled by the Logger (=> no need to load default ones).
*/
- /* log table entries are not replicated at the moment */
- tmp_disable_binlog(current_thd);
-
/* Set current time. Required for CURRENT_TIMESTAMP to work */
general_log_thd->start_time= event_time;
@@ -406,21 +441,36 @@ bool Log_to_csv_event_handler::
default value (which is CURRENT_TIMESTAMP).
*/
- table->field[1]->store(user_host, user_host_len, client_cs);
+ /* check that all columns exist */
+ if (!table->field[1] || !table->field[2] || !table->field[3] ||
+ !table->field[4] || !table->field[5])
+ goto err;
+
+ /* do a write */
+ if (table->field[1]->store(user_host, user_host_len, client_cs) ||
+ table->field[2]->store((longlong) thread_id, TRUE) ||
+ table->field[3]->store((longlong) server_id, TRUE) ||
+ table->field[4]->store(command_type, command_type_len, client_cs) ||
+ table->field[5]->store(sql_text, sql_text_len, client_cs))
+ goto err;
+
+ /* mark tables as not null */
table->field[1]->set_notnull();
- table->field[2]->store((longlong) thread_id, TRUE);
table->field[2]->set_notnull();
- table->field[3]->store((longlong) server_id, TRUE);
table->field[3]->set_notnull();
- table->field[4]->store(command_type, command_type_len, client_cs);
table->field[4]->set_notnull();
- table->field[5]->store(sql_text, sql_text_len, client_cs);
table->field[5]->set_notnull();
+
+ /* log table entries are not replicated at the moment */
+ tmp_disable_binlog(current_thd);
+
table->file->ha_write_row(table->record[0]);
reenable_binlog(current_thd);
return FALSE;
+err:
+ return TRUE;
}
@@ -469,9 +519,6 @@ bool Log_to_csv_event_handler::
if (unlikely(!logger.is_log_tables_initialized))
return FALSE;
- /* log table entries are not replicated at the moment */
- tmp_disable_binlog(current_thd);
-
/*
Set start time for CURRENT_TIMESTAMP to the start of the query.
This will be default value for the field[0]
@@ -484,19 +531,30 @@ bool Log_to_csv_event_handler::
default value.
*/
+ if (!table->field[1] || !table->field[2] || !table->field[3] ||
+ !table->field[4] || !table->field[5] || !table->field[6] ||
+ !table->field[7] || !table->field[8] || !table->field[9] ||
+ !table->field[10])
+ goto err;
+
/* store the value */
- table->field[1]->store(user_host, user_host_len, client_cs);
+ if (table->field[1]->store(user_host, user_host_len, client_cs))
+ goto err;
if (query_start_arg)
{
/* fill in query_time field */
- table->field[2]->store(query_time, TRUE);
+ if (table->field[2]->store(query_time, TRUE))
+ goto err;
/* lock_time */
- table->field[3]->store(lock_time, TRUE);
+ if (table->field[3]->store(lock_time, TRUE))
+ goto err;
/* rows_sent */
- table->field[4]->store((longlong) thd->sent_row_count, TRUE);
+ if (table->field[4]->store((longlong) thd->sent_row_count, TRUE))
+ goto err;
/* rows_examined */
- table->field[5]->store((longlong) thd->examined_row_count, TRUE);
+ if (table->field[5]->store((longlong) thd->examined_row_count, TRUE))
+ goto err;
}
else
{
@@ -509,14 +567,18 @@ bool Log_to_csv_event_handler::
/* fill database field */
if (thd->db)
{
- table->field[6]->store(thd->db, thd->db_length, client_cs);
+ if (table->field[6]->store(thd->db, thd->db_length, client_cs))
+ goto err;
table->field[6]->set_notnull();
}
if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
{
- table->field[7]->store((longlong)
- thd->first_successful_insert_id_in_prev_stmt_for_binlog, TRUE);
+ if (table->
+ field[7]->store((longlong)
+ thd->first_successful_insert_id_in_prev_stmt_for_binlog,
+ TRUE))
+ goto err;
table->field[7]->set_notnull();
}
@@ -528,16 +590,23 @@ bool Log_to_csv_event_handler::
*/
if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
{
- table->field[8]->store((longlong)
- thd->auto_inc_intervals_in_cur_stmt_for_binlog.minimum(), TRUE);
+ if (table->
+ field[8]->store((longlong)
+ thd->auto_inc_intervals_in_cur_stmt_for_binlog.minimum(), TRUE))
+ goto err;
table->field[8]->set_notnull();
}
- table->field[9]->store((longlong) server_id, TRUE);
+ if (table->field[9]->store((longlong) server_id, TRUE))
+ goto err;
table->field[9]->set_notnull();
/* sql_text */
- table->field[10]->store(sql_text,sql_text_len, client_cs);
+ if (table->field[10]->store(sql_text,sql_text_len, client_cs))
+ goto err;
+
+ /* log table entries are not replicated at the moment */
+ tmp_disable_binlog(current_thd);
/* write the row */
table->file->ha_write_row(table->record[0]);
@@ -545,6 +614,8 @@ bool Log_to_csv_event_handler::
reenable_binlog(current_thd);
DBUG_RETURN(0);
+err:
+ DBUG_RETURN(1);
}
bool Log_to_csv_event_handler::
@@ -733,61 +804,48 @@ bool LOGGER::reopen_log_table(uint log_table_type)
return table_log_handler->reopen_log_table(log_table_type);
}
-
-bool LOGGER::flush_logs(THD *thd)
+bool LOGGER::reopen_log_tables()
{
- TABLE_LIST close_slow_log, close_general_log;
+ /*
+ we use | and not || here, to ensure that both reopen_log_table
+ are called, even if the first one fails
+ */
+ if ((opt_slow_log && logger.reopen_log_table(QUERY_LOG_SLOW)) |
+ (opt_log && logger.reopen_log_table(QUERY_LOG_GENERAL)))
+ return TRUE;
+ return FALSE;
+}
- /* reopen log tables */
- bzero((char*) &close_slow_log, sizeof(TABLE_LIST));
- close_slow_log.alias= close_slow_log.table_name=(char*) "slow_log";
- close_slow_log.table_name_length= 8;
- close_slow_log.db= (char*) "mysql";
- close_slow_log.db_length= 5;
- bzero((char*) &close_general_log, sizeof(TABLE_LIST));
- close_general_log.alias= close_general_log.table_name=(char*) "general_log";
- close_general_log.table_name_length= 11;
- close_general_log.db= (char*) "mysql";
- close_general_log.db_length= 5;
+void LOGGER::tmp_close_log_tables(THD *thd)
+{
+ table_log_handler->tmp_close_log_tables(thd);
+}
- /* lock tables, in the case they are enabled */
- if (logger.is_log_tables_initialized)
- {
- /*
- This will lock and wait for all but the logger thread to release the
- tables. Then we could reopen log tables. Then release the name locks.
-
- NOTE: in fact, the first parameter used in lock_and_wait_for_table_name()
- and table_log_handler->flush() could be any non-NULL THD, as the
- underlying code makes certain assumptions about this.
- Here we use one of the logger handler THD's. Simply because it
- seems appropriate.
- */
- if (opt_slow_log)
- lock_and_wait_for_table_name(table_log_handler->general_log_thd,
- &close_slow_log);
- if (opt_log)
- lock_and_wait_for_table_name(table_log_handler->general_log_thd,
- &close_general_log);
- }
+bool LOGGER::flush_logs(THD *thd)
+{
+ int rc= 0;
/*
- Deny others from logging to general and slow log,
- while reopening tables.
+ Now we lock logger, as nobody should be able to use logging routines while
+ log tables are closed
*/
logger.lock();
+ if (logger.is_log_tables_initialized)
+ table_log_handler->tmp_close_log_tables(thd); // the locking happens here
/* reopen log files */
file_log_handler->flush();
- /* flush tables, in the case they are enabled */
+ /* reopen tables in the case they were enabled */
if (logger.is_log_tables_initialized)
- table_log_handler->flush(table_log_handler->general_log_thd,
- &close_slow_log, &close_general_log);
+ {
+ if (reopen_log_tables())
+ rc= TRUE;
+ }
/* end of log flush */
logger.unlock();
- return FALSE;
+ return rc;
}
@@ -1095,31 +1153,50 @@ void LOGGER::deactivate_log_handler(THD *thd, uint log_type)
}
-bool Log_to_csv_event_handler::flush(THD *thd, TABLE_LIST *close_slow_log,
- TABLE_LIST *close_general_log)
+/*
+ Close log tables temporarily. The thread which closed
+ them this way can lock them in any mode it needs.
+ NOTE: one should call logger.lock() before entering this
+ function.
+*/
+void Log_to_csv_event_handler::tmp_close_log_tables(THD *thd)
{
+ TABLE_LIST close_slow_log, close_general_log;
+
+ /* fill lists, we will need to perform operations on tables */
+ bzero((char*) &close_slow_log, sizeof(TABLE_LIST));
+ close_slow_log.alias= close_slow_log.table_name=(char*) "slow_log";
+ close_slow_log.table_name_length= 8;
+ close_slow_log.db= (char*) "mysql";
+ close_slow_log.db_length= 5;
+
+ bzero((char*) &close_general_log, sizeof(TABLE_LIST));
+ close_general_log.alias= close_general_log.table_name=(char*) "general_log";
+ close_general_log.table_name_length= 11;
+ close_general_log.db= (char*) "mysql";
+ close_general_log.db_length= 5;
+
+ privileged_thread= thd;
+
VOID(pthread_mutex_lock(&LOCK_open));
+ /*
+ NOTE: in fact, the first parameter used in query_cache_invalidate3()
+ could be any non-NULL THD, as the underlying code makes certain
+ assumptions about this.
+ Here we use one of the logger handler THD's. Simply because it
+ seems appropriate.
+ */
if (opt_log)
{
close_log_table(QUERY_LOG_GENERAL, TRUE);
- query_cache_invalidate3(thd, close_general_log, 0);
- unlock_table_name(thd, close_general_log);
+ query_cache_invalidate3(general_log_thd, &close_general_log, 0);
}
if (opt_slow_log)
{
close_log_table(QUERY_LOG_SLOW, TRUE);
- query_cache_invalidate3(thd, close_slow_log, 0);
- unlock_table_name(thd, close_slow_log);
+ query_cache_invalidate3(general_log_thd, &close_slow_log, 0);
}
VOID(pthread_mutex_unlock(&LOCK_open));
- /*
- we use | and not || here, to ensure that both reopen_log_table
- are called, even if the first one fails
- */
- if ((opt_slow_log && reopen_log_table(QUERY_LOG_SLOW)) |
- (opt_log && reopen_log_table(QUERY_LOG_GENERAL)))
- return 1;
- return 0;
}
/* the parameters are unused for the log tables */
@@ -1187,16 +1264,15 @@ void Log_to_csv_event_handler::
THD *log_thd, *curr= current_thd;
TABLE_LIST *table;
+ if (!logger.is_log_table_enabled(log_table_type))
+ return; /* do nothing */
+
switch (log_table_type) {
case QUERY_LOG_GENERAL:
- if (!logger.is_general_log_table_enabled())
- return; /* do nothing */
log_thd= general_log_thd;
table= &general_log;
break;
case QUERY_LOG_SLOW:
- if (!logger.is_slow_log_table_enabled())
- return; /* do nothing */
log_thd= slow_log_thd;
table= &slow_log;
break;
@@ -2010,7 +2086,7 @@ bool MYSQL_QUERY_LOG::write(time_t event_time, const char *user_host,
goto err;
/* command_type, thread_id */
- length= my_snprintf(buff, 32, "%5ld ", thread_id);
+ length= my_snprintf(buff, 32, "%5ld ", (long) thread_id);
if (my_b_write(&log_file, (byte*) buff, length))
goto err;
diff --git a/sql/log.h b/sql/log.h
index 8f75601f02b..f39b52f5db2 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -404,6 +404,9 @@ public:
};
+int check_if_log_table(uint db_len, const char *db, uint table_name_len,
+ const char *table_name, uint check_if_opened);
+
class Log_to_csv_event_handler: public Log_event_handler
{
/*
@@ -412,6 +415,16 @@ class Log_to_csv_event_handler: public Log_event_handler
THD's of the query. The reason is the locking order and duration.
*/
THD *general_log_thd, *slow_log_thd;
+ /*
+ This is for the thread, which called tmp_close_log_tables. The thread
+ will be allowed to write-lock the log tables (as it explicitly disabled
+ logging). This is used for such operations as REPAIR, which require
+ exclusive lock on the log tables.
+ NOTE: there can be only one priviliged thread, as one should
+ lock logger with logger.lock() before calling tmp_close_log_tables().
+ So no other thread could get privileged status at the same time.
+ */
+ THD *privileged_thread;
friend class LOGGER;
TABLE_LIST general_log, slow_log;
@@ -436,13 +449,20 @@ public:
const char *command_type, uint command_type_len,
const char *sql_text, uint sql_text_len,
CHARSET_INFO *client_cs);
- bool flush(THD *thd, TABLE_LIST *close_slow_Log,
- TABLE_LIST* close_general_log);
+ void tmp_close_log_tables(THD *thd);
void close_log_table(uint log_type, bool lock_in_use);
bool reopen_log_table(uint log_type);
+ THD* get_privileged_thread()
+ {
+ return privileged_thread;
+ }
};
+/* type of the log table */
+#define QUERY_LOG_SLOW 1
+#define QUERY_LOG_GENERAL 2
+
class Log_to_file_event_handler: public Log_event_handler
{
MYSQL_QUERY_LOG mysql_log;
@@ -498,13 +518,18 @@ public:
{}
void lock() { (void) pthread_mutex_lock(&LOCK_logger); }
void unlock() { (void) pthread_mutex_unlock(&LOCK_logger); }
- bool is_general_log_table_enabled()
+ void tmp_close_log_tables(THD *thd);
+ bool is_log_table_enabled(uint log_table_type)
{
- return table_log_handler && table_log_handler->general_log.table != 0;
- }
- bool is_slow_log_table_enabled()
- {
- return table_log_handler && table_log_handler->slow_log.table != 0;
+ switch (log_table_type) {
+ case QUERY_LOG_SLOW:
+ return table_log_handler && table_log_handler->slow_log.table != 0;
+ case QUERY_LOG_GENERAL:
+ return table_log_handler && table_log_handler->general_log.table != 0;
+ default:
+ DBUG_ASSERT(0);
+ return FALSE; /* make compiler happy */
+ }
}
/*
We want to initialize all log mutexes as soon as possible,
@@ -542,6 +567,7 @@ public:
void close_log_table(uint log_type, bool lock_in_use);
bool reopen_log_table(uint log_type);
+ bool reopen_log_tables();
/* we use this function to setup all enabled log event handlers */
int set_handlers(uint error_log_printer,
@@ -564,6 +590,13 @@ public:
return file_log_handler->get_mysql_log();
return NULL;
}
+ THD* get_privileged_thread()
+ {
+ if (table_log_handler)
+ return table_log_handler->get_privileged_thread();
+ else
+ return NULL;
+ }
};
enum enum_binlog_format {
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 0bf75982626..b0947249439 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -140,6 +140,8 @@ MY_LOCALE *my_locale_by_name(const char *name);
#define MAX_ACCEPT_RETRY 10 // Test accept this many times
#define MAX_FIELDS_BEFORE_HASH 32
#define USER_VARS_HASH_SIZE 16
+#define TABLE_OPEN_CACHE_MIN 64
+#define TABLE_OPEN_CACHE_DEFAULT 64
/*
Value of 9236 discovered through binary search 2006-09-26 on Ubuntu Dapper
@@ -221,12 +223,6 @@ MY_LOCALE *my_locale_by_name(const char *name);
/* Characters shown for the command in 'information_schema.processlist' */
#define PROCESS_LIST_INFO_WIDTH 65535
-/* Time handling defaults */
-#define TIMESTAMP_MAX_YEAR 2038
-#define YY_PART_YEAR 70
-#define TIMESTAMP_MIN_YEAR (1900 + YY_PART_YEAR - 1)
-#define TIMESTAMP_MAX_VALUE 2145916799
-#define TIMESTAMP_MIN_VALUE 1
#define PRECISION_FOR_DOUBLE 53
#define PRECISION_FOR_FLOAT 24
@@ -1451,10 +1447,6 @@ typedef void (*sql_print_message_func)(const char *format, ...)
ATTRIBUTE_FORMAT(printf, 1, 2);
extern sql_print_message_func sql_print_message_handlers[];
-/* type of the log table */
-#define QUERY_LOG_SLOW 1
-#define QUERY_LOG_GENERAL 2
-
int error_log_print(enum loglevel level, const char *format,
va_list args);
@@ -1485,6 +1477,8 @@ uint find_type2(TYPELIB *lib, const char *find, uint length, CHARSET_INFO *cs);
void unhex_type2(TYPELIB *lib);
uint check_word(TYPELIB *lib, const char *val, const char *end,
const char **end_of_word);
+int find_string_in_array(LEX_STRING * const haystack, LEX_STRING * const needle,
+ CHARSET_INFO * const cs);
bool is_keyword(const char *name, uint len);
@@ -2052,6 +2046,10 @@ inline void kill_delayed_threads(void) {}
void init_fill_schema_files_row(TABLE* table);
bool schema_table_store_record(THD *thd, TABLE *table);
+/* sql/item_create.cc */
+int item_create_init();
+void item_create_cleanup();
+
#endif /* MYSQL_SERVER */
#endif /* MYSQL_CLIENT */
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 819695fc67f..bcc2d4c49dd 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -372,7 +372,6 @@ extern longlong innobase_log_file_size;
extern long innobase_log_buffer_size;
extern longlong innobase_buffer_pool_size;
extern long innobase_additional_mem_pool_size;
-extern long innobase_buffer_pool_awe_mem_mb;
extern long innobase_file_io_threads, innobase_lock_wait_timeout;
extern long innobase_force_recovery;
extern long innobase_open_files;
@@ -1184,9 +1183,9 @@ void clean_up(bool print_message)
hostname_cache_free();
item_user_lock_free();
lex_free(); /* Free some memory */
+ item_create_cleanup();
set_var_free();
free_charsets();
- (void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */
if (!opt_noacl)
{
#ifdef HAVE_DLOPEN
@@ -1194,6 +1193,7 @@ void clean_up(bool print_message)
#endif
}
plugin_shutdown();
+ ha_end();
if (tc_log)
tc_log->close();
xid_cache_free();
@@ -1609,7 +1609,7 @@ static void network_init(void)
if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))
{
- sql_print_error("The socket file path is too long (> %lu): %s",
+ sql_print_error("The socket file path is too long (> %u): %s",
sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
unireg_abort(1);
}
@@ -2663,19 +2663,43 @@ static int init_common_variables(const char *conf_file_name, int argc,
/* connections and databases needs lots of files */
{
- uint files, wanted_files;
+ uint files, wanted_files, max_open_files;
- wanted_files= 10+(uint) max(max_connections*5,
- max_connections+table_cache_size*2);
- set_if_bigger(wanted_files, open_files_limit);
- files= my_set_max_open_files(wanted_files);
+ /* MyISAM requires two file handles per table. */
+ wanted_files= 10+max_connections+table_cache_size*2;
+ /*
+ We are trying to allocate no less than max_connections*5 file
+ handles (i.e. we are trying to set the limit so that they will
+ be available). In addition, we allocate no less than how much
+ was already allocated. However below we report a warning and
+ recompute values only if we got less file handles than were
+ explicitly requested. No warning and re-computation occur if we
+ can't get max_connections*5 but still got no less than was
+ requested (value of wanted_files).
+ */
+ max_open_files= max(max(wanted_files, max_connections*5),
+ open_files_limit);
+ files= my_set_max_open_files(max_open_files);
if (files < wanted_files)
{
if (!open_files_limit)
{
- max_connections= (ulong) min((files-10),max_connections);
- table_cache_size= (ulong) max((files-10-max_connections)/2,64);
+ /*
+ If we have requested too much file handles than we bring
+ max_connections in supported bounds.
+ */
+ max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
+ max_connections);
+ /*
+ Decrease table_cache_size according to max_connections, but
+ not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we
+ never increase table_cache_size automatically (that could
+ happen if max_connections is decreased above).
+ */
+ table_cache_size= (ulong) min(max((files-10-max_connections)/2,
+ TABLE_OPEN_CACHE_MIN),
+ table_cache_size);
DBUG_PRINT("warning",
("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
files, max_connections, table_cache_size));
@@ -2693,6 +2717,8 @@ static int init_common_variables(const char *conf_file_name, int argc,
return 1;
init_client_errs();
lex_init();
+ if (item_create_init())
+ return 1;
item_init();
set_var_init();
mysys_uses_curses=0;
@@ -3506,7 +3532,7 @@ int main(int argc, char **argv)
{
if (global_system_variables.log_warnings)
sql_print_warning("Asked for %ld thread stack, but got %ld",
- thread_stack, stack_size);
+ thread_stack, (long) stack_size);
#if defined(__ia64__) || defined(__ia64)
thread_stack= stack_size*2;
#else
@@ -5315,7 +5341,7 @@ master-ssl",
(gptr*) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"merge", OPT_MERGE, "Enable Merge storage engine. Disable with \
--skip-merge.",
- (gptr*) &opt_merge, (gptr*) &opt_merge, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0},
+ (gptr*) &opt_merge, (gptr*) &opt_merge, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"myisam-recover", OPT_MYISAM_RECOVER,
"Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
(gptr*) &myisam_recover_options_str, (gptr*) &myisam_recover_options_str, 0,
@@ -5774,10 +5800,6 @@ log and this option does nothing anymore.",
(gptr*) &srv_auto_extend_increment,
(gptr*) &srv_auto_extend_increment,
0, GET_LONG, REQUIRED_ARG, 8L, 1L, 1000L, 0, 1L, 0},
- {"innodb_buffer_pool_awe_mem_mb", OPT_INNODB_BUFFER_POOL_AWE_MEM_MB,
- "If Windows AWE is used, the size of InnoDB buffer pool allocated from the AWE memory.",
- (gptr*) &innobase_buffer_pool_awe_mem_mb, (gptr*) &innobase_buffer_pool_awe_mem_mb, 0,
- GET_LONG, REQUIRED_ARG, 0, 0, 63000, 0, 1, 0},
{"innodb_buffer_pool_size", OPT_INNODB_BUFFER_POOL_SIZE,
"The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
(gptr*) &innobase_buffer_pool_size, (gptr*) &innobase_buffer_pool_size, 0,
@@ -6185,15 +6207,15 @@ The minimum value for this variable is 4096.",
{"table_cache", OPT_TABLE_OPEN_CACHE,
"Deprecated; use --table_open_cache instead.",
(gptr*) &table_cache_size, (gptr*) &table_cache_size, 0, GET_ULONG,
- REQUIRED_ARG, 64, 1, 512*1024L, 0, 1, 0},
+ REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
{"table_definition_cache", OPT_TABLE_DEF_CACHE,
"The number of cached table definitions.",
(gptr*) &table_def_size, (gptr*) &table_def_size,
0, GET_ULONG, REQUIRED_ARG, 128, 1, 512*1024L, 0, 1, 0},
{"table_open_cache", OPT_TABLE_OPEN_CACHE,
"The number of cached open tables.",
- (gptr*) &table_cache_size, (gptr*) &table_cache_size,
- 0, GET_ULONG, REQUIRED_ARG, 64, 1, 512*1024L, 0, 1, 0},
+ (gptr*) &table_cache_size, (gptr*) &table_cache_size, 0, GET_ULONG,
+ REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
{"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
"Timeout in seconds to wait for a table level lock before returning an "
"error. Used only if the connection has active cursors.",
@@ -6568,6 +6590,10 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff)
#endif /* HAVE_OPENSSL */
+/*
+ Variables shown by SHOW STATUS in alphabetical order
+*/
+
SHOW_VAR status_vars[]= {
{"Aborted_clients", (char*) &aborted_threads, SHOW_LONG},
{"Aborted_connects", (char*) &aborted_connects, SHOW_LONG},
@@ -8075,16 +8101,20 @@ void refresh_status(THD *thd)
{
pthread_mutex_lock(&LOCK_status);
- /* We must update the global status before cleaning up the thread */
+ /* Add thread's status variabes to global status */
add_to_status(&global_status_var, &thd->status_var);
+
+ /* Reset thread's status variables */
bzero((char*) &thd->status_var, sizeof(thd->status_var));
+ /* Reset some global variables */
for (SHOW_VAR *ptr= status_vars; ptr->name; ptr++)
{
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
if (ptr->type == SHOW_LONG)
*(ulong*) ptr->value= 0;
}
+
/* Reset the counters of all key caches (default and named). */
process_key_caches(reset_key_cache_counters);
pthread_mutex_unlock(&LOCK_status);
@@ -8132,7 +8162,6 @@ longlong innobase_log_file_size;
long innobase_log_buffer_size;
longlong innobase_buffer_pool_size;
long innobase_additional_mem_pool_size;
-long innobase_buffer_pool_awe_mem_mb;
long innobase_file_io_threads, innobase_lock_wait_timeout;
long innobase_force_recovery;
long innobase_open_files;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 5878771c096..79b3e023a5f 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -2101,6 +2101,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
key_parts->null_bit= key_part_info->null_bit;
key_parts->image_type =
(key_info->flags & HA_SPATIAL) ? Field::itMBR : Field::itRAW;
+ key_parts->flag= key_part_info->key_part_flag;
}
param.real_keynr[param.keys++]=idx;
}
@@ -3236,6 +3237,11 @@ static bool create_partition_index_description(PART_PRUNE_PARAM *ppar)
key_part->field= (*field);
key_part->image_type = Field::itRAW;
+ /*
+ We set keypart flag to 0 here as the only HA_PART_KEY_SEG is checked
+ in the RangeAnalysisModule.
+ */
+ key_part->flag= 0;
/* We don't set key_parts->null_bit as it will not be used */
ppar->is_part_keypart[part]= !in_subpart_fields;
@@ -5655,7 +5661,9 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
}
break;
case Item_func::GT_FUNC:
- if (field_is_equal_to_item(field,value))
+ /* Don't use open ranges for partial key_segments */
+ if (field_is_equal_to_item(field,value) &&
+ !(key_part->flag & HA_PART_KEY_SEG))
tree->min_flag=NEAR_MIN;
/* fall through */
case Item_func::GE_FUNC:
@@ -7644,6 +7652,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
key_part->length= key_info->key_part[part].length;
key_part->store_length= key_info->key_part[part].store_length;
key_part->null_bit= key_info->key_part[part].null_bit;
+ key_part->flag= key_info->key_part[part].key_part_flag;
}
if (insert_dynamic(&quick->ranges,(gptr)&range))
goto err;
diff --git a/sql/opt_range.h b/sql/opt_range.h
index a88c79e8bab..170766c7c10 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -27,6 +27,8 @@
typedef struct st_key_part {
uint16 key,part, store_length, length;
uint8 null_bit;
+ /* Keypart flags (0 if partition pruning is used) */
+ uint8 flag;
Field *field;
Field::imagetype image_type;
} KEY_PART;
diff --git a/sql/parse_file.h b/sql/parse_file.h
index 33871588e11..5fb65b4c7ec 100644
--- a/sql/parse_file.h
+++ b/sql/parse_file.h
@@ -107,4 +107,20 @@ public:
bool bad_format_errors);
};
+
+/*
+ Custom version of standard offsetof() macro which can be used to get
+ offsets of members in class for non-POD types (according to the current
+ version of C++ standard offsetof() macro can't be used in such cases and
+ attempt to do so causes warnings to be emitted, OTOH in many cases it is
+ still OK to assume that all instances of the class has the same offsets
+ for the same members).
+
+ This is temporary solution which should be removed once File_parser class
+ and related routines are refactored.
+*/
+
+#define my_offsetof(TYPE, MEMBER) \
+ ((size_t)((char *)&(((TYPE *)0x10)->MEMBER) - (char*)0x10))
+
#endif /* _PARSE_FILE_H_ */
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index a20fca9404b..c3e67752396 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -485,6 +485,8 @@ bool partition_info::check_range_constants()
DBUG_ENTER("partition_info::check_range_constants");
DBUG_PRINT("enter", ("INT_RESULT with %d parts", no_parts));
+ LINT_INIT(current_largest);
+
part_result_type= INT_RESULT;
range_int_array= (longlong*)sql_alloc(no_parts * sizeof(longlong));
if (unlikely(range_int_array == NULL))
@@ -877,7 +879,6 @@ void partition_info::print_no_partition_found(TABLE *table)
bool partition_info::set_up_charset_field_preps()
{
Field *field, **ptr;
- char *field_buf;
char **char_ptrs;
unsigned i;
bool found;
@@ -919,6 +920,7 @@ bool partition_info::set_up_charset_field_preps()
{
if (field_is_partition_charset(field))
{
+ char *field_buf;
CHARSET_INFO *cs= ((Field_str*)field)->charset();
size= field->pack_length();
if (!(field_buf= sql_calloc(size)))
@@ -956,6 +958,8 @@ bool partition_info::set_up_charset_field_preps()
unsigned j= 0;
Field *part_field;
CHARSET_INFO *cs;
+ char *field_buf;
+ LINT_INIT(field_buf);
if (!field_is_partition_charset(field))
continue;
diff --git a/sql/protocol.cc b/sql/protocol.cc
index e00a70cf3a2..a2ae194c374 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -79,6 +79,7 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
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;
}
@@ -111,7 +112,7 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
net_send_error_packet(thd, sql_errno, err);
- thd->is_fatal_error=0; // Error message is given
+ thd->is_fatal_error= 0; // Error message is given
thd->net.report_error= 0;
/* Abort multi-result sets */
@@ -156,6 +157,7 @@ net_printf_error(THD *thd, uint errcode, ...)
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;
}
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 4369c288cd5..5590e71c810 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -67,7 +67,6 @@ extern longlong innobase_log_file_size;
extern long innobase_log_buffer_size;
extern longlong innobase_buffer_pool_size;
extern long innobase_additional_mem_pool_size;
-extern long innobase_buffer_pool_awe_mem_mb;
extern long innobase_file_io_threads, innobase_lock_wait_timeout;
extern long innobase_force_recovery;
extern long innobase_open_files;
@@ -743,7 +742,7 @@ static int show_slave_skip_errors(THD *thd, SHOW_VAR *var, char *buff)
#endif /* HAVE_REPLICATION */
/*
- Variables shown by SHOW variables in alphabetical order
+ Variables shown by SHOW VARIABLES in alphabetical order
*/
SHOW_VAR init_vars[]= {
@@ -819,7 +818,6 @@ SHOW_VAR init_vars[]= {
#ifdef WITH_INNOBASE_STORAGE_ENGINE
{"innodb_additional_mem_pool_size", (char*) &innobase_additional_mem_pool_size, SHOW_LONG },
{sys_innodb_autoextend_increment.name, (char*) &sys_innodb_autoextend_increment, SHOW_SYS},
- {"innodb_buffer_pool_awe_mem_mb", (char*) &innobase_buffer_pool_awe_mem_mb, SHOW_LONG },
{"innodb_buffer_pool_size", (char*) &innobase_buffer_pool_size, SHOW_LONGLONG },
{"innodb_checksums", (char*) &innobase_use_checksums, SHOW_MY_BOOL},
{sys_innodb_commit_concurrency.name, (char*) &sys_innodb_commit_concurrency, SHOW_SYS},
@@ -3141,6 +3139,7 @@ static byte *get_warning_count(THD *thd)
{
thd->sys_var_tmp.long_value=
(thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] +
+ thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR] +
thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]);
return (byte*) &thd->sys_var_tmp.long_value;
}
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 0bcd15c2b82..3022967eeeb 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -6004,4 +6004,10 @@ ER_BAD_LOG_STATEMENT
ger "Sie können eine Logtabelle nicht '%s', wenn Loggen angeschaltet ist"
ER_NON_INSERTABLE_TABLE
eng "The target table %-.100s of the %s is not insertable-into"
+ER_CANT_RENAME_LOG_TABLE
+ eng "Cannot rename '%s'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to '%s'"
+ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT 42000
+ eng "Incorrect parameter count in the call to native function '%-.64s'"
+ER_WRONG_PARAMETERS_TO_NATIVE_FCT 42000
+ eng "Incorrect parameters in the call to native function '%-.64s'"
diff --git a/sql/slave.cc b/sql/slave.cc
index 1852ff68070..00d6d168fb8 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -2618,9 +2618,21 @@ improper_arguments: %d timed_out: %d",
void set_slave_thread_options(THD* thd)
{
DBUG_ENTER("set_slave_thread_options");
-
- thd->options = ((opt_log_slave_updates) ? OPTION_BIN_LOG:0) |
- OPTION_AUTO_IS_NULL;
+ /*
+ It's nonsense to constrain the slave threads with max_join_size; if a
+ query succeeded on master, we HAVE to execute it. So set
+ OPTION_BIG_SELECTS. Setting max_join_size to HA_POS_ERROR is not enough
+ (and it's not needed if we have OPTION_BIG_SELECTS) because an INSERT
+ SELECT examining more than 4 billion rows would still fail (yes, because
+ when max_join_size is 4G, OPTION_BIG_SELECTS is automatically set, but
+ only for client threads.
+ */
+ ulonglong options= thd->options | OPTION_BIG_SELECTS;
+ if (opt_log_slave_updates)
+ options|= OPTION_BIN_LOG;
+ else
+ options&= ~OPTION_BIN_LOG;
+ thd->options= options;
thd->variables.completion_type= 0;
DBUG_VOID_RETURN;
}
@@ -2654,17 +2666,6 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
thd->net.read_timeout = slave_net_timeout;
thd->slave_thread = 1;
set_slave_thread_options(thd);
- /*
- It's nonsense to constrain the slave threads with max_join_size; if a
- query succeeded on master, we HAVE to execute it. So set
- OPTION_BIG_SELECTS. Setting max_join_size to HA_POS_ERROR is not enough
- (and it's not needed if we have OPTION_BIG_SELECTS) because an INSERT
- SELECT examining more than 4 billion rows would still fail (yes, because
- when max_join_size is 4G, OPTION_BIG_SELECTS is automatically set, but
- only for client threads.
- */
- thd->options = ((opt_log_slave_updates) ? OPTION_BIN_LOG:0) |
- OPTION_AUTO_IS_NULL | OPTION_BIG_SELECTS;
thd->client_capabilities = CLIENT_LOCAL_FILES;
thd->real_id=pthread_self();
pthread_mutex_lock(&LOCK_thread_count);
diff --git a/sql/sp.cc b/sql/sp.cc
index 3411a18c17a..45a177d3e7a 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -653,6 +653,17 @@ db_drop_routine(THD *thd, int type, sp_name *name)
if (table->file->ha_delete_row(table->record[0]))
ret= SP_DELETE_ROW_FAILED;
}
+
+ if (ret == SP_OK)
+ {
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
+ }
+ }
+
close_thread_tables(thd);
DBUG_RETURN(ret);
}
@@ -687,6 +698,17 @@ db_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
if ((table->file->ha_update_row(table->record[1],table->record[0])))
ret= SP_WRITE_ROW_FAILED;
}
+
+ if (ret == SP_OK)
+ {
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
+ }
+ }
+
close_thread_tables(thd);
DBUG_RETURN(ret);
}
@@ -765,6 +787,7 @@ print_field_values(THD *thd, TABLE *table,
return SP_INTERNAL_ERROR;
}
}
+
return SP_OK;
}
@@ -1371,6 +1394,10 @@ static bool add_used_routine(LEX *lex, Query_arena *arena,
const LEX_STRING *key,
TABLE_LIST *belong_to_view)
{
+ hash_init_opt(&lex->sroutines, system_charset_info,
+ Query_tables_list::START_SROUTINES_HASH_SIZE,
+ 0, 0, sp_sroutine_key, 0, 0);
+
if (!hash_search(&lex->sroutines, (byte *)key->str, key->length))
{
Sroutine_hash_entry *rn=
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index a061ae12dd1..47a623ec749 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1029,8 +1029,7 @@ sp_head::execute(THD *thd)
save_sql_mode= thd->variables.sql_mode;
thd->variables.sql_mode= m_sql_mode;
save_abort_on_warning= thd->abort_on_warning;
- thd->abort_on_warning=
- (m_sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES));
+ thd->abort_on_warning= 0;
/*
It is also more efficient to save/restore current thd->lex once when
@@ -1143,6 +1142,7 @@ sp_head::execute(THD *thd)
ctx->clear_handler();
ctx->enter_handler(hip);
thd->clear_error();
+ thd->is_fatal_error= 0;
thd->killed= THD::NOT_KILLED;
continue;
}
@@ -1170,8 +1170,9 @@ sp_head::execute(THD *thd)
state= EXECUTED;
done:
- DBUG_PRINT("info", ("err_status: %d killed: %d query_error: %d",
- err_status, thd->killed, thd->query_error));
+ DBUG_PRINT("info", ("err_status: %d killed: %d query_error: %d report_error: %d",
+ err_status, thd->killed, thd->query_error,
+ thd->net.report_error));
if (thd->killed)
err_status= TRUE;
@@ -2375,6 +2376,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
bool open_tables, sp_instr* instr)
{
int res= 0;
+ DBUG_ENTER("reset_lex_and_exec_core");
DBUG_ASSERT(!thd->derived_tables);
DBUG_ASSERT(thd->change_list.is_empty());
@@ -2419,7 +2421,10 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
res= -1;
if (!res)
+ {
res= instr->exec_core(thd, nextp);
+ DBUG_PRINT("info",("exec_core returned: %d", res));
+ }
m_lex->unit.cleanup();
@@ -2457,7 +2462,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
cleanup_items() is called in sp_head::execute()
*/
- return res || thd->net.report_error;
+ DBUG_RETURN(res || thd->net.report_error);
}
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index c55fc744cd0..aa13c2f08f4 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -3140,9 +3140,22 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
grant_option=TRUE;
thd->mem_root= old_root;
pthread_mutex_unlock(&acl_cache->lock);
+
+ if (!result) /* success */
+ {
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
+ }
+ }
+
rw_unlock(&LOCK_grant);
- if (!result)
+
+ if (!result) /* success */
send_ok(thd);
+
/* Tables are automatically closed */
DBUG_RETURN(result);
}
@@ -3294,9 +3307,21 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
grant_option=TRUE;
thd->mem_root= old_root;
pthread_mutex_unlock(&acl_cache->lock);
+ if (!result && !no_error)
+ {
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
+ }
+ }
+
rw_unlock(&LOCK_grant);
+
if (!result && !no_error)
send_ok(thd);
+
/* Tables are automatically closed */
DBUG_RETURN(result);
}
@@ -3394,11 +3419,23 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
}
}
VOID(pthread_mutex_unlock(&acl_cache->lock));
+
+ if (!result)
+ {
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
+ }
+ }
+
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
if (!result)
send_ok(thd);
+
DBUG_RETURN(result);
}
@@ -5398,6 +5435,13 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
}
VOID(pthread_mutex_unlock(&acl_cache->lock));
+
+ if (mysql_bin_log.is_open())
+ {
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
+ }
+
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
if (result)
@@ -5454,6 +5498,13 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
rebuild_check_host();
VOID(pthread_mutex_unlock(&acl_cache->lock));
+
+ if (mysql_bin_log.is_open())
+ {
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
+ }
+
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
if (result)
@@ -5523,6 +5574,13 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
rebuild_check_host();
VOID(pthread_mutex_unlock(&acl_cache->lock));
+
+ if (mysql_bin_log.is_open())
+ {
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
+ }
+
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
if (result)
@@ -5697,6 +5755,13 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
}
VOID(pthread_mutex_unlock(&acl_cache->lock));
+
+ if (mysql_bin_log.is_open())
+ {
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
+ }
+
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 3e7bcf7798a..28bc1e9dcbf 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1365,6 +1365,10 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
Also SELECT::exclude_from_table_unique_test used to exclude from check
tables of main SELECT of multi-delete and multi-update
+ We also skip tables with TABLE_LIST::prelocking_placeholder set,
+ because we want to allow SELECTs from them, and their modification
+ will rise the error anyway.
+
TODO: when we will have table/view change detection we can do this check
only once for PS/SP
@@ -1411,12 +1415,13 @@ TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list)
if (((! (res= find_table_in_global_list(table_list, d_name, t_name))) &&
(! (res= mysql_lock_have_duplicate(thd, table, table_list)))) ||
((!res->table || res->table != table->table) &&
- res->select_lex && !res->select_lex->exclude_from_table_unique_test))
+ res->select_lex && !res->select_lex->exclude_from_table_unique_test &&
+ !res->prelocking_placeholder))
break;
/*
- If we found entry of this table or or table of SELECT which already
+ If we found entry of this table or table of SELECT which already
processed in derived table or top select of multi-update/multi-delete
- (exclude_from_table_unique_test).
+ (exclude_from_table_unique_test) or prelocking placeholder.
*/
table_list= res->next_global;
DBUG_PRINT("info",
@@ -6558,6 +6563,8 @@ static bool
has_two_write_locked_tables_with_auto_increment(TABLE_LIST *tables)
{
char *first_table_name= NULL, *first_db;
+ LINT_INIT(first_db);
+
for (TABLE_LIST *table= tables; table; table= table->next_global)
{
/* we must do preliminary checks as table->table may be NULL */
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 5da8d27a887..776ba4dabea 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -241,6 +241,7 @@ THD::THD()
// Must be reset to handle error with THD's created for init of mysqld
lex->current_select= 0;
start_time=(time_t) 0;
+ time_after_lock=(time_t) 0;
current_linfo = 0;
slave_thread = 0;
variables.pseudo_thread_id= 0;
@@ -512,14 +513,13 @@ THD::~THD()
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
{
- ulong *end= (ulong*) ((byte*) to_var + offsetof(STATUS_VAR,
- last_system_status_var) +
+ ulong *end= (ulong*) ((byte*) to_var +
+ offsetof(STATUS_VAR, last_system_status_var) +
sizeof(ulong));
ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
while (to != end)
*(to++)+= *(from++);
- /* it doesn't make sense to add last_query_cost values */
}
/*
@@ -858,7 +858,6 @@ int THD::send_explain_fields(select_result *result)
field_list.push_back(new Item_empty_string("select_type", 19, cs));
field_list.push_back(item= new Item_empty_string("table", NAME_LEN, cs));
item->maybe_null= 1;
-#ifdef WITH_PARTITION_STORAGE_ENGINE
if (lex->describe & DESCRIBE_PARTITIONS)
{
/* Maximum length of string that make_used_partitions_str() can produce */
@@ -867,7 +866,6 @@ int THD::send_explain_fields(select_result *result)
field_list.push_back(item);
item->maybe_null= 1;
}
-#endif
field_list.push_back(item= new Item_empty_string("type", 10, cs));
item->maybe_null= 1;
field_list.push_back(item=new Item_empty_string("possible_keys",
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 508cd7fc04b..2cf7de5ee9e 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -337,12 +337,17 @@ typedef struct system_status_var
ulong com_stmt_reset;
ulong com_stmt_close;
+ /*
+ Status variables which it does not make sense to add to
+ global status variable counter
+ */
double last_query_cost;
} STATUS_VAR;
/*
- This is used for 'show status'. It must be updated to the last ulong
- variable in system_status_var
+ This is used for 'SHOW STATUS'. It must be updated to the last ulong
+ variable in system_status_var which is makes sens to add to the global
+ counter
*/
#define last_system_status_var com_stmt_close
@@ -1449,10 +1454,12 @@ public:
#ifndef EMBEDDED_LIBRARY
inline void clear_error()
{
+ DBUG_ENTER("clear_error");
net.last_error[0]= 0;
net.last_errno= 0;
net.report_error= 0;
query_error= 0;
+ DBUG_VOID_RETURN;
}
inline bool vio_ok() const { return net.vio != 0; }
#else
@@ -1570,10 +1577,11 @@ public:
or trigger is decided when it starts executing, depending for example on
the caller (for a stored function: if caller is SELECT or
INSERT/UPDATE/DELETE...).
+
Don't reset binlog format for NDB binlog injector thread.
*/
if ((temporary_tables == NULL) && (in_sub_stmt == 0) &&
- (system_thread != SYSTEM_THREAD_NDBCLUSTER_BINLOG))
+ (system_thread != SYSTEM_THREAD_NDBCLUSTER_BINLOG))
{
current_stmt_binlog_row_based=
test(variables.binlog_format == BINLOG_FORMAT_ROW);
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 3960236e828..37096fd897e 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -705,6 +705,7 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
qinfo.db = db;
qinfo.db_len = strlen(db);
+ /* These DDL methods and logging protected with LOCK_mysql_create_db */
mysql_bin_log.write(&qinfo);
}
send_ok(thd, result);
@@ -783,6 +784,7 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
qinfo.db_len = strlen(db);
thd->clear_error();
+ /* These DDL methods and logging protected with LOCK_mysql_create_db */
mysql_bin_log.write(&qinfo);
}
send_ok(thd, result);
@@ -905,6 +907,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
qinfo.db_len = strlen(db);
thd->clear_error();
+ /* These DDL methods and logging protected with LOCK_mysql_create_db */
mysql_bin_log.write(&qinfo);
}
thd->server_status|= SERVER_STATUS_DB_DROPPED;
@@ -931,6 +934,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
tbl_name_len= strlen(tbl->table_name) + 3;
if (query_pos + tbl_name_len + 1 >= query_end)
{
+ /* These DDL methods and logging protected with LOCK_mysql_create_db */
write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
query_pos= query_data_start;
}
@@ -943,6 +947,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
if (query_pos != query_data_start)
{
+ /* These DDL methods and logging protected with LOCK_mysql_create_db */
write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
}
}
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index f128b5e8706..a0cd419e6c6 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -350,7 +350,7 @@ cleanup:
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
}
- if (error < 0)
+ if (error < 0 || (thd->lex->ignore && !thd->is_fatal_error))
{
thd->row_count_func= deleted;
send_ok(thd,deleted);
@@ -862,6 +862,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
bool error;
uint closed_log_tables= 0, lock_logger= 0;
uint path_length;
+ uint log_type;
DBUG_ENTER("mysql_truncate");
bzero((char*) &create_info,sizeof(create_info));
@@ -913,28 +914,16 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
DBUG_RETURN(TRUE);
}
+ log_type= check_if_log_table(table_list->db_length, table_list->db,
+ table_list->table_name_length,
+ table_list->table_name, 1);
/* close log tables in use */
- if (!my_strcasecmp(system_charset_info, table_list->db, "mysql"))
+ if (log_type)
{
- if (opt_log &&
- !my_strcasecmp(system_charset_info, table_list->table_name,
- "general_log"))
- {
- lock_logger= 1;
- logger.lock();
- logger.close_log_table(QUERY_LOG_GENERAL, FALSE);
- closed_log_tables= closed_log_tables | QUERY_LOG_GENERAL;
- }
- else
- if (opt_slow_log &&
- !my_strcasecmp(system_charset_info, table_list->table_name,
- "slow_log"))
- {
- lock_logger= 1;
- logger.lock();
- logger.close_log_table(QUERY_LOG_SLOW, FALSE);
- closed_log_tables= closed_log_tables | QUERY_LOG_SLOW;
- }
+ lock_logger= 1;
+ logger.lock();
+ logger.close_log_table(log_type, FALSE);
+ closed_log_tables= closed_log_tables | log_type;
}
// Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 4dcbf9af4a0..dcb4152f64f 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -261,6 +261,8 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
TABLE *table= insert_table_list->table;
my_bool timestamp_mark;
+ LINT_INIT(timestamp_mark);
+
if (table->timestamp_field)
{
/*
@@ -1699,7 +1701,7 @@ static int
write_delayed(THD *thd,TABLE *table, enum_duplicates duplic,
LEX_STRING query, bool ignore, bool log_on)
{
- delayed_row *row;
+ delayed_row *row= 0;
delayed_insert *di=thd->di;
const Discrete_interval *forced_auto_inc;
DBUG_ENTER("write_delayed");
@@ -2306,14 +2308,18 @@ bool delayed_insert::handle_inserts(void)
DBUG_RETURN(0);
err:
- DBUG_EXECUTE("error", max_rows= 0;);
+#ifndef DBUG_OFF
+ max_rows= 0; // For DBUG output
+#endif
/* Remove all not used rows */
while ((row=rows.get()))
{
delete row;
thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
stacked_inserts--;
- DBUG_EXECUTE("error", max_rows++;);
+#ifndef DBUG_OFF
+ max_rows++;
+#endif
}
DBUG_PRINT("error", ("dropped %lu rows after an error", max_rows));
thread_safe_increment(delayed_insert_errors, &LOCK_delayed_status);
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index dd358492d0d..c35ef4079d3 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -151,7 +151,6 @@ void lex_start(THD *thd, const uchar *buf, uint length)
lex->safe_to_cache_query= 1;
lex->time_zone_tables_used= 0;
lex->leaf_tables_insert= 0;
- lex->variables_used= 0;
lex->empty_field_list_on_rset= 0;
lex->select_lex.select_number= 1;
lex->next_state=MY_LEX_START;
@@ -1644,9 +1643,18 @@ void Query_tables_list::reset_query_tables_list(bool init)
query_tables_last= &query_tables;
query_tables_own_last= 0;
if (init)
- hash_init(&sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0);
+ {
+ /*
+ We delay real initialization of hash (and therefore related
+ memory allocation) until first insertion into this hash.
+ */
+ hash_clear(&sroutines);
+ }
else if (sroutines.records)
+ {
+ /* Non-zero sroutines.records means that hash was initialized. */
my_hash_reset(&sroutines);
+ }
sroutines_list.empty();
sroutines_list_own_last= sroutines_list.next;
sroutines_list_own_elements= 0;
@@ -2142,6 +2150,28 @@ void st_lex::restore_backup_query_tables_list(Query_tables_list *backup)
/*
+ Checks for usage of routines and/or tables in a parsed statement
+
+ SYNOPSIS
+ st_lex:table_or_sp_used()
+
+ RETURN
+ FALSE No routines and tables used
+ TRUE Either or both routines and tables are used.
+*/
+
+bool st_lex::table_or_sp_used()
+{
+ DBUG_ENTER("table_or_sp_used");
+
+ if (sroutines.records || query_tables)
+ DBUG_RETURN(TRUE);
+
+ DBUG_RETURN(FALSE);
+}
+
+
+/*
Do end-of-prepare fixup for list of tables and their merge-VIEWed tables
SYNOPSIS
@@ -2208,6 +2238,7 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds,
}
}
+
/*
There are st_select_lex::add_table_to_list &
st_select_lex::set_lock_for_tables are in sql_parse.cc
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 1815774526f..7e09675cb0a 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -792,7 +792,11 @@ public:
0 - indicates that this query does not need prelocking.
*/
TABLE_LIST **query_tables_own_last;
- /* Set of stored routines called by statement. */
+ /*
+ Set of stored routines called by statement.
+ (Note that we use lazy-initialization for this hash).
+ */
+ enum { START_SROUTINES_HASH_SIZE= 16 };
HASH sroutines;
/*
List linking elements of 'sroutines' set. Allows you to add new elements
@@ -867,6 +871,25 @@ public:
};
+/*
+ st_parsing_options contains the flags for constructions that are
+ allowed in the current statement.
+*/
+
+struct st_parsing_options
+{
+ bool allows_variable;
+ bool allows_select_into;
+ bool allows_select_procedure;
+ bool allows_derived;
+
+ st_parsing_options()
+ : allows_variable(TRUE), allows_select_into(TRUE),
+ allows_select_procedure(TRUE), allows_derived(TRUE)
+ {}
+};
+
+
/* The state of the lex parsing. This is saved in the THD struct */
typedef struct st_lex : public Query_tables_list
@@ -1023,7 +1046,7 @@ typedef struct st_lex : public Query_tables_list
bool stmt_prepare_mode;
bool safe_to_cache_query;
bool subqueries, ignore;
- bool variables_used;
+ st_parsing_options parsing_options;
ALTER_INFO alter_info;
/* Prepared statements SQL syntax:*/
LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */
@@ -1180,6 +1203,8 @@ typedef struct st_lex : public Query_tables_list
void reset_n_backup_query_tables_list(Query_tables_list *backup);
void restore_backup_query_tables_list(Query_tables_list *backup);
+
+ bool table_or_sp_used();
} LEX;
struct st_lex_local: public st_lex
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index fc7ed7ff673..d88478b9702 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1214,7 +1214,14 @@ pthread_handler_t handle_one_connection(void *arg)
{
execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
if (thd->query_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", net->last_error);
+ }
thd->proc_info=0;
thd->set_time();
thd->init_for_queries();
@@ -3075,11 +3082,6 @@ end_with_restore_list:
case SQLCOM_ALTER_TABLE:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
-#if defined(DONT_ALLOW_SHOW_COMMANDS)
- my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
- MYF(0)); /* purecov: inspected */
- goto error;
-#else
{
ulong priv=0;
ulong priv_needed= ALTER_ACL;
@@ -3148,7 +3150,6 @@ end_with_restore_list:
lex->ignore, &lex->alter_info, 1);
break;
}
-#endif /*DONT_ALLOW_SHOW_COMMANDS*/
case SQLCOM_RENAME_TABLE:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
@@ -3237,6 +3238,7 @@ end_with_restore_list:
/* ! we write after unlocking the table */
if (!res && !lex->no_write_to_binlog)
{
+ /* Presumably, REPAIR and binlog writing doesn't require synchronization */
if (mysql_bin_log.is_open())
{
thd->clear_error(); // No binlog error generated
@@ -3269,6 +3271,7 @@ end_with_restore_list:
/* ! we write after unlocking the table */
if (!res && !lex->no_write_to_binlog)
{
+ /* Presumably, ANALYZE and binlog writing doesn't require synchronization */
if (mysql_bin_log.is_open())
{
thd->clear_error(); // No binlog error generated
@@ -3293,6 +3296,7 @@ end_with_restore_list:
/* ! we write after unlocking the table */
if (!res && !lex->no_write_to_binlog)
{
+ /* Presumably, OPTIMIZE and binlog writing doesn't require synchronization */
if (mysql_bin_log.is_open())
{
thd->clear_error(); // No binlog error generated
@@ -3394,9 +3398,17 @@ end_with_restore_list:
res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
lex->update_list, lex->value_list,
lex->duplicates, lex->ignore);
- /* do not show last insert ID if VIEW does not have auto_inc */
+
+ /*
+ If we have inserted into a VIEW, and the base table has
+ AUTO_INCREMENT column, but this column is not accessible through
+ a view, then we should restore LAST_INSERT_ID to the value it
+ had before the statement.
+ */
if (first_table->view && !first_table->contain_auto_increment)
- thd->first_successful_insert_id_in_cur_stmt= 0;
+ thd->first_successful_insert_id_in_cur_stmt=
+ thd->first_successful_insert_id_in_prev_stmt;
+
break;
}
case SQLCOM_REPLACE_SELECT:
@@ -3456,9 +3468,17 @@ end_with_restore_list:
/* revert changes for SP */
select_lex->table_list.first= (byte*) first_table;
}
- /* do not show last insert ID if VIEW does not have auto_inc */
+
+ /*
+ If we have inserted into a VIEW, and the base table has
+ AUTO_INCREMENT column, but this column is not accessible through
+ a view, then we should restore LAST_INSERT_ID to the value it
+ had before the statement.
+ */
if (first_table->view && !first_table->contain_auto_increment)
- thd->first_successful_insert_id_in_cur_stmt= 0;
+ thd->first_successful_insert_id_in_cur_stmt=
+ thd->first_successful_insert_id_in_prev_stmt;
+
break;
}
case SQLCOM_TRUNCATE:
@@ -3580,6 +3600,7 @@ end_with_restore_list:
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
thd->options|= OPTION_KEEP_LOG;
}
+ /* DDL and binlog write order protected by LOCK_open */
res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
lex->drop_temporary);
}
@@ -3890,6 +3911,12 @@ end_with_restore_list:
case SQLCOM_ALTER_EVENT:
{
DBUG_ASSERT(lex->event_parse_data);
+ if (lex->table_or_sp_used())
+ {
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
+ "function calls as part of this statement");
+ break;
+ }
switch (lex->sql_command) {
case SQLCOM_CREATE_EVENT:
res= Events::get_instance()->
@@ -3979,13 +4006,9 @@ end_with_restore_list:
break;
if (end_active_trans(thd))
goto error;
+ /* Conditionally writes to binlog */
if (!(res= mysql_create_user(thd, lex->users_list)))
- {
- if (mysql_bin_log.is_open())
- thd->binlog_query(THD::MYSQL_QUERY_TYPE,
- thd->query, thd->query_length, FALSE, FALSE);
send_ok(thd);
- }
break;
}
case SQLCOM_DROP_USER:
@@ -3995,15 +4018,9 @@ end_with_restore_list:
break;
if (end_active_trans(thd))
goto error;
+ /* Conditionally writes to binlog */
if (!(res= mysql_drop_user(thd, lex->users_list)))
- {
- if (mysql_bin_log.is_open())
- {
- thd->binlog_query(THD::MYSQL_QUERY_TYPE,
- thd->query, thd->query_length, FALSE, FALSE);
- }
send_ok(thd);
- }
break;
}
case SQLCOM_RENAME_USER:
@@ -4013,15 +4030,9 @@ end_with_restore_list:
break;
if (end_active_trans(thd))
goto error;
+ /* Conditionally writes to binlog */
if (!(res= mysql_rename_user(thd, lex->users_list)))
- {
- if (mysql_bin_log.is_open())
- {
- thd->binlog_query(THD::MYSQL_QUERY_TYPE,
- thd->query, thd->query_length, FALSE, FALSE);
- }
send_ok(thd);
- }
break;
}
case SQLCOM_REVOKE_ALL:
@@ -4029,15 +4040,9 @@ end_with_restore_list:
if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
check_global_access(thd,CREATE_USER_ACL))
break;
+ /* Conditionally writes to binlog */
if (!(res = mysql_revoke_all(thd, lex->users_list)))
- {
- if (mysql_bin_log.is_open())
- {
- thd->binlog_query(THD::MYSQL_QUERY_TYPE,
- thd->query, thd->query_length, FALSE, FALSE);
- }
send_ok(thd);
- }
break;
}
case SQLCOM_REVOKE:
@@ -4096,6 +4101,7 @@ end_with_restore_list:
check_grant_routine(thd, grants | GRANT_ACL, all_tables,
lex->type == TYPE_ENUM_PROCEDURE, 0))
goto error;
+ /* Conditionally writes to binlog */
res= mysql_routine_grant(thd, all_tables,
lex->type == TYPE_ENUM_PROCEDURE,
lex->users_list, grants,
@@ -4108,16 +4114,11 @@ end_with_restore_list:
GRANT_ACL),
all_tables, 0, UINT_MAX, 0))
goto error;
+ /* Conditionally writes to binlog */
res= mysql_table_grant(thd, all_tables, lex->users_list,
lex->columns, lex->grant,
lex->sql_command == SQLCOM_REVOKE);
}
- if (!res && mysql_bin_log.is_open())
- {
- thd->clear_error();
- thd->binlog_query(THD::MYSQL_QUERY_TYPE,
- thd->query, thd->query_length, FALSE, FALSE);
- }
}
else
{
@@ -4128,16 +4129,11 @@ end_with_restore_list:
goto error;
}
else
+ /* Conditionally writes to binlog */
res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
lex->sql_command == SQLCOM_REVOKE);
if (!res)
{
- if (mysql_bin_log.is_open())
- {
- thd->clear_error();
- thd->binlog_query(THD::MYSQL_QUERY_TYPE,
- thd->query, thd->query_length, FALSE, FALSE);
- }
if (lex->sql_command == SQLCOM_GRANT)
{
List_iterator <LEX_USER> str_list(lex->users_list);
@@ -4175,6 +4171,7 @@ end_with_restore_list:
We WANT to write and we CAN write.
! we write after unlocking the table.
*/
+ /* Presumably, RESET and binlog writing doesn't require synchronization */
if (!lex->no_write_to_binlog && write_to_binlog)
{
if (mysql_bin_log.is_open())
@@ -4191,6 +4188,13 @@ end_with_restore_list:
{
Item *it= (Item *)lex->value_list.head();
+ if (lex->table_or_sp_used())
+ {
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
+ "function calls as part of this statement");
+ break;
+ }
+
if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
{
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
@@ -4633,7 +4637,10 @@ end_with_restore_list:
send_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 :
thd->row_count_func));
else
+ {
+ DBUG_ASSERT(thd->net.report_error == 1 || thd->killed);
goto error; // Substatement should already have sent error
+ }
}
break;
}
@@ -4691,20 +4698,16 @@ end_with_restore_list:
already puts on CREATE FUNCTION.
*/
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
+ /* Conditionally writes to binlog */
result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics);
else
+ /* Conditionally writes to binlog */
result= sp_update_function(thd, lex->spname, &lex->sp_chistics);
}
}
switch (result)
{
case SP_OK:
- if (mysql_bin_log.is_open())
- {
- thd->clear_error();
- thd->binlog_query(THD::MYSQL_QUERY_TYPE,
- thd->query, thd->query_length, FALSE, FALSE);
- }
send_ok(thd);
break;
case SP_KEY_NOT_FOUND:
@@ -4749,9 +4752,11 @@ end_with_restore_list:
}
#endif
if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
- result= sp_drop_procedure(thd, lex->spname);
+ /* Conditionally writes to binlog */
+ result= sp_drop_procedure(thd, lex->spname); /* Conditionally writes to binlog */
else
- result= sp_drop_function(thd, lex->spname);
+ /* Conditionally writes to binlog */
+ result= sp_drop_function(thd, lex->spname); /* Conditionally writes to binlog */
}
else
{
@@ -4764,6 +4769,8 @@ end_with_restore_list:
{
if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0, 0))
goto error;
+
+ /* Does NOT write to binlog */
if (!(res = mysql_drop_function(thd, &lex->spname->m_name)))
{
send_ok(thd);
@@ -4784,12 +4791,6 @@ end_with_restore_list:
switch (result)
{
case SP_OK:
- if (mysql_bin_log.is_open())
- {
- thd->clear_error();
- thd->binlog_query(THD::MYSQL_QUERY_TYPE,
- thd->query, thd->query_length, FALSE, FALSE);
- }
send_ok(thd);
break;
case SP_KEY_NOT_FOUND:
@@ -4888,49 +4889,7 @@ end_with_restore_list:
if (end_active_trans(thd))
goto error;
- if (!(res= mysql_create_view(thd, thd->lex->create_view_mode)) &&
- mysql_bin_log.is_open())
- {
- String buff;
- const LEX_STRING command[3]=
- {{ C_STRING_WITH_LEN("CREATE ") },
- { C_STRING_WITH_LEN("ALTER ") },
- { C_STRING_WITH_LEN("CREATE OR REPLACE ") }};
- thd->clear_error();
-
- buff.append(command[thd->lex->create_view_mode].str,
- command[thd->lex->create_view_mode].length);
- view_store_options(thd, first_table, &buff);
- buff.append(STRING_WITH_LEN("VIEW "));
- /* Test if user supplied a db (ie: we did not use thd->db) */
- if (first_table->db && first_table->db[0] &&
- (thd->db == NULL || strcmp(first_table->db, thd->db)))
- {
- append_identifier(thd, &buff, first_table->db,
- first_table->db_length);
- buff.append('.');
- }
- append_identifier(thd, &buff, first_table->table_name,
- first_table->table_name_length);
- if (lex->view_list.elements)
- {
- List_iterator_fast<LEX_STRING> names(lex->view_list);
- LEX_STRING *name;
- int i;
-
- for (i= 0; name= names++; i++)
- {
- buff.append(i ? ", " : "(");
- append_identifier(thd, &buff, name->str, name->length);
- }
- buff.append(')');
- }
- buff.append(STRING_WITH_LEN(" AS "));
- buff.append(first_table->source.str, first_table->source.length);
-
- thd->binlog_query(THD::STMT_QUERY_TYPE,
- buff.ptr(), buff.length(), FALSE, FALSE);
- }
+ res= mysql_create_view(thd, first_table, thd->lex->create_view_mode);
break;
}
case SQLCOM_DROP_VIEW:
@@ -4938,13 +4897,8 @@ end_with_restore_list:
if (check_table_access(thd, DROP_ACL, all_tables, 0) ||
end_active_trans(thd))
goto error;
- if (!(res= mysql_drop_view(thd, first_table, thd->lex->drop_mode)) &&
- mysql_bin_log.is_open())
- {
- thd->clear_error();
- thd->binlog_query(THD::STMT_QUERY_TYPE,
- thd->query, thd->query_length, FALSE, FALSE);
- }
+ /* Conditionally writes to binlog. */
+ res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
break;
}
case SQLCOM_CREATE_TRIGGER:
@@ -4952,6 +4906,7 @@ end_with_restore_list:
if (end_active_trans(thd))
goto error;
+ /* Conditionally writes to binlog. */
res= mysql_create_or_drop_trigger(thd, all_tables, 1);
/* We don't care about trigger body after this point */
@@ -4964,6 +4919,7 @@ end_with_restore_list:
if (end_active_trans(thd))
goto error;
+ /* Conditionally writes to binlog. */
res= mysql_create_or_drop_trigger(thd, all_tables, 0);
break;
}
@@ -6088,14 +6044,19 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
DBUG_ASSERT(thd->net.report_error);
DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
thd->is_fatal_error));
- query_cache_abort(&thd->net);
- lex->unit.cleanup();
+
+ /*
+ The first thing we do after parse error is freeing sp_head to
+ ensure that we have restored original memroot.
+ */
if (lex->sphead)
{
/* Clean up after failed stored procedure/function */
delete lex->sphead;
lex->sphead= NULL;
}
+ query_cache_abort(&thd->net);
+ lex->unit.cleanup();
}
thd->proc_info="freeing items";
thd->end_statement();
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 34fb447792e..7a0a143dcc9 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -502,7 +502,7 @@ void plugin_deinitialize(struct st_plugin_int *plugin)
if ((*plugin_type_deinitialize[plugin->plugin->type])(plugin))
{
sql_print_error("Plugin '%s' of type %s failed deinitialization",
- plugin->name.str, plugin_type_names[plugin->plugin->type]);
+ plugin->name.str, plugin_type_names[plugin->plugin->type].str);
}
}
else if (plugin->plugin->deinit)
@@ -562,7 +562,7 @@ static int plugin_initialize(struct st_plugin_int *plugin)
if ((*plugin_type_initialize[plugin->plugin->type])(plugin))
{
sql_print_error("Plugin '%s' registration as a %s failed.",
- plugin->name.str, plugin_type_names[plugin->plugin->type]);
+ plugin->name.str, plugin_type_names[plugin->plugin->type].str);
goto err;
}
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 63a129918d0..013c3a17fd6 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -2287,6 +2287,14 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
#endif
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
+
+ /*
+ If the free_list is not empty, we'll wrongly free some externally
+ allocated items when cleaning up after validation of the prepared
+ statement.
+ */
+ DBUG_ASSERT(thd->free_list == NULL);
+
error= stmt->execute(&expanded_query,
test(flags & (ulong) CURSOR_TYPE_READ_ONLY));
if (!(specialflag & SPECIAL_NO_PRIOR))
@@ -2349,6 +2357,13 @@ void mysql_sql_stmt_execute(THD *thd)
DBUG_PRINT("info",("stmt: %p", stmt));
+ /*
+ If the free_list is not empty, we'll wrongly free some externally
+ allocated items when cleaning up after validation of the prepared
+ statement.
+ */
+ DBUG_ASSERT(thd->free_list == NULL);
+
if (stmt->set_params_from_vars(stmt, lex->prepared_stmt_params,
&expanded_query))
goto set_params_data_err;
@@ -2811,7 +2826,19 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
error= MYSQLparse((void *)thd) || thd->is_fatal_error ||
thd->net.report_error || init_param_array(this);
+
+ /*
+ The first thing we do after parse error is freeing sp_head to
+ ensure that we have restored original memroot.
+ */
+ if (error && lex->sphead)
+ {
+ delete lex->sphead;
+ lex->sphead= NULL;
+ }
+
lex->safe_to_cache_query= FALSE;
+
/*
While doing context analysis of the query (in check_prepared_statement)
we allocate a lot of additional memory: for open tables, JOINs, derived
@@ -2827,16 +2854,17 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
external changes when cleaning up after validation.
*/
DBUG_ASSERT(thd->change_list.is_empty());
- /*
- If the free_list is not empty, we'll wrongly free some externally
- allocated items when cleaning up after validation of the prepared
- statement.
+
+ /*
+ The only case where we should have items in the thd->free_list is
+ after stmt->set_params_from_vars(), which may in some cases create
+ Item_null objects.
*/
- DBUG_ASSERT(thd->free_list == NULL);
if (error == 0)
error= check_prepared_statement(this, name.str != 0);
+ /* Free sp_head if check_prepared_statement() failed. */
if (error && lex->sphead)
{
delete lex->sphead;
@@ -2930,7 +2958,13 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
allocated items when cleaning up after execution of this statement.
*/
DBUG_ASSERT(thd->change_list.is_empty());
- DBUG_ASSERT(thd->free_list == NULL);
+
+ /*
+ The only case where we should have items in the thd->free_list is
+ after stmt->set_params_from_vars(), which may in some cases create
+ Item_null objects.
+ */
+
thd->set_n_backup_statement(this, &stmt_backup);
if (expanded_query->length() &&
alloc_query(thd, (char*) expanded_query->ptr(),
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index bf2e2d506cd..cd2c3c348d4 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -35,7 +35,10 @@ static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list);
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
{
bool error= 1;
- TABLE_LIST *ren_table= 0;
+ TABLE_LIST *ren_table= 0, *new_table;
+ int to_table;
+ char *rename_log_table[2]= {NULL, NULL};
+ int disable_logs= 0;
DBUG_ENTER("mysql_rename_tables");
/*
@@ -52,6 +55,96 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
if (wait_if_global_read_lock(thd,0,1))
DBUG_RETURN(1);
+
+ if (logger.is_log_table_enabled(QUERY_LOG_GENERAL) ||
+ logger.is_log_table_enabled(QUERY_LOG_SLOW))
+ {
+
+ /*
+ Rules for rename of a log table:
+
+ IF 1. Log tables are enabled
+ AND 2. Rename operates on the log table and nothing is being
+ renamed to the log table.
+ DO 3. Throw an error message.
+ ELSE 4. Perform rename.
+ */
+
+ for (to_table= 0, ren_table= table_list; ren_table;
+ to_table= 1 - to_table, ren_table= ren_table->next_local)
+ {
+ int log_table_rename= 0;
+
+ if ((log_table_rename=
+ check_if_log_table(ren_table->db_length, ren_table->db,
+ ren_table->table_name_length,
+ ren_table->table_name, 1)))
+ {
+ /*
+ Log table encoutered we will need to disable and lock logs
+ for duration of rename.
+ */
+ disable_logs= TRUE;
+
+ /*
+ as we use log_table_rename as an array index, we need it to start
+ with 0, while QUERY_LOG_SLOW == 1 and QUERY_LOG_GENERAL == 2.
+ So, we shift the value to start with 0;
+ */
+ log_table_rename--;
+ if (rename_log_table[log_table_rename])
+ {
+ if (to_table)
+ rename_log_table[log_table_rename]= NULL;
+ else
+ {
+ /*
+ Two renames of "log_table TO" w/o rename "TO log_table" in
+ between.
+ */
+ my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), ren_table->table_name,
+ ren_table->table_name);
+ DBUG_RETURN(1);
+ }
+ }
+ else
+ {
+ if (to_table)
+ {
+ /*
+ Attempt to rename a table TO log_table w/o renaming
+ log_table TO some table.
+ */
+ my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), ren_table->table_name,
+ ren_table->table_name);
+ DBUG_RETURN(1);
+ }
+ else
+ {
+ /* save the name of the log table to report an error */
+ rename_log_table[log_table_rename]= ren_table->table_name;
+ }
+ }
+ }
+ }
+ if (rename_log_table[0] || rename_log_table[1])
+ {
+ if (rename_log_table[0])
+ my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), rename_log_table[0],
+ rename_log_table[0]);
+ else
+ my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), rename_log_table[1],
+ rename_log_table[1]);
+ DBUG_RETURN(1);
+ }
+
+ if (disable_logs)
+ {
+ logger.lock();
+ logger.tmp_close_log_tables(thd);
+ }
+ }
+
VOID(pthread_mutex_lock(&LOCK_open));
if (lock_table_names(thd, table_list))
goto err;
@@ -95,6 +188,13 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
err:
pthread_mutex_unlock(&LOCK_open);
+ /* enable logging back if needed */
+ if (disable_logs)
+ {
+ if (logger.reopen_log_tables())
+ error= TRUE;
+ logger.unlock();
+ }
start_waiting_global_read_lock(thd);
DBUG_RETURN(error);
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index e5cbe0180ad..d40d9f16bb5 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2207,7 +2207,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
continue;
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
- bool no_partitions_used= table->no_partitions_used;
+ const bool no_partitions_used= table->no_partitions_used;
#else
const bool no_partitions_used= FALSE;
#endif
@@ -3605,7 +3605,7 @@ best_access_path(JOIN *join,
double best= DBL_MAX;
double best_time= DBL_MAX;
double records= DBL_MAX;
- table_map best_ref_depends_map;
+ table_map best_ref_depends_map= 0;
double tmp;
ha_rows rec;
@@ -10106,7 +10106,8 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
enum_nested_loop_state error= NESTED_LOOP_OK;
JOIN_TAB *join_tab;
DBUG_ENTER("do_select");
-
+ LINT_INIT(join_tab);
+
join->procedure=procedure;
join->tmp_table= table; /* Save for easy recursion */
join->fields= fields;
@@ -10136,9 +10137,9 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
*/
if (!join->conds || join->conds->val_int())
{
- error= (*end_select)(join,join_tab,0);
+ error= (*end_select)(join, 0, 0);
if (error == NESTED_LOOP_OK || error == NESTED_LOOP_QUERY_LIMIT)
- error= (*end_select)(join,join_tab,1);
+ error= (*end_select)(join, 0, 1);
}
else if (join->send_row_on_empty_set())
{
@@ -10694,7 +10695,7 @@ int report_error(TABLE *table, int error)
*/
if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
sql_print_error("Got error %d when reading table '%s'",
- error, table->s->path);
+ error, table->s->path.str);
table->file->print_error(error,MYF(0));
return 1;
}
@@ -11791,7 +11792,7 @@ part_of_refkey(TABLE *table,Field *field)
for (uint part=0 ; part < ref_parts ; part++,key_part++)
if (field->eq(key_part->field) &&
- !(key_part->key_part_flag & HA_PART_KEY_SEG))
+ !(key_part->key_part_flag & (HA_PART_KEY_SEG | HA_NULL_PART)))
return table->reginfo.join_tab->ref.items[part];
}
return (Item*) 0;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 34f022d9478..c39cdfa6d7e 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1664,7 +1664,9 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
"%s:%u", tmp_sctx->host_or_ip, tmp->peer_port);
}
else
- thd_info->host= thd->strdup(tmp_sctx->host_or_ip);
+ thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
+ tmp_sctx->host_or_ip :
+ tmp_sctx->host ? tmp_sctx->host : "");
if ((thd_info->db=tmp->db)) // Safe test
thd_info->db=thd->strdup(thd_info->db);
thd_info->command=(int) tmp->command;
@@ -5260,7 +5262,7 @@ ST_FIELD_INFO columns_fields_info[]=
{"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
{"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Field"},
{"ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
- {"COLUMN_DEFAULT", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Default"},
+ {"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, MYSQL_TYPE_STRING, 0, 1, "Default"},
{"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null"},
{"DATA_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
{"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index c024ee8ddbe..511d9fa6677 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1639,11 +1639,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
/* Disable drop of enabled log tables */
if (share && share->log_table &&
- ((!my_strcasecmp(system_charset_info, table->table_name,
- "general_log") && opt_log &&
- logger.is_general_log_table_enabled()) ||
- (!my_strcasecmp(system_charset_info, table->table_name, "slow_log")
- && opt_slow_log && logger.is_slow_log_table_enabled())))
+ check_if_log_table(table->db_length, table->db,
+ table->table_name_length, table->table_name, 1))
{
my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP");
DBUG_RETURN(1);
@@ -4043,7 +4040,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
Item *item;
Protocol *protocol= thd->protocol;
LEX *lex= thd->lex;
- int result_code;
+ int result_code, disable_logs= 0;
DBUG_ENTER("mysql_admin_table");
if (end_active_trans(thd))
@@ -4088,6 +4085,23 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
thd->no_warnings_for_error= no_warnings_for_error;
if (view_operator_func == NULL)
table->required_type=FRMTYPE_TABLE;
+
+ /*
+ If we want to perform an admin operation on the log table
+ (E.g. rename) and lock_type >= TL_READ_NO_INSERT disable
+ log tables
+ */
+
+ if (check_if_log_table(table->db_length, table->db,
+ table->table_name_length,
+ table->table_name, 1) &&
+ lock_type >= TL_READ_NO_INSERT)
+ {
+ disable_logs= 1;
+ logger.lock();
+ logger.tmp_close_log_tables(thd);
+ }
+
open_and_lock_tables(thd, table);
thd->no_warnings_for_error= 0;
table->next_global= save_next_global;
@@ -4404,11 +4418,24 @@ send_result_message:
}
send_eof(thd);
+ if (disable_logs)
+ {
+ if (logger.reopen_log_tables())
+ my_error(ER_CANT_ACTIVATE_LOG, MYF(0));
+ logger.unlock();
+ }
DBUG_RETURN(FALSE);
err:
ha_autocommit_or_rollback(thd, 1);
close_thread_tables(thd); // Shouldn't be needed
+ /* enable logging back if needed */
+ if (disable_logs)
+ {
+ if (logger.reopen_log_tables())
+ my_error(ER_CANT_ACTIVATE_LOG, MYF(0));
+ logger.unlock();
+ }
if (table)
table->table=0;
DBUG_RETURN(TRUE);
@@ -4573,17 +4600,18 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
{
TABLE *tmp_table;
char src_path[FN_REFLEN], dst_path[FN_REFLEN], tmp_path[FN_REFLEN];
+ char src_table_name_buff[FN_REFLEN], src_db_name_buff[FN_REFLEN];
uint dst_path_length;
char *db= table->db;
char *table_name= table->table_name;
char *src_db;
char *src_table= table_ident->table.str;
int err;
- bool res= TRUE;
+ bool res= TRUE, unlock_dst_table= FALSE;
enum legacy_db_type not_used;
HA_CREATE_INFO *create_info;
- TABLE_LIST src_tables_list;
+ TABLE_LIST src_tables_list, dst_tables_list;
DBUG_ENTER("mysql_create_like_table");
if (!(create_info= copy_create_info(lex_create_info)))
@@ -4609,13 +4637,6 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
DBUG_RETURN(-1);
}
- bzero((gptr)&src_tables_list, sizeof(src_tables_list));
- src_tables_list.db= src_db;
- src_tables_list.table_name= src_table;
-
- if (lock_and_wait_for_table_name(thd, &src_tables_list))
- goto err;
-
if ((tmp_table= find_temporary_table(thd, src_db, src_table)))
strxmov(src_path, tmp_table->s->path.str, reg_ext, NullS);
else
@@ -4642,6 +4663,34 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
goto err;
}
+ if (lower_case_table_names)
+ {
+ if (src_db)
+ {
+ strmake(src_db_name_buff, src_db,
+ min(sizeof(src_db_name_buff) - 1, table_ident->db.length));
+ my_casedn_str(files_charset_info, src_db_name_buff);
+ src_db= src_db_name_buff;
+ }
+ if (src_table)
+ {
+ strmake(src_table_name_buff, src_table,
+ min(sizeof(src_table_name_buff) - 1, table_ident->table.length));
+ my_casedn_str(files_charset_info, src_table_name_buff);
+ src_table= src_table_name_buff;
+ }
+ }
+
+ bzero((gptr)&src_tables_list, sizeof(src_tables_list));
+ src_tables_list.db= src_db;
+ src_tables_list.db_length= table_ident->db.length;
+ src_tables_list.lock_type= TL_READ;
+ src_tables_list.table_name= src_table;
+ src_tables_list.alias= src_table;
+
+ if (simple_open_n_lock_tables(thd, &src_tables_list))
+ DBUG_RETURN(TRUE);
+
/*
Validate the destination table
@@ -4745,17 +4794,29 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
char buf[2048];
String query(buf, sizeof(buf), system_charset_info);
query.length(0); // Have to zero it since constructor doesn't
- TABLE *table_ptr;
- int error;
+ uint counter;
/*
- Let's open and lock the table: it will be closed (and
- unlocked) by close_thread_tables() at the end of the
- statement anyway.
- */
- if (!(table_ptr= open_ltable(thd, table, TL_READ_NO_INSERT)))
+ Here we open the destination table. This is needed for
+ store_create_info() to work. The table will be closed
+ by close_thread_tables() at the end of the statement.
+ */
+ if (open_tables(thd, &table, &counter, 0))
goto err;
+ bzero((gptr)&dst_tables_list, sizeof(dst_tables_list));
+ dst_tables_list.db= table->db;
+ dst_tables_list.table_name= table->table_name;
+
+ /*
+ lock destination table name, to make sure that nobody
+ can drop/alter the table while we execute store_create_info()
+ */
+ if (lock_and_wait_for_table_name(thd, &dst_tables_list))
+ goto err;
+ else
+ unlock_dst_table= TRUE;
+
int result= store_create_info(thd, table, &query, create_info);
DBUG_ASSERT(result == 0); // store_create_info() always return 0
@@ -4788,9 +4849,12 @@ table_exists:
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
err:
- pthread_mutex_lock(&LOCK_open);
- unlock_table_name(thd, &src_tables_list);
- pthread_mutex_unlock(&LOCK_open);
+ if (unlock_dst_table)
+ {
+ pthread_mutex_lock(&LOCK_open);
+ unlock_table_name(thd, &dst_tables_list);
+ pthread_mutex_unlock(&LOCK_open);
+ }
DBUG_RETURN(res);
}
@@ -5179,33 +5243,23 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
LINT_INIT(index_add_buffer);
LINT_INIT(index_drop_buffer);
- if (table_list && table_list->db &&
- !my_strcasecmp(system_charset_info, table_list->db, "mysql") &&
- table_list->table_name)
+ if (table_list && table_list->db && table_list->table_name)
{
- enum enum_table_kind { NOT_LOG_TABLE= 1, GENERAL_LOG, SLOW_LOG }
- table_kind= NOT_LOG_TABLE;
+ int table_kind= 0;
- if (!my_strcasecmp(system_charset_info, table_list->table_name,
- "general_log"))
- table_kind= GENERAL_LOG;
- else
- if (!my_strcasecmp(system_charset_info, table_list->table_name,
- "slow_log"))
- table_kind= SLOW_LOG;
+ table_kind= check_if_log_table(table_list->db_length, table_list->db,
+ table_list->table_name_length,
+ table_list->table_name, 0);
/* Disable alter of enabled log tables */
- if ((table_kind == GENERAL_LOG && opt_log &&
- logger.is_general_log_table_enabled()) ||
- (table_kind == SLOW_LOG && opt_slow_log &&
- logger.is_slow_log_table_enabled()))
+ if (table_kind && logger.is_log_table_enabled(table_kind))
{
my_error(ER_BAD_LOG_STATEMENT, MYF(0), "ALTER");
DBUG_RETURN(TRUE);
}
/* Disable alter of log tables to unsupported engine */
- if ((table_kind == GENERAL_LOG || table_kind == SLOW_LOG) &&
+ if (table_kind &&
(lex_create_info->used_fields & HA_CREATE_USED_ENGINE) &&
(!lex_create_info->db_type || /* unknown engine */
!(lex_create_info->db_type->flags & HTON_SUPPORT_LOG_TABLES)))
@@ -5234,6 +5288,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
+ /* Conditionally writes to binlog. */
DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
alter_info->tablespace_op));
strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db,
@@ -5389,10 +5444,10 @@ view_err:
!table->s->tmp_table) // no need to touch frm
{
error=0;
+ VOID(pthread_mutex_lock(&LOCK_open));
if (new_name != table_name || new_db != db)
{
thd->proc_info="rename";
- VOID(pthread_mutex_lock(&LOCK_open));
/* Then do a 'simple' rename of the table */
error=0;
if (!access(new_name_buff,F_OK))
@@ -5415,7 +5470,6 @@ view_err:
error= -1;
}
}
- VOID(pthread_mutex_unlock(&LOCK_open));
}
if (!error)
@@ -5424,16 +5478,12 @@ view_err:
case LEAVE_AS_IS:
break;
case ENABLE:
- VOID(pthread_mutex_lock(&LOCK_open));
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
- VOID(pthread_mutex_unlock(&LOCK_open));
error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
/* COND_refresh will be signaled in close_thread_tables() */
break;
case DISABLE:
- VOID(pthread_mutex_lock(&LOCK_open));
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
- VOID(pthread_mutex_unlock(&LOCK_open));
error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
/* COND_refresh will be signaled in close_thread_tables() */
break;
@@ -5458,6 +5508,7 @@ view_err:
table->file->print_error(error, MYF(0));
error= -1;
}
+ VOID(pthread_mutex_unlock(&LOCK_open));
table_list->table=0; // For query cache
query_cache_invalidate3(thd, table_list, 0);
DBUG_RETURN(error);
@@ -6458,7 +6509,7 @@ end_temporary:
thd->some_tables_deleted=0;
DBUG_RETURN(FALSE);
- err1:
+err1:
if (new_table)
{
/* close_temporary_table() frees the new_table pointer. */
@@ -6467,7 +6518,7 @@ end_temporary:
else
VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
- err:
+err:
DBUG_RETURN(TRUE);
}
/* mysql_alter_table */
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index acb7d5b61df..fb56b7ae3b0 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -36,17 +36,17 @@ static File_option triggers_file_parameters[]=
{
{
{ C_STRING_WITH_LEN("triggers") },
- offsetof(class Table_triggers_list, definitions_list),
+ my_offsetof(class Table_triggers_list, definitions_list),
FILE_OPTIONS_STRLIST
},
{
{ C_STRING_WITH_LEN("sql_modes") },
- offsetof(class Table_triggers_list, definition_modes_list),
+ my_offsetof(class Table_triggers_list, definition_modes_list),
FILE_OPTIONS_ULLLIST
},
{
{ C_STRING_WITH_LEN("definers") },
- offsetof(class Table_triggers_list, definers_list),
+ my_offsetof(class Table_triggers_list, definers_list),
FILE_OPTIONS_STRLIST
},
{ { 0, 0 }, 0, FILE_OPTIONS_STRING }
@@ -55,7 +55,7 @@ static File_option triggers_file_parameters[]=
File_option sql_modes_parameters=
{
{ C_STRING_WITH_LEN("sql_modes") },
- offsetof(class Table_triggers_list, definition_modes_list),
+ my_offsetof(class Table_triggers_list, definition_modes_list),
FILE_OPTIONS_ULLLIST
};
@@ -276,8 +276,6 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
table->triggers->drop_trigger(thd, tables, &stmt_query));
end:
- VOID(pthread_mutex_unlock(&LOCK_open));
- start_waiting_global_read_lock(thd);
if (!result)
{
@@ -286,13 +284,16 @@ end:
thd->clear_error();
/* Such a statement can always go directly to binlog, no trans cache. */
- Query_log_event qinfo(thd, stmt_query.ptr(), stmt_query.length(), 0,
- FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ stmt_query.ptr(), stmt_query.length(), FALSE, FALSE);
}
+ }
+
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ start_waiting_global_read_lock(thd);
+ if (!result)
send_ok(thd);
- }
DBUG_RETURN(result);
}
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index cfaf21fa957..722a99eb2d1 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -694,7 +694,17 @@ bool st_select_lex_unit::change_result(select_subselect *result,
List<Item> *st_select_lex_unit::get_unit_column_types()
{
- bool is_union= test(first_select()->next_select());
+ SELECT_LEX *sl= first_select();
+ bool is_union= test(sl->next_select());
+ bool is_procedure= test(sl->join->procedure);
+
+ if (is_procedure)
+ {
+ /* Types for "SELECT * FROM t1 procedure analyse()"
+ are generated during execute */
+ return &sl->join->procedure_fields_list;
+ }
+
if (is_union)
{
@@ -702,7 +712,8 @@ List<Item> *st_select_lex_unit::get_unit_column_types()
/* Types are generated during prepare */
return &types;
}
- return &first_select()->item_list;
+
+ return &sl->item_list;
}
bool st_select_lex::cleanup()
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 7f6d935ff5e..5bf67af9271 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -212,6 +212,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
SYNOPSIS
mysql_create_view()
thd - thread handler
+ views - views to create
mode - VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE
RETURN VALUE
@@ -219,7 +220,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
TRUE Error
*/
-bool mysql_create_view(THD *thd,
+bool mysql_create_view(THD *thd, TABLE_LIST *views,
enum_view_create_mode mode)
{
LEX *lex= thd->lex;
@@ -236,25 +237,9 @@ bool mysql_create_view(THD *thd,
bool res= FALSE;
DBUG_ENTER("mysql_create_view");
- if (lex->proc_list.first ||
- lex->result)
- {
- my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), (lex->result ?
- "INTO" :
- "PROCEDURE"));
- res= TRUE;
- goto err;
- }
- if (lex->derived_tables ||
- lex->variables_used || lex->param_list.elements)
- {
- int err= (lex->derived_tables ?
- ER_VIEW_SELECT_DERIVED :
- ER_VIEW_SELECT_VARIABLE);
- my_message(err, ER(err), MYF(0));
- res= TRUE;
- goto err;
- }
+ /* This is ensured in the parser. */
+ DBUG_ASSERT(!lex->proc_list.first && !lex->result &&
+ !lex->param_list.elements && !lex->derived_tables);
if (mode != VIEW_CREATE_NEW)
{
@@ -548,6 +533,49 @@ bool mysql_create_view(THD *thd,
}
VOID(pthread_mutex_lock(&LOCK_open));
res= mysql_register_view(thd, view, mode);
+
+ if (mysql_bin_log.is_open())
+ {
+ String buff;
+ const LEX_STRING command[3]=
+ {{ C_STRING_WITH_LEN("CREATE ") },
+ { C_STRING_WITH_LEN("ALTER ") },
+ { C_STRING_WITH_LEN("CREATE OR REPLACE ") }};
+
+ buff.append(command[thd->lex->create_view_mode].str,
+ command[thd->lex->create_view_mode].length);
+ view_store_options(thd, views, &buff);
+ buff.append(STRING_WITH_LEN("VIEW "));
+ /* Test if user supplied a db (ie: we did not use thd->db) */
+ if (views->db && views->db[0] &&
+ (thd->db == NULL || strcmp(views->db, thd->db)))
+ {
+ append_identifier(thd, &buff, views->db,
+ views->db_length);
+ buff.append('.');
+ }
+ append_identifier(thd, &buff, views->table_name,
+ views->table_name_length);
+ if (lex->view_list.elements)
+ {
+ List_iterator_fast<LEX_STRING> names(lex->view_list);
+ LEX_STRING *name;
+ int i;
+
+ for (i= 0; (name= names++); i++)
+ {
+ buff.append(i ? ", " : "(");
+ append_identifier(thd, &buff, name->str, name->length);
+ }
+ buff.append(')');
+ }
+ buff.append(STRING_WITH_LEN(" AS "));
+ buff.append(views->source.str, views->source.length);
+
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ buff.ptr(), buff.length(), FALSE, FALSE);
+ }
+
VOID(pthread_mutex_unlock(&LOCK_open));
if (view->revision != 1)
query_cache_invalidate3(thd, view, 0);
@@ -582,40 +610,40 @@ static const int num_view_backups= 3;
*/
static File_option view_parameters[]=
{{{ C_STRING_WITH_LEN("query")},
- offsetof(TABLE_LIST, query),
+ my_offsetof(TABLE_LIST, query),
FILE_OPTIONS_ESTRING},
{{ C_STRING_WITH_LEN("md5")},
- offsetof(TABLE_LIST, md5),
+ my_offsetof(TABLE_LIST, md5),
FILE_OPTIONS_STRING},
{{ C_STRING_WITH_LEN("updatable")},
- offsetof(TABLE_LIST, updatable_view),
+ my_offsetof(TABLE_LIST, updatable_view),
FILE_OPTIONS_ULONGLONG},
{{ C_STRING_WITH_LEN("algorithm")},
- offsetof(TABLE_LIST, algorithm),
+ my_offsetof(TABLE_LIST, algorithm),
FILE_OPTIONS_ULONGLONG},
{{ C_STRING_WITH_LEN("definer_user")},
- offsetof(TABLE_LIST, definer.user),
+ my_offsetof(TABLE_LIST, definer.user),
FILE_OPTIONS_STRING},
{{ C_STRING_WITH_LEN("definer_host")},
- offsetof(TABLE_LIST, definer.host),
+ my_offsetof(TABLE_LIST, definer.host),
FILE_OPTIONS_STRING},
{{ C_STRING_WITH_LEN("suid")},
- offsetof(TABLE_LIST, view_suid),
+ my_offsetof(TABLE_LIST, view_suid),
FILE_OPTIONS_ULONGLONG},
{{ C_STRING_WITH_LEN("with_check_option")},
- offsetof(TABLE_LIST, with_check),
+ my_offsetof(TABLE_LIST, with_check),
FILE_OPTIONS_ULONGLONG},
{{ C_STRING_WITH_LEN("revision")},
- offsetof(TABLE_LIST, revision),
+ my_offsetof(TABLE_LIST, revision),
FILE_OPTIONS_REV},
{{ C_STRING_WITH_LEN("timestamp")},
- offsetof(TABLE_LIST, timestamp),
+ my_offsetof(TABLE_LIST, timestamp),
FILE_OPTIONS_TIMESTAMP},
{{ C_STRING_WITH_LEN("create-version")},
- offsetof(TABLE_LIST, file_version),
+ my_offsetof(TABLE_LIST, file_version),
FILE_OPTIONS_ULONGLONG},
{{ C_STRING_WITH_LEN("source")},
- offsetof(TABLE_LIST, source),
+ my_offsetof(TABLE_LIST, source),
FILE_OPTIONS_ESTRING},
{{NullS, 0}, 0,
FILE_OPTIONS_STRING}
@@ -1073,6 +1101,8 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
bool view_is_mergeable= (table->algorithm != VIEW_ALGORITHM_TMPTABLE &&
lex->can_be_merged());
TABLE_LIST *view_main_select_tables;
+ LINT_INIT(view_main_select_tables);
+
if (view_is_mergeable)
{
/*
@@ -1318,13 +1348,13 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
enum legacy_db_type not_used;
DBUG_ENTER("mysql_drop_view");
+ VOID(pthread_mutex_lock(&LOCK_open));
for (view= views; view; view= view->next_local)
{
TABLE_SHARE *share;
frm_type_enum type= FRMTYPE_ERROR;
build_table_filename(path, sizeof(path),
view->db, view->table_name, reg_ext, 0);
- VOID(pthread_mutex_lock(&LOCK_open));
if (access(path, F_OK) ||
FRMTYPE_VIEW != (type= mysql_frm_type(thd, path, &not_used)))
@@ -1336,7 +1366,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
name);
- VOID(pthread_mutex_unlock(&LOCK_open));
continue;
}
if (type == FRMTYPE_TABLE)
@@ -1353,7 +1382,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
non_existant_views.append(',');
non_existant_views.append(String(view->table_name,system_charset_info));
}
- VOID(pthread_mutex_unlock(&LOCK_open));
continue;
}
if (my_delete(path, MYF(MY_WME)))
@@ -1374,24 +1402,36 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
}
query_cache_invalidate3(thd, view, 0);
sp_cache_invalidate();
- VOID(pthread_mutex_unlock(&LOCK_open));
}
+
if (error)
{
+ VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(TRUE);
}
if (wrong_object_name)
{
+ VOID(pthread_mutex_unlock(&LOCK_open));
my_error(ER_WRONG_OBJECT, MYF(0), wrong_object_db, wrong_object_name,
"VIEW");
DBUG_RETURN(TRUE);
}
if (non_existant_views.length())
{
+ VOID(pthread_mutex_unlock(&LOCK_open));
my_error(ER_BAD_TABLE_ERROR, MYF(0), non_existant_views.c_ptr());
DBUG_RETURN(TRUE);
}
+
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
+ }
+
send_ok(thd);
+ VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_view.h b/sql/sql_view.h
index 7e54d57cfdf..fc480167216 100644
--- a/sql/sql_view.h
+++ b/sql/sql_view.h
@@ -16,7 +16,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-bool mysql_create_view(THD *thd,
+bool mysql_create_view(THD *thd, TABLE_LIST *view,
enum_view_create_mode mode);
bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index a5a9430504e..6a829171125 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -56,12 +56,17 @@ const LEX_STRING null_lex_str={0,0};
}
/* Helper for parsing "IS [NOT] truth_value" */
-inline Item *is_truth_value(Item *A, bool v1, bool v2)
+inline Item *is_truth_value(THD *thd, Item *A, bool v1, bool v2)
{
- return new Item_func_if(create_func_ifnull(A,
- new Item_int((char *) (v2 ? "TRUE" : "FALSE"), v2, 1)),
- new Item_int((char *) (v1 ? "TRUE" : "FALSE"), v1, 1),
- new Item_int((char *) (v1 ? "FALSE" : "TRUE"),!v1, 1));
+ Item *v1_t= new (thd->mem_root) Item_int((char *) (v1 ? "TRUE" : "FALSE"),
+ v1, 1);
+ Item *v1_f= new (thd->mem_root) Item_int((char *) (v1 ? "FALSE" : "TRUE"),
+ !v1, 1);
+ Item *v2_t= new (thd->mem_root) Item_int((char *) (v2 ? "TRUE" : "FALSE"),
+ v2, 1);
+ Item *ifnull= new (thd->mem_root) Item_func_ifnull(A, v2_t);
+
+ return new (thd->mem_root) Item_func_if(ifnull, v1_t, v1_f);
}
#ifndef DBUG_OFF
@@ -142,213 +147,209 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%pure_parser /* We have threads */
-%token END_OF_INPUT
+/*
+ Comments for TOKENS.
+ For each token, please include in the same line a comment that contains
+ the following tags:
+ SQL-2003-R : Reserved keyword as per SQL-2003
+ SQL-2003-N : Non Reserved keyword as per SQL-2003
+ SQL-1999-R : Reserved keyword as per SQL-1999
+ SQL-1999-N : Non Reserved keyword as per SQL-1999
+ MYSQL : MySQL extention (unspecified)
+ MYSQL-FUNC : MySQL extention, function
+ INTERNAL : Not a real token, lex optimization
+ OPERATOR : SQL operator
+ FUTURE-USE : Reserved for futur use
+
+ This makes the code grep-able, and helps maintenance.
+*/
-%token ABORT_SYM
+%token ABORT_SYM /* INTERNAL (used in lex) */
%token ACCESSIBLE_SYM
-%token ACTION
-%token ADD
-%token ADDDATE_SYM
-%token AFTER_SYM
+%token ACTION /* SQL-2003-N */
+%token ADD /* SQL-2003-R */
+%token ADDDATE_SYM /* MYSQL-FUNC */
+%token AFTER_SYM /* SQL-2003-N */
%token AGAINST
%token AGGREGATE_SYM
%token ALGORITHM_SYM
-%token ALL
-%token ALTER
+%token ALL /* SQL-2003-R */
+%token ALTER /* SQL-2003-R */
%token ANALYZE_SYM
-%token AND_AND_SYM
-%token AND_SYM
-%token ANY_SYM
-%token AS
-%token ASC
-%token ASCII_SYM
-%token ASENSITIVE_SYM
-%token AT_SYM
-%token ATAN
+%token AND_AND_SYM /* OPERATOR */
+%token AND_SYM /* SQL-2003-R */
+%token ANY_SYM /* SQL-2003-R */
+%token AS /* SQL-2003-R */
+%token ASC /* SQL-2003-N */
+%token ASCII_SYM /* MYSQL-FUNC */
+%token ASENSITIVE_SYM /* FUTURE-USE */
+%token AT_SYM /* SQL-2003-R */
%token AUTHORS_SYM
-%token AUTO_INC
%token AUTOEXTEND_SIZE_SYM
+%token AUTO_INC
%token AVG_ROW_LENGTH
-%token AVG_SYM
+%token AVG_SYM /* SQL-2003-N */
%token BACKUP_SYM
-%token BEFORE_SYM
-%token BEGIN_SYM
-%token BENCHMARK_SYM
-%token BIGINT
-%token BINARY
+%token BEFORE_SYM /* SQL-2003-N */
+%token BEGIN_SYM /* SQL-2003-R */
+%token BETWEEN_SYM /* SQL-2003-R */
+%token BIGINT /* SQL-2003-R */
+%token BINARY /* SQL-2003-R */
%token BINLOG_SYM
%token BIN_NUM
-%token BIT_AND
-%token BIT_OR
-%token BIT_SYM
-%token BIT_XOR
-%token BLOB_SYM
-%token BOOLEAN_SYM
+%token BIT_AND /* MYSQL-FUNC */
+%token BIT_OR /* MYSQL-FUNC */
+%token BIT_SYM /* MYSQL-FUNC */
+%token BIT_XOR /* MYSQL-FUNC */
+%token BLOB_SYM /* SQL-2003-R */
+%token BOOLEAN_SYM /* SQL-2003-R */
%token BOOL_SYM
-%token BOTH
+%token BOTH /* SQL-2003-R */
%token BTREE_SYM
-%token BY
+%token BY /* SQL-2003-R */
%token BYTE_SYM
%token CACHE_SYM
-%token CALL_SYM
-%token CASCADE
-%token CASCADED
-%token CAST_SYM
-%token CHAIN_SYM
+%token CALL_SYM /* SQL-2003-R */
+%token CASCADE /* SQL-2003-N */
+%token CASCADED /* SQL-2003-R */
+%token CASE_SYM /* SQL-2003-R */
+%token CAST_SYM /* SQL-2003-R */
+%token CHAIN_SYM /* SQL-2003-N */
%token CHANGE
%token CHANGED
%token CHARSET
-%token CHAR_SYM
+%token CHAR_SYM /* SQL-2003-R */
%token CHECKSUM_SYM
-%token CHECK_SYM
+%token CHECK_SYM /* SQL-2003-R */
%token CIPHER_SYM
%token CLIENT_SYM
-%token CLOSE_SYM
-%token COALESCE
+%token CLOSE_SYM /* SQL-2003-R */
+%token COALESCE /* SQL-2003-N */
%token CODE_SYM
-%token COLLATE_SYM
-%token COLLATION_SYM
+%token COLLATE_SYM /* SQL-2003-R */
+%token COLLATION_SYM /* SQL-2003-N */
%token COLUMNS
-%token COLUMN_SYM
+%token COLUMN_SYM /* SQL-2003-R */
%token COMMENT_SYM
-%token COMMITTED_SYM
-%token COMMIT_SYM
+%token COMMITTED_SYM /* SQL-2003-N */
+%token COMMIT_SYM /* SQL-2003-R */
%token COMPACT_SYM
%token COMPLETION_SYM
%token COMPRESSED_SYM
-%token CONCAT
-%token CONCAT_WS
%token CONCURRENT
-%token CONDITION_SYM
+%token CONDITION_SYM /* SQL-2003-N */
%token CONNECTION_SYM
%token CONSISTENT_SYM
-%token CONSTRAINT
-%token CONTAINS_SYM
-%token CONTINUE_SYM
+%token CONSTRAINT /* SQL-2003-R */
+%token CONTAINS_SYM /* SQL-2003-N */
+%token CONTINUE_SYM /* SQL-2003-R */
%token CONTRIBUTORS_SYM
-%token CONVERT_SYM
-%token CONVERT_TZ_SYM
-%token COUNT_SYM
-%token CREATE
-%token CROSS
-%token CUBE_SYM
-%token CURDATE
-%token CURRENT_USER
-%token CURSOR_SYM
-%token CURTIME
+%token CONVERT_SYM /* SQL-2003-N */
+%token COUNT_SYM /* SQL-2003-N */
+%token CREATE /* SQL-2003-R */
+%token CROSS /* SQL-2003-R */
+%token CUBE_SYM /* SQL-2003-R */
+%token CURDATE /* MYSQL-FUNC */
+%token CURRENT_USER /* SQL-2003-R */
+%token CURSOR_SYM /* SQL-2003-R */
+%token CURTIME /* MYSQL-FUNC */
%token DATABASE
%token DATABASES
%token DATAFILE_SYM
-%token DATA_SYM
+%token DATA_SYM /* SQL-2003-N */
%token DATETIME
-%token DATE_ADD_INTERVAL
-%token DATE_SUB_INTERVAL
-%token DATE_SYM
+%token DATE_ADD_INTERVAL /* MYSQL-FUNC */
+%token DATE_SUB_INTERVAL /* MYSQL-FUNC */
+%token DATE_SYM /* SQL-2003-R */
%token DAY_HOUR_SYM
%token DAY_MICROSECOND_SYM
%token DAY_MINUTE_SYM
%token DAY_SECOND_SYM
-%token DAY_SYM
-%token DEALLOCATE_SYM
+%token DAY_SYM /* SQL-2003-R */
+%token DEALLOCATE_SYM /* SQL-2003-R */
%token DECIMAL_NUM
-%token DECIMAL_SYM
-%token DECLARE_SYM
-%token DECODE_SYM
-%token DEFAULT
+%token DECIMAL_SYM /* SQL-2003-R */
+%token DECLARE_SYM /* SQL-2003-R */
+%token DEFAULT /* SQL-2003-R */
%token DEFINER_SYM
%token DELAYED_SYM
%token DELAY_KEY_WRITE_SYM
-%token DELETE_SYM
-%token DESC
-%token DESCRIBE
-%token DES_DECRYPT_SYM
-%token DES_ENCRYPT_SYM
+%token DELETE_SYM /* SQL-2003-R */
+%token DESC /* SQL-2003-N */
+%token DESCRIBE /* SQL-2003-R */
%token DES_KEY_FILE
-%token DETERMINISTIC_SYM
+%token DETERMINISTIC_SYM /* SQL-2003-R */
%token DIRECTORY_SYM
%token DISABLE_SYM
%token DISCARD
%token DISK_SYM
-%token DISTINCT
+%token DISTINCT /* SQL-2003-R */
%token DIV_SYM
-%token DOUBLE_SYM
+%token DOUBLE_SYM /* SQL-2003-R */
%token DO_SYM
-%token DROP
+%token DROP /* SQL-2003-R */
%token DUAL_SYM
%token DUMPFILE
%token DUPLICATE_SYM
-%token DYNAMIC_SYM
-%token EACH_SYM
+%token DYNAMIC_SYM /* SQL-2003-R */
+%token EACH_SYM /* SQL-2003-R */
+%token ELSE /* SQL-2003-R */
%token ELSEIF_SYM
-%token ELT_FUNC
%token ENABLE_SYM
%token ENCLOSED
-%token ENCODE_SYM
-%token ENCRYPT
-%token END
+%token END /* SQL-2003-R */
%token ENDS_SYM
+%token END_OF_INPUT /* INTERNAL */
%token ENGINES_SYM
%token ENGINE_SYM
%token ENUM
-%token EQ
-%token EQUAL_SYM
+%token EQ /* OPERATOR */
+%token EQUAL_SYM /* OPERATOR */
%token ERRORS
%token ESCAPED
-%token ESCAPE_SYM
-%token EVENT_SYM
+%token ESCAPE_SYM /* SQL-2003-R */
%token EVENTS_SYM
-%token EVERY_SYM
-%token EXECUTE_SYM
-%token EXISTS
+%token EVENT_SYM
+%token EVERY_SYM /* SQL-2003-N */
+%token EXECUTE_SYM /* SQL-2003-R */
+%token EXISTS /* SQL-2003-R */
%token EXIT_SYM
%token EXPANSION_SYM
-%token EXPORT_SET
%token EXTENDED_SYM
%token EXTENT_SIZE_SYM
-%token EXTRACT_SYM
-%token FALSE_SYM
+%token EXTRACT_SYM /* SQL-2003-N */
+%token FALSE_SYM /* SQL-2003-R */
%token FAST_SYM
-%token FETCH_SYM
-%token FIELD_FUNC
+%token FETCH_SYM /* SQL-2003-R */
%token FILE_SYM
-%token FIRST_SYM
+%token FIRST_SYM /* SQL-2003-N */
%token FIXED_SYM
%token FLOAT_NUM
-%token FLOAT_SYM
+%token FLOAT_SYM /* SQL-2003-R */
%token FLUSH_SYM
%token FORCE_SYM
-%token FOREIGN
-%token FORMAT_SYM
-%token FOR_SYM
-%token FOUND_SYM
+%token FOREIGN /* SQL-2003-R */
+%token FOR_SYM /* SQL-2003-R */
+%token FOUND_SYM /* SQL-2003-R */
%token FRAC_SECOND_SYM
%token FROM
-%token FROM_UNIXTIME
-%token FULL
+%token FULL /* SQL-2003-R */
%token FULLTEXT_SYM
-%token FUNCTION_SYM
-%token FUNC_ARG0
-%token FUNC_ARG1
-%token FUNC_ARG2
-%token FUNC_ARG3
+%token FUNCTION_SYM /* SQL-2003-R */
%token GE
-%token GEOMCOLLFROMTEXT
%token GEOMETRYCOLLECTION
%token GEOMETRY_SYM
-%token GEOMFROMTEXT
-%token GEOMFROMWKB
-%token GET_FORMAT
-%token GLOBAL_SYM
-%token GRANT
+%token GET_FORMAT /* MYSQL-FUNC */
+%token GLOBAL_SYM /* SQL-2003-R */
+%token GRANT /* SQL-2003-R */
%token GRANTS
-%token GREATEST_SYM
-%token GROUP
+%token GROUP /* SQL-2003-R */
%token GROUP_CONCAT_SYM
%token GROUP_UNIQUE_USERS
-%token GT_SYM
+%token GT_SYM /* OPERATOR */
%token HANDLER_SYM
%token HASH_SYM
-%token HAVING
+%token HAVING /* SQL-2003-R */
%token HELP_SYM
%token HEX_NUM
%token HIGH_PRIORITY
@@ -356,7 +357,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token HOUR_MICROSECOND_SYM
%token HOUR_MINUTE_SYM
%token HOUR_SECOND_SYM
-%token HOUR_SYM
+%token HOUR_SYM /* SQL-2003-R */
%token IDENT
%token IDENTIFIED_SYM
%token IDENT_QUOTED
@@ -367,70 +368,63 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token INDEX_SYM
%token INFILE
%token INITIAL_SIZE_SYM
-%token INNER_SYM
+%token INNER_SYM /* SQL-2003-R */
%token INNOBASE_SYM
-%token INOUT_SYM
-%token INSENSITIVE_SYM
-%token INSERT
+%token INOUT_SYM /* SQL-2003-R */
+%token INSENSITIVE_SYM /* SQL-2003-R */
+%token INSERT /* SQL-2003-R */
%token INSERT_METHOD
%token INSTALL_SYM
-%token INTERVAL_SYM
-%token INTO
-%token INT_SYM
+%token INTERVAL_SYM /* SQL-2003-R */
+%token INTO /* SQL-2003-R */
+%token INT_SYM /* SQL-2003-R */
%token INVOKER_SYM
-%token IN_SYM
-%token IS
-%token ISOLATION
+%token IN_SYM /* SQL-2003-R */
+%token IS /* SQL-2003-R */
+%token ISOLATION /* SQL-2003-R */
%token ISSUER_SYM
%token ITERATE_SYM
-%token JOIN_SYM
+%token JOIN_SYM /* SQL-2003-R */
%token KEYS
-%token KEY_SYM
%token KEY_BLOCK_SIZE
+%token KEY_SYM /* SQL-2003-N */
%token KILL_SYM
-%token LANGUAGE_SYM
-%token LAST_INSERT_ID
-%token LAST_SYM
-%token LE
-%token LEADING
-%token LEAST_SYM
+%token LANGUAGE_SYM /* SQL-2003-R */
+%token LAST_SYM /* SQL-2003-N */
+%token LE /* OPERATOR */
+%token LEADING /* SQL-2003-R */
%token LEAVES
%token LEAVE_SYM
-%token LEFT
+%token LEFT /* SQL-2003-R */
%token LESS_SYM
%token LEVEL_SYM
%token LEX_HOSTNAME
-%token LIKE
+%token LIKE /* SQL-2003-R */
%token LIMIT
%token LINEAR_SYM
-%token LINEFROMTEXT
%token LINES
%token LINESTRING
%token LIST_SYM
%token LOAD
-%token LOCAL_SYM
-%token LOCATE
-%token LOCATOR_SYM
+%token LOCAL_SYM /* SQL-2003-R */
+%token LOCATOR_SYM /* SQL-2003-N */
%token LOCKS_SYM
%token LOCK_SYM
%token LOGFILE_SYM
%token LOGS_SYM
-%token LOG_SYM
%token LONGBLOB
%token LONGTEXT
%token LONG_NUM
%token LONG_SYM
%token LOOP_SYM
%token LOW_PRIORITY
-%token LT
-%token MAKE_SET_SYM
+%token LT /* OPERATOR */
%token MASTER_CONNECT_RETRY_SYM
%token MASTER_HOST_SYM
%token MASTER_LOG_FILE_SYM
%token MASTER_LOG_POS_SYM
%token MASTER_PASSWORD_SYM
%token MASTER_PORT_SYM
-%token MASTER_POS_WAIT
%token MASTER_SERVER_ID_SYM
%token MASTER_SSL_CAPATH_SYM
%token MASTER_SSL_CA_SYM
@@ -440,134 +434,128 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token MASTER_SSL_SYM
%token MASTER_SYM
%token MASTER_USER_SYM
-%token MATCH
+%token MATCH /* SQL-2003-R */
%token MAX_CONNECTIONS_PER_HOUR
%token MAX_QUERIES_PER_HOUR
%token MAX_ROWS
%token MAX_SIZE_SYM
-%token MAX_SYM
+%token MAX_SYM /* SQL-2003-N */
%token MAX_UPDATES_PER_HOUR
%token MAX_USER_CONNECTIONS_SYM
-%token MAX_VALUE_SYM
+%token MAX_VALUE_SYM /* SQL-2003-N */
%token MEDIUMBLOB
%token MEDIUMINT
%token MEDIUMTEXT
%token MEDIUM_SYM
%token MEMORY_SYM
-%token MERGE_SYM
-%token MICROSECOND_SYM
+%token MERGE_SYM /* SQL-2003-R */
+%token MICROSECOND_SYM /* MYSQL-FUNC */
%token MIGRATE_SYM
%token MINUTE_MICROSECOND_SYM
%token MINUTE_SECOND_SYM
-%token MINUTE_SYM
+%token MINUTE_SYM /* SQL-2003-R */
%token MIN_ROWS
-%token MIN_SYM
-%token MLINEFROMTEXT
+%token MIN_SYM /* SQL-2003-N */
%token MODE_SYM
-%token MODIFIES_SYM
+%token MODIFIES_SYM /* SQL-2003-R */
%token MODIFY_SYM
-%token MOD_SYM
-%token MONTH_SYM
-%token MPOINTFROMTEXT
-%token MPOLYFROMTEXT
+%token MOD_SYM /* SQL-2003-N */
+%token MONTH_SYM /* SQL-2003-R */
%token MULTILINESTRING
%token MULTIPOINT
%token MULTIPOLYGON
%token MUTEX_SYM
-%token NAMES_SYM
-%token NAME_SYM
-%token NATIONAL_SYM
-%token NATURAL
+%token NAMES_SYM /* SQL-2003-N */
+%token NAME_SYM /* SQL-2003-N */
+%token NATIONAL_SYM /* SQL-2003-R */
+%token NATURAL /* SQL-2003-R */
%token NCHAR_STRING
-%token NCHAR_SYM
+%token NCHAR_SYM /* SQL-2003-R */
%token NDBCLUSTER_SYM
-%token NE
-%token NEW_SYM
-%token NEXT_SYM
+%token NE /* OPERATOR */
+%token NEG
+%token NEW_SYM /* SQL-2003-R */
+%token NEXT_SYM /* SQL-2003-N */
%token NODEGROUP_SYM
-%token NONE_SYM
+%token NONE_SYM /* SQL-2003-R */
%token NOT2_SYM
-%token NOT_SYM
+%token NOT_SYM /* SQL-2003-R */
%token NOW_SYM
-%token NO_SYM
+%token NO_SYM /* SQL-2003-R */
%token NO_WAIT_SYM
%token NO_WRITE_TO_BINLOG
-%token NULL_SYM
+%token NULL_SYM /* SQL-2003-R */
%token NUM
-%token NUMERIC_SYM
+%token NUMERIC_SYM /* SQL-2003-R */
%token NVARCHAR_SYM
%token OFFSET_SYM
-%token OJ_SYM
%token OLD_PASSWORD
-%token ON
+%token ON /* SQL-2003-R */
%token ONE_SHOT_SYM
%token ONE_SYM
-%token OPEN_SYM
+%token OPEN_SYM /* SQL-2003-R */
%token OPTIMIZE
-%token OPTION
+%token OPTION /* SQL-2003-N */
%token OPTIONALLY
%token OR2_SYM
-%token ORDER_SYM
-%token OR_OR_SYM
-%token OR_SYM
+%token ORDER_SYM /* SQL-2003-R */
+%token OR_OR_SYM /* OPERATOR */
+%token OR_SYM /* SQL-2003-R */
%token OUTER
%token OUTFILE
-%token OUT_SYM
+%token OUT_SYM /* SQL-2003-R */
%token PACK_KEYS_SYM
+%token PARAM_MARKER
%token PARSER_SYM
-%token PARTIAL
-%token PARTITION_SYM
+%token PARTIAL /* SQL-2003-N */
%token PARTITIONING_SYM
%token PARTITIONS_SYM
+%token PARTITION_SYM /* SQL-2003-R */
%token PASSWORD
-%token PARAM_MARKER
%token PHASE_SYM
-%token PLUGIN_SYM
%token PLUGINS_SYM
-%token POINTFROMTEXT
+%token PLUGIN_SYM
%token POINT_SYM
-%token POLYFROMTEXT
%token POLYGON
-%token POSITION_SYM
-%token PRECISION
-%token PREPARE_SYM
+%token POSITION_SYM /* SQL-2003-N */
+%token PRECISION /* SQL-2003-R */
+%token PREPARE_SYM /* SQL-2003-R */
%token PRESERVE_SYM
%token PREV_SYM
-%token PRIMARY_SYM
-%token PRIVILEGES
-%token PROCEDURE
+%token PRIMARY_SYM /* SQL-2003-R */
+%token PRIVILEGES /* SQL-2003-N */
+%token PROCEDURE /* SQL-2003-R */
%token PROCESS
%token PROCESSLIST_SYM
%token PURGE
%token QUARTER_SYM
%token QUERY_SYM
%token QUICK
-%token RAND
-%token RANGE_SYM
-%token READS_SYM
+%token RANGE_SYM /* SQL-2003-R */
+%token READS_SYM /* SQL-2003-R */
%token READ_ONLY_SYM
-%token READ_SYM
+%token READ_SYM /* SQL-2003-N */
%token READ_WRITE_SYM
-%token REAL
+%token REAL /* SQL-2003-R */
%token REBUILD_SYM
%token RECOVER_SYM
-%token REDO_BUFFER_SIZE_SYM
%token REDOFILE_SYM
+%token REDO_BUFFER_SIZE_SYM
%token REDUNDANT_SYM
-%token REFERENCES
+%token REFERENCES /* SQL-2003-R */
%token REGEXP
%token RELAY_LOG_FILE_SYM
%token RELAY_LOG_POS_SYM
%token RELAY_THREAD
-%token RELEASE_SYM
+%token RELEASE_SYM /* SQL-2003-R */
%token RELOAD
%token REMOVE_SYM
%token RENAME
%token REORGANIZE_SYM
%token REPAIR
-%token REPEATABLE_SYM
-%token REPEAT_SYM
-%token REPLACE
+%token REPEATABLE_SYM /* SQL-2003-N */
+%token REPEAT_SYM /* MYSQL-FUNC */
+%token REPLACE /* MYSQL-FUNC */
%token REPLICATION
%token REQUIRE_SYM
%token RESET_SYM
@@ -575,159 +563,155 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token RESTORE_SYM
%token RESTRICT
%token RESUME_SYM
-%token RETURNS_SYM
-%token RETURN_SYM
-%token REVOKE
-%token RIGHT
-%token ROLLBACK_SYM
-%token ROLLUP_SYM
-%token ROUND
-%token ROUTINE_SYM
-%token ROWS_SYM
-%token ROW_COUNT_SYM
+%token RETURNS_SYM /* SQL-2003-R */
+%token RETURN_SYM /* SQL-2003-R */
+%token REVOKE /* SQL-2003-R */
+%token RIGHT /* SQL-2003-R */
+%token ROLLBACK_SYM /* SQL-2003-R */
+%token ROLLUP_SYM /* SQL-2003-R */
+%token ROUTINE_SYM /* SQL-2003-N */
+%token ROWS_SYM /* SQL-2003-R */
%token ROW_FORMAT_SYM
-%token ROW_SYM
+%token ROW_SYM /* SQL-2003-R */
%token RTREE_SYM
-%token SAVEPOINT_SYM
+%token SAVEPOINT_SYM /* SQL-2003-R */
%token SCHEDULE_SYM
%token SECOND_MICROSECOND_SYM
-%token SECOND_SYM
-%token SECURITY_SYM
-%token SELECT_SYM
-%token SENSITIVE_SYM
+%token SECOND_SYM /* SQL-2003-R */
+%token SECURITY_SYM /* SQL-2003-N */
+%token SELECT_SYM /* SQL-2003-R */
+%token SENSITIVE_SYM /* FUTURE-USE */
%token SEPARATOR_SYM
-%token SERIALIZABLE_SYM
+%token SERIALIZABLE_SYM /* SQL-2003-N */
%token SERIAL_SYM
-%token SESSION_SYM
-%token SET
+%token SESSION_SYM /* SQL-2003-N */
+%token SET /* SQL-2003-R */
%token SET_VAR
%token SHARE_SYM
-%token SHIFT_LEFT
-%token SHIFT_RIGHT
+%token SHIFT_LEFT /* OPERATOR */
+%token SHIFT_RIGHT /* OPERATOR */
%token SHOW
%token SHUTDOWN
%token SIGNED_SYM
-%token SIMPLE_SYM
+%token SIMPLE_SYM /* SQL-2003-N */
%token SLAVE
-%token SMALLINT
+%token SMALLINT /* SQL-2003-R */
%token SNAPSHOT_SYM
%token SONAME_SYM
%token SOUNDS_SYM
%token SPATIAL_SYM
-%token SPECIFIC_SYM
-%token SQLEXCEPTION_SYM
-%token SQLSTATE_SYM
-%token SQLWARNING_SYM
+%token SPECIFIC_SYM /* SQL-2003-R */
+%token SQLEXCEPTION_SYM /* SQL-2003-R */
+%token SQLSTATE_SYM /* SQL-2003-R */
+%token SQLWARNING_SYM /* SQL-2003-R */
%token SQL_BIG_RESULT
%token SQL_BUFFER_RESULT
%token SQL_CACHE_SYM
%token SQL_CALC_FOUND_ROWS
%token SQL_NO_CACHE_SYM
%token SQL_SMALL_RESULT
-%token SQL_SYM
+%token SQL_SYM /* SQL-2003-R */
%token SQL_THREAD
%token SSL_SYM
%token STARTING
-%token START_SYM
%token STARTS_SYM
+%token START_SYM /* SQL-2003-R */
%token STATUS_SYM
+%token STDDEV_SAMP_SYM /* SQL-2003-N */
%token STD_SYM
-%token STDDEV_SAMP_SYM
%token STOP_SYM
%token STORAGE_SYM
%token STRAIGHT_JOIN
%token STRING_SYM
%token SUBDATE_SYM
%token SUBJECT_SYM
-%token SUBPARTITION_SYM
%token SUBPARTITIONS_SYM
-%token SUBSTRING
-%token SUBSTRING_INDEX
-%token SUM_SYM
+%token SUBPARTITION_SYM
+%token SUBSTRING /* SQL-2003-N */
+%token SUM_SYM /* SQL-2003-N */
%token SUPER_SYM
%token SUSPEND_SYM
%token SYSDATE
%token TABLES
%token TABLESPACE
-%token TABLE_SYM
-%token TEMPORARY
+%token TABLE_REF_PRIORITY
+%token TABLE_SYM /* SQL-2003-R */
+%token TEMPORARY /* SQL-2003-N */
%token TEMPTABLE_SYM
%token TERMINATED
%token TEXT_STRING
%token TEXT_SYM
-%token TIMESTAMP
+%token THAN_SYM
+%token THEN_SYM /* SQL-2003-R */
+%token TIMESTAMP /* SQL-2003-R */
%token TIMESTAMP_ADD
%token TIMESTAMP_DIFF
-%token TIME_SYM
+%token TIME_SYM /* SQL-2003-R */
%token TINYBLOB
%token TINYINT
%token TINYTEXT
-%token THAN_SYM
-%token TO_SYM
-%token TRAILING
+%token TO_SYM /* SQL-2003-R */
+%token TRAILING /* SQL-2003-R */
%token TRANSACTION_SYM
-%token TRIGGER_SYM
%token TRIGGERS_SYM
-%token TRIM
-%token TRUE_SYM
+%token TRIGGER_SYM /* SQL-2003-R */
+%token TRIM /* SQL-2003-N */
+%token TRUE_SYM /* SQL-2003-R */
%token TRUNCATE_SYM
%token TYPES_SYM
-%token TYPE_SYM
+%token TYPE_SYM /* SQL-2003-N */
%token UDF_RETURNS_SYM
%token ULONGLONG_NUM
-%token UNCOMMITTED_SYM
+%token UNCOMMITTED_SYM /* SQL-2003-N */
%token UNDEFINED_SYM
-%token UNDO_BUFFER_SIZE_SYM
-%token UNDOFILE_SYM
%token UNDERSCORE_CHARSET
-%token UNDO_SYM
+%token UNDOFILE_SYM
+%token UNDO_BUFFER_SIZE_SYM
+%token UNDO_SYM /* FUTURE-USE */
%token UNICODE_SYM
%token UNINSTALL_SYM
-%token UNION_SYM
+%token UNION_SYM /* SQL-2003-R */
%token UNIQUE_SYM
%token UNIQUE_USERS
-%token UNIX_TIMESTAMP
-%token UNKNOWN_SYM
+%token UNKNOWN_SYM /* SQL-2003-R */
%token UNLOCK_SYM
%token UNSIGNED
%token UNTIL_SYM
-%token UPDATE_SYM
+%token UPDATE_SYM /* SQL-2003-R */
%token UPGRADE_SYM
-%token USAGE
-%token USER
+%token USAGE /* SQL-2003-N */
+%token USER /* SQL-2003-R */
%token USE_FRM
%token USE_SYM
-%token USING
+%token USING /* SQL-2003-R */
%token UTC_DATE_SYM
%token UTC_TIMESTAMP_SYM
%token UTC_TIME_SYM
-%token VAR_SAMP_SYM
-%token VALUES
-%token VALUE_SYM
+%token VALUES /* SQL-2003-R */
+%token VALUE_SYM /* SQL-2003-R */
%token VARBINARY
-%token VARCHAR
+%token VARCHAR /* SQL-2003-R */
%token VARIABLES
%token VARIANCE_SYM
-%token VARYING
-%token VIEW_SYM
+%token VARYING /* SQL-2003-R */
+%token VAR_SAMP_SYM
+%token VIEW_SYM /* SQL-2003-N */
%token WAIT_SYM
%token WARNINGS
%token WEEK_SYM
-%token WHEN_SYM
-%token WHERE
+%token WHEN_SYM /* SQL-2003-R */
+%token WHERE /* SQL-2003-R */
%token WHILE_SYM
-%token WITH
-%token WORK_SYM
-%token WRITE_SYM
+%token WITH /* SQL-2003-R */
+%token WORK_SYM /* SQL-2003-N */
+%token WRITE_SYM /* SQL-2003-N */
%token X509_SYM
%token XA_SYM
%token XOR
-%token YEARWEEK
%token YEAR_MONTH_SYM
-%token YEAR_SYM
+%token YEAR_SYM /* SQL-2003-R */
%token ZEROFILL
-
%left JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT
/* A dummy token to force the priority of table_ref production in a join. */
%left TABLE_REF_PRIORITY
@@ -793,7 +777,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <item>
literal text_literal insert_ident order_ident
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
- bool_term bool_factor bool_test bool_pri
+ variable variable_aux bool_term bool_factor bool_test bool_pri
predicate bit_expr bit_term bit_factor value_expr term factor
table_wild simple_expr udf_expr
expr_or_default set_expr_or_default interval_expr
@@ -803,6 +787,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
simple_ident_nospvar simple_ident_q
field_or_var limit_option
part_func_expr
+ function_call_keyword
+ function_call_nonkeyword
+ function_call_generic
+ function_call_conflict
%type <item_num>
NUM_literal
@@ -810,6 +798,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <item_list>
expr_list udf_expr_list udf_expr_list2 when_list
ident_list ident_list_arg
+ expr_list_opt
%type <var_type>
option_type opt_var_type opt_var_ident_type
@@ -848,7 +837,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <udf_type> udf_func_type
-%type <symbol> FUNC_ARG0 FUNC_ARG1 FUNC_ARG2 FUNC_ARG3 keyword keyword_sp
+%type <symbol> keyword keyword_sp
%type <lex_user> user grant_user
@@ -1329,7 +1318,6 @@ event_tail:
Lex->sql_command= SQLCOM_CREATE_EVENT;
/* We need that for disallowing subqueries */
- Lex->expr_allows_subselect= FALSE;
}
ON SCHEDULE_SYM ev_schedule_time
opt_ev_on_completion
@@ -1351,7 +1339,6 @@ event_tail:
can overwrite it
*/
Lex->sql_command= SQLCOM_CREATE_EVENT;
- Lex->expr_allows_subselect= TRUE;
}
;
@@ -1725,15 +1712,20 @@ call:
lex->value_list.empty();
sp_add_used_routine(lex, YYTHD, $2, TYPE_ENUM_PROCEDURE);
}
- '(' sp_cparam_list ')' {}
+ opt_sp_cparam_list {}
;
/* CALL parameters */
-sp_cparam_list:
+opt_sp_cparam_list:
/* Empty */
- | sp_cparams
+ | '(' opt_sp_cparams ')'
;
+opt_sp_cparams:
+ /* Empty */
+ | sp_cparams
+ ;
+
sp_cparams:
sp_cparams ',' expr
{
@@ -3226,6 +3218,7 @@ opt_partitioning:
partitioning:
PARTITION_SYM
{
+#ifdef WITH_PARTITION_STORAGE_ENGINE
LEX *lex= Lex;
lex->part_info= new partition_info();
if (!lex->part_info)
@@ -3237,6 +3230,12 @@ partitioning:
{
lex->alter_info.flags|= ALTER_PARTITION;
}
+#else
+ my_error(ER_FEATURE_DISABLED, MYF(0),
+ "partitioning", "--with-partition");
+ YYABORT;
+#endif
+
}
partition
;
@@ -4732,8 +4731,6 @@ alter:
YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
Lex->sql_command= SQLCOM_ALTER_EVENT;
- /* we need that for disallowing subqueries */
- Lex->expr_allows_subselect= FALSE;
}
ev_alter_on_schedule_completion
opt_ev_rename_to
@@ -4759,7 +4756,6 @@ alter:
can overwrite it
*/
Lex->sql_command= SQLCOM_ALTER_EVENT;
- Lex->expr_allows_subselect= TRUE;
}
| ALTER TABLESPACE alter_tablespace_info
{
@@ -5821,10 +5817,10 @@ bool_factor:
| bool_test ;
bool_test:
- bool_pri IS TRUE_SYM { $$= is_truth_value($1,1,0); }
- | bool_pri IS not TRUE_SYM { $$= is_truth_value($1,0,0); }
- | bool_pri IS FALSE_SYM { $$= is_truth_value($1,0,1); }
- | bool_pri IS not FALSE_SYM { $$= is_truth_value($1,1,1); }
+ bool_pri IS TRUE_SYM { $$= is_truth_value(YYTHD, $1,1,0); }
+ | bool_pri IS not TRUE_SYM { $$= is_truth_value(YYTHD, $1,0,0); }
+ | bool_pri IS FALSE_SYM { $$= is_truth_value(YYTHD, $1,0,1); }
+ | bool_pri IS not FALSE_SYM { $$= is_truth_value(YYTHD, $1,1,1); }
| bool_pri IS UNKNOWN_SYM { $$= new Item_func_isnull($1); }
| bool_pri IS not UNKNOWN_SYM { $$= new Item_func_isnotnull($1); }
| bool_pri ;
@@ -5945,81 +5941,67 @@ interval_expr:
simple_expr:
simple_ident
+ | function_call_keyword
+ | function_call_nonkeyword
+ | function_call_generic
+ | function_call_conflict
| simple_expr COLLATE_SYM ident_or_text %prec NEG
{
- $$= new Item_func_set_collation($1,
- new Item_string($3.str,
- $3.length,
- YYTHD->charset()));
+ THD *thd= YYTHD;
+ Item *i1= new (thd->mem_root) Item_string($3.str,
+ $3.length,
+ thd->charset());
+ $$= new (thd->mem_root) Item_func_set_collation($1, i1);
}
| literal
| param_marker
- | '@' ident_or_text SET_VAR expr
- {
- $$= new Item_func_set_user_var($2,$4);
- LEX *lex= Lex;
- lex->uncacheable(UNCACHEABLE_RAND);
- lex->variables_used= 1;
- }
- | '@' ident_or_text
- {
- $$= new Item_func_get_user_var($2);
- LEX *lex= Lex;
- lex->uncacheable(UNCACHEABLE_RAND);
- lex->variables_used= 1;
- }
- | '@' '@' opt_var_ident_type ident_or_text opt_component
- {
-
- if ($4.str && $5.str && check_reserved_words(&$4))
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- if (!($$= get_system_var(YYTHD, $3, $4, $5)))
- YYABORT;
- Lex->variables_used= 1;
- }
+ | variable
| sum_expr
| simple_expr OR_OR_SYM simple_expr
- { $$= new Item_func_concat($1, $3); }
+ { $$= new (YYTHD->mem_root) Item_func_concat($1, $3); }
| '+' simple_expr %prec NEG { $$= $2; }
- | '-' simple_expr %prec NEG { $$= new Item_func_neg($2); }
- | '~' simple_expr %prec NEG { $$= new Item_func_bit_neg($2); }
- | not2 simple_expr %prec NEG { $$= negate_expression(YYTHD, $2); }
+ | '-' simple_expr %prec NEG
+ { $$= new (YYTHD->mem_root) Item_func_neg($2); }
+ | '~' simple_expr %prec NEG
+ { $$= new (YYTHD->mem_root) Item_func_bit_neg($2); }
+ | not2 simple_expr %prec NEG
+ { $$= negate_expression(YYTHD, $2); }
| '(' subselect ')'
{
- $$= new Item_singlerow_subselect($2);
+ $$= new (YYTHD->mem_root) Item_singlerow_subselect($2);
}
| '(' expr ')' { $$= $2; }
| '(' expr ',' expr_list ')'
{
$4->push_front($2);
- $$= new Item_row(*$4);
+ $$= new (YYTHD->mem_root) Item_row(*$4);
}
| ROW_SYM '(' expr ',' expr_list ')'
{
$5->push_front($3);
- $$= new Item_row(*$5);
+ $$= new (YYTHD->mem_root) Item_row(*$5);
}
| EXISTS '(' subselect ')'
{
- $$= new Item_exists_subselect($3);
+ $$= new (YYTHD->mem_root) Item_exists_subselect($3);
}
| '{' ident expr '}' { $$= $3; }
| MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
- { $2->push_front($5);
- Select->add_ftfunc_to_list((Item_func_match*)
- ($$=new Item_func_match(*$2,$6))); }
- | ASCII_SYM '(' expr ')' { $$= new Item_func_ascii($3); }
+ {
+ $2->push_front($5);
+ Item_func_match *i1= new (YYTHD->mem_root) Item_func_match(*$2, $6);
+ Select->add_ftfunc_to_list(i1);
+ $$= i1;
+ }
| BINARY simple_expr %prec NEG
{
- $$= create_func_cast($2, ITEM_CAST_CHAR, -1, 0, &my_charset_bin);
+ $$= create_func_cast(YYTHD, $2, ITEM_CAST_CHAR, -1, 0,
+ &my_charset_bin);
}
| CAST_SYM '(' expr AS cast_type ')'
{
LEX *lex= Lex;
- $$= create_func_cast($3, $5,
+ $$= create_func_cast(YYTHD, $3, $5,
lex->length ? atoi(lex->length) : -1,
lex->dec ? atoi(lex->dec) : 0,
lex->charset);
@@ -6027,10 +6009,10 @@ simple_expr:
YYABORT;
}
| CASE_SYM opt_expr WHEN_SYM when_list opt_else END
- { $$= new Item_func_case(* $4, $2, $5 ); }
+ { $$= new (YYTHD->mem_root) Item_func_case(* $4, $2, $5 ); }
| CONVERT_SYM '(' expr ',' cast_type ')'
{
- $$= create_func_cast($3, $5,
+ $$= create_func_cast(YYTHD, $3, $5,
Lex->length ? atoi(Lex->length) : -1,
Lex->dec ? atoi(Lex->dec) : 0,
Lex->charset);
@@ -6038,7 +6020,7 @@ simple_expr:
YYABORT;
}
| CONVERT_SYM '(' expr USING charset_name ')'
- { $$= new Item_func_conv_charset($3,$5); }
+ { $$= new (YYTHD->mem_root) Item_func_conv_charset($3,$5); }
| DEFAULT '(' simple_ident ')'
{
if ($3->is_splocal())
@@ -6048,545 +6030,432 @@ simple_expr:
my_error(ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str);
YYABORT;
}
- $$= new Item_default_value(Lex->current_context(), $3);
+ $$= new (YYTHD->mem_root) Item_default_value(Lex->current_context(),
+ $3);
}
| VALUES '(' simple_ident_nospvar ')'
- { $$= new Item_insert_value(Lex->current_context(), $3); }
- | FUNC_ARG0 '(' ')'
- {
- if (!$1.symbol->create_func)
- {
- my_error(ER_FEATURE_DISABLED, MYF(0),
- $1.symbol->group->name,
- $1.symbol->group->needed_define);
- YYABORT;
- }
- $$= ((Item*(*)(void))($1.symbol->create_func))();
- }
- | FUNC_ARG1 '(' expr ')'
- {
- if (!$1.symbol->create_func)
- {
- my_error(ER_FEATURE_DISABLED, MYF(0),
- $1.symbol->group->name,
- $1.symbol->group->needed_define);
- YYABORT;
- }
- $$= ((Item*(*)(Item*))($1.symbol->create_func))($3);
- }
- | FUNC_ARG2 '(' expr ',' expr ')'
- {
- if (!$1.symbol->create_func)
- {
- my_error(ER_FEATURE_DISABLED, MYF(0),
- $1.symbol->group->name,
- $1.symbol->group->needed_define);
- YYABORT;
- }
- $$= ((Item*(*)(Item*,Item*))($1.symbol->create_func))($3,$5);
- }
- | FUNC_ARG3 '(' expr ',' expr ',' expr ')'
+ { $$= new (YYTHD->mem_root) Item_insert_value(Lex->current_context(),
+ $3); }
+ | interval_expr interval '+' expr
+ /* we cannot put interval before - */
+ { $$= new (YYTHD->mem_root) Item_date_add_interval($4,$1,$2,0); }
+ | interval_expr
{
- if (!$1.symbol->create_func)
- {
- my_error(ER_FEATURE_DISABLED, MYF(0),
- $1.symbol->group->name,
- $1.symbol->group->needed_define);
- YYABORT;
- }
- $$= ((Item*(*)(Item*,Item*,Item*))($1.symbol->create_func))($3,$5,$7);
- }
- | ADDDATE_SYM '(' expr ',' expr ')'
- { $$= new Item_date_add_interval($3, $5, INTERVAL_DAY, 0);}
- | ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
- { $$= new Item_date_add_interval($3, $6, $7, 0); }
- | REPEAT_SYM '(' expr ',' expr ')'
- { $$= new Item_func_repeat($3,$5); }
- | ATAN '(' expr ')'
- { $$= new Item_func_atan($3); }
- | ATAN '(' expr ',' expr ')'
- { $$= new Item_func_atan($3,$5); }
- | CHAR_SYM '(' expr_list ')'
- { $$= new Item_func_char(*$3); }
- | CHAR_SYM '(' expr_list USING charset_name ')'
- { $$= new Item_func_char(*$3, $5); }
- | CHARSET '(' expr ')'
- { $$= new Item_func_charset($3); }
- | COALESCE '(' expr_list ')'
- { $$= new Item_func_coalesce(* $3); }
- | COLLATION_SYM '(' expr ')'
- { $$= new Item_func_collation($3); }
- | CONCAT '(' expr_list ')'
- { $$= new Item_func_concat(* $3); }
- | CONCAT_WS '(' expr ',' expr_list ')'
- { $5->push_front($3); $$= new Item_func_concat_ws(*$5); }
- | CONVERT_TZ_SYM '(' expr ',' expr ',' expr ')'
- {
- if (Lex->add_time_zone_tables_to_query_tables(YYTHD))
+ if ($1->type() != Item::ROW_ITEM)
+ {
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
- $$= new Item_func_convert_tz($3, $5, $7);
- }
- | CURDATE optional_braces
- { $$= new Item_func_curdate_local(); Lex->safe_to_cache_query=0; }
- | CURTIME optional_braces
- { $$= new Item_func_curtime_local(); Lex->safe_to_cache_query=0; }
- | CURTIME '(' expr ')'
+ }
+ $$= new (YYTHD->mem_root) Item_func_interval((Item_row *)$1);
+ }
+ | UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' expr_list ')'
{
- $$= new Item_func_curtime_local($3);
- Lex->safe_to_cache_query=0;
+ $$= new Item_func_unique_users($3,atoi($5.str),atoi($7.str), * $9);
}
+ ;
+
+/*
+ Function call syntax using official SQL 2003 keywords.
+ Because the function name is an official token,
+ a dedicated grammar rule is needed in the parser.
+ There is no potential for conflicts
+*/
+function_call_keyword:
+ CHAR_SYM '(' expr_list ')'
+ { $$= new (YYTHD->mem_root) Item_func_char(*$3); }
+ | CHAR_SYM '(' expr_list USING charset_name ')'
+ { $$= new (YYTHD->mem_root) Item_func_char(*$3, $5); }
| CURRENT_USER optional_braces
{
- $$= new Item_func_current_user(Lex->current_context());
+ $$= new (YYTHD->mem_root) Item_func_current_user(Lex->current_context());
Lex->safe_to_cache_query= 0;
}
- | DATE_ADD_INTERVAL '(' expr ',' interval_expr interval ')'
- { $$= new Item_date_add_interval($3,$5,$6,0); }
- | DATE_SUB_INTERVAL '(' expr ',' interval_expr interval ')'
- { $$= new Item_date_add_interval($3,$5,$6,1); }
- | DATABASE '(' ')'
- {
- $$= new Item_func_database();
- Lex->safe_to_cache_query=0;
- }
| DATE_SYM '(' expr ')'
- { $$= new Item_date_typecast($3); }
+ { $$= new (YYTHD->mem_root) Item_date_typecast($3); }
| DAY_SYM '(' expr ')'
- { $$= new Item_func_dayofmonth($3); }
- | ELT_FUNC '(' expr ',' expr_list ')'
- { $5->push_front($3); $$= new Item_func_elt(*$5); }
- | MAKE_SET_SYM '(' expr ',' expr_list ')'
- { $$= new Item_func_make_set($3, *$5); }
- | ENCRYPT '(' expr ')'
- {
- $$= new Item_func_encrypt($3);
- Lex->uncacheable(UNCACHEABLE_RAND);
- }
- | ENCRYPT '(' expr ',' expr ')' { $$= new Item_func_encrypt($3,$5); }
- | DECODE_SYM '(' expr ',' TEXT_STRING_literal ')'
- { $$= new Item_func_decode($3,$5.str); }
- | ENCODE_SYM '(' expr ',' TEXT_STRING_literal ')'
- { $$= new Item_func_encode($3,$5.str); }
- | DES_DECRYPT_SYM '(' expr ')'
- { $$= new Item_func_des_decrypt($3); }
- | DES_DECRYPT_SYM '(' expr ',' expr ')'
- { $$= new Item_func_des_decrypt($3,$5); }
- | DES_ENCRYPT_SYM '(' expr ')'
- { $$= new Item_func_des_encrypt($3); }
- | DES_ENCRYPT_SYM '(' expr ',' expr ')'
- { $$= new Item_func_des_encrypt($3,$5); }
- | EXPORT_SET '(' expr ',' expr ',' expr ')'
- { $$= new Item_func_export_set($3, $5, $7); }
- | EXPORT_SET '(' expr ',' expr ',' expr ',' expr ')'
- { $$= new Item_func_export_set($3, $5, $7, $9); }
- | EXPORT_SET '(' expr ',' expr ',' expr ',' expr ',' expr ')'
- { $$= new Item_func_export_set($3, $5, $7, $9, $11); }
- | FORMAT_SYM '(' expr ',' NUM ')'
- { $$= new Item_func_format($3,atoi($5.str)); }
- | FROM_UNIXTIME '(' expr ')'
- { $$= new Item_func_from_unixtime($3); }
- | FROM_UNIXTIME '(' expr ',' expr ')'
- {
- $$= new Item_func_date_format (new Item_func_from_unixtime($3),$5,0);
- }
- | FIELD_FUNC '(' expr ',' expr_list ')'
- { $5->push_front($3); $$= new Item_func_field(*$5); }
- | geometry_function
- {
-#ifdef HAVE_SPATIAL
- $$= $1;
-#else
- my_error(ER_FEATURE_DISABLED, MYF(0),
- sym_group_geom.name, sym_group_geom.needed_define);
- YYABORT;
-#endif
- }
- | GET_FORMAT '(' date_time_type ',' expr ')'
- { $$= new Item_func_get_format($3, $5); }
+ { $$= new (YYTHD->mem_root) Item_func_dayofmonth($3); }
| HOUR_SYM '(' expr ')'
- { $$= new Item_func_hour($3); }
- | IF '(' expr ',' expr ',' expr ')'
- { $$= new Item_func_if($3,$5,$7); }
+ { $$= new (YYTHD->mem_root) Item_func_hour($3); }
| INSERT '(' expr ',' expr ',' expr ',' expr ')'
- { $$= new Item_func_insert($3,$5,$7,$9); }
- | interval_expr interval '+' expr
- /* we cannot put interval before - */
- { $$= new Item_date_add_interval($4,$1,$2,0); }
- | interval_expr
+ { $$= new (YYTHD->mem_root) Item_func_insert($3,$5,$7,$9); }
+ | LEFT '(' expr ',' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_left($3,$5); }
+ | MINUTE_SYM '(' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_minute($3); }
+ | MONTH_SYM '(' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_month($3); }
+ | RIGHT '(' expr ',' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_right($3,$5); }
+ | SECOND_SYM '(' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_second($3); }
+ | TIME_SYM '(' expr ')'
+ { $$= new (YYTHD->mem_root) Item_time_typecast($3); }
+ | TIMESTAMP '(' expr ')'
+ { $$= new (YYTHD->mem_root) Item_datetime_typecast($3); }
+ | TIMESTAMP '(' expr ',' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_add_time($3, $5, 1, 0); }
+ | TRIM '(' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_trim($3); }
+ | TRIM '(' LEADING expr FROM expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_ltrim($6,$4); }
+ | TRIM '(' TRAILING expr FROM expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_rtrim($6,$4); }
+ | TRIM '(' BOTH expr FROM expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_trim($6,$4); }
+ | TRIM '(' LEADING FROM expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_ltrim($5); }
+ | TRIM '(' TRAILING FROM expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_rtrim($5); }
+ | TRIM '(' BOTH FROM expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_trim($5); }
+ | TRIM '(' expr FROM expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_trim($5,$3); }
+ | USER '(' ')'
{
- if ($1->type() != Item::ROW_ITEM)
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- $$= new Item_func_interval((Item_row *)$1);
+ $$= new (YYTHD->mem_root) Item_func_user();
+ Lex->safe_to_cache_query=0;
}
- | LAST_INSERT_ID '(' ')'
+ | YEAR_SYM '(' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_year($3); }
+ ;
+
+/*
+ Function calls using non reserved keywords, with special syntaxic forms.
+ Dedicated grammar rules are needed because of the syntax,
+ but also have the potential to cause incompatibilities with other
+ parts of the language.
+ MAINTAINER:
+ The only reasons a function should be added here are:
+ - for compatibility reasons with another SQL syntax (CURDATE),
+ - for typing reasons (GET_FORMAT)
+ Any other 'Syntaxic sugar' enhancements should be *STRONGLY*
+ discouraged.
+*/
+function_call_nonkeyword:
+ ADDDATE_SYM '(' expr ',' expr ')'
{
- $$= new Item_func_last_insert_id();
- Lex->safe_to_cache_query= 0;
- }
- | LAST_INSERT_ID '(' expr ')'
+ $$= new (YYTHD->mem_root) Item_date_add_interval($3, $5,
+ INTERVAL_DAY, 0);
+ }
+ | ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
+ { $$= new (YYTHD->mem_root) Item_date_add_interval($3, $6, $7, 0); }
+ | CURDATE optional_braces
{
- $$= new Item_func_last_insert_id($3);
- Lex->safe_to_cache_query= 0;
- }
- | LEFT '(' expr ',' expr ')'
- { $$= new Item_func_left($3,$5); }
- | LOCATE '(' expr ',' expr ')'
- { $$= new Item_func_locate($5,$3); }
- | LOCATE '(' expr ',' expr ',' expr ')'
- { $$= new Item_func_locate($5,$3,$7); }
- | GREATEST_SYM '(' expr ',' expr_list ')'
- { $5->push_front($3); $$= new Item_func_max(*$5); }
- | LEAST_SYM '(' expr ',' expr_list ')'
- { $5->push_front($3); $$= new Item_func_min(*$5); }
- | LOG_SYM '(' expr ')'
- { $$= new Item_func_log($3); }
- | LOG_SYM '(' expr ',' expr ')'
- { $$= new Item_func_log($3, $5); }
- | MASTER_POS_WAIT '(' expr ',' expr ')'
- {
- $$= new Item_master_pos_wait($3, $5);
- Lex->safe_to_cache_query=0;
- }
- | MASTER_POS_WAIT '(' expr ',' expr ',' expr ')'
+ $$= new (YYTHD->mem_root) Item_func_curdate_local();
+ Lex->safe_to_cache_query=0;
+ }
+ | CURTIME optional_braces
{
- $$= new Item_master_pos_wait($3, $5, $7);
+ $$= new (YYTHD->mem_root) Item_func_curtime_local();
+ Lex->safe_to_cache_query=0;
+ }
+ | CURTIME '(' expr ')'
+ {
+ $$= new (YYTHD->mem_root) Item_func_curtime_local($3);
Lex->safe_to_cache_query=0;
}
- | MICROSECOND_SYM '(' expr ')'
- { $$= new Item_func_microsecond($3); }
- | MINUTE_SYM '(' expr ')'
- { $$= new Item_func_minute($3); }
- | MOD_SYM '(' expr ',' expr ')'
- { $$ = new Item_func_mod( $3, $5); }
- | MONTH_SYM '(' expr ')'
- { $$= new Item_func_month($3); }
+ | DATE_ADD_INTERVAL '(' expr ',' interval_expr interval ')'
+ { $$= new (YYTHD->mem_root) Item_date_add_interval($3,$5,$6,0); }
+ | DATE_SUB_INTERVAL '(' expr ',' interval_expr interval ')'
+ { $$= new (YYTHD->mem_root) Item_date_add_interval($3,$5,$6,1); }
+ | EXTRACT_SYM '(' interval FROM expr ')'
+ { $$=new (YYTHD->mem_root) Item_extract( $3, $5); }
+ | GET_FORMAT '(' date_time_type ',' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_get_format($3, $5); }
| NOW_SYM optional_braces
- { $$= new Item_func_now_local(); Lex->safe_to_cache_query=0;}
+ {
+ $$= new (YYTHD->mem_root) Item_func_now_local();
+ Lex->safe_to_cache_query=0;
+ }
| NOW_SYM '(' expr ')'
- { $$= new Item_func_now_local($3); Lex->safe_to_cache_query=0;}
- | PASSWORD '(' expr ')'
{
- $$= YYTHD->variables.old_passwords ?
- (Item *) new Item_func_old_password($3) :
- (Item *) new Item_func_password($3);
- }
- | OLD_PASSWORD '(' expr ')'
- { $$= new Item_func_old_password($3); }
+ $$= new (YYTHD->mem_root) Item_func_now_local($3);
+ Lex->safe_to_cache_query=0;
+ }
| POSITION_SYM '(' bit_expr IN_SYM expr ')'
- { $$ = new Item_func_locate($5,$3); }
- | QUARTER_SYM '(' expr ')'
- { $$ = new Item_func_quarter($3); }
- | RAND '(' expr ')'
- { $$= new Item_func_rand($3); Lex->uncacheable(UNCACHEABLE_RAND);}
- | RAND '(' ')'
- { $$= new Item_func_rand(); Lex->uncacheable(UNCACHEABLE_RAND);}
- | REPLACE '(' expr ',' expr ',' expr ')'
- { $$= new Item_func_replace($3,$5,$7); }
- | RIGHT '(' expr ',' expr ')'
- { $$= new Item_func_right($3,$5); }
- | ROUND '(' expr ')'
- { $$= new Item_func_round($3, new Item_int((char*)"0",0,1),0); }
- | ROUND '(' expr ',' expr ')' { $$= new Item_func_round($3,$5,0); }
- | ROW_COUNT_SYM '(' ')'
- {
- $$= new Item_func_row_count();
- Lex->safe_to_cache_query= 0;
- }
+ { $$ = new (YYTHD->mem_root) Item_func_locate($5,$3); }
| SUBDATE_SYM '(' expr ',' expr ')'
- { $$= new Item_date_add_interval($3, $5, INTERVAL_DAY, 1);}
+ {
+ $$= new (YYTHD->mem_root) Item_date_add_interval($3, $5,
+ INTERVAL_DAY, 1);
+ }
| SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
- { $$= new Item_date_add_interval($3, $6, $7, 1); }
- | SECOND_SYM '(' expr ')'
- { $$= new Item_func_second($3); }
+ { $$= new (YYTHD->mem_root) Item_date_add_interval($3, $6, $7, 1); }
| SUBSTRING '(' expr ',' expr ',' expr ')'
- { $$= new Item_func_substr($3,$5,$7); }
+ { $$= new (YYTHD->mem_root) Item_func_substr($3,$5,$7); }
| SUBSTRING '(' expr ',' expr ')'
- { $$= new Item_func_substr($3,$5); }
+ { $$= new (YYTHD->mem_root) Item_func_substr($3,$5); }
| SUBSTRING '(' expr FROM expr FOR_SYM expr ')'
- { $$= new Item_func_substr($3,$5,$7); }
+ { $$= new (YYTHD->mem_root) Item_func_substr($3,$5,$7); }
| SUBSTRING '(' expr FROM expr ')'
- { $$= new Item_func_substr($3,$5); }
- | SUBSTRING_INDEX '(' expr ',' expr ',' expr ')'
- { $$= new Item_func_substr_index($3,$5,$7); }
+ { $$= new (YYTHD->mem_root) Item_func_substr($3,$5); }
| SYSDATE optional_braces
{
if (global_system_variables.sysdate_is_now == 0)
- $$= new Item_func_sysdate_local();
- else $$= new Item_func_now_local();
+ $$= new (YYTHD->mem_root) Item_func_sysdate_local();
+ else
+ $$= new (YYTHD->mem_root) Item_func_now_local();
Lex->safe_to_cache_query=0;
}
| SYSDATE '(' expr ')'
{
if (global_system_variables.sysdate_is_now == 0)
- $$= new Item_func_sysdate_local($3);
- else $$= new Item_func_now_local($3);
+ $$= new (YYTHD->mem_root) Item_func_sysdate_local($3);
+ else
+ $$= new (YYTHD->mem_root) Item_func_now_local($3);
Lex->safe_to_cache_query=0;
}
- | TIME_SYM '(' expr ')'
- { $$= new Item_time_typecast($3); }
- | TIMESTAMP '(' expr ')'
- { $$= new Item_datetime_typecast($3); }
- | TIMESTAMP '(' expr ',' expr ')'
- { $$= new Item_func_add_time($3, $5, 1, 0); }
| TIMESTAMP_ADD '(' interval_time_st ',' expr ',' expr ')'
- { $$= new Item_date_add_interval($7,$5,$3,0); }
+ { $$= new (YYTHD->mem_root) Item_date_add_interval($7,$5,$3,0); }
| TIMESTAMP_DIFF '(' interval_time_st ',' expr ',' expr ')'
- { $$= new Item_func_timestamp_diff($5,$7,$3); }
- | TRIM '(' expr ')'
- { $$= new Item_func_trim($3); }
- | TRIM '(' LEADING expr FROM expr ')'
- { $$= new Item_func_ltrim($6,$4); }
- | TRIM '(' TRAILING expr FROM expr ')'
- { $$= new Item_func_rtrim($6,$4); }
- | TRIM '(' BOTH expr FROM expr ')'
- { $$= new Item_func_trim($6,$4); }
- | TRIM '(' LEADING FROM expr ')'
- { $$= new Item_func_ltrim($5); }
- | TRIM '(' TRAILING FROM expr ')'
- { $$= new Item_func_rtrim($5); }
- | TRIM '(' BOTH FROM expr ')'
- { $$= new Item_func_trim($5); }
- | TRIM '(' expr FROM expr ')'
- { $$= new Item_func_trim($5,$3); }
- | TRUNCATE_SYM '(' expr ',' expr ')'
- { $$= new Item_func_round($3,$5,1); }
- | ident '.' ident '(' udf_expr_list ')'
+ { $$= new (YYTHD->mem_root) Item_func_timestamp_diff($5,$7,$3); }
+ | UTC_DATE_SYM optional_braces
{
- LEX *lex= Lex;
- sp_name *name= new sp_name($1, $3);
+ $$= new (YYTHD->mem_root) Item_func_curdate_utc();
+ Lex->safe_to_cache_query=0;
+ }
+ | UTC_TIME_SYM optional_braces
+ {
+ $$= new (YYTHD->mem_root) Item_func_curtime_utc();
+ Lex->safe_to_cache_query=0;
+ }
+ | UTC_TIMESTAMP_SYM optional_braces
+ {
+ $$= new (YYTHD->mem_root) Item_func_now_utc();
+ Lex->safe_to_cache_query=0;
+ }
+ ;
- name->init_qname(YYTHD);
- sp_add_used_routine(lex, YYTHD, name, TYPE_ENUM_FUNCTION);
- if ($5)
- $$= new Item_func_sp(Lex->current_context(), name, *$5);
- else
- $$= new Item_func_sp(Lex->current_context(), name);
- lex->safe_to_cache_query=0;
+/*
+ Functions calls using a non reserved keywork, and using a regular syntax.
+ Because the non reserved keyword is used in another part of the grammar,
+ a dedicated rule is needed here.
+*/
+function_call_conflict:
+ ASCII_SYM '(' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_ascii($3); }
+ | CHARSET '(' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_charset($3); }
+ | COALESCE '(' expr_list ')'
+ { $$= new (YYTHD->mem_root) Item_func_coalesce(* $3); }
+ | COLLATION_SYM '(' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_collation($3); }
+ | DATABASE '(' ')'
+ {
+ $$= new (YYTHD->mem_root) Item_func_database();
+ Lex->safe_to_cache_query=0;
}
- | IDENT_sys '('
+ | IF '(' expr ',' expr ',' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_if($3,$5,$7); }
+ | MICROSECOND_SYM '(' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_microsecond($3); }
+ | MOD_SYM '(' expr ',' expr ')'
+ { $$ = new (YYTHD->mem_root) Item_func_mod( $3, $5); }
+ | OLD_PASSWORD '(' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_old_password($3); }
+ | PASSWORD '(' expr ')'
+ {
+ THD *thd= YYTHD;
+ Item* i1;
+ if (thd->variables.old_passwords)
+ i1= new (thd->mem_root) Item_func_old_password($3);
+ else
+ i1= new (thd->mem_root) Item_func_password($3);
+ $$= i1;
+ }
+ | QUARTER_SYM '(' expr ')'
+ { $$ = new (YYTHD->mem_root) Item_func_quarter($3); }
+ | REPEAT_SYM '(' expr ',' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_repeat($3,$5); }
+ | REPLACE '(' expr ',' expr ',' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_replace($3,$5,$7); }
+ | TRUNCATE_SYM '(' expr ',' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_round($3,$5,1); }
+ | WEEK_SYM '(' expr ')'
+ {
+ THD *thd= YYTHD;
+ Item *i1= new (thd->mem_root) Item_int((char*) "0",
+ thd->variables.default_week_format,
+ 1);
+
+ $$= new (thd->mem_root) Item_func_week($3, i1);
+ }
+ | WEEK_SYM '(' expr ',' expr ')'
+ { $$= new (YYTHD->mem_root) Item_func_week($3,$5); }
+ | geometry_function
{
+#ifdef HAVE_SPATIAL
+ $$= $1;
+#else
+ my_error(ER_FEATURE_DISABLED, MYF(0),
+ sym_group_geom.name, sym_group_geom.needed_define);
+ YYABORT;
+#endif
+ }
+ ;
+
+geometry_function:
+ CONTAINS_SYM '(' expr ',' expr ')'
+ {
+ $$= GEOM_NEW(YYTHD,
+ Item_func_spatial_rel($3, $5,
+ Item_func::SP_CONTAINS_FUNC));
+ }
+ | GEOMETRYCOLLECTION '(' expr_list ')'
+ {
+ $$= GEOM_NEW(YYTHD,
+ Item_func_spatial_collection(* $3,
+ Geometry::wkb_geometrycollection,
+ Geometry::wkb_point));
+ }
+ | LINESTRING '(' expr_list ')'
+ {
+ $$= GEOM_NEW(YYTHD,
+ Item_func_spatial_collection(* $3,
+ Geometry::wkb_linestring,
+ Geometry::wkb_point));
+ }
+ | MULTILINESTRING '(' expr_list ')'
+ {
+ $$= GEOM_NEW(YYTHD,
+ Item_func_spatial_collection(* $3,
+ Geometry::wkb_multilinestring,
+ Geometry::wkb_linestring));
+ }
+ | MULTIPOINT '(' expr_list ')'
+ {
+ $$= GEOM_NEW(YYTHD,
+ Item_func_spatial_collection(* $3,
+ Geometry::wkb_multipoint,
+ Geometry::wkb_point));
+ }
+ | MULTIPOLYGON '(' expr_list ')'
+ {
+ $$= GEOM_NEW(YYTHD,
+ Item_func_spatial_collection(* $3,
+ Geometry::wkb_multipolygon,
+ Geometry::wkb_polygon));
+ }
+ | POINT_SYM '(' expr ',' expr ')'
+ { $$= GEOM_NEW(YYTHD, Item_func_point($3,$5)); }
+ | POLYGON '(' expr_list ')'
+ {
+ $$= GEOM_NEW(YYTHD,
+ Item_func_spatial_collection(* $3,
+ Geometry::wkb_polygon,
+ Geometry::wkb_linestring));
+ }
+ ;
+
+/*
+ Regular function calls.
+ The function name is *not* a token, and therefore is guaranteed to not
+ introduce side effects to the language in general.
+ MAINTAINER:
+ All the new functions implemented for new features should fit into
+ this category. The place to implement the function itself is
+ in sql/item_create.cc
+*/
+function_call_generic:
+ IDENT_sys '('
+ {
#ifdef HAVE_DLOPEN
- udf_func *udf= 0;
- if (using_udf_functions &&
- (udf= find_udf($1.str, $1.length)) &&
- udf->type == UDFTYPE_AGGREGATE)
+ udf_func *udf= 0;
+ if (using_udf_functions &&
+ (udf= find_udf($1.str, $1.length)) &&
+ udf->type == UDFTYPE_AGGREGATE)
+ {
+ LEX *lex= Lex;
+ if (lex->current_select->inc_in_sum_expr())
{
- LEX *lex= Lex;
- if (lex->current_select->inc_in_sum_expr())
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
+ yyerror(ER(ER_SYNTAX_ERROR));
+ YYABORT;
}
- $<udf>$= udf;
+ }
+ /* Temporary placing the result of find_udf in $3 */
+ $<udf>$= udf;
#endif
+ }
+ expr_list_opt ')'
+ {
+ THD *thd= YYTHD;
+ LEX *lex= Lex;
+ Create_func *builder;
+ Item *item= NULL;
+
+ /*
+ Implementation note:
+ names are resolved with the following order:
+ - MySQL native functions,
+ - User Defined Functions,
+ - Stored Functions (assuming the current <use> database)
+
+ This will be revised with WL#2128 (SQL PATH)
+ */
+ builder= find_native_function_builder(thd, $1);
+ if (builder)
+ {
+ item= builder->create(thd, $1, $4);
}
- udf_expr_list ')'
+ else
{
#ifdef HAVE_DLOPEN
+ /* Retrieving the result of find_udf */
udf_func *udf= $<udf>3;
- SELECT_LEX *sel= Select;
if (udf)
{
if (udf->type == UDFTYPE_AGGREGATE)
+ {
Select->in_sum_expr--;
-
- Lex->binlog_row_based_if_mixed= TRUE;
-
- switch (udf->returns) {
- case STRING_RESULT:
- if (udf->type == UDFTYPE_FUNCTION)
- {
- if ($4 != NULL)
- $$ = new Item_func_udf_str(udf, *$4);
- else
- $$ = new Item_func_udf_str(udf);
- }
- else
- {
- if ($4 != NULL)
- $$ = new Item_sum_udf_str(udf, *$4);
- else
- $$ = new Item_sum_udf_str(udf);
- }
- break;
- case REAL_RESULT:
- if (udf->type == UDFTYPE_FUNCTION)
- {
- if ($4 != NULL)
- $$ = new Item_func_udf_float(udf, *$4);
- else
- $$ = new Item_func_udf_float(udf);
- }
- else
- {
- if ($4 != NULL)
- $$ = new Item_sum_udf_float(udf, *$4);
- else
- $$ = new Item_sum_udf_float(udf);
- }
- break;
- case INT_RESULT:
- if (udf->type == UDFTYPE_FUNCTION)
- {
- if ($4 != NULL)
- $$ = new Item_func_udf_int(udf, *$4);
- else
- $$ = new Item_func_udf_int(udf);
- }
- else
- {
- if ($4 != NULL)
- $$ = new Item_sum_udf_int(udf, *$4);
- else
- $$ = new Item_sum_udf_int(udf);
- }
- break;
- case DECIMAL_RESULT:
- if (udf->type == UDFTYPE_FUNCTION)
- {
- if ($4 != NULL)
- $$ = new Item_func_udf_decimal(udf, *$4);
- else
- $$ = new Item_func_udf_decimal(udf);
- }
- else
- {
- if ($4 != NULL)
- $$ = new Item_sum_udf_decimal(udf, *$4);
- else
- $$ = new Item_sum_udf_decimal(udf);
- }
- break;
- default:
- YYABORT;
}
+
+ item= Create_udf_func::s_singleton.create(thd, udf, $4);
}
else
-#endif /* HAVE_DLOPEN */
+#endif
{
- LEX *lex= Lex;
- THD *thd= lex->thd;
- LEX_STRING db;
- if (thd->copy_db_to(&db.str, &db.length))
- YYABORT;
- sp_name *name= new sp_name(db, $1);
- if (name)
- name->init_qname(thd);
-
- sp_add_used_routine(lex, YYTHD, name, TYPE_ENUM_FUNCTION);
- if ($4)
- $$= new Item_func_sp(Lex->current_context(), name, *$4);
- else
- $$= new Item_func_sp(Lex->current_context(), name);
- lex->safe_to_cache_query=0;
- }
+ builder= find_qualified_function_builder(thd);
+ DBUG_ASSERT(builder);
+ item= builder->create(thd, $1, $4);
+ }
}
- | UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' expr_list ')'
- {
- $$= new Item_func_unique_users($3,atoi($5.str),atoi($7.str), * $9);
- }
- | UNIX_TIMESTAMP '(' ')'
- {
- $$= new Item_func_unix_timestamp();
- Lex->safe_to_cache_query=0;
- }
- | UNIX_TIMESTAMP '(' expr ')'
- { $$= new Item_func_unix_timestamp($3); }
- | USER '(' ')'
- { $$= new Item_func_user(); Lex->safe_to_cache_query=0; }
- | UTC_DATE_SYM optional_braces
- { $$= new Item_func_curdate_utc(); Lex->safe_to_cache_query=0;}
- | UTC_TIME_SYM optional_braces
- { $$= new Item_func_curtime_utc(); Lex->safe_to_cache_query=0;}
- | UTC_TIMESTAMP_SYM optional_braces
- { $$= new Item_func_now_utc(); Lex->safe_to_cache_query=0;}
- | WEEK_SYM '(' expr ')'
- {
- $$= new Item_func_week($3,new Item_int((char*) "0",
- YYTHD->variables.default_week_format,1));
+
+ if (! ($$= item))
+ {
+ YYABORT;
}
- | WEEK_SYM '(' expr ',' expr ')'
- { $$= new Item_func_week($3,$5); }
- | YEAR_SYM '(' expr ')'
- { $$= new Item_func_year($3); }
- | YEARWEEK '(' expr ')'
- { $$= new Item_func_yearweek($3,new Item_int((char*) "0",0,1)); }
- | YEARWEEK '(' expr ',' expr ')'
- { $$= new Item_func_yearweek($3, $5); }
- | BENCHMARK_SYM '(' ulong_num ',' expr ')'
- {
- $$=new Item_func_benchmark($3,$5);
- Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
- }
- | EXTRACT_SYM '(' interval FROM expr ')'
- { $$=new Item_extract( $3, $5); };
+ }
+ | ident '.' ident '(' udf_expr_list ')'
+ {
+ THD *thd= YYTHD;
+ Create_qfunc *builder;
+ Item *item= NULL;
-geometry_function:
- CONTAINS_SYM '(' expr ',' expr ')'
- { $$= GEOM_NEW(Item_func_spatial_rel($3, $5, Item_func::SP_CONTAINS_FUNC)); }
- | GEOMFROMTEXT '(' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
- | GEOMFROMTEXT '(' expr ',' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
- | GEOMFROMWKB '(' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_wkb($3)); }
- | GEOMFROMWKB '(' expr ',' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_wkb($3, $5)); }
- | GEOMETRYCOLLECTION '(' expr_list ')'
- { $$= GEOM_NEW(Item_func_spatial_collection(* $3,
- Geometry::wkb_geometrycollection,
- Geometry::wkb_point)); }
- | LINESTRING '(' expr_list ')'
- { $$= GEOM_NEW(Item_func_spatial_collection(* $3,
- Geometry::wkb_linestring, Geometry::wkb_point)); }
- | MULTILINESTRING '(' expr_list ')'
- { $$= GEOM_NEW( Item_func_spatial_collection(* $3,
- Geometry::wkb_multilinestring, Geometry::wkb_linestring)); }
- | MLINEFROMTEXT '(' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
- | MLINEFROMTEXT '(' expr ',' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
- | MPOINTFROMTEXT '(' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
- | MPOINTFROMTEXT '(' expr ',' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
- | MPOLYFROMTEXT '(' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
- | MPOLYFROMTEXT '(' expr ',' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
- | MULTIPOINT '(' expr_list ')'
- { $$= GEOM_NEW(Item_func_spatial_collection(* $3,
- Geometry::wkb_multipoint, Geometry::wkb_point)); }
- | MULTIPOLYGON '(' expr_list ')'
- { $$= GEOM_NEW(Item_func_spatial_collection(* $3,
- Geometry::wkb_multipolygon, Geometry::wkb_polygon)); }
- | POINT_SYM '(' expr ',' expr ')'
- { $$= GEOM_NEW(Item_func_point($3,$5)); }
- | POINTFROMTEXT '(' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
- | POINTFROMTEXT '(' expr ',' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
- | POLYFROMTEXT '(' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
- | POLYFROMTEXT '(' expr ',' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
- | POLYGON '(' expr_list ')'
- { $$= GEOM_NEW(Item_func_spatial_collection(* $3,
- Geometry::wkb_polygon, Geometry::wkb_linestring)); }
- | GEOMCOLLFROMTEXT '(' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
- | GEOMCOLLFROMTEXT '(' expr ',' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
- | LINEFROMTEXT '(' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
- | LINEFROMTEXT '(' expr ',' expr ')'
- { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
- ;
+ /*
+ The following in practice calls:
+ <code>Create_sp_func::create()</code>
+ and builds a stored function.
+
+ However, it's important to maintain the interface between the
+ parser and the implementation in item_create.cc clean,
+ since this will change with WL#2128 (SQL PATH):
+ - INFORMATION_SCHEMA.version() is the SQL 99 syntax for the native
+ funtion version(),
+ - MySQL.version() is the SQL 2003 syntax for the native function
+ version() (a vendor can specify any schema).
+ */
+
+ builder= find_qualified_function_builder(thd);
+ DBUG_ASSERT(builder);
+ item= builder->create(thd, $1, $3, $5);
+
+ if (! ($$= item))
+ {
+ YYABORT;
+ }
+ }
+ ;
fulltext_options:
opt_natural_language_mode opt_query_expansion
@@ -6702,6 +6571,46 @@ sum_expr:
$5->empty();
};
+variable:
+ '@'
+ {
+ if (! Lex->parsing_options.allows_variable)
+ {
+ my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
+ YYABORT;
+ }
+ }
+ variable_aux
+ {
+ $$= $3;
+ }
+ ;
+
+variable_aux:
+ ident_or_text SET_VAR expr
+ {
+ $$= new Item_func_set_user_var($1, $3);
+ LEX *lex= Lex;
+ lex->uncacheable(UNCACHEABLE_RAND);
+ }
+ | ident_or_text
+ {
+ $$= new Item_func_get_user_var($1);
+ LEX *lex= Lex;
+ lex->uncacheable(UNCACHEABLE_RAND);
+ }
+ | '@' opt_var_ident_type ident_or_text opt_component
+ {
+ if ($3.str && $4.str && check_reserved_words(&$3))
+ {
+ yyerror(ER(ER_SYNTAX_ERROR));
+ YYABORT;
+ }
+ if (!($$= get_system_var(YYTHD, $2, $3, $4)))
+ YYABORT;
+ }
+ ;
+
opt_distinct:
/* empty */ { $$ = 0; }
|DISTINCT { $$ = 1; };
@@ -6756,6 +6665,13 @@ cast_type:
| DECIMAL_SYM float_options { $$=ITEM_CAST_DECIMAL; Lex->charset= NULL; }
;
+expr_list_opt:
+ /* empty */
+ { $$ = NULL; }
+ | expr_list
+ { $$ = $1;}
+ ;
+
expr_list:
{ Select->expr_list.push_front(new List<Item>); }
expr_list2
@@ -6808,7 +6724,7 @@ when_list2:
/* Warning - may return NULL in case of incomplete SELECT */
table_ref:
table_factor { $$=$1; }
- | join_table { $$=$1; }
+ | join_table
{
LEX *lex= Lex;
if (!($$= lex->current_select->nest_last_join(lex->thd)))
@@ -6850,7 +6766,7 @@ join_table:
| table_ref normal_join table_ref
ON
{
- YYERROR_UNLESS($1 && ($$=$3));
+ YYERROR_UNLESS($1 && $3);
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
@@ -6865,7 +6781,7 @@ join_table:
| table_ref STRAIGHT_JOIN table_factor
ON
{
- YYERROR_UNLESS($1 && ($$=$3));
+ YYERROR_UNLESS($1 && $3);
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
@@ -7131,6 +7047,13 @@ select_derived_init:
SELECT_SYM
{
LEX *lex= Lex;
+
+ if (! lex->parsing_options.allows_derived)
+ {
+ my_error(ER_VIEW_SELECT_DERIVED, MYF(0));
+ YYABORT;
+ }
+
SELECT_LEX *sel= lex->current_select;
TABLE_LIST *embedding;
if (!sel->embedding || sel->end_nested_join(lex->thd))
@@ -7515,6 +7438,13 @@ procedure_clause:
| PROCEDURE ident /* Procedure name */
{
LEX *lex=Lex;
+
+ if (! lex->parsing_options.allows_select_procedure)
+ {
+ my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "PROCEDURE");
+ YYABORT;
+ }
+
if (&lex->select_lex != lex->current_select)
{
my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery");
@@ -7614,28 +7544,40 @@ select_var_ident:
;
into:
- INTO OUTFILE TEXT_STRING_filesystem
+ INTO
+ {
+ if (! Lex->parsing_options.allows_select_into)
+ {
+ my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "INTO");
+ YYABORT;
+ }
+ }
+ into_destination
+ ;
+
+into_destination:
+ OUTFILE TEXT_STRING_filesystem
{
LEX *lex= Lex;
lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
- if (!(lex->exchange= new sql_exchange($3.str, 0)) ||
+ if (!(lex->exchange= new sql_exchange($2.str, 0)) ||
!(lex->result= new select_export(lex->exchange)))
YYABORT;
}
opt_field_term opt_line_term
- | INTO DUMPFILE TEXT_STRING_filesystem
+ | DUMPFILE TEXT_STRING_filesystem
{
LEX *lex=Lex;
if (!lex->describe)
{
lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
- if (!(lex->exchange= new sql_exchange($3.str,1)))
+ if (!(lex->exchange= new sql_exchange($2.str,1)))
YYABORT;
if (!(lex->result= new select_dump(lex->exchange)))
YYABORT;
}
}
- | INTO select_var_list_init
+ | select_var_list_init
{
Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
}
@@ -8593,17 +8535,12 @@ purge_option:
/* kill threads */
kill:
- KILL_SYM
- {
- Lex->sql_command= SQLCOM_KILL;
- Lex->expr_allows_subselect= FALSE;
- }
- kill_option expr
+ KILL_SYM kill_option expr
{
LEX *lex=Lex;
lex->value_list.empty();
- lex->value_list.push_front($4);
- Lex->expr_allows_subselect= TRUE;
+ lex->value_list.push_front($3);
+ lex->sql_command= SQLCOM_KILL;
};
kill_option:
@@ -8844,8 +8781,13 @@ param_marker:
{
THD *thd=YYTHD;
LEX *lex= thd->lex;
- Item_param *item= new Item_param((uint) (lex->tok_start -
- (uchar *) thd->query));
+ Item_param *item;
+ if (! lex->parsing_options.allows_variable)
+ {
+ my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
+ YYABORT;
+ }
+ item= new Item_param((uint) (lex->tok_start - (uchar *) thd->query));
if (!($$= item) || lex->param_list.push_back(item))
{
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
@@ -8965,6 +8907,12 @@ simple_ident:
if (spc && (spv = spc->find_variable(&$1)))
{
/* We're compiling a stored procedure and found a variable */
+ if (! lex->parsing_options.allows_variable)
+ {
+ my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
+ YYABORT;
+ }
+
Item_splocal *splocal;
splocal= new Item_splocal($1, spv->offset, spv->type,
lex->tok_start_prev -
@@ -8974,7 +8922,6 @@ simple_ident:
splocal->m_sp= lex->sphead;
#endif
$$ = (Item*) splocal;
- lex->variables_used= 1;
lex->safe_to_cache_query=0;
}
else
@@ -10873,6 +10820,24 @@ view_list:
;
view_select:
+ {
+ LEX *lex= Lex;
+ lex->parsing_options.allows_variable= FALSE;
+ lex->parsing_options.allows_select_into= FALSE;
+ lex->parsing_options.allows_select_procedure= FALSE;
+ lex->parsing_options.allows_derived= FALSE;
+ }
+ view_select_aux
+ {
+ LEX *lex= Lex;
+ lex->parsing_options.allows_variable= TRUE;
+ lex->parsing_options.allows_select_into= TRUE;
+ lex->parsing_options.allows_select_procedure= TRUE;
+ lex->parsing_options.allows_derived= TRUE;
+ }
+ ;
+
+view_select_aux:
SELECT_SYM remember_name select_init2
{
THD *thd=YYTHD;
diff --git a/sql/stacktrace.c b/sql/stacktrace.c
index a2fe2ab88f1..77e7707592d 100644
--- a/sql/stacktrace.c
+++ b/sql/stacktrace.c
@@ -186,7 +186,7 @@ terribly wrong...\n");
#if defined(__alpha__) && defined(__GNUC__)
uchar** new_fp = find_prev_fp(pc, fp);
- if (frame_count == SIGRETURN_FRAME_COUNT - 1)
+ if (frame_count == sigreturn_frame_count - 1)
{
new_fp += 90;
}
diff --git a/sql/strfunc.cc b/sql/strfunc.cc
index 2525703172f..ef769a5b16e 100644
--- a/sql/strfunc.cc
+++ b/sql/strfunc.cc
@@ -312,3 +312,33 @@ outp:
return (uint32) (to - to_start);
}
+
+
+/*
+ Searches for a LEX_STRING in an LEX_STRING array.
+
+ SYNOPSIS
+ find_string_in_array()
+ heap The array
+ needle The string to search for
+
+ NOTE
+ The last LEX_STRING in the array should have str member set to NULL
+
+ RETURN VALUES
+ -1 Not found
+ >=0 Ordinal position
+*/
+
+int find_string_in_array(LEX_STRING * const haystack, LEX_STRING * const needle,
+ CHARSET_INFO * const cs)
+{
+ const LEX_STRING *pos;
+ for (pos= haystack; pos->str; pos++)
+ if (!cs->coll->strnncollsp(cs, (uchar *) pos->str, pos->length,
+ (uchar *) needle->str, needle->length, 0))
+ {
+ return (pos - haystack);
+ }
+ return -1;
+}
diff --git a/sql/table.cc b/sql/table.cc
index 8505b15459b..7f80b95c954 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -363,25 +363,24 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
error= open_binary_frm(thd, share, head, file);
*root_ptr= old_root;
- if (share->db.length == 5 &&
- !my_strcasecmp(system_charset_info, share->db.str, "mysql"))
+ if (share->db.length == 5 && !(lower_case_table_names ?
+ my_strcasecmp(system_charset_info, share->db.str, "mysql") :
+ strcmp(share->db.str, "mysql")))
{
/*
We can't mark all tables in 'mysql' database as system since we don't
allow to lock such tables for writing with any other tables (even with
other system tables) and some privilege tables need this.
*/
- if (!my_strcasecmp(system_charset_info, share->table_name.str, "proc"))
+ if (!(lower_case_table_names ?
+ my_strcasecmp(system_charset_info, share->table_name.str, "proc") :
+ strcmp(share->table_name.str, "proc")))
share->system_table= 1;
else
{
- if (!my_strcasecmp(system_charset_info, share->table_name.str,
- "general_log"))
- share->log_table= QUERY_LOG_GENERAL;
- else
- if (!my_strcasecmp(system_charset_info, share->table_name.str,
- "slow_log"))
- share->log_table= QUERY_LOG_SLOW;
+ share->log_table= check_if_log_table(share->db.length, share->db.str,
+ share->table_name.length,
+ share->table_name.str, 0);
}
}
error_given= 1;
@@ -480,7 +479,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
sql_print_warning("'%s' had no or invalid character set, "
"and default character set is multi-byte, "
"so character column sizes may have changed",
- share->path);
+ share->path.str);
}
share->table_charset= default_charset_info;
}
@@ -1182,7 +1181,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
as we need to test for NULL = NULL.
*/
if (field->real_maybe_null())
- key_part->key_part_flag|= HA_PART_KEY_SEG;
+ key_part->key_part_flag|= HA_NULL_PART;
}
keyinfo->usable_key_parts= usable_parts; // Filesort
diff --git a/sql/time.cc b/sql/time.cc
index 0461f7723c6..85096cd27ac 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -25,14 +25,25 @@
#ifndef TESTTIME
+/*
+ Name description of interval names used in statements.
+
+ 'interval_type_to_name' is ordered and sorted on interval size and
+ interval complexity.
+ Order of elements in 'interval_type_to_name' should correspond to
+ the order of elements in 'interval_type' enum
+
+ See also interval_type, interval_names
+*/
+
LEX_STRING interval_type_to_name[INTERVAL_LAST] = {
{ C_STRING_WITH_LEN("YEAR")},
{ C_STRING_WITH_LEN("QUARTER")},
{ C_STRING_WITH_LEN("MONTH")},
+ { C_STRING_WITH_LEN("WEEK")},
{ C_STRING_WITH_LEN("DAY")},
{ C_STRING_WITH_LEN("HOUR")},
{ C_STRING_WITH_LEN("MINUTE")},
- { C_STRING_WITH_LEN("WEEK")},
{ C_STRING_WITH_LEN("SECOND")},
{ C_STRING_WITH_LEN("MICROSECOND")},
{ C_STRING_WITH_LEN("YEAR_MONTH")},
@@ -253,14 +264,11 @@ my_time_t TIME_to_timestamp(THD *thd, const TIME *t, my_bool *in_dst_time_gap)
*in_dst_time_gap= 0;
- if (t->year < TIMESTAMP_MAX_YEAR && t->year > TIMESTAMP_MIN_YEAR ||
- t->year == TIMESTAMP_MAX_YEAR && t->month == 1 && t->day == 1 ||
- t->year == TIMESTAMP_MIN_YEAR && t->month == 12 && t->day == 31)
+ timestamp= thd->variables.time_zone->TIME_to_gmt_sec(t, in_dst_time_gap);
+ if (timestamp)
{
thd->time_zone_used= 1;
- timestamp= thd->variables.time_zone->TIME_to_gmt_sec(t, in_dst_time_gap);
- if (timestamp >= TIMESTAMP_MIN_VALUE && timestamp <= TIMESTAMP_MAX_VALUE)
- return timestamp;
+ return timestamp;
}
/* If we are here we have range error. */
@@ -278,9 +286,9 @@ my_time_t TIME_to_timestamp(THD *thd, const TIME *t, my_bool *in_dst_time_gap)
bool
str_to_time_with_warn(const char *str, uint length, TIME *l_time)
{
- int was_cut;
- bool ret_val= str_to_time(str, length, l_time, &was_cut);
- if (was_cut)
+ int warning;
+ bool ret_val= str_to_time(str, length, l_time, &warning);
+ if (ret_val || warning)
make_truncated_value_warning(current_thd, str, length,
MYSQL_TIMESTAMP_TIME, NullS);
return ret_val;
diff --git a/sql/tztime.cc b/sql/tztime.cc
index a1bcf25bb51..3d9f278b3f7 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -898,8 +898,14 @@ TIME_to_gmt_sec(const TIME *t, const TIME_ZONE_INFO *sp,
my_time_t local_t;
uint saved_seconds;
uint i;
+ int shift= 0;
+
DBUG_ENTER("TIME_to_gmt_sec");
+ if (!validate_timestamp_range(t))
+ DBUG_RETURN(0);
+
+
/* We need this for correct leap seconds handling */
if (t->second < SECS_PER_MIN)
saved_seconds= 0;
@@ -907,11 +913,29 @@ TIME_to_gmt_sec(const TIME *t, const TIME_ZONE_INFO *sp,
saved_seconds= t->second;
/*
- NOTE If we want to convert full my_time_t range without MySQL
- restrictions we should catch overflow here somehow.
+ NOTE: to convert full my_time_t range we do a shift of the
+ boundary dates here to avoid overflow of my_time_t.
+ We use alike approach in my_system_gmt_sec().
+
+ However in that function we also have to take into account
+ overflow near 0 on some platforms. That's because my_system_gmt_sec
+ uses localtime_r(), which doesn't work with negative values correctly
+ on platforms with unsigned time_t (QNX). Here we don't use localtime()
+ => we negative values of local_t are ok.
*/
- local_t= sec_since_epoch(t->year, t->month, t->day,
+ if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && t->day > 4)
+ {
+ /*
+ We will pass (t->day - shift) to sec_since_epoch(), and
+ want this value to be a positive number, so we shift
+ only dates > 4.01.2038 (to avoid owerflow).
+ */
+ shift= 2;
+ }
+
+
+ local_t= sec_since_epoch(t->year, t->month, (t->day - shift),
t->hour, t->minute,
saved_seconds ? 0 : t->second);
@@ -930,6 +954,22 @@ TIME_to_gmt_sec(const TIME *t, const TIME_ZONE_INFO *sp,
/* binary search for our range */
i= find_time_range(local_t, sp->revts, sp->revcnt);
+ /*
+ As there are no offset switches at the end of TIMESTAMP range,
+ we could simply check for overflow here (and don't need to bother
+ about DST gaps etc)
+ */
+ if (shift)
+ {
+ if (local_t > (TIMESTAMP_MAX_VALUE - shift*86400L +
+ sp->revtis[i].rt_offset - saved_seconds))
+ {
+ DBUG_RETURN(0); /* my_time_t overflow */
+ }
+ else
+ local_t+= shift*86400L;
+ }
+
if (sp->revtis[i].rt_type)
{
/*
@@ -939,10 +979,16 @@ TIME_to_gmt_sec(const TIME *t, const TIME_ZONE_INFO *sp,
beginning of the gap.
*/
*in_dst_time_gap= 1;
- DBUG_RETURN(sp->revts[i] - sp->revtis[i].rt_offset + saved_seconds);
+ local_t= sp->revts[i] - sp->revtis[i].rt_offset + saved_seconds;
}
else
- DBUG_RETURN(local_t - sp->revtis[i].rt_offset + saved_seconds);
+ local_t= local_t - sp->revtis[i].rt_offset + saved_seconds;
+
+ /* check for TIMESTAMP_MAX_VALUE was already done above */
+ if (local_t < TIMESTAMP_MIN_VALUE)
+ local_t= 0;
+
+ DBUG_RETURN(local_t);
}
@@ -1308,9 +1354,24 @@ Time_zone_offset::Time_zone_offset(long tz_offset_arg):
my_time_t
Time_zone_offset::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
{
- return sec_since_epoch(t->year, t->month, t->day,
- t->hour, t->minute, t->second) -
- offset;
+ my_time_t local_t;
+
+ /*
+ Check timestamp range.we have to do this as calling function relies on
+ us to make all validation checks here.
+ */
+ if (!validate_timestamp_range(t))
+ return 0;
+
+ local_t= sec_since_epoch(t->year, t->month, t->day,
+ t->hour, t->minute, t->second) -
+ offset;
+
+ if (local_t >= TIMESTAMP_MIN_VALUE && local_t <= TIMESTAMP_MAX_VALUE)
+ return local_t;
+
+ /* range error*/
+ return 0;
}
diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc
index 26eed928964..f7e5aa9d50c 100644
--- a/storage/csv/ha_tina.cc
+++ b/storage/csv/ha_tina.cc
@@ -826,9 +826,9 @@ void ha_tina::update_status()
bool ha_tina::check_if_locking_is_allowed(uint sql_command,
ulong type, TABLE *table,
uint count,
- bool called_by_logger_thread)
+ bool called_by_privileged_thread)
{
- if (!called_by_logger_thread)
+ if (!called_by_privileged_thread)
return check_if_log_table_locking_is_allowed(sql_command, type, table);
return TRUE;
diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c
index ffaf2065045..7a8e5626e25 100644
--- a/storage/innobase/btr/btr0btr.c
+++ b/storage/innobase/btr/btr0btr.c
@@ -571,9 +571,6 @@ btr_page_get_father_for_rec(
tuple = dict_index_build_node_ptr(index, user_rec, 0, heap,
btr_page_get_level(page, mtr));
- /* In the following, we choose just any index from the tree as the
- first parameter for btr_cur_search_to_nth_level. */
-
btr_cur_search_to_nth_level(index,
btr_page_get_level(page, mtr) + 1,
tuple, PAGE_CUR_LE,
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index 44a374fe550..7c2fc18accd 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -3547,6 +3547,7 @@ syntax_error:
/*==================== END OF FOREIGN KEY PROCESSING ====================*/
+#ifdef UNIV_DEBUG
/**************************************************************************
Returns an index object if it is found in the dictionary cache. */
@@ -3556,7 +3557,6 @@ dict_index_get_if_in_cache(
/* out: index, NULL if not found */
dulint index_id) /* in: index id */
{
- dict_table_t* table;
dict_index_t* index;
if (dict_sys == NULL) {
@@ -3565,29 +3565,13 @@ dict_index_get_if_in_cache(
mutex_enter(&(dict_sys->mutex));
- table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
-
- while (table) {
- index = UT_LIST_GET_FIRST(table->indexes);
-
- while (index) {
- if (0 == ut_dulint_cmp(index->id, index_id)) {
-
- goto found;
- }
+ index = dict_index_find_on_id_low(index_id);
- index = UT_LIST_GET_NEXT(indexes, index);
- }
-
- table = UT_LIST_GET_NEXT(table_LRU, table);
- }
-
- index = NULL;
-found:
mutex_exit(&(dict_sys->mutex));
return(index);
}
+#endif /* UNIV_DEBUG */
#ifdef UNIV_DEBUG
/**************************************************************************
@@ -4162,18 +4146,8 @@ dict_print_info_on_foreign_key_in_create_format(
dict_remove_db_name(
foreign->referenced_table_name));
} else {
- /* Look for the '/' in the table name */
-
- i = 0;
- while (foreign->referenced_table_name[i] != '/') {
- i++;
- }
-
- ut_print_namel(file, trx, TRUE,
- foreign->referenced_table_name, i);
- putc('.', file);
ut_print_name(file, trx, TRUE,
- foreign->referenced_table_name + i + 1);
+ foreign->referenced_table_name);
}
putc(' ', file);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 3434cf6b8ba..ec86b9a2e68 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -6630,7 +6630,7 @@ innodb_mutex_show_status(
mutex->count_spin_rounds,
mutex->count_os_wait,
mutex->count_os_yield,
- mutex->lspent_time/1000);
+ (ulong) mutex->lspent_time/1000);
if (stat_print(thd, innobase_hton_name,
hton_name_len, buf1, buf1len,
@@ -6660,7 +6660,7 @@ innodb_mutex_show_status(
rw_lock_count, rw_lock_count_spin_loop,
rw_lock_count_spin_rounds,
rw_lock_count_os_wait, rw_lock_count_os_yield,
- rw_lock_wait_time/1000);
+ (ulong) rw_lock_wait_time/1000);
if (stat_print(thd, innobase_hton_name, hton_name_len,
STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
@@ -6812,7 +6812,8 @@ ha_innobase::store_lock(
&& lock_type != TL_IGNORE)) {
/* The OR cases above are in this order:
- 1) MySQL is doing LOCK TABLES ... READ LOCAL, or
+ 1) MySQL is doing LOCK TABLES ... READ LOCAL, or we
+ are processing a stored procedure or function, or
2) (we do not know when TL_READ_HIGH_PRIORITY is used), or
3) this is a SELECT ... IN SHARE MODE, or
4) we are doing a complex SQL statement like
@@ -6880,7 +6881,8 @@ ha_innobase::store_lock(
single transaction stored procedure call deterministic
(if it does not use a consistent read). */
- if (lock_type == TL_READ && thd->in_lock_tables) {
+ if (lock_type == TL_READ
+ && thd->lex->sql_command == SQLCOM_LOCK_TABLES) {
/* We come here if MySQL is processing LOCK TABLES
... READ LOCAL. MyISAM under that table lock type
reads the table as it was at the time the lock was
@@ -6939,8 +6941,7 @@ ha_innobase::store_lock(
(MySQL does have thd->in_lock_tables TRUE there). */
if (lock_type == TL_READ_NO_INSERT
- && (!thd->in_lock_tables
- || thd->lex->sql_command == SQLCOM_CALL)) {
+ && thd->lex->sql_command != SQLCOM_LOCK_TABLES) {
lock_type = TL_READ;
}
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index a9775ab3d40..2582effbb29 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -778,9 +778,8 @@ const dict_col_t*
dict_field_get_col(
/*===============*/
const dict_field_t* field);
-/**************************************************************************
-In an index tree, finds the index corresponding to a record in the tree. */
+#ifdef UNIV_DEBUG
/**************************************************************************
Returns an index object if it is found in the dictionary cache. */
@@ -789,7 +788,6 @@ dict_index_get_if_in_cache(
/*=======================*/
/* out: index, NULL if not found */
dulint index_id); /* in: index id */
-#ifdef UNIV_DEBUG
/**************************************************************************
Checks that a tuple has n_fields_cmp value in a sensible range, so that
no comparison can occur with the page number field in a node pointer. */
diff --git a/storage/innobase/include/mem0dbg.h b/storage/innobase/include/mem0dbg.h
index 0f4441f4f9d..36cd7a89565 100644
--- a/storage/innobase/include/mem0dbg.h
+++ b/storage/innobase/include/mem0dbg.h
@@ -30,6 +30,7 @@ check fields at the both ends of the field. */
#define MEM_SPACE_NEEDED(N) ut_calc_align((N), UNIV_MEM_ALIGNMENT)
#endif
+#if defined UNIV_MEM_DEBUG || defined UNIV_DEBUG
/*******************************************************************
Checks a memory heap for consistency and prints the contents if requested.
Outputs the sum of sizes of buffers given to the user (only in
@@ -59,15 +60,8 @@ mem_heap_validate_or_print(
ulint* n_blocks); /* out: number of blocks in the heap,
if a NULL pointer is passed as this
argument, it is ignored */
-#ifdef UNIV_MEM_DEBUG
-/******************************************************************
-Prints the contents of a memory heap. */
-
-void
-mem_heap_print(
-/*===========*/
- mem_heap_t* heap); /* in: memory heap */
-#endif /* UNIV_MEM_DEBUG */
+#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
+#ifdef UNIV_DEBUG
/******************************************************************
Checks that an object is a memory heap (or a block of it) */
@@ -76,6 +70,7 @@ mem_heap_check(
/*===========*/
/* out: TRUE if ok */
mem_heap_t* heap); /* in: memory heap */
+#endif /* UNIV_DEBUG */
/******************************************************************
Validates the contents of a memory heap. */
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index 9e8250cb545..2a160d27e0c 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -265,6 +265,7 @@ mtr_memo_release(
mtr_t* mtr, /* in: mtr */
void* object, /* in: object */
ulint type); /* in: object type: MTR_MEMO_S_LOCK, ... */
+#ifdef UNIV_DEBUG
/**************************************************************
Checks if memo contains the given item. */
UNIV_INLINE
@@ -282,6 +283,7 @@ void
mtr_print(
/*======*/
mtr_t* mtr); /* in: mtr */
+#endif /* UNIV_DEBUG */
/*######################################################################*/
#define MTR_BUF_MEMO_SIZE 200 /* number of slots in memo */
diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic
index d81f6cb9c0d..81eec3bfc92 100644
--- a/storage/innobase/include/mtr0mtr.ic
+++ b/storage/innobase/include/mtr0mtr.ic
@@ -113,6 +113,7 @@ mtr_release_s_latch_at_savepoint(
slot->object = NULL;
}
+#ifdef UNIV_DEBUG
/**************************************************************
Checks if memo contains the given item. */
UNIV_INLINE
@@ -148,6 +149,7 @@ mtr_memo_contains(
return(FALSE);
}
+#endif /* UNIV_DEBUG */
/*******************************************************************
Returns the log object of a mini-transaction buffer. */
diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
index d8f3c400918..7c0241f2e02 100644
--- a/storage/innobase/include/sync0rw.h
+++ b/storage/innobase/include/sync0rw.h
@@ -358,8 +358,9 @@ rw_lock_print(
Prints debug info of currently locked rw-locks. */
void
-rw_lock_list_print_info(void);
-/*=========================*/
+rw_lock_list_print_info(
+/*====================*/
+ FILE* file); /* in: file where to print */
/*******************************************************************
Returns the number of currently locked rw-locks.
Works only in the debug version. */
diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
index 7d795e60efd..a1184d44257 100644
--- a/storage/innobase/include/sync0sync.h
+++ b/storage/innobase/include/sync0sync.h
@@ -224,12 +224,6 @@ Counts currently reserved mutexes. Works only in the debug version. */
ulint
mutex_n_reserved(void);
/*==================*/
-/**********************************************************************
-Prints debug info of currently reserved mutexes. */
-
-void
-mutex_list_print_info(void);
-/*========================*/
#endif /* UNIV_SYNC_DEBUG */
/**********************************************************************
NOT to be used outside this module except in debugging! Gets the value
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 63fdabbe823..f471fe136b0 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -10,18 +10,18 @@ Created 1/20/1994 Heikki Tuuri
#define univ_i
#if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) && !defined(__WIN__)
-#undef __WIN__
-#define __WIN__
+# undef __WIN__
+# define __WIN__
-#include <windows.h>
+# include <windows.h>
-#if !defined(WIN64) && !defined(_WIN64)
-#define UNIV_CAN_USE_X86_ASSEMBLER
-#endif
+# if !defined(WIN64) && !defined(_WIN64)
+# define UNIV_CAN_USE_X86_ASSEMBLER
+# endif
-#ifdef _NT_
-#define __NT__
-#endif
+# ifdef _NT_
+# define __NT__
+# endif
#else
/* The defines used with MySQL */
@@ -30,23 +30,23 @@ Created 1/20/1994 Heikki Tuuri
in compiling more Posix-compatible. These headers also define __WIN__
if we are compiling on Windows. */
-#include <my_global.h>
-#include <my_pthread.h>
+# include <my_global.h>
+# include <my_pthread.h>
/* Include <sys/stat.h> to get S_I... macros defined for os0file.c */
-#include <sys/stat.h>
+# include <sys/stat.h>
-#undef PACKAGE
-#undef VERSION
+# undef PACKAGE
+# undef VERSION
/* Include the header file generated by GNU autoconf */
#ifndef __WIN__
-#include "config.h"
+# include "config.h"
#endif
-#ifdef HAVE_SCHED_H
-#include <sched.h>
-#endif
+# ifdef HAVE_SCHED_H
+# include <sched.h>
+# endif
/* When compiling for Itanium IA64, undefine the flag below to prevent use
of the 32-bit x86 assembler in mutex operations. */
@@ -58,14 +58,14 @@ of the 32-bit x86 assembler in mutex operations. */
/* We only try to do explicit inlining of functions with gcc and
Microsoft Visual C++ */
-#if !defined(__GNUC__) && !defined(__WIN__)
-#undef UNIV_MUST_NOT_INLINE /* Remove compiler warning */
-#define UNIV_MUST_NOT_INLINE
-#endif
+# if !defined(__GNUC__)
+# undef UNIV_MUST_NOT_INLINE /* Remove compiler warning */
+# define UNIV_MUST_NOT_INLINE
+# endif
-#ifdef HAVE_PREAD
-#define HAVE_PWRITE
-#endif
+# ifdef HAVE_PREAD
+# define HAVE_PWRITE
+# endif
#endif /* #if (defined(WIN32) || ... */
diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h
index 1eafa680d8d..b4e9fa91491 100644
--- a/storage/innobase/include/ut0ut.h
+++ b/storage/innobase/include/ut0ut.h
@@ -218,7 +218,10 @@ ut_print_filename(
struct trx_struct;
/**************************************************************************
-Outputs a NUL-terminated string, quoted as an SQL identifier. */
+Outputs a fixed-length string, quoted as an SQL identifier.
+If the string contains a slash '/', the string will be
+output as two identifiers separated by a period (.),
+as in SQL database_name.identifier. */
void
ut_print_name(
@@ -230,7 +233,10 @@ ut_print_name(
const char* name); /* in: name to print */
/**************************************************************************
-Outputs a fixed-length string, quoted as an SQL identifier. */
+Outputs a fixed-length string, quoted as an SQL identifier.
+If the string contains a slash '/', the string will be
+output as two identifiers separated by a period (.),
+as in SQL database_name.identifier. */
void
ut_print_namel(
diff --git a/storage/innobase/mem/mem0dbg.c b/storage/innobase/mem/mem0dbg.c
index 419f410cf1b..eb77dd01f6d 100644
--- a/storage/innobase/mem/mem0dbg.c
+++ b/storage/innobase/mem/mem0dbg.c
@@ -66,7 +66,6 @@ mem_hash_get_nth_cell(ulint i)
return(&(mem_hash_table[i]));
}
-#endif /* UNIV_MEM_DEBUG */
/* Accessor functions for a memory field in the debug version */
@@ -106,6 +105,7 @@ mem_field_trailer_get_check(byte* field)
return(mach_read_from_4(field
+ mem_field_header_get_len(field)));
}
+#endif /* UNIV_MEM_DEBUG */
/**********************************************************************
Initializes the memory system. */
@@ -136,6 +136,7 @@ mem_init(
mem_comm_pool = mem_pool_create(size);
}
+#ifdef UNIV_MEM_DEBUG
/**********************************************************************
Initializes an allocated memory field in the debug version. */
@@ -163,7 +164,6 @@ mem_field_init(
mem_field_header_set_check(usr_buf, rnd);
mem_field_trailer_set_check(usr_buf, rnd);
-#ifdef UNIV_MEM_DEBUG
/* Update the memory allocation information */
mutex_enter(&mem_hash_mutex);
@@ -182,7 +182,6 @@ mem_field_init(
combination of 0xBA and 0xBE */
mem_init_buf(usr_buf, n);
-#endif /* UNIV_MEM_DEBUG */
}
/**********************************************************************
@@ -199,7 +198,6 @@ mem_field_erase(
usr_buf = buf + MEM_FIELD_HEADER_SIZE;
-#ifdef UNIV_MEM_DEBUG
mutex_enter(&mem_hash_mutex);
mem_current_allocated_memory -= n;
mutex_exit(&mem_hash_mutex);
@@ -211,10 +209,8 @@ mem_field_erase(
combination of 0xDE and 0xAD */
mem_erase_buf(buf, MEM_SPACE_NEEDED(n));
-#endif /* UNIV_MEM_DEBUG */
}
-#ifdef UNIV_MEM_DEBUG
/*******************************************************************
Initializes a buffer to a random combination of hex BA and BE.
Used to initialize allocated memory. */
@@ -376,6 +372,7 @@ mem_hash_remove(
}
#endif /* UNIV_MEM_DEBUG */
+#if defined UNIV_MEM_DEBUG || defined UNIV_DEBUG
/*******************************************************************
Checks a memory heap for consistency and prints the contents if requested.
Outputs the sum of sizes of buffers given to the user (only in
@@ -549,10 +546,12 @@ completed:
}
*error = FALSE;
}
+#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
+#ifdef UNIV_DEBUG
/******************************************************************
Prints the contents of a memory heap. */
-
+static
void
mem_heap_print(
/*===========*/
@@ -615,6 +614,7 @@ mem_heap_validate(
return(TRUE);
}
+#endif /* UNIV_DEBUG */
#ifdef UNIV_MEM_DEBUG
/*********************************************************************
diff --git a/storage/innobase/mem/mem0pool.c b/storage/innobase/mem/mem0pool.c
index 6a419ff33ec..a7acd331e16 100644
--- a/storage/innobase/mem/mem0pool.c
+++ b/storage/innobase/mem/mem0pool.c
@@ -35,7 +35,7 @@ The main components of the memory consumption are:
8. session for each user, and
9. stack for each OS thread.
-Items 1-3 are managed by an LRU algorithm. Items 5 and 6 can potentially
+Items 1 and 2 are managed by an LRU algorithm. Items 5 and 6 can potentially
consume very much memory. Items 7 and 8 should consume quite little memory,
and the OS should take care of item 9, which too should consume little memory.
@@ -54,16 +54,15 @@ common pool and the buffers in the buffer pool into a single LRU list and
manage it uniformly, but this approach does not take into account the parsing
and other costs unique to SQL statements.
-So, let the SQL statements and the data dictionary entries form one single
-LRU list, let us call it the dictionary LRU list. The locks for a transaction
-can be seen as a part of the state of the transaction. Hence, they should be
-stored in the common pool. We still have the problem of a very big update
-transaction, for example, which will set very many x-locks on rows, and the
-locks will consume a lot of memory, say, half of the buffer pool size.
+The locks for a transaction can be seen as a part of the state of the
+transaction. Hence, they should be stored in the common pool. We still
+have the problem of a very big update transaction, for example, which
+will set very many x-locks on rows, and the locks will consume a lot
+of memory, say, half of the buffer pool size.
Another problem is what to do if we are not able to malloc a requested
-block of memory from the common pool. Then we can truncate the LRU list of
-the dictionary cache. If it does not help, a system error results.
+block of memory from the common pool. Then we can request memory from
+the operating system. If it does not help, a system error results.
Because 5 and 6 may potentially consume very much memory, we let them grow
into the buffer pool. We may let the locks of a transaction take frames
diff --git a/storage/innobase/mtr/mtr0mtr.c b/storage/innobase/mtr/mtr0mtr.c
index 1a65da6e7f4..365fa15878a 100644
--- a/storage/innobase/mtr/mtr0mtr.c
+++ b/storage/innobase/mtr/mtr0mtr.c
@@ -318,6 +318,7 @@ mtr_read_dulint(
return(mach_read_from_8(ptr));
}
+#ifdef UNIV_DEBUG
/*************************************************************
Prints info of an mtr handle. */
@@ -332,3 +333,4 @@ mtr_print(
(ulong) dyn_array_get_data_size(&(mtr->memo)),
(ulong) dyn_array_get_data_size(&(mtr->log)));
}
+#endif /* UNIV_DEBUG */
diff --git a/storage/innobase/row/row0purge.c b/storage/innobase/row/row0purge.c
index 889a11a7a76..1fef47da13f 100644
--- a/storage/innobase/row/row0purge.c
+++ b/storage/innobase/row/row0purge.c
@@ -563,7 +563,7 @@ row_purge_parse_undo_rec(
/* Read to the partial row the fields that occur in indexes */
- if (!cmpl_info & UPD_NODE_NO_ORD_CHANGE) {
+ if (!(cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
ptr = trx_undo_rec_get_partial_row(ptr, clust_index,
&(node->row), node->heap);
}
diff --git a/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c
index 304801d0a3b..441933843d7 100644
--- a/storage/innobase/sync/sync0rw.c
+++ b/storage/innobase/sync/sync0rw.c
@@ -758,8 +758,9 @@ rw_lock_is_locked(
Prints debug info of currently locked rw-locks. */
void
-rw_lock_list_print_info(void)
-/*=========================*/
+rw_lock_list_print_info(
+/*====================*/
+ FILE* file) /* in: file where to print */
{
rw_lock_t* lock;
ulint count = 0;
@@ -769,7 +770,7 @@ rw_lock_list_print_info(void)
fputs("-------------\n"
"RW-LATCH INFO\n"
- "-------------\n", stderr);
+ "-------------\n", file);
lock = UT_LIST_GET_FIRST(rw_lock_list);
@@ -783,12 +784,12 @@ rw_lock_list_print_info(void)
|| (rw_lock_get_reader_count(lock) != 0)
|| (rw_lock_get_waiters(lock) != 0)) {
- fprintf(stderr, "RW-LOCK: %p ", (void*) lock);
+ fprintf(file, "RW-LOCK: %p ", (void*) lock);
if (rw_lock_get_waiters(lock)) {
- fputs(" Waiters for the lock exist\n", stderr);
+ fputs(" Waiters for the lock exist\n", file);
} else {
- putc('\n', stderr);
+ putc('\n', file);
}
info = UT_LIST_GET_FIRST(lock->debug_list);
@@ -802,7 +803,7 @@ rw_lock_list_print_info(void)
lock = UT_LIST_GET_NEXT(list, lock);
}
- fprintf(stderr, "Total number of rw-locks %ld\n", count);
+ fprintf(file, "Total number of rw-locks %ld\n", count);
mutex_exit(&rw_lock_list_mutex);
}
diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
index 91fd248502a..ff7056b0afe 100644
--- a/storage/innobase/sync/sync0sync.c
+++ b/storage/innobase/sync/sync0sync.c
@@ -628,10 +628,11 @@ mutex_own(
/**********************************************************************
Prints debug info of currently reserved mutexes. */
-
+static
void
-mutex_list_print_info(void)
-/*=======================*/
+mutex_list_print_info(
+/*==================*/
+ FILE* file) /* in: file where to print */
{
mutex_t* mutex;
const char* file_name;
@@ -641,7 +642,7 @@ mutex_list_print_info(void)
fputs("----------\n"
"MUTEX INFO\n"
- "----------\n", stderr);
+ "----------\n", file);
mutex_enter(&mutex_list_mutex);
@@ -653,7 +654,7 @@ mutex_list_print_info(void)
if (mutex_get_lock_word(mutex) != 0) {
mutex_get_debug_info(mutex, &file_name, &line,
&thread_id);
- fprintf(stderr,
+ fprintf(file,
"Locked mutex: addr %p thread %ld"
" file %s line %ld\n",
(void*) mutex, os_thread_pf(thread_id),
@@ -663,7 +664,7 @@ mutex_list_print_info(void)
mutex = UT_LIST_GET_NEXT(list, mutex);
}
- fprintf(stderr, "Total number of mutexes %ld\n", count);
+ fprintf(file, "Total number of mutexes %ld\n", count);
mutex_exit(&mutex_list_mutex);
}
@@ -1343,7 +1344,7 @@ sync_print_wait_info(
FILE* file) /* in: file where to print */
{
#ifdef UNIV_SYNC_DEBUG
- fprintf(stderr, "Mutex exits %lu, rws exits %lu, rwx exits %lu\n",
+ fprintf(file, "Mutex exits %lu, rws exits %lu, rwx exits %lu\n",
mutex_exit_count, rw_s_exit_count, rw_x_exit_count);
#endif
@@ -1369,9 +1370,9 @@ sync_print(
FILE* file) /* in: file where to print */
{
#ifdef UNIV_SYNC_DEBUG
- mutex_list_print_info();
+ mutex_list_print_info(file);
- rw_lock_list_print_info();
+ rw_lock_list_print_info(file);
#endif /* UNIV_SYNC_DEBUG */
sync_array_print_info(file, sync_primary_wait_array);
diff --git a/storage/innobase/ut/ut0ut.c b/storage/innobase/ut/ut0ut.c
index 10641b88a17..d805cc3b4b2 100644
--- a/storage/innobase/ut/ut0ut.c
+++ b/storage/innobase/ut/ut0ut.c
@@ -394,7 +394,10 @@ done:
}
/**************************************************************************
-Outputs a NUL-terminated string, quoted as an SQL identifier. */
+Outputs a fixed-length string, quoted as an SQL identifier.
+If the string contains a slash '/', the string will be
+output as two identifiers separated by a period (.),
+as in SQL database_name.identifier. */
void
ut_print_name(
@@ -409,7 +412,10 @@ ut_print_name(
}
/**************************************************************************
-Outputs a fixed-length string, quoted as an SQL identifier. */
+Outputs a fixed-length string, quoted as an SQL identifier.
+If the string contains a slash '/', the string will be
+output as two identifiers separated by a period (.),
+as in SQL database_name.identifier. */
void
ut_print_namel(
@@ -424,7 +430,7 @@ ut_print_namel(
#ifdef UNIV_HOTBACKUP
fwrite(name, 1, namelen, f);
#else
- char* slash = strchr(name, '/');
+ char* slash = memchr(name, '/', namelen);
if (UNIV_LIKELY_NULL(slash)) {
/* Print the database name and table name separately. */
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index e4da7652860..85968110a77 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -265,7 +265,7 @@ err:
bool ha_myisam::check_if_locking_is_allowed(uint sql_command,
ulong type, TABLE *table,
uint count,
- bool called_by_logger_thread)
+ bool called_by_privileged_thread)
{
/*
To be able to open and lock for reading system tables like 'mysql.proc',
@@ -283,10 +283,10 @@ bool ha_myisam::check_if_locking_is_allowed(uint sql_command,
/*
Deny locking of the log tables, which is incompatible with
- concurrent insert. Unless called from a logger THD:
- general_log_thd or slow_log_thd.
+ concurrent insert. Unless called from a logger THD (general_log_thd
+ or slow_log_thd) or by a privileged thread.
*/
- if (!called_by_logger_thread)
+ if (!called_by_privileged_thread)
return check_if_log_table_locking_is_allowed(sql_command, type, table);
return TRUE;
diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c
index bdbfa91ced4..a6bf3934959 100644
--- a/storage/myisam/sort.c
+++ b/storage/myisam/sort.c
@@ -322,160 +322,164 @@ pthread_handler_t thr_find_all_keys(void *arg)
if (my_thread_init())
goto err;
- DBUG_ENTER("thr_find_all_keys");
- DBUG_PRINT("enter", ("master: %d", sort_param->master));
- if (sort_param->sort_info->got_error)
- goto err;
- if (sort_param->keyinfo->flag && HA_VAR_LENGTH_KEY)
- {
- sort_param->write_keys= write_keys_varlen;
- sort_param->read_to_buffer= read_to_buffer_varlen;
- sort_param->write_key= write_merge_key_varlen;
- }
- else
- {
- sort_param->write_keys= write_keys;
- sort_param->read_to_buffer= read_to_buffer;
- sort_param->write_key= write_merge_key;
- }
+ { /* Add extra block since DBUG_ENTER declare variables */
+ DBUG_ENTER("thr_find_all_keys");
+ DBUG_PRINT("enter", ("master: %d", sort_param->master));
+ if (sort_param->sort_info->got_error)
+ goto err;
- my_b_clear(&sort_param->tempfile);
- my_b_clear(&sort_param->tempfile_for_exceptions);
- bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek));
- bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
- sort_keys= (uchar **) NULL;
+ if (sort_param->keyinfo->flag & HA_VAR_LENGTH_KEY)
+ {
+ sort_param->write_keys= write_keys_varlen;
+ sort_param->read_to_buffer= read_to_buffer_varlen;
+ sort_param->write_key= write_merge_key_varlen;
+ }
+ else
+ {
+ sort_param->write_keys= write_keys;
+ sort_param->read_to_buffer= read_to_buffer;
+ sort_param->write_key= write_merge_key;
+ }
- memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY);
- idx= sort_param->sort_info->max_records;
- sort_length= sort_param->key_length;
- maxbuffer= 1;
+ my_b_clear(&sort_param->tempfile);
+ my_b_clear(&sort_param->tempfile_for_exceptions);
+ bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek));
+ bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
+ sort_keys= (uchar **) NULL;
- while (memavl >= MIN_SORT_MEMORY)
- {
- if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
- (my_off_t) memavl)
- keys= idx+1;
- else
+ memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY);
+ idx= sort_param->sort_info->max_records;
+ sort_length= sort_param->key_length;
+ maxbuffer= 1;
+
+ while (memavl >= MIN_SORT_MEMORY)
{
- uint skr;
- do
+ if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
+ (my_off_t) memavl)
+ keys= idx+1;
+ else
{
- skr=maxbuffer;
- if (memavl < sizeof(BUFFPEK)*maxbuffer ||
- (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
- (sort_length+sizeof(char*))) <= 1 ||
- keys < (uint) maxbuffer)
+ uint skr;
+ do
{
- mi_check_print_error(sort_param->sort_info->param,
- "sort_buffer_size is to small");
- goto err;
+ skr= maxbuffer;
+ if (memavl < sizeof(BUFFPEK)*maxbuffer ||
+ (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
+ (sort_length+sizeof(char*))) <= 1 ||
+ keys < (uint) maxbuffer)
+ {
+ mi_check_print_error(sort_param->sort_info->param,
+ "sort_buffer_size is to small");
+ goto err;
+ }
}
+ while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
}
- while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
- }
- if ((sort_keys= (uchar**)
- my_malloc(keys*(sort_length+sizeof(char*))+
- ((sort_param->keyinfo->flag & HA_FULLTEXT) ?
- HA_FT_MAXBYTELEN : 0), MYF(0))))
- {
- if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK),
- maxbuffer, maxbuffer/2))
+ if ((sort_keys= (uchar**)
+ my_malloc(keys*(sort_length+sizeof(char*))+
+ ((sort_param->keyinfo->flag & HA_FULLTEXT) ?
+ HA_FT_MAXBYTELEN : 0), MYF(0))))
{
- my_free((gptr) sort_keys,MYF(0));
- sort_keys= (uchar **) NULL; /* for err: label */
+ if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK),
+ maxbuffer, maxbuffer/2))
+ {
+ my_free((gptr) sort_keys,MYF(0));
+ sort_keys= (uchar **) NULL; /* for err: label */
+ }
+ else
+ break;
}
- else
- break;
+ old_memavl= memavl;
+ if ((memavl= memavl/4*3) < MIN_SORT_MEMORY &&
+ old_memavl > MIN_SORT_MEMORY)
+ memavl= MIN_SORT_MEMORY;
+ }
+ if (memavl < MIN_SORT_MEMORY)
+ {
+ mi_check_print_error(sort_param->sort_info->param,
+ "Sort buffer too small");
+ goto err; /* purecov: tested */
}
- old_memavl=memavl;
- if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY)
- memavl=MIN_SORT_MEMORY;
- }
- if (memavl < MIN_SORT_MEMORY)
- {
- mi_check_print_error(sort_param->sort_info->param, "Sort buffer too small");
- goto err; /* purecov: tested */
- }
- if (sort_param->sort_info->param->testflag & T_VERBOSE)
- printf("Key %d - Allocating buffer for %d keys\n",
- sort_param->key + 1, keys);
- sort_param->sort_keys= sort_keys;
+ if (sort_param->sort_info->param->testflag & T_VERBOSE)
+ printf("Key %d - Allocating buffer for %d keys\n",
+ sort_param->key + 1, keys);
+ sort_param->sort_keys= sort_keys;
- idx=error=0;
- sort_keys[0]=(uchar*) (sort_keys+keys);
+ idx= error= 0;
+ sort_keys[0]= (uchar*) (sort_keys+keys);
- DBUG_PRINT("info", ("reading keys"));
- while (!(error= sort_param->sort_info->got_error) &&
- !(error= (*sort_param->key_read)(sort_param, sort_keys[idx])))
- {
- if (sort_param->real_key_length > sort_param->key_length)
+ DBUG_PRINT("info", ("reading keys"));
+ while (!(error= sort_param->sort_info->got_error) &&
+ !(error= (*sort_param->key_read)(sort_param, sort_keys[idx])))
{
- if (write_key(sort_param, sort_keys[idx],
- &sort_param->tempfile_for_exceptions))
- goto err;
- continue;
- }
+ if (sort_param->real_key_length > sort_param->key_length)
+ {
+ if (write_key(sort_param, sort_keys[idx],
+ &sort_param->tempfile_for_exceptions))
+ goto err;
+ continue;
+ }
- if (++idx == keys)
+ if (++idx == keys)
+ {
+ if (sort_param->write_keys(sort_param, sort_keys, idx - 1,
+ (BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
+ &sort_param->tempfile))
+ goto err;
+ sort_keys[0]= (uchar*) (sort_keys+keys);
+ memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length);
+ idx= 1;
+ }
+ sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length;
+ }
+ if (error > 0)
+ goto err;
+ if (sort_param->buffpek.elements)
{
- if (sort_param->write_keys(sort_param, sort_keys, idx - 1,
+ if (sort_param->write_keys(sort_param, sort_keys, idx,
(BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
&sort_param->tempfile))
goto err;
- sort_keys[0]=(uchar*) (sort_keys+keys);
- memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length);
- idx=1;
+ sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx;
}
- sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length;
- }
- if (error > 0)
- goto err;
- if (sort_param->buffpek.elements)
- {
- if (sort_param->write_keys(sort_param, sort_keys, idx,
- (BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
- &sort_param->tempfile))
- goto err;
- sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx;
- }
- else
- sort_param->keys= idx;
+ else
+ sort_param->keys= idx;
- sort_param->sort_keys_length= keys;
- goto ok;
+ sort_param->sort_keys_length= keys;
+ goto ok;
err:
- DBUG_PRINT("error", ("got some error"));
- sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */
- if (sort_keys)
- my_free((gptr) sort_keys,MYF(0));
- sort_param->sort_keys= 0;
- delete_dynamic(& sort_param->buffpek);
- close_cached_file(&sort_param->tempfile);
- close_cached_file(&sort_param->tempfile_for_exceptions);
+ DBUG_PRINT("error", ("got some error"));
+ sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */
+ if (sort_keys)
+ my_free((gptr) sort_keys,MYF(0));
+ sort_param->sort_keys= 0;
+ delete_dynamic(& sort_param->buffpek);
+ close_cached_file(&sort_param->tempfile);
+ close_cached_file(&sort_param->tempfile_for_exceptions);
ok:
- free_root(&sort_param->wordroot, MYF(0));
- /*
- Detach from the share if the writer is involved. Avoid others to
- be blocked. This includes a flush of the write buffer. This will
- also indicate EOF to the readers.
- */
- if (sort_param->sort_info->info->rec_cache.share)
- remove_io_thread(&sort_param->sort_info->info->rec_cache);
-
- /* Readers detach from the share if any. Avoid others to be blocked. */
- if (sort_param->read_cache.share)
- remove_io_thread(&sort_param->read_cache);
-
- pthread_mutex_lock(&sort_param->sort_info->mutex);
- if (!--sort_param->sort_info->threads_running)
- pthread_cond_signal(&sort_param->sort_info->cond);
- pthread_mutex_unlock(&sort_param->sort_info->mutex);
-
- DBUG_PRINT("exit", ("======== ending thread ========"));
+ free_root(&sort_param->wordroot, MYF(0));
+ /*
+ Detach from the share if the writer is involved. Avoid others to
+ be blocked. This includes a flush of the write buffer. This will
+ also indicate EOF to the readers.
+ */
+ if (sort_param->sort_info->info->rec_cache.share)
+ remove_io_thread(&sort_param->sort_info->info->rec_cache);
+
+ /* Readers detach from the share if any. Avoid others to be blocked. */
+ if (sort_param->read_cache.share)
+ remove_io_thread(&sort_param->read_cache);
+
+ pthread_mutex_lock(&sort_param->sort_info->mutex);
+ if (!--sort_param->sort_info->threads_running)
+ pthread_cond_signal(&sort_param->sort_info->cond);
+ pthread_mutex_unlock(&sort_param->sort_info->mutex);
+ DBUG_PRINT("exit", ("======== ending thread ========"));
+ }
my_thread_end();
return NULL;
}
@@ -543,7 +547,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
{
if (got_error)
continue;
- if (sinfo->keyinfo->flag && HA_VAR_LENGTH_KEY)
+ if (sinfo->keyinfo->flag & HA_VAR_LENGTH_KEY)
{
sinfo->write_keys=write_keys_varlen;
sinfo->read_to_buffer=read_to_buffer_varlen;
diff --git a/storage/ndb/tools/ndb_size.pl b/storage/ndb/tools/ndb_size.pl
index c285a7590fd..3d1ea3f4231 100644
--- a/storage/ndb/tools/ndb_size.pl
+++ b/storage/ndb/tools/ndb_size.pl
@@ -57,7 +57,7 @@ if(@ARGV < 3 || $ARGV[0] eq '--usage' || $ARGV[0] eq '--help')
$template->param(dsn => $dsn);
}
-my @releases = ({rel=>'4.1'},{rel=>'5.0'},{rel=>'5.1'});
+my @releases = ({rel=>'4.1'},{rel=>'5.0'},{rel=>'5.1'}); #,{rel=>'5.1-dd'});
$template->param(releases => \@releases);
my $tables = $dbh->selectall_arrayref("show tables");
@@ -81,25 +81,29 @@ sub align {
return @aligned;
}
-foreach(@{$tables})
-{
- my $table= @{$_}[0];
+sub do_table {
+ my $table= shift;
+ my $info= shift;
+ my %indexes= %{$_[0]};
+ my @count= @{$_[1]};
+
my @columns;
- my $info= $dbh->selectall_hashref('describe `'.$table.'`',"Field");
- my @count = $dbh->selectrow_array('select count(*) from `'.$table.'`');
my %columnsize; # used for index calculations
-
# We now work out the DataMemory usage
- # sizes for 4.1, 5.0, 5.1
- my @totalsize= (0,0,0);
+ # sizes for 4.1, 5.0, 5.1 and 5.1-dd
+ my @totalsize= (0,0,0,0);
+ @totalsize= @totalsize[0..$#releases]; # limit to releases we're outputting
+ my $nrvarsize= 0;
foreach(keys %$info)
{
- my @realsize = (0,0,0);
+ my @realsize = (0,0,0,0);
+ my @varsize = (0,0,0,0);
my $type;
my $size;
my $name= $_;
+ my $is_varsize= 0;
if($$info{$_}{Type} =~ /^(.*?)\((\d+)\)/)
{
@@ -112,54 +116,86 @@ foreach(@{$tables})
}
if($type =~ /tinyint/)
- {@realsize=(1,1,1)}
+ {@realsize=(1,1,1,1)}
elsif($type =~ /smallint/)
- {@realsize=(2,2,2)}
+ {@realsize=(2,2,2,2)}
elsif($type =~ /mediumint/)
- {@realsize=(3,3,3)}
+ {@realsize=(3,3,3,3)}
elsif($type =~ /bigint/)
- {@realsize=(8,8,8)}
+ {@realsize=(8,8,8,8)}
elsif($type =~ /int/)
- {@realsize=(4,4,4)}
+ {@realsize=(4,4,4,4)}
elsif($type =~ /float/)
{
if($size<=24)
- {@realsize=(4,4,4)}
+ {@realsize=(4,4,4,4)}
else
- {@realsize=(8,8,8)}
+ {@realsize=(8,8,8,8)}
}
elsif($type =~ /double/ || $type =~ /real/)
- {@realsize=(8,8,8)}
+ {@realsize=(8,8,8,8)}
elsif($type =~ /bit/)
{
my $a=($size+7)/8;
- @realsize = ($a,$a,$a);
+ @realsize = ($a,$a,$a,$a);
}
elsif($type =~ /datetime/)
- {@realsize=(8,8,8)}
+ {@realsize=(8,8,8,8)}
elsif($type =~ /timestamp/)
- {@realsize=(4,4,4)}
+ {@realsize=(4,4,4,4)}
elsif($type =~ /date/ || $type =~ /time/)
- {@realsize=(3,3,3)}
+ {@realsize=(3,3,3,3)}
elsif($type =~ /year/)
- {@realsize=(1,1,1)}
+ {@realsize=(1,1,1,1)}
elsif($type =~ /varchar/ || $type =~ /varbinary/)
{
- my $fixed= 1+$size;
+ my $fixed=$size+ceil($size/256);
my @dynamic=$dbh->selectrow_array("select avg(length(`"
.$name
."`)) from `".$table.'`');
$dynamic[0]=0 if !$dynamic[0];
- @realsize= ($fixed,$fixed,ceil($dynamic[0]));
+ $dynamic[0]+=ceil($dynamic[0]/256); # size bit
+ $nrvarsize++;
+ $is_varsize= 1;
+ $varsize[3]= ceil($dynamic[0]);
+ @realsize= ($fixed,$fixed,ceil($dynamic[0]),$fixed);
}
elsif($type =~ /binary/ || $type =~ /char/)
- {@realsize=($size,$size,$size)}
+ {@realsize=($size,$size,$size,$size)}
elsif($type =~ /text/ || $type =~ /blob/)
{
- @realsize=(256,256,1);
- $NoOfTables[$_]{val} += 1 foreach 0..$#releases; # blob uses table
- } # FIXME check if 5.1 is correct
+ @realsize=(8+256,8+256,8+256,8+256);
+
+ my $blobhunk= 2000;
+ $blobhunk= 8000 if $type=~ /longblob/;
+ $blobhunk= 4000 if $type=~ /mediumblob/;
+
+ my @blobsize=$dbh->selectrow_array("select SUM(CEILING(".
+ "length(`$name`)/$blobhunk))".
+ "from `".$table."`");
+ $blobsize[0]=0 if !defined($blobsize[0]);
+ #$NoOfTables[$_]{val} += 1 foreach 0..$#releases; # blob uses table
+ do_table($table."\$BLOB_$name",
+ {'PK'=>{Type=>'int'},
+ 'DIST'=>{Type=>'int'},
+ 'PART'=>{Type=>'int'},
+ 'DATA'=>{Type=>"binary($blobhunk)"}
+ },
+ {'PRIMARY' => {
+ 'unique' => 1,
+ 'comment' => '',
+ 'columns' => [
+ 'PK',
+ 'DIST',
+ 'PART',
+ ],
+ 'type' => 'HASH'
+ }
+ },
+ \@blobsize);
+ }
+ @realsize= @realsize[0..$#releases];
@realsize= align(4,@realsize);
$totalsize[$_]+=$realsize[$_] foreach 0..$#totalsize;
@@ -170,6 +206,7 @@ foreach(@{$tables})
push @columns, {
name=>$name,
type=>$type,
+ is_varsize=>$is_varsize,
size=>$size,
key=>$$info{$_}{Key},
datamemory=>\@realout,
@@ -183,24 +220,10 @@ foreach(@{$tables})
# Firstly, we assemble some information about the indexes.
# We use SHOW INDEX instead of using INFORMATION_SCHEMA so
# we can still connect to pre-5.0 mysqlds.
- my %indexes;
- {
- my $sth= $dbh->prepare("show index from `".$table.'`');
- $sth->execute;
- while(my $i = $sth->fetchrow_hashref)
- {
- $indexes{${%$i}{Key_name}}= {
- type=>${%$i}{Index_type},
- unique=>!${%$i}{Non_unique},
- comment=>${%$i}{Comment},
- } if !defined($indexes{${%$i}{Key_name}});
-
- $indexes{${%$i}{Key_name}}{columns}[${%$i}{Seq_in_index}-1]=
- ${%$i}{Column_name};
- }
- }
if(!defined($indexes{PRIMARY})) {
+ my @usage= ({val=>8},{val=>8},{val=>8},{val=>8});
+ @usage= @usage[0..$#releases];
$indexes{PRIMARY}= {
type=>'BTREE',
unique=>1,
@@ -212,20 +235,22 @@ foreach(@{$tables})
type=>'bigint',
size=>8,
key=>'PRI',
- datamemory=>[{val=>8},{val=>8},{val=>8}],
+ datamemory=>\@usage,
};
$columnsize{'HIDDEN_NDB_PKEY'}= [8,8,8];
}
- my @IndexDataMemory= ({val=>0},{val=>0},{val=>0});
- my @RowIndexMemory= ({val=>0},{val=>0},{val=>0});
+ my @IndexDataMemory= ({val=>0},{val=>0},{val=>0},{val=>0});
+ my @RowIndexMemory= ({val=>0},{val=>0},{val=>0},{val=>0});
+ @IndexDataMemory= @IndexDataMemory[0..$#releases];
+ @RowIndexMemory= @RowIndexMemory[0..$#releases];
my @indexes;
foreach my $index (keys %indexes) {
my $im41= 25;
$im41+=$columnsize{$_}[0] foreach @{$indexes{$index}{columns}};
- my @im = ({val=>$im41},{val=>25},{val=>25});
- my @dm = ({val=>10},{val=>10},{val=>10});
+ my @im = ({val=>$im41},{val=>25},{val=>25}); #,{val=>25});
+ my @dm = ({val=>10},{val=>10},{val=>10}); #,{val=>10});
push @indexes, {
name=>$index,
type=>$indexes{$index}{type},
@@ -233,13 +258,22 @@ foreach(@{$tables})
indexmemory=>\@im,
datamemory=>\@dm,
};
- $IndexDataMemory[$_]{val}+=$dm[$_]{val} foreach 0..2;
- $RowIndexMemory[$_]{val}+=$im[$_]{val} foreach 0..2;
+ $IndexDataMemory[$_]{val}+=$dm[$_]{val} foreach 0..$#releases;
+ $RowIndexMemory[$_]{val}+=$im[$_]{val} foreach 0..$#releases;
}
# total size + 16 bytes overhead
my @TotalDataMemory;
- $TotalDataMemory[$_]{val}=$IndexDataMemory[$_]{val}+$totalsize[$_]+16 foreach 0..2;
+ my @RowOverhead = ({val=>16},{val=>16},{val=>16}); #,{val=>24});
+ # 5.1 has ptr to varsize page, and per-varsize overhead
+ my @nrvarsize_mem= ({val=>0},{val=>0},
+ {val=>8}); #,{val=>0});
+ {
+ my @a= align(4,$nrvarsize*2);
+ $nrvarsize_mem[2]{val}+=$a[0]+$nrvarsize*4;
+ }
+
+ $TotalDataMemory[$_]{val}=$IndexDataMemory[$_]{val}+$totalsize[$_]+$RowOverhead[$_]{val}+$nrvarsize_mem[$_]{val} foreach 0..$#releases;
my @RowDataMemory;
push @RowDataMemory,{val=>$_} foreach @totalsize;
@@ -260,12 +294,18 @@ foreach(@{$tables})
my @counts;
$counts[$_]{val}= $count foreach 0..$#releases;
+ my @nrvarsize_rel= ({val=>0},{val=>0},
+ {val=>$nrvarsize}); #,{val=>0});
+
push @table_size, {
table=>$table,
indexes=>\@indexes,
columns=>\@columns,
count=>\@counts,
+ RowOverhead=>\@RowOverhead,
RowDataMemory=>\@RowDataMemory,
+ nrvarsize=>\@nrvarsize_rel,
+ nrvarsize_mem=>\@nrvarsize_mem,
releases=>\@releases,
IndexDataMemory=>\@IndexDataMemory,
TotalDataMemory=>\@TotalDataMemory,
@@ -283,6 +323,31 @@ foreach(@{$tables})
$NoOfIndexes[$_]{val} += @indexes foreach 0..$#releases;
}
+foreach(@{$tables})
+{
+ my $table= @{$_}[0];
+ my $info= $dbh->selectall_hashref('describe `'.$table.'`',"Field");
+ my @count = $dbh->selectrow_array('select count(*) from `'.$table.'`');
+
+ my %indexes;
+ {
+ my $sth= $dbh->prepare("show index from `".$table.'`');
+ $sth->execute;
+ while(my $i = $sth->fetchrow_hashref)
+ {
+ $indexes{${%$i}{Key_name}}= {
+ type=>${%$i}{Index_type},
+ unique=>!${%$i}{Non_unique},
+ comment=>${%$i}{Comment},
+ } if !defined($indexes{${%$i}{Key_name}});
+
+ $indexes{${%$i}{Key_name}}{columns}[${%$i}{Seq_in_index}-1]=
+ ${%$i}{Column_name};
+ }
+ }
+ do_table($table, $info, \%indexes, \@count);
+}
+
my @NoOfTriggers;
# for unique hash indexes
$NoOfTriggers[$_]{val} += $NoOfIndexes[$_]{val}*3 foreach 0..$#releases;
diff --git a/storage/ndb/tools/ndb_size.tmpl b/storage/ndb/tools/ndb_size.tmpl
index dc02b5a5970..1e19ea132ba 100644
--- a/storage/ndb/tools/ndb_size.tmpl
+++ b/storage/ndb/tools/ndb_size.tmpl
@@ -15,6 +15,8 @@ td,th { border: 1px solid black }
<p>This information should be valid for MySQL 4.1 and 5.0. Since 5.1 is not a final release yet, the numbers should be used as a guide only.</p>
+<p>5.1-dd is for tables stored on disk. The ndb_size.pl estimates are <b>experimental</b> and should not be trusted. Notably we don't take into account indexed columns being in DataMemory versus non-indexed on disk.</p>
+
<h2>Parameter Settings</h2>
<p><b>NOTE</b> the configuration parameters below do not take into account system tables and other requirements.</p>
<table>
@@ -69,6 +71,7 @@ td,th { border: 1px solid black }
<tr>
<th>Column</th>
<th>Type</th>
+ <th>VARSIZE</th>
<th>Size</th>
<th>Key</th>
<TMPL_LOOP NAME=releases>
@@ -79,6 +82,7 @@ td,th { border: 1px solid black }
<tr>
<td><TMPL_VAR NAME=name></td>
<td><TMPL_VAR NAME=type></td>
+ <td><TMPL_IF NAME=is_varsize>YES<TMPL_ELSE>&nbsp;</TMPL_IF></td>
<td><TMPL_VAR NAME=size></td>
<td><TMPL_VAR NAME=key></td>
<TMPL_LOOP NAME=datamemory>
@@ -129,9 +133,21 @@ td,th { border: 1px solid black }
</TMPL_LOOP>
</tr>
<tr>
+ <th>Nr Varsized Attributes</th>
+ <TMPL_LOOP NAME=nrvarsize>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
<th>Row Overhead</th>
- <TMPL_LOOP NAME=releases>
- <td>16</td>
+ <TMPL_LOOP NAME=RowOverhead>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Varsized Overhead</th>
+ <TMPL_LOOP NAME=nrvarsize_mem>
+ <td><TMPL_VAR NAME=val></td>
</TMPL_LOOP>
</tr>
<tr>
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 148295398f4..a44ada5dd72 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -121,8 +121,9 @@ static void client_disconnect();
void die(const char *file, int line, const char *expr)
{
+ fflush(stdout);
fprintf(stderr, "%s:%d: check failed: '%s'\n", file, line, expr);
- fflush(NULL);
+ fflush(stderr);
abort();
}
@@ -7496,10 +7497,22 @@ static void test_explain_bug()
MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
0, 0, "", 3, 0);
- verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
- mysql_get_server_version(mysql) <= 50000 ?
- MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
- 0, 0, "", 64, 0);
+ if ( mysql_get_server_version(mysql) >= 50027 )
+ {
+ /* The patch for bug#23037 changes column type of DEAULT to blob */
+ verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
+ MYSQL_TYPE_BLOB, 0, 0, "", 0, 0);
+ }
+ else
+ {
+ verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
+ mysql_get_server_version(mysql) >= 50027 ?
+ MYSQL_TYPE_BLOB :
+ mysql_get_server_version(mysql) <= 50000 ?
+ MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
+ 0, 0, "",
+ mysql_get_server_version(mysql) >= 50027 ? 0 :64, 0);
+ }
verify_prepare_field(result, 5, "Extra", "EXTRA",
mysql_get_server_version(mysql) <= 50000 ?
@@ -8685,7 +8698,7 @@ static void test_sqlmode()
if (!opt_silent)
fprintf(stdout, "\n query: %s", query);
stmt= mysql_simple_prepare(mysql, query);
- check_stmt_r(stmt);
+ check_stmt(stmt);
/* ANSI */
strmov(query, "SET SQL_MODE= \"ANSI\"");
@@ -11977,6 +11990,19 @@ static void test_cursors_with_union()
fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
}
+
+static void test_cursors_with_procedure()
+{
+ const char *queries[]=
+ {
+ "SELECT * FROM t1 procedure analyse()"
+ };
+ myheader("test_cursors_with_procedure");
+ fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
+ fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
+}
+
+
/*
Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they
should not crash server and should not hang in case of errors.
@@ -14454,6 +14480,7 @@ static void test_bug11718()
printf("return type: %s", (res->fields[0].type == MYSQL_TYPE_DATE)?"DATE":
"not DATE");
DIE_UNLESS(res->fields[0].type == MYSQL_TYPE_DATE);
+ mysql_free_result(res);
rc= mysql_query(mysql, "drop table t1, t2");
myquery(rc);
}
@@ -14920,6 +14947,8 @@ static void test_bug15613()
DIE_UNLESS(field[4].length == 255);
DIE_UNLESS(field[5].length == 255);
DIE_UNLESS(field[6].length == 255);
+ mysql_free_result(metadata);
+ mysql_stmt_free_result(stmt);
/* III. Cleanup */
rc= mysql_query(mysql, "drop table t1");
@@ -15096,6 +15125,9 @@ static void test_bug14169()
if (!opt_silent)
printf("GROUP_CONCAT() result type %i", field[1].type);
DIE_UNLESS(field[1].type == MYSQL_TYPE_BLOB);
+ mysql_free_result(res);
+ mysql_stmt_free_result(stmt);
+ mysql_stmt_close(stmt);
rc= mysql_query(mysql, "drop table t1");
myquery(rc);
@@ -15343,7 +15375,7 @@ static void test_bug15752()
MYSQL mysql_local;
int rc, i;
const int ITERATION_COUNT= 100;
- char *query= "CALL p1()";
+ const char *query= "CALL p1()";
myheader("test_bug15752");
@@ -15702,6 +15734,7 @@ static struct my_tests_st my_tests[]= {
{ "test_view_insert_fields", test_view_insert_fields },
{ "test_basic_cursors", test_basic_cursors },
{ "test_cursors_with_union", test_cursors_with_union },
+ { "test_cursors_with_procedure", test_cursors_with_procedure },
{ "test_truncation", test_truncation },
{ "test_truncation_option", test_truncation_option },
{ "test_client_character_set", test_client_character_set },
diff --git a/vio/viossl.c b/vio/viossl.c
index 180c7a50fa7..b5fd0e11c02 100644
--- a/vio/viossl.c
+++ b/vio/viossl.c
@@ -26,6 +26,10 @@
#ifdef HAVE_OPENSSL
#ifdef __NETWARE__
+
+/* yaSSL already uses BSD sockets */
+#ifndef HAVE_YASSL
+
/*
The default OpenSSL implementation on NetWare uses WinSock.
This code allows us to use the BSD sockets.
@@ -47,6 +51,7 @@ static int SSL_set_fd_bsd(SSL *s, int fd)
#define SSL_set_fd(A, B) SSL_set_fd_bsd((A), (B))
+#endif /* HAVE_YASSL */
#endif /* __NETWARE__ */
@@ -82,7 +87,7 @@ int vio_ssl_read(Vio *vio, gptr buf, int size)
{
int r;
DBUG_ENTER("vio_ssl_read");
- DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d, ssl_: 0x%p",
+ DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d, ssl_: 0x%lx",
vio->sd, buf, size, vio->ssl_arg));
r= SSL_read((SSL*) vio->ssl_arg, buf, size);
@@ -99,7 +104,7 @@ int vio_ssl_write(Vio *vio, const gptr buf, int size)
{
int r;
DBUG_ENTER("vio_ssl_write");
- DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size));
+ DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size));
r= SSL_write((SSL*) vio->ssl_arg, buf, size);
#ifndef DBUG_OFF
diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c
index ca7a96d5801..77eedab87e4 100644
--- a/vio/viosslfactories.c
+++ b/vio/viosslfactories.c
@@ -86,8 +86,7 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0)
{
DBUG_PRINT("error",("unable to get certificate from '%s'\n", cert_file));
- /* FIX stderr */
- fprintf(stderr,"Error when connection to server using SSL:");
+ fprintf(stderr,"SSL error: ");
ERR_print_errors_fp(stderr);
fprintf(stderr,"Unable to get certificate from '%s'\n", cert_file);
fflush(stderr);
@@ -100,8 +99,7 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0)
{
DBUG_PRINT("error", ("unable to get private key from '%s'\n", key_file));
- /* FIX stderr */
- fprintf(stderr,"Error when connection to server using SSL:");
+ fprintf(stderr,"SSL error: ");
ERR_print_errors_fp(stderr);
fprintf(stderr,"Unable to get private key from '%s'\n", key_file);
fflush(stderr);
@@ -180,11 +178,15 @@ void netware_ssl_cleanup()
/* free memory from SSL_library_init() */
EVP_cleanup();
+/* OpenSSL NetWare port specific functions */
+#ifndef HAVE_YASSL
+
/* free global X509 method */
X509_STORE_method_cleanup();
/* free the thread_hash error table */
ERR_free_state_table();
+#endif
}
@@ -248,6 +250,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
{
DBUG_PRINT("error", ("failed to set ciphers to use"));
report_errors();
+ SSL_CTX_free(ssl_fd->ssl_context);
my_free((void*)ssl_fd,MYF(0));
DBUG_RETURN(0);
}
@@ -260,6 +263,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
{
DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
report_errors();
+ SSL_CTX_free(ssl_fd->ssl_context);
my_free((void*)ssl_fd,MYF(0));
DBUG_RETURN(0);
}
@@ -269,6 +273,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
{
DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
report_errors();
+ SSL_CTX_free(ssl_fd->ssl_context);
my_free((void*)ssl_fd,MYF(0));
DBUG_RETURN(0);
}