summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore996
-rwxr-xr-xBUILD/SETUP.sh12
-rwxr-xr-xBUILD/autorun.sh2
-rwxr-xr-xBUILD/compile-pentium-debug-max-no-ndb11
-rwxr-xr-xBUILD/compile-ppc-debug-max-no-ndb11
-rw-r--r--Makefile.am19
-rw-r--r--[-rwxr-xr-x]VC++Files/bdb/bdb.vcproj (renamed from VC++Files/storage/bdb/bdb.vcproj)1
-rw-r--r--[-rwxr-xr-x]VC++Files/client/mysql.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/client/mysqladmin.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/client/mysqlclient.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/client/mysqldump.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/client/mysqlimport.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/client/mysqlshow.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/client/mysqltest.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/comp_err/comp_err.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/dbug/dbug.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/heap/heap.vcproj (renamed from VC++Files/storage/heap/heap.vcproj)9
-rw-r--r--[-rwxr-xr-x]VC++Files/innobase/innobase.vcproj (renamed from VC++Files/storage/innobase/innobase.vcproj)9
-rw-r--r--[-rwxr-xr-x]VC++Files/libmysql/libmysql.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/libmysqld/examples/test_libmysqld.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/libmysqld/libmysqld.vcproj14
-rw-r--r--[-rwxr-xr-x]VC++Files/libmysqltest/myTest.vcproj6
-rw-r--r--[-rwxr-xr-x]VC++Files/my_print_defaults/my_print_defaults.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/myisam/myisam.vcproj (renamed from VC++Files/storage/myisam/myisam.vcproj)9
-rw-r--r--[-rwxr-xr-x]VC++Files/myisam_ftdump/myisam_ftdump.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/myisamchk/myisamchk.vcproj2
-rw-r--r--[-rwxr-xr-x]VC++Files/myisamlog/myisamlog.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/myisammrg/myisammrg.vcproj (renamed from VC++Files/storage/myisammrg/myisammrg.vcproj)9
-rw-r--r--[-rwxr-xr-x]VC++Files/myisampack/myisampack.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/mysql-test/mysql_test_run_new.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/mysql.sln541
-rw-r--r--[-rwxr-xr-x]VC++Files/mysqlbinlog/mysqlbinlog.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/mysqlcheck/mysqlcheck.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/mysqldemb/mysqldemb.vcproj0
-rw-r--r--VC++Files/mysqlserver/dummy.cpp0
-rw-r--r--[-rwxr-xr-x]VC++Files/mysqlserver/mysqlserver.vcproj11
-rw-r--r--VC++Files/mysys/mysys.dsp4
-rw-r--r--[-rwxr-xr-x]VC++Files/mysys/mysys.vcproj43
-rw-r--r--VC++Files/mysys/mysys_ia64.dsp4
-rw-r--r--[-rwxr-xr-x]VC++Files/perror/perror.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/regex/regex.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/replace/replace.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/sql/mysqld.vcproj86
-rw-r--r--[-rwxr-xr-x]VC++Files/strings/strings.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/test1/test1.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/tests/mysql_client_test.vcproj6
-rw-r--r--[-rwxr-xr-x]VC++Files/thr_test/thr_test.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/vio/vio.vcproj0
-rw-r--r--[-rwxr-xr-x]VC++Files/zlib/zlib.vcproj0
-rw-r--r--client/mysql.cc31
-rw-r--r--client/mysqlbinlog.cc2
-rw-r--r--client/mysqldump.c283
-rw-r--r--client/mysqltest.c129
-rw-r--r--cmd-line-utils/readline/complete.c11
-rw-r--r--cmd-line-utils/readline/display.c6
-rw-r--r--cmd-line-utils/readline/mbutil.c7
-rw-r--r--config/ac-macros/readline.m439
-rw-r--r--config/ac-macros/yassl.m47
-rw-r--r--configure.in1
-rw-r--r--dbug/my_main.c1
-rw-r--r--extra/Makefile.am2
-rw-r--r--extra/comp_err.c30
-rw-r--r--extra/yassl/mySTL/vector.hpp3
-rw-r--r--extra/yassl/taocrypt/include/hmac.hpp10
-rw-r--r--extra/yassl/taocrypt/src/random.cpp4
-rw-r--r--include/my_global.h2
-rw-r--r--include/my_pthread.h2
-rw-r--r--include/my_sys.h7
-rw-r--r--include/myisam.h15
-rw-r--r--include/mysql_com.h1
-rw-r--r--libmysqld/Makefile.am8
-rw-r--r--libmysqld/lib_sql.cc28
-rw-r--r--man/which.254
-rw-r--r--mysql-test/include/im_check_os.inc7
-rw-r--r--mysql-test/lib/init_db.sql2
-rw-r--r--mysql-test/lib/mtr_cases.pl46
-rw-r--r--mysql-test/lib/mtr_process.pl17
-rw-r--r--mysql-test/lib/mtr_report.pl4
-rwxr-xr-xmysql-test/mysql-test-run.pl400
-rw-r--r--mysql-test/r/bdb.result12
-rw-r--r--mysql-test/r/case.result8
-rw-r--r--mysql-test/r/cast.result12
-rw-r--r--mysql-test/r/ctype_ucs_binlog.result3
-rw-r--r--mysql-test/r/ctype_ujis.result30
-rw-r--r--mysql-test/r/ctype_utf8.result39
-rw-r--r--mysql-test/r/default.result32
-rw-r--r--mysql-test/r/derived.result12
-rw-r--r--mysql-test/r/federated.result26
-rw-r--r--mysql-test/r/federated_bug_13118.result39
-rw-r--r--mysql-test/r/func_group.result136
-rw-r--r--mysql-test/r/func_in.result9
-rw-r--r--mysql-test/r/func_str.result6
-rw-r--r--mysql-test/r/group_min_max.result20
-rw-r--r--mysql-test/r/heap.result8
-rw-r--r--mysql-test/r/im_daemon_life_cycle.result7
-rw-r--r--mysql-test/r/im_life_cycle.result64
-rw-r--r--mysql-test/r/im_options_set.result20
-rw-r--r--mysql-test/r/im_options_unset.result15
-rw-r--r--mysql-test/r/im_utils.result91
-rw-r--r--mysql-test/r/information_schema.result39
-rw-r--r--mysql-test/r/information_schema_inno.result2
-rw-r--r--mysql-test/r/innodb.result133
-rw-r--r--mysql-test/r/join_nested.result28
-rw-r--r--mysql-test/r/loaddata.result11
-rw-r--r--mysql-test/r/merge.result26
-rw-r--r--mysql-test/r/metadata.result2
-rw-r--r--mysql-test/r/multi_statement.result1
-rw-r--r--mysql-test/r/myisam.result73
-rw-r--r--mysql-test/r/mysqlbinlog.result30
-rw-r--r--mysql-test/r/mysqlbinlog2.result75
-rw-r--r--mysql-test/r/mysqldump-max.result266
-rw-r--r--mysql-test/r/mysqldump.result79
-rw-r--r--mysql-test/r/mysqltest.result6
-rw-r--r--mysql-test/r/ndb_alter_table.result116
-rw-r--r--mysql-test/r/ndb_config.result2
-rw-r--r--mysql-test/r/ps_1general.result17
-rw-r--r--mysql-test/r/ps_2myisam.result4
-rw-r--r--mysql-test/r/ps_3innodb.result4
-rw-r--r--mysql-test/r/ps_4heap.result4
-rw-r--r--mysql-test/r/ps_5merge.result8
-rw-r--r--mysql-test/r/ps_6bdb.result4
-rw-r--r--mysql-test/r/ps_7ndb.result4
-rw-r--r--mysql-test/r/range.result44
-rw-r--r--mysql-test/r/rpl_charset.result3
-rw-r--r--mysql-test/r/rpl_multi_delete.result9
-rw-r--r--mysql-test/r/rpl_multi_delete2.result29
-rw-r--r--mysql-test/r/rpl_multi_update.result13
-rw-r--r--mysql-test/r/rpl_sp.result2
-rw-r--r--mysql-test/r/rpl_timezone.result3
-rw-r--r--mysql-test/r/select.result118
-rw-r--r--mysql-test/r/skip_name_resolve.result7
-rw-r--r--mysql-test/r/sp-big.result46
-rw-r--r--mysql-test/r/sp.result87
-rw-r--r--mysql-test/r/sql_mode.result26
-rw-r--r--mysql-test/r/system_mysql_db.result2
-rw-r--r--mysql-test/r/temp_table.result29
-rw-r--r--mysql-test/r/type_bit.result10
-rw-r--r--mysql-test/r/type_decimal.result13
-rw-r--r--mysql-test/r/type_float.result4
-rw-r--r--mysql-test/r/type_newdecimal.result16
-rw-r--r--mysql-test/r/union.result15
-rw-r--r--mysql-test/r/update.result12
-rw-r--r--mysql-test/r/user_var-binlog.result3
-rw-r--r--mysql-test/r/variables.result2
-rw-r--r--mysql-test/r/view.result45
-rw-r--r--mysql-test/r/view_query_cache.result9
-rw-r--r--mysql-test/r/xa.result14
-rw-r--r--mysql-test/std_data/ndb_config_mycnf1.cnf15
-rw-r--r--mysql-test/t/cast.test4
-rw-r--r--mysql-test/t/ctype_ujis.test42
-rw-r--r--mysql-test/t/ctype_utf8.test18
-rw-r--r--mysql-test/t/default.test1
-rw-r--r--mysql-test/t/derived.test13
-rw-r--r--mysql-test/t/federated.test44
-rw-r--r--mysql-test/t/federated_bug_13118.test42
-rw-r--r--mysql-test/t/func_group.test69
-rw-r--r--mysql-test/t/func_in.test7
-rw-r--r--mysql-test/t/func_str.test10
-rw-r--r--mysql-test/t/group_min_max.test23
-rw-r--r--mysql-test/t/im_daemon_life_cycle-im.opt2
-rw-r--r--mysql-test/t/im_daemon_life_cycle.imtest15
-rw-r--r--mysql-test/t/im_life_cycle.imtest141
-rw-r--r--mysql-test/t/im_options_set.imtest142
-rw-r--r--mysql-test/t/im_options_unset.imtest150
-rw-r--r--mysql-test/t/im_utils.imtest115
-rw-r--r--mysql-test/t/information_schema.test11
-rw-r--r--mysql-test/t/information_schema_inno.test2
-rw-r--r--mysql-test/t/innodb.test168
-rw-r--r--mysql-test/t/join_nested.test31
-rwxr-xr-xmysql-test/t/kill_n_check.sh66
-rw-r--r--mysql-test/t/loaddata.test28
-rw-r--r--mysql-test/t/merge.test32
-rw-r--r--mysql-test/t/multi_statement.test4
-rw-r--r--mysql-test/t/myisam.test54
-rw-r--r--mysql-test/t/mysql.test10
-rw-r--r--mysql-test/t/mysqlbinlog.test4
-rw-r--r--mysql-test/t/mysqldump-max.test73
-rw-r--r--mysql-test/t/mysqldump.test14
-rw-r--r--mysql-test/t/mysqltest.test20
-rw-r--r--mysql-test/t/ndb_alter_table.test119
-rw-r--r--mysql-test/t/ndb_config.test3
-rw-r--r--mysql-test/t/range.test50
-rw-r--r--mysql-test/t/rpl_multi_delete.test26
-rw-r--r--mysql-test/t/rpl_multi_delete2-slave.opt2
-rw-r--r--mysql-test/t/rpl_multi_delete2.test45
-rw-r--r--mysql-test/t/rpl_multi_update.test23
-rw-r--r--mysql-test/t/select.test86
-rw-r--r--mysql-test/t/skip_name_resolve.test10
-rw-r--r--mysql-test/t/sp-big.test49
-rw-r--r--mysql-test/t/sp.test108
-rw-r--r--mysql-test/t/sql_mode.test12
-rw-r--r--mysql-test/t/temp_table.test25
-rw-r--r--mysql-test/t/type_bit.test2
-rw-r--r--mysql-test/t/type_decimal.test10
-rw-r--r--mysql-test/t/type_float.test9
-rw-r--r--mysql-test/t/union.test8
-rw-r--r--mysql-test/t/update.test12
-rw-r--r--mysql-test/t/view.test43
-rw-r--r--mysql-test/t/view_query_cache.test12
-rw-r--r--mysql-test/t/xa.test14
-rw-r--r--mysql-test/valgrind.supp24
-rw-r--r--mysys/default.c6
-rw-r--r--mysys/mf_iocache.c4
-rw-r--r--mysys/mf_keycache.c72
-rw-r--r--mysys/my_alloc.c51
-rw-r--r--mysys/my_conio.c217
-rw-r--r--mysys/my_init.c25
-rw-r--r--ndb/tools/ndb_size.pl263
-rw-r--r--ndb/tools/ndb_size.tmpl175
-rw-r--r--os2/MySQL-Source.icc4
-rw-r--r--regex/Makefile.am2
-rw-r--r--regex/debug.c5
-rw-r--r--regex/debug.ih2
-rw-r--r--regex/engine.c8
-rw-r--r--regex/engine.ih2
-rw-r--r--regex/main.c52
-rw-r--r--regex/main.ih2
-rw-r--r--regex/my_regex.h (renamed from regex/regex.h)16
-rw-r--r--regex/regcomp.c10
-rw-r--r--regex/regerror.c6
-rw-r--r--regex/regerror.ih2
-rw-r--r--regex/regexec.c9
-rw-r--r--regex/regfree.c6
-rw-r--r--regex/reginit.c4
-rw-r--r--scripts/make_binary_distribution.sh3
-rw-r--r--scripts/mysql_config.sh15
-rw-r--r--scripts/mysql_create_system_tables.sh2
-rw-r--r--scripts/mysql_fix_privilege_tables.sh13
-rw-r--r--scripts/mysql_fix_privilege_tables.sql2
-rw-r--r--scripts/mysqld_multi.sh3
-rw-r--r--server-tools/instance-manager/buffer.cc4
-rw-r--r--server-tools/instance-manager/buffer.h6
-rw-r--r--server-tools/instance-manager/command.cc2
-rw-r--r--server-tools/instance-manager/command.h2
-rw-r--r--server-tools/instance-manager/commands.cc4
-rw-r--r--server-tools/instance-manager/guardian.cc2
-rw-r--r--server-tools/instance-manager/guardian.h2
-rw-r--r--server-tools/instance-manager/instance.cc2
-rw-r--r--server-tools/instance-manager/instance.h2
-rw-r--r--server-tools/instance-manager/instance_map.cc2
-rw-r--r--server-tools/instance-manager/instance_map.h2
-rw-r--r--server-tools/instance-manager/instance_options.cc4
-rw-r--r--server-tools/instance-manager/instance_options.h2
-rw-r--r--server-tools/instance-manager/listener.cc2
-rw-r--r--server-tools/instance-manager/listener.h2
-rw-r--r--server-tools/instance-manager/mysql_connection.cc2
-rw-r--r--server-tools/instance-manager/mysql_connection.h2
-rw-r--r--server-tools/instance-manager/mysqlmanager.vcproj4
-rw-r--r--server-tools/instance-manager/options.cc2
-rw-r--r--server-tools/instance-manager/options.h2
-rw-r--r--server-tools/instance-manager/parse_output.cc1
-rw-r--r--server-tools/instance-manager/portability.h4
-rw-r--r--server-tools/instance-manager/protocol.cc13
-rw-r--r--server-tools/instance-manager/thread_registry.cc2
-rw-r--r--server-tools/instance-manager/thread_registry.h2
-rw-r--r--server-tools/instance-manager/user_map.cc5
-rw-r--r--server-tools/instance-manager/user_map.h2
-rw-r--r--sql/Makefile.am8
-rw-r--r--sql/examples/ha_example.cc10
-rw-r--r--sql/examples/ha_tina.cc32
-rw-r--r--sql/examples/ha_tina.h12
-rw-r--r--sql/field.cc2
-rw-r--r--sql/ha_archive.cc (renamed from sql/examples/ha_archive.cc)36
-rw-r--r--sql/ha_archive.h (renamed from sql/examples/ha_archive.h)2
-rw-r--r--sql/ha_berkeley.cc22
-rw-r--r--sql/ha_berkeley.h4
-rw-r--r--sql/ha_blackhole.cc8
-rw-r--r--sql/ha_federated.cc90
-rw-r--r--sql/ha_heap.cc8
-rw-r--r--sql/ha_innodb.cc101
-rw-r--r--sql/ha_innodb.h8
-rw-r--r--sql/ha_myisam.cc19
-rw-r--r--sql/ha_myisammrg.cc10
-rw-r--r--sql/ha_ndbcluster.cc69
-rw-r--r--sql/ha_ndbcluster.h6
-rw-r--r--sql/handler.cc355
-rw-r--r--sql/handler.h69
-rw-r--r--sql/item.cc58
-rw-r--r--sql/item.h6
-rw-r--r--sql/item_cmpfunc.cc32
-rw-r--r--sql/item_cmpfunc.h4
-rw-r--r--sql/item_func.cc101
-rw-r--r--sql/item_func.h10
-rw-r--r--sql/item_strfunc.cc42
-rw-r--r--sql/item_subselect.cc2
-rw-r--r--sql/item_sum.cc3
-rw-r--r--sql/log.cc28
-rw-r--r--sql/mysql_priv.h13
-rw-r--r--sql/mysqld.cc57
-rw-r--r--sql/opt_range.cc17
-rw-r--r--sql/opt_sum.cc74
-rw-r--r--sql/parse_file.cc53
-rw-r--r--sql/parse_file.h3
-rw-r--r--sql/password.c4
-rw-r--r--sql/protocol.h24
-rw-r--r--sql/repl_failsafe.cc4
-rw-r--r--sql/set_var.cc27
-rw-r--r--sql/share/errmsg.txt19
-rw-r--r--sql/slave.cc11
-rw-r--r--sql/slave.h2
-rw-r--r--sql/sp.cc5
-rw-r--r--sql/sp_head.cc186
-rw-r--r--sql/sp_head.h34
-rw-r--r--sql/sp_rcontext.cc222
-rw-r--r--sql/sp_rcontext.h70
-rw-r--r--sql/sql_acl.cc217
-rw-r--r--sql/sql_acl.h3
-rw-r--r--sql/sql_base.cc106
-rw-r--r--sql/sql_cache.cc3
-rw-r--r--sql/sql_class.cc88
-rw-r--r--sql/sql_class.h70
-rw-r--r--sql/sql_cursor.cc660
-rw-r--r--sql/sql_cursor.h65
-rw-r--r--sql/sql_db.cc19
-rw-r--r--sql/sql_delete.cc34
-rw-r--r--sql/sql_derived.cc43
-rw-r--r--sql/sql_insert.cc11
-rw-r--r--sql/sql_lex.h12
-rw-r--r--sql/sql_list.h2
-rw-r--r--sql/sql_load.cc16
-rw-r--r--sql/sql_parse.cc316
-rw-r--r--sql/sql_prepare.cc260
-rw-r--r--sql/sql_rename.cc42
-rw-r--r--sql/sql_select.cc454
-rw-r--r--sql/sql_select.h59
-rw-r--r--sql/sql_show.cc81
-rw-r--r--sql/sql_table.cc29
-rw-r--r--sql/sql_trigger.cc2
-rw-r--r--sql/sql_union.cc176
-rw-r--r--sql/sql_update.cc22
-rw-r--r--sql/sql_view.cc114
-rw-r--r--sql/sql_view.h1
-rw-r--r--sql/sql_yacc.yy96
-rw-r--r--sql/table.cc101
-rw-r--r--sql/table.h5
-rw-r--r--sql/unireg.cc4
-rw-r--r--storage/innobase/buf/buf0buf.c4
-rw-r--r--storage/innobase/buf/buf0flu.c4
-rw-r--r--storage/innobase/data/data0data.c10
-rw-r--r--storage/innobase/dict/dict0dict.c24
-rw-r--r--storage/innobase/include/btr0btr.h10
-rw-r--r--storage/innobase/include/data0type.ic2
-rw-r--r--storage/innobase/include/dict0dict.h7
-rw-r--r--storage/innobase/include/dict0mem.h14
-rw-r--r--storage/innobase/include/mem0mem.h3
-rw-r--r--storage/innobase/include/mem0mem.ic3
-rw-r--r--storage/innobase/include/os0file.h11
-rw-r--r--storage/innobase/include/row0mysql.h10
-rw-r--r--storage/innobase/include/trx0trx.h21
-rw-r--r--storage/innobase/include/ut0mem.h25
-rw-r--r--storage/innobase/mem/mem0mem.c4
-rw-r--r--storage/innobase/os/os0file.c23
-rw-r--r--storage/innobase/os/os0proc.c9
-rw-r--r--storage/innobase/rem/rem0rec.c2
-rw-r--r--storage/innobase/row/row0ins.c43
-rw-r--r--storage/innobase/row/row0mysql.c21
-rw-r--r--storage/innobase/srv/srv0start.c2
-rw-r--r--storage/innobase/trx/trx0sys.c19
-rw-r--r--storage/innobase/trx/trx0trx.c27
-rw-r--r--storage/innobase/ut/ut0mem.c48
-rw-r--r--storage/myisam/ft_boolean_search.c3
-rw-r--r--storage/myisam/mi_check.c40
-rw-r--r--storage/myisam/mi_dbug.c4
-rw-r--r--storage/myisam/mi_delete.c2
-rw-r--r--storage/myisam/mi_delete_all.c2
-rw-r--r--storage/myisam/mi_key.c2
-rw-r--r--storage/myisam/mi_open.c11
-rw-r--r--storage/myisam/mi_rkey.c7
-rw-r--r--storage/myisam/mi_search.c16
-rw-r--r--storage/myisam/mi_test1.c5
-rw-r--r--storage/myisam/mi_update.c2
-rw-r--r--storage/myisam/mi_write.c2
-rw-r--r--storage/myisam/myisamchk.c30
-rw-r--r--storage/myisam/myisamdef.h7
-rw-r--r--storage/myisam/myisampack.c22
-rw-r--r--storage/myisam/sp_key.c2
-rw-r--r--storage/myisammrg/myrg_rkey.c17
-rw-r--r--storage/ndb/include/kernel/GlobalSignalNumbers.h10
-rw-r--r--storage/ndb/include/kernel/signaldata/ApiVersion.hpp5
-rw-r--r--storage/ndb/include/kernel/signaldata/StopReq.hpp10
-rw-r--r--storage/ndb/include/mgmapi/ndb_logevent.h11
-rw-r--r--storage/ndb/include/ndbapi/Ndb.hpp28
-rw-r--r--storage/ndb/include/ndbapi/NdbBlob.hpp6
-rw-r--r--storage/ndb/include/ndbapi/NdbIndexOperation.hpp1
-rw-r--r--storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp3
-rw-r--r--storage/ndb/include/ndbapi/NdbOperation.hpp7
-rw-r--r--storage/ndb/include/ndbapi/NdbRecAttr.hpp7
-rw-r--r--storage/ndb/include/ndbapi/NdbTransaction.hpp8
-rw-r--r--storage/ndb/src/common/debugger/EventLogger.cpp24
-rw-r--r--storage/ndb/src/common/util/SimpleProperties.cpp7
-rw-r--r--storage/ndb/src/kernel/blocks/backup/Backup.cpp1
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp8
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/Makefile.am12
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp169
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp15
-rw-r--r--storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp65
-rw-r--r--storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp2
-rw-r--r--storage/ndb/src/mgmapi/ndb_logevent.cpp2
-rw-r--r--storage/ndb/src/mgmclient/CommandInterpreter.cpp7
-rw-r--r--storage/ndb/src/mgmsrv/Config.cpp87
-rw-r--r--storage/ndb/src/mgmsrv/Config.hpp10
-rw-r--r--storage/ndb/src/mgmsrv/ConfigInfo.cpp52
-rw-r--r--storage/ndb/src/mgmsrv/InitConfigFileParser.cpp377
-rw-r--r--storage/ndb/src/mgmsrv/InitConfigFileParser.hpp22
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvr.cpp1536
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvr.hpp190
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp241
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp120
-rw-r--r--storage/ndb/src/mgmsrv/Services.cpp59
-rw-r--r--storage/ndb/src/mgmsrv/Services.hpp3
-rw-r--r--storage/ndb/src/mgmsrv/main.cpp24
-rw-r--r--storage/ndb/src/ndbapi/NdbApiSignal.cpp19
-rw-r--r--storage/ndb/src/ndbapi/NdbApiSignal.hpp3
-rw-r--r--storage/ndb/src/ndbapi/NdbBlob.cpp2
-rw-r--r--storage/ndb/src/ndbapi/NdbImpl.hpp119
-rw-r--r--storage/ndb/src/ndbapi/NdbRecAttr.cpp4
-rw-r--r--storage/ndb/src/ndbapi/NdbUtil.cpp16
-rw-r--r--storage/ndb/src/ndbapi/NdbUtil.hpp41
-rw-r--r--storage/ndb/src/ndbapi/Ndbif.cpp9
-rw-r--r--storage/ndb/src/ndbapi/Ndbinit.cpp46
-rw-r--r--storage/ndb/src/ndbapi/Ndblist.cpp506
-rw-r--r--storage/ndb/src/ndbapi/ObjectMap.hpp33
-rw-r--r--storage/ndb/tools/ndb_condig.cpp221
-rw-r--r--storage/ndb/tools/restore/Restore.cpp2
-rw-r--r--storage/ndb/tools/restore/consumer_restore.cpp2
-rw-r--r--strings/decimal.c2
-rw-r--r--support-files/mysql.spec.sh7
-rw-r--r--tests/mysql_client_test.c7
-rw-r--r--zlib/ChangeLog98
-rw-r--r--zlib/FAQ26
-rw-r--r--zlib/README9
-rw-r--r--zlib/README.MySQL7
-rw-r--r--zlib/adler32.c111
-rw-r--r--zlib/compress.c2
-rw-r--r--zlib/crc32.c102
-rw-r--r--zlib/deflate.c282
-rw-r--r--zlib/deflate.h10
-rw-r--r--zlib/gzio.c51
-rw-r--r--zlib/infback.c11
-rw-r--r--zlib/inffast.c13
-rw-r--r--zlib/inflate.c126
-rw-r--r--zlib/inflate.h8
-rw-r--r--zlib/inftrees.c9
-rw-r--r--zlib/trees.c36
-rw-r--r--zlib/zconf.h12
-rw-r--r--zlib/zlib.36
-rw-r--r--zlib/zlib.h229
-rw-r--r--zlib/zutil.c33
-rw-r--r--zlib/zutil.h30
449 files changed, 13068 insertions, 6096 deletions
diff --git a/.bzrignore b/.bzrignore
index 92e96bc4a23..7294be6cb60 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -115,127 +115,135 @@ autom4te.cache/*
autom4te.cache/output.0
autom4te.cache/requests
autom4te.cache/traces.0
-storage/bdb/btree/btree_auto.c
-storage/bdb/btree/btree_autop.c
-storage/bdb/build_unix/*
-storage/bdb/build_vxworks/BerkeleyDB20small.wpj
-storage/bdb/build_vxworks/BerkeleyDB20.wpj
-storage/bdb/build_vxworks/BerkeleyDB22small.wpj
-storage/bdb/build_vxworks/BerkeleyDB22.wpj
-storage/bdb/build_vxworks/db_config.h
-storage/bdb/build_vxworks/db_config_small.h
-storage/bdb/build_vxworks/db_deadlock/db_deadlock20.wpj
-storage/bdb/build_vxworks/db_deadlock/db_deadlock22.wpj
-storage/bdb/build_vxworks/dbdemo/dbdemo20.wpj
-storage/bdb/build_vxworks/dbdemo/dbdemo22.wpj
-storage/bdb/build_vxworks/dbdemo/dbdemo.c
-storage/bdb/build_vxworks/db.h
-storage/bdb/build_vxworks/db_int.h
-storage/bdb/build_win32/*.dsp
-storage/bdb/build_win32/*.h
-storage/bdb/build_win32/include.tcl
-storage/bdb/build_win32/libdb.def
-storage/bdb/build_win32/libdb.rc
-storage/bdb/db/crdel_auto.c
-storage/bdb/db/crdel_autop.c
-storage/bdb/db/db_auto.c
-storage/bdb/db/db_autop.c
-storage/bdb/dbinc_auto/*.*
-storage/bdb/dbreg/dbreg_auto.c
-storage/bdb/dbreg/dbreg_autop.c
-storage/bdb/dist/autom4te-2.53.cache/*
-storage/bdb/dist/autom4te-2.53.cache/output.0
-storage/bdb/dist/autom4te-2.53.cache/requests
-storage/bdb/dist/autom4te-2.53.cache/traces.0
-storage/bdb/dist/autom4te.cache/*
-storage/bdb/dist/autom4te.cache/output.0
-storage/bdb/dist/autom4te.cache/requests
-storage/bdb/dist/autom4te.cache/traces.0
-storage/bdb/dist/config.hin
-storage/bdb/dist/configure
-storage/bdb/dist/tags
-storage/bdb/dist/template/db_server_proc
-storage/bdb/dist/template/gen_client_ret
-storage/bdb/dist/template/rec_btree
-storage/bdb/dist/template/rec_crdel
-storage/bdb/dist/template/rec_db
-storage/bdb/dist/template/rec_dbreg
-storage/bdb/dist/template/rec_fileops
-storage/bdb/dist/template/rec_hash
-storage/bdb/dist/template/rec_log
-storage/bdb/dist/template/rec_qam
-storage/bdb/dist/template/rec_txn
-storage/bdb/examples_c/ex_apprec/ex_apprec_auto.c
-storage/bdb/examples_c/ex_apprec/ex_apprec_auto.h
-storage/bdb/examples_c/ex_apprec/ex_apprec_template
-storage/bdb/examples_java
-storage/bdb/fileops/fileops_auto.c
-storage/bdb/fileops/fileops_autop.c
-storage/bdb/hash/hash_auto.c
-storage/bdb/hash/hash_autop.c
-storage/bdb/include/btree_auto.h
-storage/bdb/include/btree_ext.h
-storage/bdb/include/clib_ext.h
-storage/bdb/include/common_ext.h
-storage/bdb/include/crdel_auto.h
-storage/bdb/include/db_auto.h
-storage/bdb/include/db_ext.h
-storage/bdb/include/db_server.h
-storage/bdb/include/env_ext.h
-storage/bdb/include/gen_client_ext.h
-storage/bdb/include/gen_server_ext.h
-storage/bdb/include/hash_auto.h
-storage/bdb/include/hash_ext.h
-storage/bdb/include/lock_ext.h
-storage/bdb/include/log_auto.h
-storage/bdb/include/log_ext.h
-storage/bdb/include/mp_ext.h
-storage/bdb/include/mutex_ext.h
-storage/bdb/include/os_ext.h
-storage/bdb/include/qam_auto.h
-storage/bdb/include/qam_ext.h
-storage/bdb/include/rpc_client_ext.h
-storage/bdb/include/rpc_server_ext.h
-storage/bdb/include/tcl_ext.h
-storage/bdb/include/txn_auto.h
-storage/bdb/include/txn_ext.h
-storage/bdb/include/xa_ext.h
-storage/bdb/java/src/com/sleepycat/db/DbBtreeStat.java
-storage/bdb/java/src/com/sleepycat/db/DbConstants.java
-storage/bdb/java/src/com/sleepycat/db/DbHashStat.java
-storage/bdb/java/src/com/sleepycat/db/Db.java
-storage/bdb/java/src/com/sleepycat/db/DbLockStat.java
-storage/bdb/java/src/com/sleepycat/db/DbLogStat.java
-storage/bdb/java/src/com/sleepycat/db/DbMpoolFStat.java
-storage/bdb/java/src/com/sleepycat/db/DbQueueStat.java
-storage/bdb/java/src/com/sleepycat/db/DbRepStat.java
-storage/bdb/java/src/com/sleepycat/db/DbTxnStat.java
-storage/bdb/libdb_java/java_stat_auto.c
-storage/bdb/libdb_java/java_stat_auto.h
-storage/bdb/libdb_java/java_util.i
-storage/bdb/log/log_auto.c
-storage/bdb/qam/qam_auto.c
-storage/bdb/qam/qam_autop.c
-storage/bdb/README
-storage/bdb/rep/rep_auto.c
-storage/bdb/rep/rep_autop.c
-storage/bdb/rpc_client/db_server_clnt.c
-storage/bdb/rpc_client/gen_client.c
-storage/bdb/rpc_server/c/db_server_proc.c
-storage/bdb/rpc_server/c/db_server_proc.sed
-storage/bdb/rpc_server/c/db_server_svc.c
-storage/bdb/rpc_server/c/db_server_xdr.c
-storage/bdb/rpc_server/c/gen_db_server.c
-storage/bdb/rpc_server/db_server_proc.sed
-storage/bdb/rpc_server/db_server_svc.c
-storage/bdb/rpc_server/db_server.x
-storage/bdb/rpc_server/db_server_xdr.c
-storage/bdb/rpc_server/gen_db_server.c
-storage/bdb/test/include.tcl
-storage/bdb/test/logtrack.list
-storage/bdb/test/TESTS
-storage/bdb/txn/txn_auto.c
-storage/bdb/txn/txn_autop.c
+bdb/README
+bdb/btree/btree_auto.c
+bdb/build_unix/*
+bdb/build_vxworks/db.h
+bdb/build_vxworks/db_int.h
+bdb/build_win32/db.h
+bdb/build_win32/db_archive.dsp
+bdb/build_win32/db_checkpoint.dsp
+bdb/build_win32/db_config.h
+bdb/build_win32/db_cxx.h
+bdb/build_win32/db_deadlock.dsp
+bdb/build_win32/db_dll.dsp
+bdb/build_win32/db_dump.dsp
+bdb/build_win32/db_int.h
+bdb/build_win32/db_java.dsp
+bdb/build_win32/db_load.dsp
+bdb/build_win32/db_perf.dsp
+bdb/build_win32/db_printlog.dsp
+bdb/build_win32/db_recover.dsp
+bdb/build_win32/db_stat.dsp
+bdb/build_win32/db_static.dsp
+bdb/build_win32/db_tcl.dsp
+bdb/build_win32/db_test.dsp
+bdb/build_win32/db_upgrade.dsp
+bdb/build_win32/db_verify.dsp
+bdb/build_win32/ex_access.dsp
+bdb/build_win32/ex_btrec.dsp
+bdb/build_win32/ex_env.dsp
+bdb/build_win32/ex_lock.dsp
+bdb/build_win32/ex_mpool.dsp
+bdb/build_win32/ex_tpcb.dsp
+bdb/build_win32/excxx_access.dsp
+bdb/build_win32/excxx_btrec.dsp
+bdb/build_win32/excxx_env.dsp
+bdb/build_win32/excxx_lock.dsp
+bdb/build_win32/excxx_mpool.dsp
+bdb/build_win32/excxx_tpcb.dsp
+bdb/build_win32/include.tcl
+bdb/build_win32/libdb.def
+bdb/build_win32/libdb.rc
+bdb/db/crdel_auto.c
+bdb/db/db_auto.c
+bdb/dbinc_auto/*.*
+bdb/dbreg/dbreg_auto.c
+bdb/dist/autom4te-2.53.cache/*
+bdb/dist/autom4te-2.53.cache/output.0
+bdb/dist/autom4te-2.53.cache/requests
+bdb/dist/autom4te-2.53.cache/traces.0
+bdb/dist/autom4te.cache/*
+bdb/dist/autom4te.cache/output.0
+bdb/dist/autom4te.cache/requests
+bdb/dist/autom4te.cache/traces.0
+bdb/dist/config.hin
+bdb/dist/configure
+bdb/dist/tags
+bdb/dist/template/db_server_proc
+bdb/dist/template/gen_client_ret
+bdb/dist/template/rec_btree
+bdb/dist/template/rec_crdel
+bdb/dist/template/rec_db
+bdb/dist/template/rec_dbreg
+bdb/dist/template/rec_fileops
+bdb/dist/template/rec_hash
+bdb/dist/template/rec_log
+bdb/dist/template/rec_qam
+bdb/dist/template/rec_txn
+bdb/examples_c/ex_apprec/ex_apprec_auto.c
+bdb/examples_c/ex_apprec/ex_apprec_auto.h
+bdb/examples_c/ex_apprec/ex_apprec_template
+bdb/examples_java
+bdb/fileops/fileops_auto.c
+bdb/hash/hash_auto.c
+bdb/include/btree_auto.h
+bdb/include/btree_ext.h
+bdb/include/clib_ext.h
+bdb/include/common_ext.h
+bdb/include/crdel_auto.h
+bdb/include/db_auto.h
+bdb/include/db_ext.h
+bdb/include/db_server.h
+bdb/include/env_ext.h
+bdb/include/gen_client_ext.h
+bdb/include/gen_server_ext.h
+bdb/include/hash_auto.h
+bdb/include/hash_ext.h
+bdb/include/lock_ext.h
+bdb/include/log_auto.h
+bdb/include/log_ext.h
+bdb/include/mp_ext.h
+bdb/include/mutex_ext.h
+bdb/include/os_ext.h
+bdb/include/qam_auto.h
+bdb/include/qam_ext.h
+bdb/include/rpc_client_ext.h
+bdb/include/rpc_server_ext.h
+bdb/include/tcl_ext.h
+bdb/include/txn_auto.h
+bdb/include/txn_ext.h
+bdb/include/xa_ext.h
+bdb/java/src/com/sleepycat/db/Db.java
+bdb/java/src/com/sleepycat/db/DbBtreeStat.java
+bdb/java/src/com/sleepycat/db/DbConstants.java
+bdb/java/src/com/sleepycat/db/DbHashStat.java
+bdb/java/src/com/sleepycat/db/DbLockStat.java
+bdb/java/src/com/sleepycat/db/DbLogStat.java
+bdb/java/src/com/sleepycat/db/DbMpoolFStat.java
+bdb/java/src/com/sleepycat/db/DbQueueStat.java
+bdb/java/src/com/sleepycat/db/DbRepStat.java
+bdb/java/src/com/sleepycat/db/DbTxnStat.java
+bdb/libdb_java/java_stat_auto.c
+bdb/libdb_java/java_stat_auto.h
+bdb/log/log_auto.c
+bdb/qam/qam_auto.c
+bdb/rpc_client/db_server_clnt.c
+bdb/rpc_client/gen_client.c
+bdb/rpc_server/c/db_server_proc.c
+bdb/rpc_server/c/db_server_proc.sed
+bdb/rpc_server/c/db_server_svc.c
+bdb/rpc_server/c/db_server_xdr.c
+bdb/rpc_server/c/gen_db_server.c
+bdb/rpc_server/db_server.x
+bdb/rpc_server/db_server_proc.sed
+bdb/rpc_server/db_server_svc.c
+bdb/rpc_server/db_server_xdr.c
+bdb/rpc_server/gen_db_server.c
+bdb/test/TESTS
+bdb/test/include.tcl
+bdb/test/logtrack.list
+bdb/txn/txn_auto.c
binary/*
bkpull.log
bkpull.log*
@@ -322,8 +330,8 @@ fcns.h
gdbinit
gmon.out
hardcopy.0
-storage/heap/hp_test1
-storage/heap/hp_test2
+heap/hp_test1
+heap/hp_test2
help
help.c
help.h
@@ -337,21 +345,21 @@ include/readline/*.h
include/readline/readline.h
include/sql_state.h
include/widec.h
-storage/innobase/autom4te-2.53.cache/*
-storage/innobase/autom4te-2.53.cache/output.0
-storage/innobase/autom4te-2.53.cache/requests
-storage/innobase/autom4te-2.53.cache/traces.0
-storage/innobase/autom4te.cache/*
-storage/innobase/autom4te.cache/output.0
-storage/innobase/autom4te.cache/requests
-storage/innobase/autom4te.cache/traces.0
-storage/innobase/configure.lineno
-storage/innobase/conftest.s1
-storage/innobase/conftest.subs
-storage/innobase/ib_config.h
-storage/innobase/ib_config.h.in
-storage/innobase/mkinstalldirs
-storage/innobase/stamp-h1
+innobase/autom4te-2.53.cache/*
+innobase/autom4te-2.53.cache/output.0
+innobase/autom4te-2.53.cache/requests
+innobase/autom4te-2.53.cache/traces.0
+innobase/autom4te.cache/*
+innobase/autom4te.cache/output.0
+innobase/autom4te.cache/requests
+innobase/autom4te.cache/traces.0
+innobase/configure.lineno
+innobase/conftest.s1
+innobase/conftest.subs
+innobase/ib_config.h
+innobase/ib_config.h.in
+innobase/mkinstalldirs
+innobase/stamp-h1
insert_test
install
install-sh
@@ -472,6 +480,8 @@ libmysqld/sql_cache.cc
libmysqld/sql_class.cc
libmysqld/sql_command
libmysqld/sql_crypt.cc
+libmysqld/sql_cursor.cc
+libmysqld/sql_cursor.h
libmysqld/sql_db.cc
libmysqld/sql_delete.cc
libmysqld/sql_derived.cc
@@ -535,31 +545,31 @@ mit-pthreads/pg++
mit-pthreads/pgcc
mit-pthreads/syscall.S
mkinstalldirs
-storage/myisam/FT1.MYD
-storage/myisam/FT1.MYI
-storage/myisam/ft_dump
-storage/myisam/ft_eval
-storage/myisam/ft_test1
-storage/myisam/ftbench/data
-storage/myisam/ftbench/t
-storage/myisam/ftbench/var/*
-storage/myisam/mi_test1
-storage/myisam/mi_test2
-storage/myisam/mi_test3
-storage/myisam/mi_test_all
-storage/myisam/myisam.log
-storage/myisam/myisam_ftdump
-storage/myisam/myisamchk
-storage/myisam/myisamlog
-storage/myisam/myisampack
-storage/myisam/rt_test
-storage/myisam/rt_test.MYD
-storage/myisam/rt_test.MYI
-storage/myisam/sp_test
-storage/myisam/test1.MYD
-storage/myisam/test1.MYI
-storage/myisam/test2.MYD
-storage/myisam/test2.MYI
+myisam/FT1.MYD
+myisam/FT1.MYI
+myisam/ft_dump
+myisam/ft_eval
+myisam/ft_test1
+myisam/ftbench/data
+myisam/ftbench/t
+myisam/ftbench/var/*
+myisam/mi_test1
+myisam/mi_test2
+myisam/mi_test3
+myisam/mi_test_all
+myisam/myisam.log
+myisam/myisam_ftdump
+myisam/myisamchk
+myisam/myisamlog
+myisam/myisampack
+myisam/rt_test
+myisam/rt_test.MYD
+myisam/rt_test.MYI
+myisam/sp_test
+myisam/test1.MYD
+myisam/test1.MYI
+myisam/test2.MYD
+myisam/test2.MYI
mysql-4.0.2-alpha-pc-linux-gnu-i686.tar.gz
mysql-4.0.2-alpha.tar.gz
mysql-4.1.8-win-src.zip
@@ -658,6 +668,538 @@ mysys/test_thr_alarm
mysys/test_thr_lock
mysys/test_vsnprintf
mysys/testhash
+ndb/bin/DbAsyncGenerator
+ndb/bin/DbCreate
+ndb/bin/acid
+ndb/bin/async-lmc-bench-l-p10.sh
+ndb/bin/async-lmc-bench-l.sh
+ndb/bin/async-lmc-bench-p10.sh
+ndb/bin/async-lmc-bench.sh
+ndb/bin/atrt
+ndb/bin/atrt-analyze-result.sh
+ndb/bin/atrt-clear-result.sh
+ndb/bin/atrt-gather-result.sh
+ndb/bin/atrt-setup.sh
+ndb/bin/bankCreator
+ndb/bin/bankMakeGL
+ndb/bin/bankSumAccounts
+ndb/bin/bankTimer
+ndb/bin/bankTransactionMaker
+ndb/bin/bankValidateAllGLs
+ndb/bin/basicTransporterTest
+ndb/bin/benchronja
+ndb/bin/bulk_copy
+ndb/bin/copy_tab
+ndb/bin/create_all_tabs
+ndb/bin/create_index
+ndb/bin/create_tab
+ndb/bin/delete_all
+ndb/bin/desc
+ndb/bin/drop_all_tabs
+ndb/bin/drop_index
+ndb/bin/drop_tab
+ndb/bin/flexAsynch
+ndb/bin/flexBench
+ndb/bin/flexHammer
+ndb/bin/flexScan
+ndb/bin/flexTT
+ndb/bin/hugoCalculator
+ndb/bin/hugoFill
+ndb/bin/hugoLoad
+ndb/bin/hugoLockRecords
+ndb/bin/hugoPkDelete
+ndb/bin/hugoPkRead
+ndb/bin/hugoPkReadRecord
+ndb/bin/hugoPkUpdate
+ndb/bin/hugoScanRead
+ndb/bin/hugoScanUpdate
+ndb/bin/index
+ndb/bin/index2
+ndb/bin/initronja
+ndb/bin/interpreterInTup
+ndb/bin/list_tables
+ndb/bin/make-config.sh
+ndb/bin/mgmtclient
+ndb/bin/mgmtsrvr
+ndb/bin/mkconfig
+ndb/bin/ndb
+ndb/bin/ndb_cpcc
+ndb/bin/ndb_cpcd
+ndb/bin/ndb_rep
+ndb/bin/ndbsql
+ndb/bin/newton_basic
+ndb/bin/newton_br
+ndb/bin/newton_pb
+ndb/bin/newton_perf
+ndb/bin/perfTransporterTest
+ndb/bin/printConfig
+ndb/bin/printSchemafile
+ndb/bin/printSysfile
+ndb/bin/redoLogFileReader
+ndb/bin/restart
+ndb/bin/restarter
+ndb/bin/restarter2
+ndb/bin/restarts
+ndb/bin/restore
+ndb/bin/select_all
+ndb/bin/select_count
+ndb/bin/telco
+ndb/bin/testBackup
+ndb/bin/testBank
+ndb/bin/testBasic
+ndb/bin/testBasicAsynch
+ndb/bin/testCopy
+ndb/bin/testDataBuffers
+ndb/bin/testDict
+ndb/bin/testGrep
+ndb/bin/testGrepVerify
+ndb/bin/testIndex
+ndb/bin/testInterpreter
+ndb/bin/testKernelDataBuffer
+ndb/bin/testLongSig
+ndb/bin/testMgm
+ndb/bin/testMgmapi
+ndb/bin/testNdbApi
+ndb/bin/testNodeRestart
+ndb/bin/testOIBasic
+ndb/bin/testOdbcDriver
+ndb/bin/testOperations
+ndb/bin/testRestartGci
+ndb/bin/testScan
+ndb/bin/testScanInterpreter
+ndb/bin/testSimplePropertiesSection
+ndb/bin/testSystemRestart
+ndb/bin/testTimeout
+ndb/bin/testTransactions
+ndb/bin/test_cpcd
+ndb/bin/test_event
+ndb/bin/verify_index
+ndb/bin/waiter
+ndb/config/autom4te.cache/*
+ndb/config/config.mk
+ndb/examples/ndbapi_example1/ndbapi_example1
+ndb/examples/ndbapi_example2/ndbapi_example2
+ndb/examples/ndbapi_example3/ndbapi_example3
+ndb/examples/ndbapi_example5/ndbapi_example5
+ndb/examples/select_all/select_all
+ndb/include/ndb_global.h
+ndb/include/ndb_types.h
+ndb/include/ndb_version.h
+ndb/lib/libMGM_API.so
+ndb/lib/libNDB_API.so
+ndb/lib/libNDB_ODBC.so
+ndb/lib/libNEWTON_API.so
+ndb/lib/libNEWTON_BASICTEST_COMMON.so
+ndb/lib/libREP_API.so
+ndb/lib/libndbclient.so
+ndb/lib/libndbclient_extra.so
+ndb/src/common/debugger/libtrace.dsp
+ndb/src/common/debugger/signaldata/libsignaldataprint.dsp
+ndb/src/common/logger/liblogger.dsp
+ndb/src/common/mgmcommon/libmgmsrvcommon.dsp
+ndb/src/common/mgmcommon/printConfig/*.d
+ndb/src/common/portlib/libportlib.dsp
+ndb/src/common/transporter/libtransporter.dsp
+ndb/src/common/util/libgeneral.dsp
+ndb/src/cw/cpcd/ndb_cpcd
+ndb/src/dummy.cpp
+ndb/src/kernel/blocks/backup/libbackup.dsp
+ndb/src/kernel/blocks/backup/restore/ndb_restore
+ndb/src/kernel/blocks/cmvmi/libcmvmi.dsp
+ndb/src/kernel/blocks/dbacc/libdbacc.dsp
+ndb/src/kernel/blocks/dbdict/libdbdict.dsp
+ndb/src/kernel/blocks/dbdih/libdbdih.dsp
+ndb/src/kernel/blocks/dblqh/libdblqh.dsp
+ndb/src/kernel/blocks/dbtc/libdbtc.dsp
+ndb/src/kernel/blocks/dbtup/libdbtup.dsp
+ndb/src/kernel/blocks/dbtux/libdbtux.dsp
+ndb/src/kernel/blocks/dbutil/libdbutil.dsp
+ndb/src/kernel/blocks/grep/libgrep.dsp
+ndb/src/kernel/blocks/ndbcntr/libndbcntr.dsp
+ndb/src/kernel/blocks/ndbfs/libndbfs.dsp
+ndb/src/kernel/blocks/qmgr/libqmgr.dsp
+ndb/src/kernel/blocks/suma/libsuma.dsp
+ndb/src/kernel/blocks/trix/libtrix.dsp
+ndb/src/kernel/error/liberror.dsp
+ndb/src/kernel/ndbd
+ndb/src/kernel/ndbd.dsp
+ndb/src/kernel/vm/libkernel.dsp
+ndb/src/libndbclient.dsp
+ndb/src/mgmapi/libmgmapi.dsp
+ndb/src/mgmclient/libndbmgmclient.dsp
+ndb/src/mgmclient/ndb_mgm
+ndb/src/mgmclient/ndb_mgm.dsp
+ndb/src/mgmclient/test_cpcd/*.d
+ndb/src/mgmsrv/ndb_mgmd
+ndb/src/mgmsrv/ndb_mgmd.dsp
+ndb/src/ndbapi/libndbapi.dsp
+ndb/test/ndbapi/bank/bankCreator
+ndb/test/ndbapi/bank/bankMakeGL
+ndb/test/ndbapi/bank/bankSumAccounts
+ndb/test/ndbapi/bank/bankTimer
+ndb/test/ndbapi/bank/bankTransactionMaker
+ndb/test/ndbapi/bank/bankValidateAllGLs
+ndb/test/ndbapi/bank/testBank
+ndb/test/ndbapi/create_all_tabs
+ndb/test/ndbapi/create_tab
+ndb/test/ndbapi/drop_all_tabs
+ndb/test/ndbapi/flexAsynch
+ndb/test/ndbapi/flexBench
+ndb/test/ndbapi/flexBench.dsp
+ndb/test/ndbapi/flexHammer
+ndb/test/ndbapi/flexTT
+ndb/test/ndbapi/testBackup
+ndb/test/ndbapi/testBasic
+ndb/test/ndbapi/testBasic.dsp
+ndb/test/ndbapi/testBasicAsynch
+ndb/test/ndbapi/testBlobs
+ndb/test/ndbapi/testBlobs.dsp
+ndb/test/ndbapi/testDataBuffers
+ndb/test/ndbapi/testDeadlock
+ndb/test/ndbapi/testDict
+ndb/test/ndbapi/testIndex
+ndb/test/ndbapi/testMgm
+ndb/test/ndbapi/testNdbApi
+ndb/test/ndbapi/testNodeRestart
+ndb/test/ndbapi/testOIBasic
+ndb/test/ndbapi/testOperations
+ndb/test/ndbapi/testRestartGci
+ndb/test/ndbapi/testSRBank
+ndb/test/ndbapi/testScan
+ndb/test/ndbapi/testScan.dsp
+ndb/test/ndbapi/testScanInterpreter
+ndb/test/ndbapi/testScanPerf
+ndb/test/ndbapi/testSystemRestart
+ndb/test/ndbapi/testTimeout
+ndb/test/ndbapi/testTransactions
+ndb/test/ndbapi/test_event
+ndb/test/run-test/atrt
+ndb/test/src/libNDBT.dsp
+ndb/test/tools/copy_tab
+ndb/test/tools/create_index
+ndb/test/tools/hugoCalculator
+ndb/test/tools/hugoFill
+ndb/test/tools/hugoLoad
+ndb/test/tools/hugoLockRecords
+ndb/test/tools/hugoPkDelete
+ndb/test/tools/hugoPkRead
+ndb/test/tools/hugoPkReadRecord
+ndb/test/tools/hugoPkUpdate
+ndb/test/tools/hugoScanRead
+ndb/test/tools/hugoScanUpdate
+ndb/test/tools/ndb_cpcc
+ndb/test/tools/restart
+ndb/test/tools/verify_index
+ndb/tools/ndb_config
+ndb/tools/ndb_delete_all
+ndb/tools/ndb_delete_all.dsp
+ndb/tools/ndb_desc
+ndb/tools/ndb_desc.dsp
+ndb/tools/ndb_drop_index
+ndb/tools/ndb_drop_index.dsp
+ndb/tools/ndb_drop_table
+ndb/tools/ndb_drop_table.dsp
+ndb/tools/ndb_restore
+ndb/tools/ndb_select_all
+ndb/tools/ndb_select_all.dsp
+ndb/tools/ndb_select_count
+ndb/tools/ndb_select_count.dsp
+ndb/tools/ndb_show_tables
+ndb/tools/ndb_show_tables.dsp
+ndb/tools/ndb_test_platform
+ndb/tools/ndb_waiter
+ndb/tools/ndb_waiter.dsp
+ndbcluster-1186
+ndbcluster-1186/SCCS
+ndbcluster-1186/config.ini
+ndbcluster-1186/ndb_1.pid
+ndbcluster-1186/ndb_1_out.log
+ndbcluster-1186/ndb_1_signal.log
+ndbcluster-1186/ndb_2.pid
+ndbcluster-1186/ndb_2_out.log
+ndbcluster-1186/ndb_2_signal.log
+ndbcluster-1186/ndb_3.pid
+ndbcluster-1186/ndb_3_cluster.log
+ndbcluster-1186/ndb_3_out.log
+ndbcluster-1186/ndbcluster.pid
+pull.log
+regex/re
+repl-tests/test-repl-ts/repl-timestamp.master.reject
+repl-tests/test-repl/foo-dump-slave.master.
+repl-tests/test-repl/sum-wlen-slave.master.
+repl-tests/test-repl/sum-wlen-slave.master.re
+repl-tests/test-repl/sum-wlen-slave.master.reje
+scripts/fill_func_tables
+scripts/fill_func_tables.sql
+scripts/fill_help_tables
+scripts/fill_help_tables.sql
+scripts/make_binary_distribution
+scripts/make_sharedlib_distribution
+scripts/make_win_binary_distribution
+scripts/make_win_src_distribution
+scripts/msql2mysql
+scripts/mysql_config
+scripts/mysql_convert_table_format
+scripts/mysql_create_system_tables
+scripts/mysql_explain_log
+scripts/mysql_find_rows
+scripts/mysql_fix_extensions
+scripts/mysql_fix_privilege_tables
+scripts/mysql_install_db
+scripts/mysql_secure_installation
+scripts/mysql_setpermission
+scripts/mysql_tableinfo
+scripts/mysql_zap
+scripts/mysqlaccess
+scripts/mysqlbug
+scripts/mysqld_multi
+scripts/mysqld_safe
+scripts/mysqldumpslow
+scripts/mysqlhotcopy
+scripts/mysqlhotcopy.sh.rej
+scripts/safe_mysqld
+select_test
+server-tools/instance-manager/client.c
+server-tools/instance-manager/client_settings.h
+server-tools/instance-manager/errmsg.c
+server-tools/instance-manager/mysqlmanager
+server-tools/instance-manager/thr_alarm.c
+sql-bench/Results-linux/ATIS-mysql_bdb-Linux_2.2.14_my_SMP_i686
+sql-bench/bench-count-distinct
+sql-bench/bench-init.pl
+sql-bench/compare-results
+sql-bench/compare-results-all
+sql-bench/copy-db
+sql-bench/crash-me
+sql-bench/gif/*
+sql-bench/graph-compare-results
+sql-bench/innotest1
+sql-bench/innotest1a
+sql-bench/innotest1b
+sql-bench/innotest2
+sql-bench/innotest2a
+sql-bench/innotest2b
+sql-bench/output/*
+sql-bench/run-all-tests
+sql-bench/server-cfg
+sql-bench/template.html
+sql-bench/test-ATIS
+sql-bench/test-alter-table
+sql-bench/test-big-tables
+sql-bench/test-connect
+sql-bench/test-create
+sql-bench/test-insert
+sql-bench/test-select
+sql-bench/test-transactions
+sql-bench/test-wisconsin
+sql/.gdbinit
+sql/client.c
+sql/gen_lex_hash
+sql/gmon.out
+sql/lex_hash.h
+sql/mini_client_errors.c
+sql/my_time.c
+sql/mysql_tzinfo_to_sql
+sql/mysql_tzinfo_to_sql.cc
+sql/mysql_tzinfo_to_sql_tztime.cc
+sql/mysqlbinlog
+sql/mysqld
+sql/mysqld-purecov
+sql/mysqld-purify
+sql/mysqld-quantify
+sql/new.cc
+sql/pack.c
+sql/safe_to_cache_query.txt
+sql/share/*.sys
+sql/share/charsets/gmon.out
+sql/share/gmon.out
+sql/share/mysql
+sql/share/norwegian-ny/errmsg.sys
+sql/share/norwegian/errmsg.sys
+sql/sql_select.cc.orig
+sql/sql_yacc.cc
+sql/sql_yacc.h
+sql/sql_yacc.output
+sql/sql_yacc.yy.orig
+sql/test_time
+sql/udf_example.so
+sql_error.cc
+sql_prepare.cc
+stamp-h
+stamp-h.in
+stamp-h1
+stamp-h1.in
+stamp-h2
+stamp-h2.in
+stamp-h3
+stamp-h4
+start_mysqld.sh
+storage/bdb/README
+storage/bdb/btree/btree_auto.c
+storage/bdb/btree/btree_autop.c
+storage/bdb/build_unix/*
+storage/bdb/build_vxworks/BerkeleyDB20.wpj
+storage/bdb/build_vxworks/BerkeleyDB20small.wpj
+storage/bdb/build_vxworks/BerkeleyDB22.wpj
+storage/bdb/build_vxworks/BerkeleyDB22small.wpj
+storage/bdb/build_vxworks/db.h
+storage/bdb/build_vxworks/db_config.h
+storage/bdb/build_vxworks/db_config_small.h
+storage/bdb/build_vxworks/db_deadlock/db_deadlock20.wpj
+storage/bdb/build_vxworks/db_deadlock/db_deadlock22.wpj
+storage/bdb/build_vxworks/db_int.h
+storage/bdb/build_vxworks/dbdemo/dbdemo.c
+storage/bdb/build_vxworks/dbdemo/dbdemo20.wpj
+storage/bdb/build_vxworks/dbdemo/dbdemo22.wpj
+storage/bdb/build_win32/*.dsp
+storage/bdb/build_win32/*.h
+storage/bdb/build_win32/include.tcl
+storage/bdb/build_win32/libdb.def
+storage/bdb/build_win32/libdb.rc
+storage/bdb/build_win64/*.dsp
+storage/bdb/build_win64/*.dsw
+storage/bdb/build_win64/*.h
+storage/bdb/db/crdel_auto.c
+storage/bdb/db/crdel_autop.c
+storage/bdb/db/db_auto.c
+storage/bdb/db/db_autop.c
+storage/bdb/dbinc_auto/*.*
+storage/bdb/dbreg/dbreg_auto.c
+storage/bdb/dbreg/dbreg_autop.c
+storage/bdb/dist/autom4te-2.53.cache/*
+storage/bdb/dist/autom4te-2.53.cache/output.0
+storage/bdb/dist/autom4te-2.53.cache/requests
+storage/bdb/dist/autom4te-2.53.cache/traces.0
+storage/bdb/dist/autom4te.cache/*
+storage/bdb/dist/autom4te.cache/output.0
+storage/bdb/dist/autom4te.cache/requests
+storage/bdb/dist/autom4te.cache/traces.0
+storage/bdb/dist/config.hin
+storage/bdb/dist/configure
+storage/bdb/dist/tags
+storage/bdb/dist/template/db_server_proc
+storage/bdb/dist/template/gen_client_ret
+storage/bdb/dist/template/rec_btree
+storage/bdb/dist/template/rec_crdel
+storage/bdb/dist/template/rec_db
+storage/bdb/dist/template/rec_dbreg
+storage/bdb/dist/template/rec_fileops
+storage/bdb/dist/template/rec_hash
+storage/bdb/dist/template/rec_log
+storage/bdb/dist/template/rec_qam
+storage/bdb/dist/template/rec_txn
+storage/bdb/examples_c/ex_apprec/ex_apprec_auto.c
+storage/bdb/examples_c/ex_apprec/ex_apprec_auto.h
+storage/bdb/examples_c/ex_apprec/ex_apprec_template
+storage/bdb/examples_java
+storage/bdb/fileops/fileops_auto.c
+storage/bdb/fileops/fileops_autop.c
+storage/bdb/hash/hash_auto.c
+storage/bdb/hash/hash_autop.c
+storage/bdb/include/btree_auto.h
+storage/bdb/include/btree_ext.h
+storage/bdb/include/clib_ext.h
+storage/bdb/include/common_ext.h
+storage/bdb/include/crdel_auto.h
+storage/bdb/include/db_auto.h
+storage/bdb/include/db_ext.h
+storage/bdb/include/db_server.h
+storage/bdb/include/env_ext.h
+storage/bdb/include/gen_client_ext.h
+storage/bdb/include/gen_server_ext.h
+storage/bdb/include/hash_auto.h
+storage/bdb/include/hash_ext.h
+storage/bdb/include/lock_ext.h
+storage/bdb/include/log_auto.h
+storage/bdb/include/log_ext.h
+storage/bdb/include/mp_ext.h
+storage/bdb/include/mutex_ext.h
+storage/bdb/include/os_ext.h
+storage/bdb/include/qam_auto.h
+storage/bdb/include/qam_ext.h
+storage/bdb/include/rpc_client_ext.h
+storage/bdb/include/rpc_server_ext.h
+storage/bdb/include/tcl_ext.h
+storage/bdb/include/txn_auto.h
+storage/bdb/include/txn_ext.h
+storage/bdb/include/xa_ext.h
+storage/bdb/java/src/com/sleepycat/db/Db.java
+storage/bdb/java/src/com/sleepycat/db/DbBtreeStat.java
+storage/bdb/java/src/com/sleepycat/db/DbConstants.java
+storage/bdb/java/src/com/sleepycat/db/DbHashStat.java
+storage/bdb/java/src/com/sleepycat/db/DbLockStat.java
+storage/bdb/java/src/com/sleepycat/db/DbLogStat.java
+storage/bdb/java/src/com/sleepycat/db/DbMpoolFStat.java
+storage/bdb/java/src/com/sleepycat/db/DbQueueStat.java
+storage/bdb/java/src/com/sleepycat/db/DbRepStat.java
+storage/bdb/java/src/com/sleepycat/db/DbTxnStat.java
+storage/bdb/libdb_java/java_stat_auto.c
+storage/bdb/libdb_java/java_stat_auto.h
+storage/bdb/libdb_java/java_util.i
+storage/bdb/log/log_auto.c
+storage/bdb/qam/qam_auto.c
+storage/bdb/qam/qam_autop.c
+storage/bdb/rep/rep_auto.c
+storage/bdb/rep/rep_autop.c
+storage/bdb/rpc_client/db_server_clnt.c
+storage/bdb/rpc_client/gen_client.c
+storage/bdb/rpc_server/c/db_server_proc.c
+storage/bdb/rpc_server/c/db_server_proc.sed
+storage/bdb/rpc_server/c/db_server_svc.c
+storage/bdb/rpc_server/c/db_server_xdr.c
+storage/bdb/rpc_server/c/gen_db_server.c
+storage/bdb/rpc_server/db_server.x
+storage/bdb/rpc_server/db_server_proc.sed
+storage/bdb/rpc_server/db_server_svc.c
+storage/bdb/rpc_server/db_server_xdr.c
+storage/bdb/rpc_server/gen_db_server.c
+storage/bdb/test/TESTS
+storage/bdb/test/include.tcl
+storage/bdb/test/logtrack.list
+storage/bdb/txn/txn_auto.c
+storage/bdb/txn/txn_autop.c
+storage/heap/hp_test1
+storage/heap/hp_test2
+storage/innobase/autom4te-2.53.cache/*
+storage/innobase/autom4te-2.53.cache/output.0
+storage/innobase/autom4te-2.53.cache/requests
+storage/innobase/autom4te-2.53.cache/traces.0
+storage/innobase/autom4te.cache/*
+storage/innobase/autom4te.cache/output.0
+storage/innobase/autom4te.cache/requests
+storage/innobase/autom4te.cache/traces.0
+storage/innobase/configure.lineno
+storage/innobase/conftest.s1
+storage/innobase/conftest.subs
+storage/innobase/ib_config.h
+storage/innobase/ib_config.h.in
+storage/innobase/mkinstalldirs
+storage/innobase/stamp-h1
+storage/myisam/FT1.MYD
+storage/myisam/FT1.MYI
+storage/myisam/ft_dump
+storage/myisam/ft_eval
+storage/myisam/ft_test1
+storage/myisam/ftbench/data
+storage/myisam/ftbench/t
+storage/myisam/ftbench/var/*
+storage/myisam/mi_test1
+storage/myisam/mi_test2
+storage/myisam/mi_test3
+storage/myisam/mi_test_all
+storage/myisam/myisam.log
+storage/myisam/myisam_ftdump
+storage/myisam/myisamchk
+storage/myisam/myisamlog
+storage/myisam/myisampack
+storage/myisam/rt_test
+storage/myisam/rt_test.MYD
+storage/myisam/rt_test.MYI
+storage/myisam/sp_test
+storage/myisam/test1.MYD
+storage/myisam/test1.MYI
+storage/myisam/test2.MYD
+storage/myisam/test2.MYI
storage/ndb/bin/DbAsyncGenerator
storage/ndb/bin/DbCreate
storage/ndb/bin/acid
@@ -899,131 +1441,6 @@ storage/ndb/tools/ndb_show_tables.dsp
storage/ndb/tools/ndb_test_platform
storage/ndb/tools/ndb_waiter
storage/ndb/tools/ndb_waiter.dsp
-ndbcluster-1186
-ndbcluster-1186/SCCS
-ndbcluster-1186/config.ini
-ndbcluster-1186/ndb_1.pid
-ndbcluster-1186/ndb_1_out.log
-ndbcluster-1186/ndb_1_signal.log
-ndbcluster-1186/ndb_2.pid
-ndbcluster-1186/ndb_2_out.log
-ndbcluster-1186/ndb_2_signal.log
-ndbcluster-1186/ndb_3.pid
-ndbcluster-1186/ndb_3_cluster.log
-ndbcluster-1186/ndb_3_out.log
-ndbcluster-1186/ndbcluster.pid
-pull.log
-regex/re
-repl-tests/test-repl-ts/repl-timestamp.master.reject
-repl-tests/test-repl/foo-dump-slave.master.
-repl-tests/test-repl/sum-wlen-slave.master.
-repl-tests/test-repl/sum-wlen-slave.master.re
-repl-tests/test-repl/sum-wlen-slave.master.reje
-scripts/fill_func_tables
-scripts/fill_func_tables.sql
-scripts/fill_help_tables
-scripts/fill_help_tables.sql
-scripts/make_binary_distribution
-scripts/make_sharedlib_distribution
-scripts/make_win_binary_distribution
-scripts/make_win_src_distribution
-scripts/msql2mysql
-scripts/mysql_config
-scripts/mysql_convert_table_format
-scripts/mysql_create_system_tables
-scripts/mysql_explain_log
-scripts/mysql_find_rows
-scripts/mysql_fix_extensions
-scripts/mysql_fix_privilege_tables
-scripts/mysql_install_db
-scripts/mysql_secure_installation
-scripts/mysql_setpermission
-scripts/mysql_tableinfo
-scripts/mysql_zap
-scripts/mysqlaccess
-scripts/mysqlbug
-scripts/mysqld_multi
-scripts/mysqld_safe
-scripts/mysqldumpslow
-scripts/mysqlhotcopy
-scripts/mysqlhotcopy.sh.rej
-scripts/safe_mysqld
-select_test
-server-tools/instance-manager/client.c
-server-tools/instance-manager/client_settings.h
-server-tools/instance-manager/errmsg.c
-server-tools/instance-manager/mysqlmanager
-server-tools/instance-manager/thr_alarm.c
-sql-bench/Results-linux/ATIS-mysql_bdb-Linux_2.2.14_my_SMP_i686
-sql-bench/bench-count-distinct
-sql-bench/bench-init.pl
-sql-bench/compare-results
-sql-bench/compare-results-all
-sql-bench/copy-db
-sql-bench/crash-me
-sql-bench/gif/*
-sql-bench/graph-compare-results
-sql-bench/innotest1
-sql-bench/innotest1a
-sql-bench/innotest1b
-sql-bench/innotest2
-sql-bench/innotest2a
-sql-bench/innotest2b
-sql-bench/output/*
-sql-bench/run-all-tests
-sql-bench/server-cfg
-sql-bench/template.html
-sql-bench/test-ATIS
-sql-bench/test-alter-table
-sql-bench/test-big-tables
-sql-bench/test-connect
-sql-bench/test-create
-sql-bench/test-insert
-sql-bench/test-select
-sql-bench/test-transactions
-sql-bench/test-wisconsin
-sql/.gdbinit
-sql/client.c
-sql/gen_lex_hash
-sql/gmon.out
-sql/lex_hash.h
-sql/mini_client_errors.c
-sql/my_time.c
-sql/mysql_tzinfo_to_sql
-sql/mysql_tzinfo_to_sql.cc
-sql/mysql_tzinfo_to_sql_tztime.cc
-sql/mysqlbinlog
-sql/mysqld
-sql/mysqld-purecov
-sql/mysqld-purify
-sql/mysqld-quantify
-sql/new.cc
-sql/pack.c
-sql/safe_to_cache_query.txt
-sql/share/*.sys
-sql/share/charsets/gmon.out
-sql/share/gmon.out
-sql/share/mysql
-sql/share/norwegian-ny/errmsg.sys
-sql/share/norwegian/errmsg.sys
-sql/sql_select.cc.orig
-sql/sql_yacc.cc
-sql/sql_yacc.h
-sql/sql_yacc.output
-sql/sql_yacc.yy.orig
-sql/test_time
-sql/udf_example.so
-sql_error.cc
-sql_prepare.cc
-stamp-h
-stamp-h.in
-stamp-h1
-stamp-h1.in
-stamp-h2
-stamp-h2.in
-stamp-h3
-stamp-h4
-start_mysqld.sh
strings/conf_to_src
strings/ctype_autoconf.c
strings/ctype_extra_sources.c
@@ -1120,6 +1537,3 @@ vio/test-ssl
vio/test-sslclient
vio/test-sslserver
vio/viotest-ssl
-storage/bdb/build_win64/*.dsp
-storage/bdb/build_win64/*.dsw
-storage/bdb/build_win64/*.h
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index 398a2bbbfd6..e37418cbf63 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -10,6 +10,11 @@ prefix_configs="--prefix=/usr/local/mysql"
just_print=
just_configure=
full_debug=
+if test -n "$MYSQL_BUILD_PREFIX"
+then
+ prefix_configs="--prefix=$MYSQL_BUILD_PREFIX"
+fi
+
while test $# -gt 0
do
case "$1" in
@@ -47,10 +52,11 @@ global_warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wch
#debug_extra_warnings="-Wuninitialized"
c_warnings="$global_warnings -Wunused"
cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor"
-
-base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-openssl --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-partition"
-max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-blackhole-storage-engine --with-openssl --with-embedded-server --with-big-tables --with-partition"
+base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-openssl --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine --with-partition"
+base_max_no_ndb_configs="--with-innodb --with-berkeley-db --without-ndbcluster --with-archive-storage-engine --with-openssl --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine"
+max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-blackhole-storage-engine --with-csv-storage-engine --with-openssl --with-embedded-server --with-big-tables --with-partition"
max_configs="$base_max_configs --with-embedded-server"
+max_no_ndb_configs="$base_max_no_ndb_configs --with-embedded-server"
path=`dirname $0`
. "$path/check-cpu"
diff --git a/BUILD/autorun.sh b/BUILD/autorun.sh
index 82fd1722bd0..63bab3565c6 100755
--- a/BUILD/autorun.sh
+++ b/BUILD/autorun.sh
@@ -7,7 +7,7 @@ aclocal || die "Can't execute aclocal"
autoheader || die "Can't execute autoheader"
# --force means overwrite ltmain.sh script if it already exists
# Added glibtoolize reference to make native OSX autotools work
-if [ -f /usr/bin/glibtoolize ] ; then
+if test -f /usr/bin/glibtoolize ; then
glibtoolize --automake --force || die "Can't execute glibtoolize"
else
libtoolize --automake --force || die "Can't execute libtoolize"
diff --git a/BUILD/compile-pentium-debug-max-no-ndb b/BUILD/compile-pentium-debug-max-no-ndb
new file mode 100755
index 00000000000..26ec7eacc9d
--- /dev/null
+++ b/BUILD/compile-pentium-debug-max-no-ndb
@@ -0,0 +1,11 @@
+#! /bin/sh
+
+path=`dirname $0`
+. "$path/SETUP.sh" $@ --with-debug=full
+
+extra_flags="$pentium_cflags $debug_cflags $max_cflags"
+c_warnings="$c_warnings $debug_extra_warnings"
+cxx_warnings="$cxx_warnings $debug_extra_warnings"
+extra_configs="$pentium_configs $debug_configs $max_no_ndb_configs"
+
+. "$path/FINISH.sh"
diff --git a/BUILD/compile-ppc-debug-max-no-ndb b/BUILD/compile-ppc-debug-max-no-ndb
new file mode 100755
index 00000000000..a5b922a1ec9
--- /dev/null
+++ b/BUILD/compile-ppc-debug-max-no-ndb
@@ -0,0 +1,11 @@
+#! /bin/sh
+
+path=`dirname $0`
+. "$path/SETUP.sh"
+
+extra_flags="$ppc_cflags $debug_cflags $max_cflags"
+c_warnings="$c_warnings $debug_extra_warnings"
+cxx_warnings="$cxx_warnings $debug_extra_warnings"
+extra_configs="$debug_configs $max_no_ndb_configs"
+
+. "$path/FINISH.sh"
diff --git a/Makefile.am b/Makefile.am
index d6245ac95d7..cb8f09023d6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -109,15 +109,26 @@ MYSQL_TEST_RUN_ARGS = --manager-port=$(MYSQL_TEST_MANAGER_PORT) \
--master_port=$(MYSQL_TEST_MASTER_PORT) \
--slave_port=$(MYSQL_TEST_SLAVE_PORT) \
--ndbcluster_port=$(MYSQL_TEST_NDB_PORT)
+
test:
cd mysql-test ; \
- ./mysql-test-run.pl $(MYSQL_TEST_RUN_ARGS) && \
- ./mysql-test-run.pl --ps-protocol $(MYSQL_TEST_RUN_ARGS)
+ ./mysql-test-run $(MYSQL_TEST_RUN_ARGS) && \
+ ./mysql-test-run $(MYSQL_TEST_RUN_ARGS) --ps-protocol
test-force:
cd mysql-test ; \
- ./mysql-test-run --force $(MYSQL_TEST_RUN_ARGS) ; \
- ./mysql-test-run --ps-protocol --force $(MYSQL_TEST_RUN_ARGS)
+ ./mysql-test-run $(MYSQL_TEST_RUN_ARGS) --force ; \
+ ./mysql-test-run $(MYSQL_TEST_RUN_ARGS) --ps-protocol --force
+
+test-pl:
+ cd mysql-test ; \
+ ./mysql-test-run.pl $(MYSQL_TEST_RUN_ARGS) && \
+ ./mysql-test-run.pl $(MYSQL_TEST_RUN_ARGS) --ps-protocol
+
+test-force-pl:
+ cd mysql-test ; \
+ ./mysql-test-run.pl $(MYSQL_TEST_RUN_ARGS) --force ; \
+ ./mysql-test-run.pl $(MYSQL_TEST_RUN_ARGS) --ps-protocol --force
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/VC++Files/storage/bdb/bdb.vcproj b/VC++Files/bdb/bdb.vcproj
index 758a950a6ea..6258da3cb3a 100755..100644
--- a/VC++Files/storage/bdb/bdb.vcproj
+++ b/VC++Files/bdb/bdb.vcproj
@@ -3,7 +3,6 @@
ProjectType="Visual C++"
Version="7.10"
Name="bdb"
- ProjectGUID="{FB168572-FFF4-4503-9331-4E958459DC9D}"
SccProjectName=""
SccLocalPath="">
<Platforms>
diff --git a/VC++Files/client/mysql.vcproj b/VC++Files/client/mysql.vcproj
index 72cc4ba6b89..72cc4ba6b89 100755..100644
--- a/VC++Files/client/mysql.vcproj
+++ b/VC++Files/client/mysql.vcproj
diff --git a/VC++Files/client/mysqladmin.vcproj b/VC++Files/client/mysqladmin.vcproj
index 188bf61dff7..188bf61dff7 100755..100644
--- a/VC++Files/client/mysqladmin.vcproj
+++ b/VC++Files/client/mysqladmin.vcproj
diff --git a/VC++Files/client/mysqlclient.vcproj b/VC++Files/client/mysqlclient.vcproj
index eebba9ebe0e..eebba9ebe0e 100755..100644
--- a/VC++Files/client/mysqlclient.vcproj
+++ b/VC++Files/client/mysqlclient.vcproj
diff --git a/VC++Files/client/mysqldump.vcproj b/VC++Files/client/mysqldump.vcproj
index b6a33596083..b6a33596083 100755..100644
--- a/VC++Files/client/mysqldump.vcproj
+++ b/VC++Files/client/mysqldump.vcproj
diff --git a/VC++Files/client/mysqlimport.vcproj b/VC++Files/client/mysqlimport.vcproj
index ef440c2fe5a..ef440c2fe5a 100755..100644
--- a/VC++Files/client/mysqlimport.vcproj
+++ b/VC++Files/client/mysqlimport.vcproj
diff --git a/VC++Files/client/mysqlshow.vcproj b/VC++Files/client/mysqlshow.vcproj
index a0707680728..a0707680728 100755..100644
--- a/VC++Files/client/mysqlshow.vcproj
+++ b/VC++Files/client/mysqlshow.vcproj
diff --git a/VC++Files/client/mysqltest.vcproj b/VC++Files/client/mysqltest.vcproj
index 5c075740fbd..5c075740fbd 100755..100644
--- a/VC++Files/client/mysqltest.vcproj
+++ b/VC++Files/client/mysqltest.vcproj
diff --git a/VC++Files/comp_err/comp_err.vcproj b/VC++Files/comp_err/comp_err.vcproj
index b12ef8b0af1..b12ef8b0af1 100755..100644
--- a/VC++Files/comp_err/comp_err.vcproj
+++ b/VC++Files/comp_err/comp_err.vcproj
diff --git a/VC++Files/dbug/dbug.vcproj b/VC++Files/dbug/dbug.vcproj
index 57257451aea..57257451aea 100755..100644
--- a/VC++Files/dbug/dbug.vcproj
+++ b/VC++Files/dbug/dbug.vcproj
diff --git a/VC++Files/storage/heap/heap.vcproj b/VC++Files/heap/heap.vcproj
index 86e0f5be069..b2afd752acf 100755..100644
--- a/VC++Files/storage/heap/heap.vcproj
+++ b/VC++Files/heap/heap.vcproj
@@ -3,7 +3,6 @@
ProjectType="Visual C++"
Version="7.10"
Name="heap"
- ProjectGUID="{603E5567-F3CD-4547-9F2B-E0082B702B0D}"
SccProjectName=""
SccLocalPath="">
<Platforms>
@@ -23,7 +22,7 @@
Optimization="2"
InlineFunctionExpansion="1"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="../../include"
+ AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="DBUG_OFF;_WINDOWS;NDEBUG"
StringPooling="TRUE"
RuntimeLibrary="0"
@@ -72,7 +71,7 @@
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="../../include"
+ AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="_DEBUG;SAFEMALLOC;SAFE_MUTEX;_WINDOWS;USE_TLS"
StringPooling="TRUE"
RuntimeLibrary="1"
@@ -122,7 +121,7 @@
Optimization="2"
InlineFunctionExpansion="1"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="../../include"
+ AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="DBUG_OFF;_WINDOWS;NDEBUG;USE_TLS"
StringPooling="TRUE"
RuntimeLibrary="0"
@@ -171,7 +170,7 @@
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="../../include"
+ AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="_DEBUG;SAFEMALLOC;SAFE_MUTEX;_WINDOWS"
StringPooling="TRUE"
RuntimeLibrary="1"
diff --git a/VC++Files/storage/innobase/innobase.vcproj b/VC++Files/innobase/innobase.vcproj
index 8015f3cb793..9d972366440 100755..100644
--- a/VC++Files/storage/innobase/innobase.vcproj
+++ b/VC++Files/innobase/innobase.vcproj
@@ -3,7 +3,6 @@
ProjectType="Visual C++"
Version="7.10"
Name="innobase"
- ProjectGUID="{AEFFF9CA-3387-4027-B569-33D5D26887D1}"
SccProjectName=""
SccLocalPath="">
<Platforms>
@@ -25,7 +24,7 @@
Optimization="2"
InlineFunctionExpansion="1"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="include, ../../include"
+ AdditionalIncludeDirectories="../innobase/include,../include"
PreprocessorDefinitions="_LIB;_WIN32;WIN32;NDEBUG;MYSQL_SERVER"
StringPooling="TRUE"
RuntimeLibrary="0"
@@ -76,7 +75,7 @@
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="include, ../../include"
+ AdditionalIncludeDirectories="../innobase/include,../include"
PreprocessorDefinitions="NDEBUG;_LIB;_WIN32;WIN32;MYSQL_SERVER"
RuntimeLibrary="1"
PrecompiledHeaderFile=".\debug/innobase.pch"
@@ -127,7 +126,7 @@
Optimization="2"
InlineFunctionExpansion="1"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="include, ../../include"
+ AdditionalIncludeDirectories="../innobase/include,../include"
PreprocessorDefinitions="_LIB;_WIN32;WIN32;MYSQL_SERVER;NDEBUG"
StringPooling="TRUE"
RuntimeLibrary="0"
@@ -180,7 +179,7 @@
Optimization="2"
InlineFunctionExpansion="1"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="include, ../../include"
+ AdditionalIncludeDirectories="../innobase/include,../include"
PreprocessorDefinitions="_LIB;_WIN32;WIN32;NDEBUG;MYSQL_SERVER"
StringPooling="TRUE"
RuntimeLibrary="0"
diff --git a/VC++Files/libmysql/libmysql.vcproj b/VC++Files/libmysql/libmysql.vcproj
index 9ba877e0520..9ba877e0520 100755..100644
--- a/VC++Files/libmysql/libmysql.vcproj
+++ b/VC++Files/libmysql/libmysql.vcproj
diff --git a/VC++Files/libmysqld/examples/test_libmysqld.vcproj b/VC++Files/libmysqld/examples/test_libmysqld.vcproj
index bf26fbd6588..bf26fbd6588 100755..100644
--- a/VC++Files/libmysqld/examples/test_libmysqld.vcproj
+++ b/VC++Files/libmysqld/examples/test_libmysqld.vcproj
diff --git a/VC++Files/libmysqld/libmysqld.vcproj b/VC++Files/libmysqld/libmysqld.vcproj
index 187a63ece38..eb411f79362 100755..100644
--- a/VC++Files/libmysqld/libmysqld.vcproj
+++ b/VC++Files/libmysqld/libmysqld.vcproj
@@ -24,7 +24,7 @@
AdditionalIncludeDirectories="../include,../libmysqld,../sql,../regex,../extra/yassl/include,../bdb/build_win32,../zlib"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;SAFEMALLOC;HAVE_BERKELEY_DB;USE_SYMDIR;SIGNAL_WITH_VIO_CLOSE;HAVE_DLOPEN;EMBEDDED_LIBRARY;HAVE_INNOBASE_DB;USE_TLS;__WIN__"
BasicRuntimeChecks="3"
- RuntimeLibrary="0"
+ RuntimeLibrary="1"
PrecompiledHeaderFile=".\debug/libmysqld.pch"
AssemblerListingLocation=".\debug/"
ObjectFile=".\debug/"
@@ -37,11 +37,11 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="odbc32.lib odbccp32.lib Wsock32.lib ..\lib_debug\dbug_tls.lib ..\lib_debug\mysys_tls.lib ..\lib_debug\strings.lib ..\lib_debug\regex.lib ..\lib_debug\heap_tls.lib ..\lib_debug\innodb.lib ..\extra\yassl\Debug\yassl.lib"
+ AdditionalDependencies="odbc32.lib odbccp32.lib Wsock32.lib"
OutputFile="../lib_debug/libmysqld.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
- IgnoreDefaultLibraryNames="LIBCMTD"
+ IgnoreDefaultLibraryNames=""
ModuleDefinitionFile=".\libmysqld.def"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\debug/libmysqld.pdb"
@@ -106,7 +106,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\myisam_tls.lib ..\lib_release\myisammrg_tls.lib ..\lib_release\mysys_tls.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap_tls.lib ..\lib_release\innodb.lib ..\lib_release\zlib.lib ..\extra\yassl\Release\yassl.lib"
+ AdditionalDependencies="odbc32.lib odbccp32.lib Wsock32.lib"
OutputFile="../lib_pro/libmysqld.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
@@ -172,7 +172,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\myisam_tls.lib ..\lib_release\myisammrg_tls.lib ..\lib_release\mysys_tls.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap_tls.lib ..\lib_release\innodb.lib ..\lib_release\bdb.lib ..\lib_release\zlib.lib ..\extra\yassl\Release\yassl.lib"
+ AdditionalDependencies="odbc32.lib odbccp32.lib Wsock32.lib"
OutputFile="../lib_release/libmysqld.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
@@ -238,7 +238,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="odbc32.lib odbccp32.lib Wsock32.lib ..\lib_release\myisam_tls.lib ..\lib_release\myisammrg_tls.lib ..\lib_release\mysys_tls.lib ..\lib_release\strings.lib ..\lib_release\regex.lib ..\lib_release\heap_tls.lib ..\lib_release\zlib.lib ..\extra\yassl\Release\yassl.lib"
+ AdditionalDependencies="odbc32.lib odbccp32.lib Wsock32.lib"
OutputFile="../lib_classic/libmysqld.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
@@ -2299,7 +2299,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\sql\protocol_cursor.cpp">
+ RelativePath="..\sql\sql_cursor.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
diff --git a/VC++Files/libmysqltest/myTest.vcproj b/VC++Files/libmysqltest/myTest.vcproj
index 06ce20bf021..afc44b482c9 100755..100644
--- a/VC++Files/libmysqltest/myTest.vcproj
+++ b/VC++Files/libmysqltest/myTest.vcproj
@@ -40,7 +40,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libmysql.lib odbc32.lib odbccp32.lib"
- OutputFile=".\release/myTest.exe"
+ OutputFile="..\client_release/myTest.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\lib_release"
@@ -74,7 +74,7 @@
</Configuration>
<Configuration
Name="Debug|Win32"
- OutputDirectory=".\debug"
+ OutputDirectory="..\client_debug"
IntermediateDirectory=".\debug"
ConfigurationType="1"
UseOfMFC="0"
@@ -100,7 +100,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="libmysql.lib odbc32.lib odbccp32.lib"
- OutputFile=".\debug/myTest.exe"
+ OutputFile="../client_debug/myTest.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\lib_debug"
diff --git a/VC++Files/my_print_defaults/my_print_defaults.vcproj b/VC++Files/my_print_defaults/my_print_defaults.vcproj
index e49039b6a1e..e49039b6a1e 100755..100644
--- a/VC++Files/my_print_defaults/my_print_defaults.vcproj
+++ b/VC++Files/my_print_defaults/my_print_defaults.vcproj
diff --git a/VC++Files/storage/myisam/myisam.vcproj b/VC++Files/myisam/myisam.vcproj
index 71697e30f12..b63b7ffaccc 100755..100644
--- a/VC++Files/storage/myisam/myisam.vcproj
+++ b/VC++Files/myisam/myisam.vcproj
@@ -3,7 +3,6 @@
ProjectType="Visual C++"
Version="7.10"
Name="myisam"
- ProjectGUID="{E85E5D80-641E-44C7-B909-3805A8D3167B}"
SccProjectName=""
SccLocalPath="">
<Platforms>
@@ -22,7 +21,7 @@
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="../../include"
+ AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="_DEBUG;SAFEMALLOC;SAFE_MUTEX;_WINDOWS"
StringPooling="TRUE"
RuntimeLibrary="1"
@@ -73,7 +72,7 @@
Optimization="2"
InlineFunctionExpansion="1"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="../../include"
+ AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="DBUG_OFF;_WINDOWS;NDEBUG"
StringPooling="TRUE"
RuntimeLibrary="0"
@@ -124,7 +123,7 @@
Optimization="2"
InlineFunctionExpansion="1"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="../../include"
+ AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="DBUG_OFF;_WINDOWS;NDEBUG;USE_TLS"
StringPooling="TRUE"
RuntimeLibrary="0"
@@ -174,7 +173,7 @@
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="../../include"
+ AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="_DEBUG;SAFEMALLOC;SAFE_MUTEX;_WINDOWS;USE_TLS"
StringPooling="TRUE"
RuntimeLibrary="1"
diff --git a/VC++Files/myisam_ftdump/myisam_ftdump.vcproj b/VC++Files/myisam_ftdump/myisam_ftdump.vcproj
index 4d1013775fa..4d1013775fa 100755..100644
--- a/VC++Files/myisam_ftdump/myisam_ftdump.vcproj
+++ b/VC++Files/myisam_ftdump/myisam_ftdump.vcproj
diff --git a/VC++Files/myisamchk/myisamchk.vcproj b/VC++Files/myisamchk/myisamchk.vcproj
index ce2435bc34a..33f813024b5 100755..100644
--- a/VC++Files/myisamchk/myisamchk.vcproj
+++ b/VC++Files/myisamchk/myisamchk.vcproj
@@ -101,7 +101,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="wsock32.lib setargv.obj ..\lib_release\myisam.lib ..\lib_release\mysys.lib ..\lib_release\strings.lib ..\lib_release\zlib.lib"
+ AdditionalDependencies="wsock32.lib setargv.obj"
OutputFile="../client_classic/myisamchk.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
diff --git a/VC++Files/myisamlog/myisamlog.vcproj b/VC++Files/myisamlog/myisamlog.vcproj
index 6189a54d33b..6189a54d33b 100755..100644
--- a/VC++Files/myisamlog/myisamlog.vcproj
+++ b/VC++Files/myisamlog/myisamlog.vcproj
diff --git a/VC++Files/storage/myisammrg/myisammrg.vcproj b/VC++Files/myisammrg/myisammrg.vcproj
index 5126818765b..3075f8ef9f6 100755..100644
--- a/VC++Files/storage/myisammrg/myisammrg.vcproj
+++ b/VC++Files/myisammrg/myisammrg.vcproj
@@ -3,7 +3,6 @@
ProjectType="Visual C++"
Version="7.10"
Name="myisammrg"
- ProjectGUID="{91B7E9AD-5F85-4236-9A28-B032543B123E}"
SccProjectName=""
SccLocalPath="">
<Platforms>
@@ -23,7 +22,7 @@
Optimization="2"
InlineFunctionExpansion="1"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="../../include"
+ AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="DBUG_OFF;_WINDOWS;NDEBUG"
StringPooling="TRUE"
RuntimeLibrary="0"
@@ -73,7 +72,7 @@
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="../../include"
+ AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="_DEBUG;SAFEMALLOC;SAFE_MUTEX;_WINDOWS;USE_TLS"
StringPooling="TRUE"
RuntimeLibrary="1"
@@ -124,7 +123,7 @@
Optimization="2"
InlineFunctionExpansion="1"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="../../include"
+ AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="DBUG_OFF;_WINDOWS;NDEBUG;USE_TLS"
StringPooling="TRUE"
RuntimeLibrary="0"
@@ -174,7 +173,7 @@
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="../../include"
+ AdditionalIncludeDirectories="../include"
PreprocessorDefinitions="_DEBUG;SAFEMALLOC;SAFE_MUTEX;_WINDOWS"
StringPooling="TRUE"
RuntimeLibrary="1"
diff --git a/VC++Files/myisampack/myisampack.vcproj b/VC++Files/myisampack/myisampack.vcproj
index 27a8653cc5a..27a8653cc5a 100755..100644
--- a/VC++Files/myisampack/myisampack.vcproj
+++ b/VC++Files/myisampack/myisampack.vcproj
diff --git a/VC++Files/mysql-test/mysql_test_run_new.vcproj b/VC++Files/mysql-test/mysql_test_run_new.vcproj
index 12d502e5768..12d502e5768 100755..100644
--- a/VC++Files/mysql-test/mysql_test_run_new.vcproj
+++ b/VC++Files/mysql-test/mysql_test_run_new.vcproj
diff --git a/VC++Files/mysql.sln b/VC++Files/mysql.sln
index 31bf8baa15e..ffa2050bbed 100755..100644
--- a/VC++Files/mysql.sln
+++ b/VC++Files/mysql.sln
@@ -1,4 +1,8 @@
Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bdb", "bdb\bdb.vcproj", "{6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "comp_err", "comp_err\comp_err.vcproj", "{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}"
ProjectSection(ProjectDependencies) = postProject
{EEC1300B-85A5-497C-B3E1-F708021DF859} = {EEC1300B-85A5-497C-B3E1-F708021DF859}
@@ -10,6 +14,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dbug", "dbug\dbug.vcproj",
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "heap", "heap\heap.vcproj", "{C70A6DC7-7D45-4C16-8654-7E57713A4C04}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "innobase", "innobase\innobase.vcproj", "{13D37150-54D0-46C5-9519-03923243C7C7}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmysql", "libmysql\libmysql.vcproj", "{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}"
ProjectSection(ProjectDependencies) = postProject
{EEC1300B-85A5-497C-B3E1-F708021DF859} = {EEC1300B-85A5-497C-B3E1-F708021DF859}
@@ -22,8 +34,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmysqld", "libmysqld\libm
ProjectSection(ProjectDependencies) = postProject
{EEC1300B-85A5-497C-B3E1-F708021DF859} = {EEC1300B-85A5-497C-B3E1-F708021DF859}
{207E9014-C4D1-4F6D-B76F-BC7DD7E31113} = {207E9014-C4D1-4F6D-B76F-BC7DD7E31113}
+ {13D37150-54D0-46C5-9519-03923243C7C7} = {13D37150-54D0-46C5-9519-03923243C7C7}
{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB} = {BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3} = {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}
+ {DB28DE80-837F-4497-9AA9-CC0A20584C98} = {DB28DE80-837F-4497-9AA9-CC0A20584C98}
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0} = {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}
+ {262280A8-37D5-4037-BDFB-242468DFB3D2} = {262280A8-37D5-4037-BDFB-242468DFB3D2}
{8762A9B8-72A9-462E-A9A2-F3265081F8AF} = {8762A9B8-72A9-462E-A9A2-F3265081F8AF}
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04} = {C70A6DC7-7D45-4C16-8654-7E57713A4C04}
{44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF}
{FC369DF4-AEB7-4531-BF34-A638C4363BFE} = {FC369DF4-AEB7-4531-BF34-A638C4363BFE}
EndProjectSection
@@ -40,9 +58,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "my_print_defaults", "my_pri
{FC369DF4-AEB7-4531-BF34-A638C4363BFE} = {FC369DF4-AEB7-4531-BF34-A638C4363BFE}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "myisam", "myisam\myisam.vcproj", "{262280A8-37D5-4037-BDFB-242468DFB3D2}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "myisam_ftdump", "myisam_ftdump\myisam_ftdump.vcproj", "{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}"
ProjectSection(ProjectDependencies) = postProject
{EEC1300B-85A5-497C-B3E1-F708021DF859} = {EEC1300B-85A5-497C-B3E1-F708021DF859}
+ {262280A8-37D5-4037-BDFB-242468DFB3D2} = {262280A8-37D5-4037-BDFB-242468DFB3D2}
{44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF}
{FC369DF4-AEB7-4531-BF34-A638C4363BFE} = {FC369DF4-AEB7-4531-BF34-A638C4363BFE}
EndProjectSection
@@ -50,6 +73,7 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "myisamchk", "myisamchk\myisamchk.vcproj", "{87CD9881-D234-4306-BBC6-0668C6168C0F}"
ProjectSection(ProjectDependencies) = postProject
{EEC1300B-85A5-497C-B3E1-F708021DF859} = {EEC1300B-85A5-497C-B3E1-F708021DF859}
+ {262280A8-37D5-4037-BDFB-242468DFB3D2} = {262280A8-37D5-4037-BDFB-242468DFB3D2}
{8762A9B8-72A9-462E-A9A2-F3265081F8AF} = {8762A9B8-72A9-462E-A9A2-F3265081F8AF}
{44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF}
{FC369DF4-AEB7-4531-BF34-A638C4363BFE} = {FC369DF4-AEB7-4531-BF34-A638C4363BFE}
@@ -58,14 +82,20 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "myisamlog", "myisamlog\myisamlog.vcproj", "{194F5EE6-9440-4298-A6FE-A9B4B480B44C}"
ProjectSection(ProjectDependencies) = postProject
{EEC1300B-85A5-497C-B3E1-F708021DF859} = {EEC1300B-85A5-497C-B3E1-F708021DF859}
+ {262280A8-37D5-4037-BDFB-242468DFB3D2} = {262280A8-37D5-4037-BDFB-242468DFB3D2}
{8762A9B8-72A9-462E-A9A2-F3265081F8AF} = {8762A9B8-72A9-462E-A9A2-F3265081F8AF}
{44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF}
{FC369DF4-AEB7-4531-BF34-A638C4363BFE} = {FC369DF4-AEB7-4531-BF34-A638C4363BFE}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "myisammrg", "myisammrg\myisammrg.vcproj", "{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "myisampack", "myisampack\myisampack.vcproj", "{EF833A1E-E358-4B6C-9C27-9489E85041CC}"
ProjectSection(ProjectDependencies) = postProject
{EEC1300B-85A5-497C-B3E1-F708021DF859} = {EEC1300B-85A5-497C-B3E1-F708021DF859}
+ {262280A8-37D5-4037-BDFB-242468DFB3D2} = {262280A8-37D5-4037-BDFB-242468DFB3D2}
{8762A9B8-72A9-462E-A9A2-F3265081F8AF} = {8762A9B8-72A9-462E-A9A2-F3265081F8AF}
{44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF}
{FC369DF4-AEB7-4531-BF34-A638C4363BFE} = {FC369DF4-AEB7-4531-BF34-A638C4363BFE}
@@ -111,15 +141,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqld", "sql\mysqld.vcproj
ProjectSection(ProjectDependencies) = postProject
{EEC1300B-85A5-497C-B3E1-F708021DF859} = {EEC1300B-85A5-497C-B3E1-F708021DF859}
{207E9014-C4D1-4F6D-B76F-BC7DD7E31113} = {207E9014-C4D1-4F6D-B76F-BC7DD7E31113}
- {603E5567-F3CD-4547-9F2B-E0082B702B0D} = {603E5567-F3CD-4547-9F2B-E0082B702B0D}
- {FB168572-FFF4-4503-9331-4E958459DC9D} = {FB168572-FFF4-4503-9331-4E958459DC9D}
+ {13D37150-54D0-46C5-9519-03923243C7C7} = {13D37150-54D0-46C5-9519-03923243C7C7}
{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB} = {BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}
- {E85E5D80-641E-44C7-B909-3805A8D3167B} = {E85E5D80-641E-44C7-B909-3805A8D3167B}
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3} = {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}
{DB28DE80-837F-4497-9AA9-CC0A20584C98} = {DB28DE80-837F-4497-9AA9-CC0A20584C98}
- {91B7E9AD-5F85-4236-9A28-B032543B123E} = {91B7E9AD-5F85-4236-9A28-B032543B123E}
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0} = {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}
+ {262280A8-37D5-4037-BDFB-242468DFB3D2} = {262280A8-37D5-4037-BDFB-242468DFB3D2}
{8762A9B8-72A9-462E-A9A2-F3265081F8AF} = {8762A9B8-72A9-462E-A9A2-F3265081F8AF}
{F74653C4-8003-4A79-8F53-FC69E0AD7A9B} = {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}
- {AEFFF9CA-3387-4027-B569-33D5D26887D1} = {AEFFF9CA-3387-4027-B569-33D5D26887D1}
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04} = {C70A6DC7-7D45-4C16-8654-7E57713A4C04}
{44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF}
{FC369DF4-AEB7-4531-BF34-A638C4363BFE} = {FC369DF4-AEB7-4531-BF34-A638C4363BFE}
EndProjectSection
@@ -148,8 +178,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqlserver", "mysqlserver\
ProjectSection(ProjectDependencies) = postProject
{EEC1300B-85A5-497C-B3E1-F708021DF859} = {EEC1300B-85A5-497C-B3E1-F708021DF859}
{207E9014-C4D1-4F6D-B76F-BC7DD7E31113} = {207E9014-C4D1-4F6D-B76F-BC7DD7E31113}
+ {13D37150-54D0-46C5-9519-03923243C7C7} = {13D37150-54D0-46C5-9519-03923243C7C7}
{37D9BA79-302E-4582-A545-CB5FF7982EA3} = {37D9BA79-302E-4582-A545-CB5FF7982EA3}
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0} = {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}
+ {262280A8-37D5-4037-BDFB-242468DFB3D2} = {262280A8-37D5-4037-BDFB-242468DFB3D2}
{8762A9B8-72A9-462E-A9A2-F3265081F8AF} = {8762A9B8-72A9-462E-A9A2-F3265081F8AF}
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04} = {C70A6DC7-7D45-4C16-8654-7E57713A4C04}
{44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF}
{FC369DF4-AEB7-4531-BF34-A638C4363BFE} = {FC369DF4-AEB7-4531-BF34-A638C4363BFE}
EndProjectSection
@@ -235,6 +269,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqltest", "client\mysqlte
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_client_test", "tests\mysql_client_test.vcproj", "{DA224DAB-5006-42BE-BB77-16E8BE5326D5}"
ProjectSection(ProjectDependencies) = postProject
+ {26383276-4843-494B-8BE0-8936ED3EBAAB} = {26383276-4843-494B-8BE0-8936ED3EBAAB}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_test_run_new", "mysql-test\mysql_test_run_new.vcproj", "{6189F838-21C6-42A1-B2D0-9146316573F7}"
@@ -253,24 +288,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqlmanager", "server-tool
{F74653C4-8003-4A79-8F53-FC69E0AD7A9B} = {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}
{44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF}
{FC369DF4-AEB7-4531-BF34-A638C4363BFE} = {FC369DF4-AEB7-4531-BF34-A638C4363BFE}
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bdb", "storage\bdb\bdb.vcproj", "{FB168572-FFF4-4503-9331-4E958459DC9D}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "heap", "storage\heap\heap.vcproj", "{603E5567-F3CD-4547-9F2B-E0082B702B0D}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "innobase", "storage\innobase\innobase.vcproj", "{AEFFF9CA-3387-4027-B569-33D5D26887D1}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "myisam", "storage\myisam\myisam.vcproj", "{E85E5D80-641E-44C7-B909-3805A8D3167B}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "myisammrg", "storage\myisammrg\myisammrg.vcproj", "{91B7E9AD-5F85-4236-9A28-B032543B123E}"
- ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
@@ -288,10 +305,34 @@ Global
pro = pro
pro nt = pro nt
Release = Release
- TLS = TLS
- TLS_DEBUG = TLS_DEBUG
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.classic.ActiveCfg = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.classic.Build.0 = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.classic nt.ActiveCfg = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.classic nt.Build.0 = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Debug.ActiveCfg = Debug|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Debug.Build.0 = Debug|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Embedded_Classic.ActiveCfg = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Embedded_Classic.Build.0 = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Embedded_Debug.ActiveCfg = Debug|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Embedded_Debug.Build.0 = Debug|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Embedded_Pro.ActiveCfg = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Embedded_Pro.Build.0 = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Embedded_Release.ActiveCfg = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Embedded_Release.Build.0 = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Max.ActiveCfg = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Max.Build.0 = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Max nt.ActiveCfg = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Max nt.Build.0 = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.nt.ActiveCfg = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.nt.Build.0 = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.pro.ActiveCfg = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.pro.Build.0 = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.pro nt.ActiveCfg = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.pro nt.Build.0 = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Release.ActiveCfg = Max|Win32
+ {6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Release.Build.0 = Max|Win32
{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.classic.ActiveCfg = Release|Win32
{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.classic nt.ActiveCfg = Release|Win32
{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.classic nt.Build.0 = Release|Win32
@@ -312,21 +353,20 @@ Global
{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.pro nt.Build.0 = Release|Win32
{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.Release.ActiveCfg = Release|Win32
{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.Release.Build.0 = Release|Win32
- {1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.TLS.ActiveCfg = Release|Win32
- {1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.TLS.Build.0 = Release|Win32
- {1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.TLS_DEBUG.ActiveCfg = Release|Win32
- {1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.TLS_DEBUG.Build.0 = Release|Win32
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.classic.ActiveCfg = Release|Win32
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.classic.Build.0 = Release|Win32
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.classic nt.ActiveCfg = Release|Win32
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.classic nt.Build.0 = Release|Win32
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Debug.ActiveCfg = Debug|Win32
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Debug.Build.0 = Debug|Win32
- {FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Embedded_Classic.ActiveCfg = Debug|Win32
+ {FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Embedded_Classic.ActiveCfg = Release|Win32
+ {FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Embedded_Classic.Build.0 = Release|Win32
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Embedded_Debug.ActiveCfg = TLS_DEBUG|Win32
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Embedded_Debug.Build.0 = TLS_DEBUG|Win32
- {FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Embedded_Pro.ActiveCfg = Debug|Win32
+ {FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Embedded_Pro.ActiveCfg = Release|Win32
+ {FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Embedded_Pro.Build.0 = Release|Win32
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Embedded_Release.ActiveCfg = Release|Win32
+ {FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Embedded_Release.Build.0 = Release|Win32
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Max.ActiveCfg = Release|Win32
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Max.Build.0 = Release|Win32
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Max nt.ActiveCfg = Release|Win32
@@ -339,10 +379,58 @@ Global
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.pro nt.Build.0 = Release|Win32
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Release.ActiveCfg = Release|Win32
{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Release.Build.0 = Release|Win32
- {FC369DF4-AEB7-4531-BF34-A638C4363BFE}.TLS.ActiveCfg = TLS_DEBUG|Win32
- {FC369DF4-AEB7-4531-BF34-A638C4363BFE}.TLS.Build.0 = TLS_DEBUG|Win32
- {FC369DF4-AEB7-4531-BF34-A638C4363BFE}.TLS_DEBUG.ActiveCfg = TLS_DEBUG|Win32
- {FC369DF4-AEB7-4531-BF34-A638C4363BFE}.TLS_DEBUG.Build.0 = TLS_DEBUG|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.classic.ActiveCfg = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.classic.Build.0 = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.classic nt.ActiveCfg = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.classic nt.Build.0 = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Debug.ActiveCfg = Debug|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Debug.Build.0 = Debug|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Embedded_Classic.ActiveCfg = TLS|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Embedded_Classic.Build.0 = TLS|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Embedded_Debug.ActiveCfg = TLS_DEBUG|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Embedded_Debug.Build.0 = TLS_DEBUG|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Embedded_Pro.ActiveCfg = TLS|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Embedded_Pro.Build.0 = TLS|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Embedded_Release.ActiveCfg = TLS|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Embedded_Release.Build.0 = TLS|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Max.ActiveCfg = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Max.Build.0 = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Max nt.ActiveCfg = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Max nt.Build.0 = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.nt.ActiveCfg = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.nt.Build.0 = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.pro.ActiveCfg = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.pro.Build.0 = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.pro nt.ActiveCfg = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.pro nt.Build.0 = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Release.ActiveCfg = Release|Win32
+ {C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Release.Build.0 = Release|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.classic.ActiveCfg = Release|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.classic.Build.0 = Release|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.classic nt.ActiveCfg = nt|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.classic nt.Build.0 = nt|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Debug.ActiveCfg = Debug|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Debug.Build.0 = Debug|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Embedded_Classic.ActiveCfg = Release|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Embedded_Classic.Build.0 = Release|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Embedded_Debug.ActiveCfg = Debug|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Embedded_Debug.Build.0 = Debug|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Embedded_Pro.ActiveCfg = Release|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Embedded_Pro.Build.0 = Release|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Embedded_Release.ActiveCfg = Release|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Embedded_Release.Build.0 = Release|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Max.ActiveCfg = Release|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Max.Build.0 = Release|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Max nt.ActiveCfg = Max nt|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Max nt.Build.0 = Max nt|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.nt.ActiveCfg = nt|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.nt.Build.0 = nt|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.pro.ActiveCfg = Release|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.pro.Build.0 = Release|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.pro nt.ActiveCfg = nt|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.pro nt.Build.0 = nt|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Release.ActiveCfg = Release|Win32
+ {13D37150-54D0-46C5-9519-03923243C7C7}.Release.Build.0 = Release|Win32
{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.classic.ActiveCfg = Release|Win32
{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.classic.Build.0 = Release|Win32
{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.classic nt.ActiveCfg = Release|Win32
@@ -365,10 +453,6 @@ Global
{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.pro nt.Build.0 = Release|Win32
{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.Release.ActiveCfg = Release|Win32
{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.Release.Build.0 = Release|Win32
- {1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.TLS.ActiveCfg = Release|Win32
- {1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.TLS.Build.0 = Release|Win32
- {1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.TLS_DEBUG.ActiveCfg = Release|Win32
- {1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.TLS_DEBUG.Build.0 = Release|Win32
{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.classic.ActiveCfg = classic|Win32
{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.classic nt.ActiveCfg = classic|Win32
{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.Debug.ActiveCfg = Debug|Win32
@@ -386,12 +470,8 @@ Global
{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.pro.ActiveCfg = pro|Win32
{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.pro nt.ActiveCfg = pro|Win32
{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.Release.ActiveCfg = Release|Win32
- {93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.TLS.ActiveCfg = classic|Win32
- {93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.TLS.Build.0 = classic|Win32
- {93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.TLS_DEBUG.ActiveCfg = classic|Win32
- {93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.TLS_DEBUG.Build.0 = classic|Win32
- {2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.classic.ActiveCfg = Debug|Win32
- {2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.classic.Build.0 = Debug|Win32
+ {2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.classic.ActiveCfg = Release|Win32
+ {2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.classic.Build.0 = Release|Win32
{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.classic nt.ActiveCfg = Release|Win32
{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.classic nt.Build.0 = Release|Win32
{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.Debug.ActiveCfg = Debug|Win32
@@ -412,10 +492,6 @@ Global
{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.pro nt.Build.0 = Release|Win32
{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.Release.ActiveCfg = Release|Win32
{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.Release.Build.0 = Release|Win32
- {2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.TLS.ActiveCfg = Debug|Win32
- {2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.TLS.Build.0 = Debug|Win32
- {2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.TLS_DEBUG.Build.0 = Debug|Win32
{B0EC3594-CD67-4364-826E-BA75EF2050F8}.classic.ActiveCfg = classic|Win32
{B0EC3594-CD67-4364-826E-BA75EF2050F8}.classic.Build.0 = classic|Win32
{B0EC3594-CD67-4364-826E-BA75EF2050F8}.classic nt.ActiveCfg = Release|Win32
@@ -438,10 +514,32 @@ Global
{B0EC3594-CD67-4364-826E-BA75EF2050F8}.pro nt.Build.0 = Release|Win32
{B0EC3594-CD67-4364-826E-BA75EF2050F8}.Release.ActiveCfg = Release|Win32
{B0EC3594-CD67-4364-826E-BA75EF2050F8}.Release.Build.0 = Release|Win32
- {B0EC3594-CD67-4364-826E-BA75EF2050F8}.TLS.ActiveCfg = Debug|Win32
- {B0EC3594-CD67-4364-826E-BA75EF2050F8}.TLS.Build.0 = Debug|Win32
- {B0EC3594-CD67-4364-826E-BA75EF2050F8}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {B0EC3594-CD67-4364-826E-BA75EF2050F8}.TLS_DEBUG.Build.0 = Debug|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.classic.ActiveCfg = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.classic.Build.0 = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.classic nt.ActiveCfg = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.classic nt.Build.0 = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Debug.ActiveCfg = Debug|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Debug.Build.0 = Debug|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Embedded_Classic.ActiveCfg = TLS|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Embedded_Classic.Build.0 = TLS|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Embedded_Debug.ActiveCfg = Debug|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Embedded_Debug.Build.0 = Debug|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Embedded_Pro.ActiveCfg = TLS|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Embedded_Pro.Build.0 = TLS|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Embedded_Release.ActiveCfg = TLS|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Embedded_Release.Build.0 = TLS|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Max.ActiveCfg = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Max.Build.0 = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Max nt.ActiveCfg = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Max nt.Build.0 = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.nt.ActiveCfg = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.nt.Build.0 = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.pro.ActiveCfg = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.pro.Build.0 = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.pro nt.ActiveCfg = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.pro nt.Build.0 = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Release.ActiveCfg = Release|Win32
+ {262280A8-37D5-4037-BDFB-242468DFB3D2}.Release.Build.0 = Release|Win32
{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.classic.ActiveCfg = Release|Win32
{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.classic.Build.0 = Release|Win32
{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.classic nt.ActiveCfg = Release|Win32
@@ -464,10 +562,6 @@ Global
{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.pro nt.Build.0 = Release|Win32
{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.Release.ActiveCfg = Release|Win32
{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.Release.Build.0 = Release|Win32
- {4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.TLS.ActiveCfg = Release|Win32
- {4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.TLS.Build.0 = Release|Win32
- {4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.TLS_DEBUG.ActiveCfg = Release|Win32
- {4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.TLS_DEBUG.Build.0 = Release|Win32
{87CD9881-D234-4306-BBC6-0668C6168C0F}.classic.ActiveCfg = classic|Win32
{87CD9881-D234-4306-BBC6-0668C6168C0F}.classic.Build.0 = classic|Win32
{87CD9881-D234-4306-BBC6-0668C6168C0F}.classic nt.ActiveCfg = Release|Win32
@@ -490,10 +584,6 @@ Global
{87CD9881-D234-4306-BBC6-0668C6168C0F}.pro nt.Build.0 = Release|Win32
{87CD9881-D234-4306-BBC6-0668C6168C0F}.Release.ActiveCfg = Release|Win32
{87CD9881-D234-4306-BBC6-0668C6168C0F}.Release.Build.0 = Release|Win32
- {87CD9881-D234-4306-BBC6-0668C6168C0F}.TLS.ActiveCfg = Debug|Win32
- {87CD9881-D234-4306-BBC6-0668C6168C0F}.TLS.Build.0 = Debug|Win32
- {87CD9881-D234-4306-BBC6-0668C6168C0F}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {87CD9881-D234-4306-BBC6-0668C6168C0F}.TLS_DEBUG.Build.0 = Debug|Win32
{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.classic.ActiveCfg = classic|Win32
{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.classic.Build.0 = classic|Win32
{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.classic nt.ActiveCfg = Release|Win32
@@ -516,10 +606,32 @@ Global
{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.pro nt.Build.0 = Release|Win32
{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.Release.ActiveCfg = Release|Win32
{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.Release.Build.0 = Release|Win32
- {194F5EE6-9440-4298-A6FE-A9B4B480B44C}.TLS.ActiveCfg = Release|Win32
- {194F5EE6-9440-4298-A6FE-A9B4B480B44C}.TLS.Build.0 = Release|Win32
- {194F5EE6-9440-4298-A6FE-A9B4B480B44C}.TLS_DEBUG.ActiveCfg = Release|Win32
- {194F5EE6-9440-4298-A6FE-A9B4B480B44C}.TLS_DEBUG.Build.0 = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.classic.ActiveCfg = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.classic.Build.0 = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.classic nt.ActiveCfg = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.classic nt.Build.0 = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Debug.ActiveCfg = Debug|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Debug.Build.0 = Debug|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Embedded_Classic.ActiveCfg = TLS|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Embedded_Classic.Build.0 = TLS|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Embedded_Debug.ActiveCfg = Debug|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Embedded_Debug.Build.0 = Debug|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Embedded_Pro.ActiveCfg = TLS|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Embedded_Pro.Build.0 = TLS|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Embedded_Release.ActiveCfg = TLS|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Embedded_Release.Build.0 = TLS|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Max.ActiveCfg = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Max.Build.0 = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Max nt.ActiveCfg = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Max nt.Build.0 = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.nt.ActiveCfg = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.nt.Build.0 = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.pro.ActiveCfg = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.pro.Build.0 = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.pro nt.ActiveCfg = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.pro nt.Build.0 = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Release.ActiveCfg = Release|Win32
+ {D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Release.Build.0 = Release|Win32
{EF833A1E-E358-4B6C-9C27-9489E85041CC}.classic.ActiveCfg = classic|Win32
{EF833A1E-E358-4B6C-9C27-9489E85041CC}.classic.Build.0 = classic|Win32
{EF833A1E-E358-4B6C-9C27-9489E85041CC}.classic nt.ActiveCfg = Release|Win32
@@ -542,10 +654,6 @@ Global
{EF833A1E-E358-4B6C-9C27-9489E85041CC}.pro nt.Build.0 = Release|Win32
{EF833A1E-E358-4B6C-9C27-9489E85041CC}.Release.ActiveCfg = Release|Win32
{EF833A1E-E358-4B6C-9C27-9489E85041CC}.Release.Build.0 = Release|Win32
- {EF833A1E-E358-4B6C-9C27-9489E85041CC}.TLS.ActiveCfg = classic|Win32
- {EF833A1E-E358-4B6C-9C27-9489E85041CC}.TLS.Build.0 = classic|Win32
- {EF833A1E-E358-4B6C-9C27-9489E85041CC}.TLS_DEBUG.ActiveCfg = classic|Win32
- {EF833A1E-E358-4B6C-9C27-9489E85041CC}.TLS_DEBUG.Build.0 = classic|Win32
{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.classic.ActiveCfg = classic|Win32
{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.classic.Build.0 = classic|Win32
{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.classic nt.ActiveCfg = Release|Win32
@@ -568,10 +676,6 @@ Global
{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.pro nt.Build.0 = Release|Win32
{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.Release.ActiveCfg = Release|Win32
{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.Release.Build.0 = Release|Win32
- {F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.TLS.ActiveCfg = Debug|Win32
- {F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.TLS.Build.0 = Debug|Win32
- {F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.TLS_DEBUG.Build.0 = Debug|Win32
{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.classic.ActiveCfg = classic|Win32
{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.classic.Build.0 = classic|Win32
{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.classic nt.ActiveCfg = Release|Win32
@@ -594,10 +698,6 @@ Global
{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.pro nt.Build.0 = Release|Win32
{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.Release.ActiveCfg = Release|Win32
{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.Release.Build.0 = Release|Win32
- {D2B00DE0-F6E9-40AF-B90D-A257D014F098}.TLS.ActiveCfg = Debug|Win32
- {D2B00DE0-F6E9-40AF-B90D-A257D014F098}.TLS.Build.0 = Debug|Win32
- {D2B00DE0-F6E9-40AF-B90D-A257D014F098}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {D2B00DE0-F6E9-40AF-B90D-A257D014F098}.TLS_DEBUG.Build.0 = Debug|Win32
{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.classic.ActiveCfg = classic|Win32
{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.classic.Build.0 = classic|Win32
{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.classic nt.ActiveCfg = Release|Win32
@@ -620,10 +720,6 @@ Global
{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.pro nt.Build.0 = Release|Win32
{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.Release.ActiveCfg = Release|Win32
{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.Release.Build.0 = Release|Win32
- {DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.TLS.ActiveCfg = Release|Win32
- {DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.TLS.Build.0 = Release|Win32
- {DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.TLS_DEBUG.ActiveCfg = Release|Win32
- {DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.TLS_DEBUG.Build.0 = Release|Win32
{67154F28-D076-419E-B149-819EF548E670}.classic.ActiveCfg = classic|Win32
{67154F28-D076-419E-B149-819EF548E670}.classic.Build.0 = classic|Win32
{67154F28-D076-419E-B149-819EF548E670}.classic nt.ActiveCfg = Release|Win32
@@ -646,12 +742,8 @@ Global
{67154F28-D076-419E-B149-819EF548E670}.pro nt.Build.0 = Release|Win32
{67154F28-D076-419E-B149-819EF548E670}.Release.ActiveCfg = Release|Win32
{67154F28-D076-419E-B149-819EF548E670}.Release.Build.0 = Release|Win32
- {67154F28-D076-419E-B149-819EF548E670}.TLS.ActiveCfg = Debug|Win32
- {67154F28-D076-419E-B149-819EF548E670}.TLS.Build.0 = Debug|Win32
- {67154F28-D076-419E-B149-819EF548E670}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {67154F28-D076-419E-B149-819EF548E670}.TLS_DEBUG.Build.0 = Debug|Win32
- {26383276-4843-494B-8BE0-8936ED3EBAAB}.classic.ActiveCfg = Debug|Win32
- {26383276-4843-494B-8BE0-8936ED3EBAAB}.classic.Build.0 = Debug|Win32
+ {26383276-4843-494B-8BE0-8936ED3EBAAB}.classic.ActiveCfg = Release|Win32
+ {26383276-4843-494B-8BE0-8936ED3EBAAB}.classic.Build.0 = Release|Win32
{26383276-4843-494B-8BE0-8936ED3EBAAB}.classic nt.ActiveCfg = Release|Win32
{26383276-4843-494B-8BE0-8936ED3EBAAB}.classic nt.Build.0 = Release|Win32
{26383276-4843-494B-8BE0-8936ED3EBAAB}.Debug.ActiveCfg = Debug|Win32
@@ -672,10 +764,6 @@ Global
{26383276-4843-494B-8BE0-8936ED3EBAAB}.pro nt.Build.0 = Release|Win32
{26383276-4843-494B-8BE0-8936ED3EBAAB}.Release.ActiveCfg = Release|Win32
{26383276-4843-494B-8BE0-8936ED3EBAAB}.Release.Build.0 = Release|Win32
- {26383276-4843-494B-8BE0-8936ED3EBAAB}.TLS.ActiveCfg = Debug|Win32
- {26383276-4843-494B-8BE0-8936ED3EBAAB}.TLS.Build.0 = Debug|Win32
- {26383276-4843-494B-8BE0-8936ED3EBAAB}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {26383276-4843-494B-8BE0-8936ED3EBAAB}.TLS_DEBUG.Build.0 = Debug|Win32
{62E85884-3ACF-4F4C-873B-60B878147890}.classic.ActiveCfg = classic|Win32
{62E85884-3ACF-4F4C-873B-60B878147890}.classic.Build.0 = classic|Win32
{62E85884-3ACF-4F4C-873B-60B878147890}.classic nt.ActiveCfg = classic nt|Win32
@@ -698,10 +786,6 @@ Global
{62E85884-3ACF-4F4C-873B-60B878147890}.pro nt.Build.0 = pro nt|Win32
{62E85884-3ACF-4F4C-873B-60B878147890}.Release.ActiveCfg = Release|Win32
{62E85884-3ACF-4F4C-873B-60B878147890}.Release.Build.0 = Release|Win32
- {62E85884-3ACF-4F4C-873B-60B878147890}.TLS.ActiveCfg = Release|Win32
- {62E85884-3ACF-4F4C-873B-60B878147890}.TLS.Build.0 = Release|Win32
- {62E85884-3ACF-4F4C-873B-60B878147890}.TLS_DEBUG.ActiveCfg = Release|Win32
- {62E85884-3ACF-4F4C-873B-60B878147890}.TLS_DEBUG.Build.0 = Release|Win32
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.classic.ActiveCfg = classic|Win32
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.classic.Build.0 = classic|Win32
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.classic nt.ActiveCfg = classic|Win32
@@ -724,10 +808,6 @@ Global
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro nt.Build.0 = pro|Win32
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Release.ActiveCfg = Release|Win32
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Release.Build.0 = Release|Win32
- {37D9BA79-302E-4582-A545-CB5FF7982EA3}.TLS.ActiveCfg = Release|Win32
- {37D9BA79-302E-4582-A545-CB5FF7982EA3}.TLS.Build.0 = Release|Win32
- {37D9BA79-302E-4582-A545-CB5FF7982EA3}.TLS_DEBUG.ActiveCfg = Release|Win32
- {37D9BA79-302E-4582-A545-CB5FF7982EA3}.TLS_DEBUG.Build.0 = Release|Win32
{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.classic.ActiveCfg = classic|Win32
{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.classic.Build.0 = classic|Win32
{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.classic nt.ActiveCfg = classic|Win32
@@ -750,10 +830,6 @@ Global
{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.pro nt.Build.0 = Release|Win32
{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.Release.ActiveCfg = Release|Win32
{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.Release.Build.0 = Release|Win32
- {89F24ECE-9953-40EF-BDF4-B41F5631E92B}.TLS.ActiveCfg = classic|Win32
- {89F24ECE-9953-40EF-BDF4-B41F5631E92B}.TLS.Build.0 = classic|Win32
- {89F24ECE-9953-40EF-BDF4-B41F5631E92B}.TLS_DEBUG.ActiveCfg = classic|Win32
- {89F24ECE-9953-40EF-BDF4-B41F5631E92B}.TLS_DEBUG.Build.0 = classic|Win32
{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.classic.ActiveCfg = classic|Win32
{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.classic.Build.0 = classic|Win32
{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.classic nt.ActiveCfg = classic|Win32
@@ -776,10 +852,6 @@ Global
{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.pro nt.Build.0 = Release|Win32
{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.Release.ActiveCfg = Release|Win32
{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.Release.Build.0 = Release|Win32
- {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.TLS.ActiveCfg = classic|Win32
- {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.TLS.Build.0 = classic|Win32
- {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.TLS_DEBUG.ActiveCfg = classic|Win32
- {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.TLS_DEBUG.Build.0 = classic|Win32
{94B86159-C581-42CD-825D-C69CBC237E5C}.classic.ActiveCfg = Release|Win32
{94B86159-C581-42CD-825D-C69CBC237E5C}.classic.Build.0 = Release|Win32
{94B86159-C581-42CD-825D-C69CBC237E5C}.classic nt.ActiveCfg = Release|Win32
@@ -802,10 +874,6 @@ Global
{94B86159-C581-42CD-825D-C69CBC237E5C}.pro nt.Build.0 = Release|Win32
{94B86159-C581-42CD-825D-C69CBC237E5C}.Release.ActiveCfg = Release|Win32
{94B86159-C581-42CD-825D-C69CBC237E5C}.Release.Build.0 = Release|Win32
- {94B86159-C581-42CD-825D-C69CBC237E5C}.TLS.ActiveCfg = Release|Win32
- {94B86159-C581-42CD-825D-C69CBC237E5C}.TLS.Build.0 = Release|Win32
- {94B86159-C581-42CD-825D-C69CBC237E5C}.TLS_DEBUG.ActiveCfg = Release|Win32
- {94B86159-C581-42CD-825D-C69CBC237E5C}.TLS_DEBUG.Build.0 = Release|Win32
{3737BFE2-EF25-464F-994D-BD28A9F84528}.classic.ActiveCfg = classic|Win32
{3737BFE2-EF25-464F-994D-BD28A9F84528}.classic.Build.0 = classic|Win32
{3737BFE2-EF25-464F-994D-BD28A9F84528}.classic nt.ActiveCfg = classic|Win32
@@ -828,10 +896,6 @@ Global
{3737BFE2-EF25-464F-994D-BD28A9F84528}.pro nt.Build.0 = Release|Win32
{3737BFE2-EF25-464F-994D-BD28A9F84528}.Release.ActiveCfg = Release|Win32
{3737BFE2-EF25-464F-994D-BD28A9F84528}.Release.Build.0 = Release|Win32
- {3737BFE2-EF25-464F-994D-BD28A9F84528}.TLS.ActiveCfg = Debug|Win32
- {3737BFE2-EF25-464F-994D-BD28A9F84528}.TLS.Build.0 = Debug|Win32
- {3737BFE2-EF25-464F-994D-BD28A9F84528}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {3737BFE2-EF25-464F-994D-BD28A9F84528}.TLS_DEBUG.Build.0 = Debug|Win32
{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.classic.ActiveCfg = Release|Win32
{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.classic.Build.0 = Release|Win32
{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.classic nt.ActiveCfg = Release|Win32
@@ -858,10 +922,6 @@ Global
{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.pro nt.Build.0 = Release|Win32
{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.Release.ActiveCfg = Release|Win32
{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.Release.Build.0 = Release|Win32
- {BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.TLS.ActiveCfg = Release|Win32
- {BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.TLS.Build.0 = Release|Win32
- {BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.TLS_DEBUG.ActiveCfg = Release|Win32
- {BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.TLS_DEBUG.Build.0 = Release|Win32
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.classic.ActiveCfg = Release|Win32
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.classic.Build.0 = Release|Win32
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.classic nt.ActiveCfg = Release|Win32
@@ -869,9 +929,13 @@ Global
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.Debug.ActiveCfg = Debug|Win32
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.Debug.Build.0 = Debug|Win32
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.Embedded_Classic.ActiveCfg = Release|Win32
+ {DB28DE80-837F-4497-9AA9-CC0A20584C98}.Embedded_Classic.Build.0 = Release|Win32
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.Embedded_Debug.ActiveCfg = Debug|Win32
+ {DB28DE80-837F-4497-9AA9-CC0A20584C98}.Embedded_Debug.Build.0 = Debug|Win32
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.Embedded_Pro.ActiveCfg = Release|Win32
+ {DB28DE80-837F-4497-9AA9-CC0A20584C98}.Embedded_Pro.Build.0 = Release|Win32
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.Embedded_Release.ActiveCfg = Release|Win32
+ {DB28DE80-837F-4497-9AA9-CC0A20584C98}.Embedded_Release.Build.0 = Release|Win32
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.Max.ActiveCfg = Release|Win32
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.Max.Build.0 = Release|Win32
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.Max nt.ActiveCfg = Release|Win32
@@ -884,10 +948,6 @@ Global
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.pro nt.Build.0 = Release|Win32
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.Release.ActiveCfg = Release|Win32
{DB28DE80-837F-4497-9AA9-CC0A20584C98}.Release.Build.0 = Release|Win32
- {DB28DE80-837F-4497-9AA9-CC0A20584C98}.TLS.ActiveCfg = Release|Win32
- {DB28DE80-837F-4497-9AA9-CC0A20584C98}.TLS.Build.0 = Release|Win32
- {DB28DE80-837F-4497-9AA9-CC0A20584C98}.TLS_DEBUG.ActiveCfg = Release|Win32
- {DB28DE80-837F-4497-9AA9-CC0A20584C98}.TLS_DEBUG.Build.0 = Release|Win32
{44D9C7DC-6636-4B82-BD01-6876C64017DF}.classic.ActiveCfg = TLS|Win32
{44D9C7DC-6636-4B82-BD01-6876C64017DF}.classic.Build.0 = TLS|Win32
{44D9C7DC-6636-4B82-BD01-6876C64017DF}.classic nt.ActiveCfg = Release|Win32
@@ -914,10 +974,6 @@ Global
{44D9C7DC-6636-4B82-BD01-6876C64017DF}.pro nt.Build.0 = Release|Win32
{44D9C7DC-6636-4B82-BD01-6876C64017DF}.Release.ActiveCfg = Release|Win32
{44D9C7DC-6636-4B82-BD01-6876C64017DF}.Release.Build.0 = Release|Win32
- {44D9C7DC-6636-4B82-BD01-6876C64017DF}.TLS.ActiveCfg = TLS|Win32
- {44D9C7DC-6636-4B82-BD01-6876C64017DF}.TLS.Build.0 = TLS|Win32
- {44D9C7DC-6636-4B82-BD01-6876C64017DF}.TLS_DEBUG.ActiveCfg = TLS_DEBUG|Win32
- {44D9C7DC-6636-4B82-BD01-6876C64017DF}.TLS_DEBUG.Build.0 = TLS_DEBUG|Win32
{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.classic.ActiveCfg = classic|Win32
{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.classic.Build.0 = classic|Win32
{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.classic nt.ActiveCfg = classic|Win32
@@ -940,10 +996,6 @@ Global
{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.pro nt.Build.0 = Release|Win32
{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.Release.ActiveCfg = Release|Win32
{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.Release.Build.0 = Release|Win32
- {AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.TLS.ActiveCfg = Debug|Win32
- {AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.TLS.Build.0 = Debug|Win32
- {AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.TLS_DEBUG.Build.0 = Debug|Win32
{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.classic.ActiveCfg = Release|Win32
{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.classic.Build.0 = Release|Win32
{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.classic nt.ActiveCfg = Release|Win32
@@ -970,10 +1022,6 @@ Global
{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.pro nt.Build.0 = Release|Win32
{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.Release.ActiveCfg = Release|Win32
{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.Release.Build.0 = Release|Win32
- {207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.TLS.ActiveCfg = Release|Win32
- {207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.TLS.Build.0 = Release|Win32
- {207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.TLS_DEBUG.ActiveCfg = Release|Win32
- {207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.TLS_DEBUG.Build.0 = Release|Win32
{16699B52-ECC6-4A96-A99F-A043059BA2E7}.classic.ActiveCfg = classic|Win32
{16699B52-ECC6-4A96-A99F-A043059BA2E7}.classic.Build.0 = classic|Win32
{16699B52-ECC6-4A96-A99F-A043059BA2E7}.classic nt.ActiveCfg = classic|Win32
@@ -996,18 +1044,14 @@ Global
{16699B52-ECC6-4A96-A99F-A043059BA2E7}.pro nt.Build.0 = Release|Win32
{16699B52-ECC6-4A96-A99F-A043059BA2E7}.Release.ActiveCfg = Release|Win32
{16699B52-ECC6-4A96-A99F-A043059BA2E7}.Release.Build.0 = Release|Win32
- {16699B52-ECC6-4A96-A99F-A043059BA2E7}.TLS.ActiveCfg = classic|Win32
- {16699B52-ECC6-4A96-A99F-A043059BA2E7}.TLS.Build.0 = classic|Win32
- {16699B52-ECC6-4A96-A99F-A043059BA2E7}.TLS_DEBUG.ActiveCfg = classic|Win32
- {16699B52-ECC6-4A96-A99F-A043059BA2E7}.TLS_DEBUG.Build.0 = classic|Win32
- {EEC1300B-85A5-497C-B3E1-F708021DF859}.classic.ActiveCfg = Debug|Win32
- {EEC1300B-85A5-497C-B3E1-F708021DF859}.classic.Build.0 = Debug|Win32
+ {EEC1300B-85A5-497C-B3E1-F708021DF859}.classic.ActiveCfg = Release|Win32
+ {EEC1300B-85A5-497C-B3E1-F708021DF859}.classic.Build.0 = Release|Win32
{EEC1300B-85A5-497C-B3E1-F708021DF859}.classic nt.ActiveCfg = Release|Win32
{EEC1300B-85A5-497C-B3E1-F708021DF859}.classic nt.Build.0 = Release|Win32
{EEC1300B-85A5-497C-B3E1-F708021DF859}.Debug.ActiveCfg = Debug|Win32
{EEC1300B-85A5-497C-B3E1-F708021DF859}.Debug.Build.0 = Debug|Win32
- {EEC1300B-85A5-497C-B3E1-F708021DF859}.Embedded_Classic.ActiveCfg = Debug|Win32
- {EEC1300B-85A5-497C-B3E1-F708021DF859}.Embedded_Classic.Build.0 = Debug|Win32
+ {EEC1300B-85A5-497C-B3E1-F708021DF859}.Embedded_Classic.ActiveCfg = Release|Win32
+ {EEC1300B-85A5-497C-B3E1-F708021DF859}.Embedded_Classic.Build.0 = Release|Win32
{EEC1300B-85A5-497C-B3E1-F708021DF859}.Embedded_Debug.ActiveCfg = Debug|Win32
{EEC1300B-85A5-497C-B3E1-F708021DF859}.Embedded_Debug.Build.0 = Debug|Win32
{EEC1300B-85A5-497C-B3E1-F708021DF859}.Embedded_Pro.ActiveCfg = Release|Win32
@@ -1026,12 +1070,8 @@ Global
{EEC1300B-85A5-497C-B3E1-F708021DF859}.pro nt.Build.0 = Release|Win32
{EEC1300B-85A5-497C-B3E1-F708021DF859}.Release.ActiveCfg = Release|Win32
{EEC1300B-85A5-497C-B3E1-F708021DF859}.Release.Build.0 = Release|Win32
- {EEC1300B-85A5-497C-B3E1-F708021DF859}.TLS.ActiveCfg = Debug|Win32
- {EEC1300B-85A5-497C-B3E1-F708021DF859}.TLS.Build.0 = Debug|Win32
- {EEC1300B-85A5-497C-B3E1-F708021DF859}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {EEC1300B-85A5-497C-B3E1-F708021DF859}.TLS_DEBUG.Build.0 = Debug|Win32
- {8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.classic.ActiveCfg = Debug|Win32
- {8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.classic.Build.0 = Debug|Win32
+ {8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.classic.ActiveCfg = Release|Win32
+ {8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.classic.Build.0 = Release|Win32
{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.classic nt.ActiveCfg = Debug|Win32
{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.Debug.ActiveCfg = Debug|Win32
{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.Debug.Build.0 = Debug|Win32
@@ -1046,12 +1086,7 @@ Global
{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.pro nt.ActiveCfg = Debug|Win32
{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.Release.ActiveCfg = Release|Win32
{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.Release.Build.0 = Release|Win32
- {8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.TLS.ActiveCfg = Debug|Win32
- {8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.TLS.Build.0 = Debug|Win32
- {8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.TLS_DEBUG.Build.0 = Debug|Win32
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.classic.ActiveCfg = Release|Win32
- {6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.classic.Build.0 = Release|Win32
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.classic nt.ActiveCfg = Release|Win32
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Debug.ActiveCfg = Release|Win32
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Embedded_Classic.ActiveCfg = Release|Win32
@@ -1060,16 +1095,10 @@ Global
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Embedded_Release.ActiveCfg = Release|Win32
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Max.ActiveCfg = Release|Win32
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Max nt.ActiveCfg = Release|Win32
- {6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Max nt.Build.0 = Release|Win32
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.nt.ActiveCfg = Release|Win32
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.pro.ActiveCfg = Release|Win32
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.pro nt.ActiveCfg = Release|Win32
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Release.ActiveCfg = Release|Win32
- {6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Release.Build.0 = Release|Win32
- {6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.TLS.ActiveCfg = Release|Win32
- {6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.TLS.Build.0 = Release|Win32
- {6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.TLS_DEBUG.ActiveCfg = Release|Win32
- {6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.TLS_DEBUG.Build.0 = Release|Win32
{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.classic.ActiveCfg = Release|Win32
{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.classic.Build.0 = Release|Win32
{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.classic nt.ActiveCfg = Release|Win32
@@ -1092,20 +1121,20 @@ Global
{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.pro nt.Build.0 = Release|Win32
{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.Release.ActiveCfg = Release|Win32
{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.Release.Build.0 = Release|Win32
- {7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.TLS.ActiveCfg = Release|Win32
- {7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.TLS.Build.0 = Release|Win32
- {7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.TLS_DEBUG.ActiveCfg = Release|Win32
- {7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.TLS_DEBUG.Build.0 = Release|Win32
- {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.classic.ActiveCfg = Debug|Win32
- {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.classic.Build.0 = Debug|Win32
+ {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.classic.ActiveCfg = Release|Win32
+ {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.classic.Build.0 = Release|Win32
{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.classic nt.ActiveCfg = Release|Win32
{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.classic nt.Build.0 = Release|Win32
{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Debug.ActiveCfg = Debug|Win32
{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Debug.Build.0 = Debug|Win32
- {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Embedded_Classic.ActiveCfg = Debug|Win32
+ {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Embedded_Classic.ActiveCfg = Release|Win32
+ {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Embedded_Classic.Build.0 = Release|Win32
{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Embedded_Debug.ActiveCfg = Debug|Win32
- {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Embedded_Pro.ActiveCfg = Debug|Win32
+ {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Embedded_Debug.Build.0 = Debug|Win32
+ {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Embedded_Pro.ActiveCfg = Release|Win32
+ {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Embedded_Pro.Build.0 = Release|Win32
{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Embedded_Release.ActiveCfg = Release|Win32
+ {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Embedded_Release.Build.0 = Release|Win32
{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Max.ActiveCfg = Release|Win32
{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Max.Build.0 = Release|Win32
{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Max nt.ActiveCfg = Release|Win32
@@ -1118,10 +1147,6 @@ Global
{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.pro nt.Build.0 = Release|Win32
{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Release.ActiveCfg = Release|Win32
{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Release.Build.0 = Release|Win32
- {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.TLS.ActiveCfg = Debug|Win32
- {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.TLS.Build.0 = Debug|Win32
- {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.TLS_DEBUG.Build.0 = Debug|Win32
{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.classic.ActiveCfg = Release|Win32
{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.classic.Build.0 = Release|Win32
{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.classic nt.ActiveCfg = Release|Win32
@@ -1131,6 +1156,7 @@ Global
{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.Embedded_Classic.ActiveCfg = Release|Win32
{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.Embedded_Classic.Build.0 = Release|Win32
{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.Embedded_Debug.ActiveCfg = Debug|Win32
+ {8762A9B8-72A9-462E-A9A2-F3265081F8AF}.Embedded_Debug.Build.0 = Debug|Win32
{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.Embedded_Pro.ActiveCfg = Release|Win32
{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.Embedded_Pro.Build.0 = Release|Win32
{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.Embedded_Release.ActiveCfg = Release|Win32
@@ -1147,10 +1173,6 @@ Global
{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.pro nt.Build.0 = Release|Win32
{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.Release.ActiveCfg = Release|Win32
{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.Release.Build.0 = Release|Win32
- {8762A9B8-72A9-462E-A9A2-F3265081F8AF}.TLS.ActiveCfg = Release|Win32
- {8762A9B8-72A9-462E-A9A2-F3265081F8AF}.TLS.Build.0 = Release|Win32
- {8762A9B8-72A9-462E-A9A2-F3265081F8AF}.TLS_DEBUG.ActiveCfg = Release|Win32
- {8762A9B8-72A9-462E-A9A2-F3265081F8AF}.TLS_DEBUG.Build.0 = Release|Win32
{8961F149-C68A-4154-A499-A2AB39E607E8}.classic.ActiveCfg = classic|Win32
{8961F149-C68A-4154-A499-A2AB39E607E8}.classic.Build.0 = classic|Win32
{8961F149-C68A-4154-A499-A2AB39E607E8}.classic nt.ActiveCfg = classic|Win32
@@ -1173,12 +1195,8 @@ Global
{8961F149-C68A-4154-A499-A2AB39E607E8}.pro nt.Build.0 = Release|Win32
{8961F149-C68A-4154-A499-A2AB39E607E8}.Release.ActiveCfg = Release|Win32
{8961F149-C68A-4154-A499-A2AB39E607E8}.Release.Build.0 = Release|Win32
- {8961F149-C68A-4154-A499-A2AB39E607E8}.TLS.ActiveCfg = Debug|Win32
- {8961F149-C68A-4154-A499-A2AB39E607E8}.TLS.Build.0 = Debug|Win32
- {8961F149-C68A-4154-A499-A2AB39E607E8}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {8961F149-C68A-4154-A499-A2AB39E607E8}.TLS_DEBUG.Build.0 = Debug|Win32
- {DA224DAB-5006-42BE-BB77-16E8BE5326D5}.classic.ActiveCfg = Debug|Win32
- {DA224DAB-5006-42BE-BB77-16E8BE5326D5}.classic.Build.0 = Debug|Win32
+ {DA224DAB-5006-42BE-BB77-16E8BE5326D5}.classic.ActiveCfg = Release|Win32
+ {DA224DAB-5006-42BE-BB77-16E8BE5326D5}.classic.Build.0 = Release|Win32
{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.classic nt.ActiveCfg = Release|Win32
{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.classic nt.Build.0 = Release|Win32
{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.Debug.ActiveCfg = Debug|Win32
@@ -1190,7 +1208,6 @@ Global
{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.Max.ActiveCfg = Release|Win32
{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.Max.Build.0 = Release|Win32
{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.Max nt.ActiveCfg = Release|Win32
- {DA224DAB-5006-42BE-BB77-16E8BE5326D5}.Max nt.Build.0 = Release|Win32
{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.nt.ActiveCfg = Release|Win32
{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.nt.Build.0 = Release|Win32
{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.pro.ActiveCfg = Release|Win32
@@ -1199,10 +1216,6 @@ Global
{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.pro nt.Build.0 = Release|Win32
{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.Release.ActiveCfg = Release|Win32
{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.Release.Build.0 = Release|Win32
- {DA224DAB-5006-42BE-BB77-16E8BE5326D5}.TLS.ActiveCfg = Debug|Win32
- {DA224DAB-5006-42BE-BB77-16E8BE5326D5}.TLS.Build.0 = Debug|Win32
- {DA224DAB-5006-42BE-BB77-16E8BE5326D5}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {DA224DAB-5006-42BE-BB77-16E8BE5326D5}.TLS_DEBUG.Build.0 = Debug|Win32
{6189F838-21C6-42A1-B2D0-9146316573F7}.classic.ActiveCfg = Release|Win32
{6189F838-21C6-42A1-B2D0-9146316573F7}.classic.Build.0 = Release|Win32
{6189F838-21C6-42A1-B2D0-9146316573F7}.classic nt.ActiveCfg = Release|Win32
@@ -1251,160 +1264,6 @@ Global
{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro nt.Build.0 = Release|Win32
{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Release.ActiveCfg = Release|Win32
{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Release.Build.0 = Release|Win32
- {6189F838-21C6-42A1-B2D0-9146316573F7}.TLS.ActiveCfg = Release|Win32
- {6189F838-21C6-42A1-B2D0-9146316573F7}.TLS.Build.0 = Release|Win32
- {6189F838-21C6-42A1-B2D0-9146316573F7}.TLS_DEBUG.ActiveCfg = Release|Win32
- {6189F838-21C6-42A1-B2D0-9146316573F7}.TLS_DEBUG.Build.0 = Release|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.classic.ActiveCfg = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.classic.Build.0 = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.classic nt.ActiveCfg = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.classic nt.Build.0 = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Debug.ActiveCfg = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Debug.Build.0 = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Embedded_Classic.ActiveCfg = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Embedded_Classic.Build.0 = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Embedded_Debug.ActiveCfg = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Embedded_Debug.Build.0 = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Embedded_Pro.ActiveCfg = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Embedded_Pro.Build.0 = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Embedded_Release.ActiveCfg = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Embedded_Release.Build.0 = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Max.ActiveCfg = Max|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Max.Build.0 = Max|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Max nt.ActiveCfg = Max|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Max nt.Build.0 = Max|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.nt.ActiveCfg = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.nt.Build.0 = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.pro.ActiveCfg = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.pro.Build.0 = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.pro nt.ActiveCfg = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.pro nt.Build.0 = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Release.ActiveCfg = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.Release.Build.0 = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.TLS.ActiveCfg = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.TLS.Build.0 = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.TLS_DEBUG.ActiveCfg = Debug|Win32
- {FB168572-FFF4-4503-9331-4E958459DC9D}.TLS_DEBUG.Build.0 = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.classic.ActiveCfg = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.classic.Build.0 = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.classic nt.ActiveCfg = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.classic nt.Build.0 = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Debug.ActiveCfg = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Debug.Build.0 = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Embedded_Classic.ActiveCfg = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Embedded_Classic.Build.0 = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Embedded_Debug.ActiveCfg = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Embedded_Debug.Build.0 = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Embedded_Pro.ActiveCfg = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Embedded_Pro.Build.0 = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Embedded_Release.ActiveCfg = Release|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Embedded_Release.Build.0 = Release|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Max.ActiveCfg = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Max.Build.0 = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Max nt.ActiveCfg = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Max nt.Build.0 = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.nt.ActiveCfg = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.nt.Build.0 = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.pro.ActiveCfg = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.pro.Build.0 = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.pro nt.ActiveCfg = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.pro nt.Build.0 = Debug|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Release.ActiveCfg = Release|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.Release.Build.0 = Release|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.TLS.ActiveCfg = TLS|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.TLS.Build.0 = TLS|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.TLS_DEBUG.ActiveCfg = TLS_DEBUG|Win32
- {603E5567-F3CD-4547-9F2B-E0082B702B0D}.TLS_DEBUG.Build.0 = TLS_DEBUG|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.classic.ActiveCfg = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.classic.Build.0 = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.classic nt.ActiveCfg = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.classic nt.Build.0 = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Debug.ActiveCfg = Debug|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Debug.Build.0 = Debug|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Embedded_Classic.ActiveCfg = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Embedded_Classic.Build.0 = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Embedded_Debug.ActiveCfg = Debug|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Embedded_Debug.Build.0 = Debug|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Embedded_Pro.ActiveCfg = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Embedded_Pro.Build.0 = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Embedded_Release.ActiveCfg = Release|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Embedded_Release.Build.0 = Release|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Max.ActiveCfg = Max nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Max.Build.0 = Max nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Max nt.ActiveCfg = Max nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Max nt.Build.0 = Max nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.nt.ActiveCfg = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.nt.Build.0 = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.pro.ActiveCfg = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.pro.Build.0 = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.pro nt.ActiveCfg = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.pro nt.Build.0 = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Release.ActiveCfg = Release|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.Release.Build.0 = Release|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.TLS.ActiveCfg = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.TLS.Build.0 = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.TLS_DEBUG.ActiveCfg = nt|Win32
- {AEFFF9CA-3387-4027-B569-33D5D26887D1}.TLS_DEBUG.Build.0 = nt|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.classic.ActiveCfg = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.classic.Build.0 = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.classic nt.ActiveCfg = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.classic nt.Build.0 = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Debug.ActiveCfg = Debug|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Debug.Build.0 = Debug|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Embedded_Classic.ActiveCfg = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Embedded_Classic.Build.0 = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Embedded_Debug.ActiveCfg = Debug|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Embedded_Debug.Build.0 = Debug|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Embedded_Pro.ActiveCfg = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Embedded_Pro.Build.0 = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Embedded_Release.ActiveCfg = Release|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Embedded_Release.Build.0 = Release|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Max.ActiveCfg = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Max.Build.0 = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Max nt.ActiveCfg = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Max nt.Build.0 = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.nt.ActiveCfg = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.nt.Build.0 = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.pro.ActiveCfg = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.pro.Build.0 = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.pro nt.ActiveCfg = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.pro nt.Build.0 = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Release.ActiveCfg = Release|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.Release.Build.0 = Release|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.TLS.ActiveCfg = TLS|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.TLS.Build.0 = TLS|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.TLS_DEBUG.ActiveCfg = TLS_DEBUG|Win32
- {E85E5D80-641E-44C7-B909-3805A8D3167B}.TLS_DEBUG.Build.0 = TLS_DEBUG|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.classic.ActiveCfg = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.classic.Build.0 = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.classic nt.ActiveCfg = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.classic nt.Build.0 = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Debug.ActiveCfg = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Debug.Build.0 = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Embedded_Classic.ActiveCfg = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Embedded_Classic.Build.0 = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Embedded_Debug.ActiveCfg = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Embedded_Debug.Build.0 = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Embedded_Pro.ActiveCfg = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Embedded_Pro.Build.0 = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Embedded_Release.ActiveCfg = Release|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Embedded_Release.Build.0 = Release|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Max.ActiveCfg = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Max.Build.0 = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Max nt.ActiveCfg = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Max nt.Build.0 = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.nt.ActiveCfg = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.nt.Build.0 = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.pro.ActiveCfg = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.pro.Build.0 = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.pro nt.ActiveCfg = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.pro nt.Build.0 = Debug|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Release.ActiveCfg = Release|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.Release.Build.0 = Release|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.TLS.ActiveCfg = TLS|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.TLS.Build.0 = TLS|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.TLS_DEBUG.ActiveCfg = TLS_DEBUG|Win32
- {91B7E9AD-5F85-4236-9A28-B032543B123E}.TLS_DEBUG.Build.0 = TLS_DEBUG|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
diff --git a/VC++Files/mysqlbinlog/mysqlbinlog.vcproj b/VC++Files/mysqlbinlog/mysqlbinlog.vcproj
index 9d5d4db2565..9d5d4db2565 100755..100644
--- a/VC++Files/mysqlbinlog/mysqlbinlog.vcproj
+++ b/VC++Files/mysqlbinlog/mysqlbinlog.vcproj
diff --git a/VC++Files/mysqlcheck/mysqlcheck.vcproj b/VC++Files/mysqlcheck/mysqlcheck.vcproj
index f47e171fd65..f47e171fd65 100755..100644
--- a/VC++Files/mysqlcheck/mysqlcheck.vcproj
+++ b/VC++Files/mysqlcheck/mysqlcheck.vcproj
diff --git a/VC++Files/mysqldemb/mysqldemb.vcproj b/VC++Files/mysqldemb/mysqldemb.vcproj
index 52081adb214..52081adb214 100755..100644
--- a/VC++Files/mysqldemb/mysqldemb.vcproj
+++ b/VC++Files/mysqldemb/mysqldemb.vcproj
diff --git a/VC++Files/mysqlserver/dummy.cpp b/VC++Files/mysqlserver/dummy.cpp
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/VC++Files/mysqlserver/dummy.cpp
diff --git a/VC++Files/mysqlserver/mysqlserver.vcproj b/VC++Files/mysqlserver/mysqlserver.vcproj
index 2c587e0a2d7..43988b8489c 100755..100644
--- a/VC++Files/mysqlserver/mysqlserver.vcproj
+++ b/VC++Files/mysqlserver/mysqlserver.vcproj
@@ -12,7 +12,7 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory=".\Debug"
+ OutputDirectory="..\lib_debug"
IntermediateDirectory=".\Debug"
ConfigurationType="4"
UseOfMFC="0"
@@ -38,7 +38,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
- OutputFile=".\Debug\mysqlserver.lib"
+ OutputFile="$(OutDir)\mysqlserver.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
@@ -63,7 +63,7 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory=".\release"
+ OutputDirectory="..\lib_release"
IntermediateDirectory=".\release"
ConfigurationType="4"
UseOfMFC="0"
@@ -90,7 +90,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
- OutputFile=".\release\mysqlserver.lib"
+ OutputFile="$(OutDir)\mysqlserver.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
@@ -117,6 +117,9 @@
<References>
</References>
<Files>
+ <File
+ RelativePath=".\dummy.cpp">
+ </File>
</Files>
<Globals>
</Globals>
diff --git a/VC++Files/mysys/mysys.dsp b/VC++Files/mysys/mysys.dsp
index 230c2221b6e..935f1411530 100644
--- a/VC++Files/mysys/mysys.dsp
+++ b/VC++Files/mysys/mysys.dsp
@@ -369,6 +369,10 @@ SOURCE=.\my_compress.c
# End Source File
# Begin Source File
+SOURCE=.\my_conio.c
+# End Source File
+# Begin Source File
+
SOURCE=.\my_copy.c
# End Source File
# Begin Source File
diff --git a/VC++Files/mysys/mysys.vcproj b/VC++Files/mysys/mysys.vcproj
index 87e9338e811..6ec9ca6d564 100755..100644
--- a/VC++Files/mysys/mysys.vcproj
+++ b/VC++Files/mysys/mysys.vcproj
@@ -2201,6 +2201,49 @@
</FileConfiguration>
</File>
<File
+ RelativePath="my_conio.c">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Max|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="TLS_DEBUG|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="TLS|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ </File>
+ <File
RelativePath="my_copy.c">
<FileConfiguration
Name="Debug|Win32">
diff --git a/VC++Files/mysys/mysys_ia64.dsp b/VC++Files/mysys/mysys_ia64.dsp
index b0ce2b4c579..10d6ca7960a 100644
--- a/VC++Files/mysys/mysys_ia64.dsp
+++ b/VC++Files/mysys/mysys_ia64.dsp
@@ -362,6 +362,10 @@ SOURCE=.\my_compress.c
# End Source File
# Begin Source File
+SOURCE=.\my_conio.c
+# End Source File
+# Begin Source File
+
SOURCE=.\my_copy.c
# End Source File
# Begin Source File
diff --git a/VC++Files/perror/perror.vcproj b/VC++Files/perror/perror.vcproj
index 2a7bb6407c0..2a7bb6407c0 100755..100644
--- a/VC++Files/perror/perror.vcproj
+++ b/VC++Files/perror/perror.vcproj
diff --git a/VC++Files/regex/regex.vcproj b/VC++Files/regex/regex.vcproj
index 1b52017ca3b..1b52017ca3b 100755..100644
--- a/VC++Files/regex/regex.vcproj
+++ b/VC++Files/regex/regex.vcproj
diff --git a/VC++Files/replace/replace.vcproj b/VC++Files/replace/replace.vcproj
index 270ff494539..270ff494539 100755..100644
--- a/VC++Files/replace/replace.vcproj
+++ b/VC++Files/replace/replace.vcproj
diff --git a/VC++Files/sql/mysqld.vcproj b/VC++Files/sql/mysqld.vcproj
index dd5cdbc1c0b..49bf74ae5a2 100755..100644
--- a/VC++Files/sql/mysqld.vcproj
+++ b/VC++Files/sql/mysqld.vcproj
@@ -335,7 +335,7 @@
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
- AdditionalIncludeDirectories="../storage/bdb/build_win32,../include,../regex,../extra/yassl/include,../zlib"
+ AdditionalIncludeDirectories="../bdb/build_win32,../include,../regex,../extra/yassl/include,../zlib"
PreprocessorDefinitions="_DEBUG;SAFEMALLOC;SAFE_MUTEX;HAVE_INNOBASE_DB;HAVE_BERKELEY_DB;HAVE_ARCHIVE_DB;HAVE_BLACKHOLE_DB;HAVE_EXAMPLE_DB;HAVE_FEDERATED_DB;MYSQL_SERVER;_WINDOWS;_CONSOLE;HAVE_DLOPEN"
RuntimeLibrary="1"
PrecompiledHeaderFile=".\debug/mysqld.pch"
@@ -1252,7 +1252,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="examples\ha_archive.cpp">
+ RelativePath="ha_archive.cpp">
<FileConfiguration
Name="classic nt|Win32">
<Tool
@@ -3745,7 +3745,79 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\storage\myisammrg\myrg_rnext_same.c">
+ RelativePath="..\myisammrg\myrg_rnext_same.c">
+ <FileConfiguration
+ Name="classic nt|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Max|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Max nt|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="nt|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="pro nt|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="pro|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="classic|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""/>
+ </FileConfiguration>
</File>
<File
RelativePath="mysqld.cpp">
@@ -4506,7 +4578,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="protocol_cursor.cpp">
+ RelativePath="sql_cursor.cpp">
<FileConfiguration
Name="classic nt|Win32">
<Tool
@@ -4732,9 +4804,6 @@
</FileConfiguration>
</File>
<File
- RelativePath=".\rpl_filter.cpp">
- </File>
- <File
RelativePath="set_var.cpp">
<FileConfiguration
Name="classic nt|Win32">
@@ -6924,9 +6993,6 @@
</FileConfiguration>
</File>
<File
- RelativePath=".\sql_partition.cpp">
- </File>
- <File
RelativePath="sql_prepare.cpp">
<FileConfiguration
Name="classic nt|Win32">
diff --git a/VC++Files/strings/strings.vcproj b/VC++Files/strings/strings.vcproj
index 8e16a0c7221..8e16a0c7221 100755..100644
--- a/VC++Files/strings/strings.vcproj
+++ b/VC++Files/strings/strings.vcproj
diff --git a/VC++Files/test1/test1.vcproj b/VC++Files/test1/test1.vcproj
index 6a850f7b2e3..6a850f7b2e3 100755..100644
--- a/VC++Files/test1/test1.vcproj
+++ b/VC++Files/test1/test1.vcproj
diff --git a/VC++Files/tests/mysql_client_test.vcproj b/VC++Files/tests/mysql_client_test.vcproj
index adcc680b6e7..89a9b71e60a 100755..100644
--- a/VC++Files/tests/mysql_client_test.vcproj
+++ b/VC++Files/tests/mysql_client_test.vcproj
@@ -25,7 +25,7 @@
AdditionalIncludeDirectories="../include,../"
PreprocessorDefinitions="DBUG_OFF;_WINDOWS;SAFE_MUTEX;USE_TLS;MYSQL_CLIENT;__WIN__;_WIN32"
StringPooling="TRUE"
- RuntimeLibrary="1"
+ RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
PrecompiledHeaderFile=".\Release/mysql_client_test.pch"
AssemblerListingLocation=".\Release/"
@@ -38,7 +38,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="odbc32.lib odbccp32.lib Ws2_32.lib mysqlclient.lib mysys.lib regex.lib ..\extra\yassl\Release\yassl.lib"
+ AdditionalDependencies="odbc32.lib odbccp32.lib Ws2_32.lib"
OutputFile="..\client_release\mysql_client_test.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
@@ -98,7 +98,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="odbc32.lib odbccp32.lib mysqlclient.lib wsock32.lib mysys.lib regex.lib ..\extra\yassl\Debug\yassl.lib"
+ AdditionalDependencies="odbc32.lib odbccp32.lib wsock32.lib"
OutputFile="..\client_debug\mysql_client_test.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
diff --git a/VC++Files/thr_test/thr_test.vcproj b/VC++Files/thr_test/thr_test.vcproj
index ede9bd04de8..ede9bd04de8 100755..100644
--- a/VC++Files/thr_test/thr_test.vcproj
+++ b/VC++Files/thr_test/thr_test.vcproj
diff --git a/VC++Files/vio/vio.vcproj b/VC++Files/vio/vio.vcproj
index 3f50c1546fb..3f50c1546fb 100755..100644
--- a/VC++Files/vio/vio.vcproj
+++ b/VC++Files/vio/vio.vcproj
diff --git a/VC++Files/zlib/zlib.vcproj b/VC++Files/zlib/zlib.vcproj
index ee17d915a1a..ee17d915a1a 100755..100644
--- a/VC++Files/zlib/zlib.vcproj
+++ b/VC++Files/zlib/zlib.vcproj
diff --git a/client/mysql.cc b/client/mysql.cc
index f4361f77f4c..65d520fe4b4 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -959,10 +959,15 @@ static int get_options(int argc, char **argv)
static int read_and_execute(bool interactive)
{
-#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
+#if defined(OS2) || defined(__NETWARE__)
char linebuffer[254];
String buffer;
#endif
+#if defined(__WIN__)
+ String tmpbuf;
+ String buffer;
+#endif
+
char *line;
char in_string=0;
ulong line_number=0;
@@ -993,7 +998,7 @@ static int read_and_execute(bool interactive)
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
tee_fputs(prompt, stdout);
-#ifdef __NETWARE__
+#if defined(__NETWARE__)
line=fgets(linebuffer, sizeof(linebuffer)-1, stdin);
/* Remove the '\n' */
if (line)
@@ -1002,7 +1007,22 @@ static int read_and_execute(bool interactive)
if (p != NULL)
*p = '\0';
}
-#else
+#elif defined(__WIN__)
+ if (!tmpbuf.is_alloced())
+ tmpbuf.alloc(65535);
+ buffer.length(0);
+ unsigned long clen;
+ do
+ {
+ line= my_cgets((char*)tmpbuf.ptr(), tmpbuf.alloced_length()-1, &clen);
+ buffer.append(line, clen);
+ /*
+ if we got buffer fully filled than there is a chance that
+ something else is still in console input buffer
+ */
+ } while (tmpbuf.alloced_length() <= clen);
+ line= buffer.c_ptr();
+#else /* OS2 */
buffer.length(0);
/* _cgets() expects the buffer size - 3 as the first byte */
linebuffer[0]= (char) sizeof(linebuffer) - 3;
@@ -1078,9 +1098,14 @@ static int read_and_execute(bool interactive)
status.exit_status=0;
}
}
+
#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
buffer.free();
#endif
+#if defined( __WIN__)
+ tmpbuf.free();
+#endif
+
return status.exit_status;
}
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index fb9ed3af70c..5345d6d0f54 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -1434,7 +1434,7 @@ int main(int argc, char** argv)
of transaction.
*/
fprintf(result_file,
- "ROLLBACK;\n"
+ "# End of log file\nROLLBACK /* added by mysqlbinlog */;\n"
"/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;\n");
if (disable_log_bin)
fprintf(result_file, "/*!32316 SET SQL_LOG_BIN=@OLD_SQL_LOG_BIN*/;\n");
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 322acbd26c0..460297cd1b2 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -70,6 +70,11 @@
/* Size of buffer for dump's select query */
#define QUERY_LENGTH 1536
+/* ignore table flags */
+#define IGNORE_NONE 0x00 /* no ignore */
+#define IGNORE_DATA 0x01 /* don't dump data for this table */
+#define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */
+
static char *add_load_option(char *ptr, const char *object,
const char *statement);
static ulong find_set(TYPELIB *lib, const char *x, uint length,
@@ -209,9 +214,7 @@ static struct my_option my_long_options[] =
{"default-character-set", OPT_DEFAULT_CHARSET,
"Set the default character set.", (gptr*) &default_charset,
(gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED; "
- "currently ignored because of http://bugs.mysql.com/bug.php?id=7815 "
- "but will be re-enabled later",
+ {"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED; ",
(gptr*) &opt_delayed, (gptr*) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
{"delete-master-logs", OPT_DELETE_MASTER_LOGS,
@@ -411,7 +414,7 @@ static int init_dumping(char *);
static int dump_databases(char **);
static int dump_all_databases();
static char *quote_name(const char *name, char *buff, my_bool force);
-static const char *check_if_ignore_table(const char *table_name);
+char check_if_ignore_table(const char *table_name, char *table_type);
static char *primary_key_fields(const char *table_name);
static my_bool get_view_structure(char *table, char* db);
static my_bool dump_all_views_in_db(char *database);
@@ -720,25 +723,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
}
break;
}
-#ifndef REMOVE_THIS_CODE_WHEN_FIX_BUG_7815
- case (int) OPT_DELAYED:
- /*
- Because of http://bugs.mysql.com/bug.php?id=7815, we disable
- --delayed-insert; when the bug gets fixed by checking the storage engine
- (using the table definition cache) before printing INSERT DELAYED, we
- can correct the option's description and re-enable it again (scheduled
- for later 5.0 or 5.1 versions).
- It's ok to do the if() below as get_one_option is called after
- opt_delayed is set.
- */
- if (opt_delayed)
- {
- fprintf(stderr, "Warning: ignoring --delayed-insert (as explained "
- "in the output of 'mysqldump --help').\n");
- opt_delayed= 0;
- }
- break;
-#endif
}
return 0;
}
@@ -1280,19 +1264,27 @@ static uint dump_routines_for_db (char *db)
}
/*
- getTableStructure -- retrievs database structure, prints out corresponding
- CREATE statement and fills out insert_pat.
+ get_table_structure -- retrievs database structure, prints out corresponding
+ CREATE statement and fills out insert_pat if the table is the type we will
+ be dumping.
+
+ ARGS
+ table - table name
+ db - db name
+ table_type - table type ie "InnoDB"
+ ignore_flag - what we must particularly ignore - see IGNORE_ defines above
RETURN
number of fields in table, 0 if error
*/
-static uint get_table_structure(char *table, char *db)
+static uint get_table_structure(char *table, char *db, char *table_type,
+ char *ignore_flag)
{
MYSQL_RES *tableRes;
MYSQL_ROW row;
my_bool init=0;
- uint numFields;
+ uint num_fields;
char *result_table, *opt_quoted_table;
const char *insert_option;
char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
@@ -1300,18 +1292,30 @@ static uint get_table_structure(char *table, char *db)
char query_buff[512];
FILE *sql_file = md_result_file;
int len;
+
DBUG_ENTER("get_table_structure");
DBUG_PRINT("enter", ("db: %s, table: %s", db, table));
- if (!insert_pat_inited)
+ *ignore_flag= check_if_ignore_table(table, table_type);
+
+ if (opt_delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
+ if (verbose)
+ fprintf(stderr,
+ "-- Unable to use delayed inserts for table '%s' because it's of\
+ type %s\n", table, table_type);
+
+ if (!(*ignore_flag & IGNORE_DATA))
{
- insert_pat_inited= init_dynamic_string(&insert_pat, "", 1024, 1024);
+ if (!insert_pat_inited)
+ insert_pat_inited= init_dynamic_string(&insert_pat, "", 1024, 1024);
+ else
+ dynstr_set(&insert_pat, "");
}
- else
- dynstr_set(&insert_pat, "");
- insert_option= ((opt_delayed && opt_ignore) ? " DELAYED IGNORE " :
- opt_delayed ? " DELAYED " :
+ insert_option= ((opt_delayed && opt_ignore &&
+ !(*ignore_flag & IGNORE_INSERT_DELAYED)) ?
+ " DELAYED IGNORE " :
+ opt_delayed && !(*ignore_flag & IGNORE_INSERT_DELAYED) ? " DELAYED " :
opt_ignore ? " IGNORE " : "");
if (verbose)
@@ -1321,7 +1325,8 @@ static uint get_table_structure(char *table, char *db)
"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
(opt_quoted || opt_keywords));
if (!create_options)
- strmov(query_buff+len, "/*!40102 ,SQL_MODE=concat(@@sql_mode, _utf8 ',NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS') */");
+ strmov(query_buff+len,
+ "/*!40102 ,SQL_MODE=concat(@@sql_mode, _utf8 ',NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS') */");
result_table= quote_name(table, table_buff, 1);
opt_quoted_table= quote_name(table, table_buff2, 0);
@@ -1442,34 +1447,42 @@ static uint get_table_structure(char *table, char *db)
DBUG_RETURN(0);
}
- dynstr_append_mem(&insert_pat, "INSERT ", 7);
- dynstr_append(&insert_pat, insert_option);
- dynstr_append_mem(&insert_pat, "INTO ", 5);
- dynstr_append(&insert_pat, opt_quoted_table);
- if (opt_complete_insert)
- {
- dynstr_append_mem(&insert_pat, " (", 2);
- }
- else
+ /*
+ if *ignore_flag & IGNORE_DATA is true, then we don't build up insert statements
+ for the table's data. Note: in subsequent lines of code, this test will
+ have to be performed each time we are appending to insert_pat.
+ */
+ if (!(*ignore_flag & IGNORE_DATA))
{
- dynstr_append_mem(&insert_pat, " VALUES ", 8);
- if (!extended_insert)
- dynstr_append_mem(&insert_pat, "(", 1);
+ dynstr_append_mem(&insert_pat, "INSERT ", 7);
+ dynstr_append(&insert_pat, insert_option);
+ dynstr_append_mem(&insert_pat, "INTO ", 5);
+ dynstr_append(&insert_pat, opt_quoted_table);
+ if (opt_complete_insert)
+ {
+ dynstr_append_mem(&insert_pat, " (", 2);
+ }
+ else
+ {
+ dynstr_append_mem(&insert_pat, " VALUES ", 8);
+ if (!extended_insert)
+ dynstr_append_mem(&insert_pat, "(", 1);
+ }
}
while ((row=mysql_fetch_row(tableRes)))
{
if (init)
{
- if (opt_complete_insert)
+ if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
dynstr_append_mem(&insert_pat, ", ", 2);
}
init=1;
- if (opt_complete_insert)
+ if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
dynstr_append(&insert_pat,
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
}
- numFields = (uint) mysql_num_rows(tableRes);
+ num_fields= (uint) mysql_num_rows(tableRes);
mysql_free_result(tableRes);
}
else
@@ -1515,19 +1528,20 @@ static uint get_table_structure(char *table, char *db)
check_io(sql_file);
}
- dynstr_append_mem(&insert_pat, "INSERT ", 7);
- dynstr_append(&insert_pat, insert_option);
- dynstr_append_mem(&insert_pat, "INTO ", 5);
- dynstr_append(&insert_pat, result_table);
- if (opt_complete_insert)
+ if (!(*ignore_flag & IGNORE_DATA))
{
- dynstr_append_mem(&insert_pat, " (", 2);
- }
- else
- {
- dynstr_append_mem(&insert_pat, " VALUES ", 8);
- if (!extended_insert)
- dynstr_append_mem(&insert_pat, "(", 1);
+ dynstr_append_mem(&insert_pat, "INSERT ", 7);
+ dynstr_append(&insert_pat, insert_option);
+ dynstr_append_mem(&insert_pat, "INTO ", 5);
+ dynstr_append(&insert_pat, result_table);
+ if (opt_complete_insert)
+ dynstr_append_mem(&insert_pat, " (", 2);
+ else
+ {
+ dynstr_append_mem(&insert_pat, " VALUES ", 8);
+ if (!extended_insert)
+ dynstr_append_mem(&insert_pat, "(", 1);
+ }
}
while ((row=mysql_fetch_row(tableRes)))
@@ -1540,11 +1554,11 @@ static uint get_table_structure(char *table, char *db)
fputs(",\n",sql_file);
check_io(sql_file);
}
- if (opt_complete_insert)
+ if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
dynstr_append_mem(&insert_pat, ", ", 2);
}
init=1;
- if (opt_complete_insert)
+ if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
dynstr_append(&insert_pat,
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
if (!tFlag)
@@ -1575,7 +1589,7 @@ static uint get_table_structure(char *table, char *db)
check_io(sql_file);
}
}
- numFields = (uint) mysql_num_rows(tableRes);
+ num_fields = (uint) mysql_num_rows(tableRes);
mysql_free_result(tableRes);
if (!tFlag)
{
@@ -1627,7 +1641,7 @@ static uint get_table_structure(char *table, char *db)
print_xml_row(sql_file, "key", tableRes, &row);
continue;
}
-
+
if (atoi(row[3]) == 1)
{
if (keynr++)
@@ -1684,9 +1698,7 @@ static uint get_table_structure(char *table, char *db)
else
{
if (opt_xml)
- {
print_xml_row(sql_file, "options", tableRes, &row);
- }
else
{
fputs("/*!",sql_file);
@@ -1707,7 +1719,7 @@ continue_xml:
check_io(sql_file);
}
}
- if (opt_complete_insert)
+ if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA))
{
dynstr_append_mem(&insert_pat, ") VALUES ", 9);
if (!extended_insert)
@@ -1719,7 +1731,7 @@ continue_xml:
write_footer(sql_file);
my_fclose(sql_file, MYF(MY_WME));
}
- DBUG_RETURN(numFields);
+ DBUG_RETURN(num_fields);
} /* get_table_structure */
@@ -1844,20 +1856,40 @@ static char *alloc_query_str(ulong size)
/*
-** dump_table saves database contents as a series of INSERT statements.
+
+ SYNOPSIS
+ dump_table()
+
+ dump_table saves database contents as a series of INSERT statements.
+
+ ARGS
+ table - table name
+ db - db name
+
+ RETURNS
+ void
*/
-static void dump_table(uint numFields, char *table)
+static void dump_table(char *table, char *db)
{
+ char ignore_flag;
char query_buf[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3];
+ char table_type[NAME_LEN];
char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
char *query= query_buf;
+ int error= 0;
+ ulong rownr, row_break, total_length, init_length;
+ uint num_fields;
MYSQL_RES *res;
MYSQL_FIELD *field;
MYSQL_ROW row;
- ulong rownr, row_break, total_length, init_length;
- const char *table_type;
- int error= 0;
+ DBUG_ENTER("dump_table");
+
+ /*
+ Make sure you get the create table info before the following check for
+ --no-data flag below. Otherwise, the create table info won't be printed.
+ */
+ num_fields= get_table_structure(table, db, (char *)&table_type, &ignore_flag);
/* Check --no-data flag */
if (dFlag)
@@ -1866,31 +1898,35 @@ static void dump_table(uint numFields, char *table)
fprintf(stderr,
"-- Skipping dump data for table '%s', --no-data was used\n",
table);
- return;
+ DBUG_VOID_RETURN;
}
+ DBUG_PRINT("info", ("ignore_flag %x num_fields %d", ignore_flag, num_fields));
+ /*
+ If the table type is a merge table or any type that has to be
+ _completely_ ignored and no data dumped
+ */
+ if (ignore_flag & IGNORE_DATA)
+ {
+ if (verbose)
+ fprintf(stderr,
+ "-- Skipping data for table '%s' because it's of type %s\n",
+ table, table_type);
+ DBUG_VOID_RETURN;
+ }
/* Check that there are any fields in the table */
- if (numFields == 0)
+ if (num_fields == 0)
{
if (verbose)
fprintf(stderr,
"-- Skipping dump data for table '%s', it has no fields\n",
table);
- return;
+ DBUG_VOID_RETURN;
}
result_table= quote_name(table,table_buff, 1);
opt_quoted_table= quote_name(table, table_buff2, 0);
- /* Check table type */
- if ((table_type= check_if_ignore_table(table)))
- {
- if (verbose)
- fprintf(stderr,
- "-- Skipping data for table '%s' because it's of type %s\n",
- table, table_type);
- return;
- }
if (verbose)
fprintf(stderr, "-- Sending SELECT query...\n");
@@ -1934,7 +1970,7 @@ static void dump_table(uint numFields, char *table)
if (mysql_real_query(sock, query, (uint) (end - query)))
{
DB_error(sock, "when executing 'SELECT INTO OUTFILE'");
- return;
+ DBUG_VOID_RETURN;
}
}
else
@@ -1989,7 +2025,7 @@ static void dump_table(uint numFields, char *table)
DB_error(sock, "when retrieving data from server");
if (verbose)
fprintf(stderr, "-- Retrieving rows...\n");
- if (mysql_num_fields(res) != numFields)
+ if (mysql_num_fields(res) != num_fields)
{
fprintf(stderr,"%s: Error in field count for table: %s ! Aborting.\n",
my_progname, result_table);
@@ -2052,7 +2088,7 @@ static void dump_table(uint numFields, char *table)
error= EX_CONSCHECK;
goto err;
}
-
+
/*
63 is my_charset_bin. If charsetnr is not 63,
we have not a BLOB but a TEXT column.
@@ -2287,14 +2323,14 @@ static void dump_table(uint numFields, char *table)
mysql_free_result(res);
if (query != query_buf)
my_free(query, MYF(MY_ALLOW_ZERO_PTR));
- }
- return;
+ }
+ DBUG_VOID_RETURN;
err:
if (query != query_buf)
my_free(query, MYF(MY_ALLOW_ZERO_PTR));
safe_exit(error);
- return;
+ DBUG_VOID_RETURN;
} /* dump_table */
@@ -2495,8 +2531,7 @@ static int dump_all_tables_in_db(char *database)
char *end= strmov(afterdot, table);
if (include_table(hash_key, end - hash_key))
{
- numrows = get_table_structure(table, database);
- dump_table(numrows,table);
+ dump_table(table,database);
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
order_by= 0;
if (opt_dump_triggers && ! opt_xml &&
@@ -2630,7 +2665,7 @@ static int get_actual_table_name(const char *old_table_name,
static int dump_selected_tables(char *db, char **table_names, int tables)
{
- uint numrows, i;
+ uint i;
char table_buff[NAME_LEN*+3];
char new_table_name[NAME_LEN];
DYNAMIC_STRING lock_tables_query;
@@ -2699,8 +2734,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
{
table_name= hash_element(&dump_tables, i);
DBUG_PRINT("info",("Dumping table %s", table_name));
- numrows= get_table_structure(table_name, db);
- dump_table(numrows, table_name);
+ dump_table(table_name,db);
if (opt_dump_triggers &&
mysql_get_server_version(sock) >= 50009)
dump_triggers_for_table(table_name, db);
@@ -2899,28 +2933,37 @@ static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
/*
- Check if we the table is one of the table types that should be ignored:
- MRG_ISAM, MRG_MYISAM
SYNOPSIS
+
+ Check if we the table is one of the table types that should be ignored:
+ MRG_ISAM, MRG_MYISAM, if opt_delayed, if that table supports delayed inserts.
+ If the table should be altogether ignored, it returns a TRUE, FALSE if it
+ should not be ignored. If the user has selected to use INSERT DELAYED, it
+ sets the value of the bool pointer supports_delayed_inserts to 0 if not
+ supported, 1 if it is supported.
+
+ ARGS
+
check_if_ignore_table()
table_name Table name to check
+ table_type Type of table
GLOBAL VARIABLES
sock MySQL socket
verbose Write warning messages
RETURN
- 0 Table should be backuped
- # Type of table (that should be skipped)
+ char (bit value) See IGNORE_ values at top
*/
-static const char *check_if_ignore_table(const char *table_name)
+char check_if_ignore_table(const char *table_name, char *table_type)
{
+ char result= IGNORE_NONE;
char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN];
MYSQL_RES *res;
MYSQL_ROW row;
- const char *result= 0;
+ DBUG_ENTER("check_if_ignore_table");
/* Check memory for quote_for_like() */
DBUG_ASSERT(2*sizeof(table_name) < sizeof(show_name_buff));
@@ -2934,7 +2977,7 @@ static const char *check_if_ignore_table(const char *table_name)
fprintf(stderr,
"-- Warning: Couldn't get status information for table %s (%s)\n",
table_name,mysql_error(sock));
- return 0; /* assume table is ok */
+ DBUG_RETURN(result); /* assume table is ok */
}
}
if (!(row= mysql_fetch_row(res)))
@@ -2943,18 +2986,38 @@ static const char *check_if_ignore_table(const char *table_name)
"Error: Couldn't read status information for table %s (%s)\n",
table_name, mysql_error(sock));
mysql_free_result(res);
- return 0; /* assume table is ok */
+ DBUG_RETURN(result); /* assume table is ok */
}
if (!(row[1]))
- result= "VIEW";
+ strmake(table_type,"VIEW", NAME_LEN-1);
else
{
- if (strcmp(row[1], (result= "MRG_MyISAM")) &&
- strcmp(row[1], (result= "MRG_ISAM")))
- result= 0;
+ /*
+ If the table type matches any of these, we do support delayed inserts.
+ Note: we do not want to skip dumping this table if if is not one of
+ these types, but we do want to use delayed inserts in the dump if
+ the table type is _NOT_ one of these types
+ */
+ strmake(table_type, row[1], NAME_LEN-1);
+ if (opt_delayed)
+ {
+ if (strcmp(table_type,"MyISAM") &&
+ strcmp(table_type,"ISAM") &&
+ strcmp(table_type,"ARCHIVE") &&
+ strcmp(table_type,"HEAP") &&
+ strcmp(table_type,"MEMORY"))
+ result= IGNORE_INSERT_DELAYED;
+ }
+
+ /*
+ If these two types, we do want to skip dumping the table
+ */
+ if (!dFlag &&
+ (!strcmp(table_type,"MRG_MyISAM") || !strcmp(table_type,"MRG_ISAM")))
+ result= IGNORE_DATA;
}
mysql_free_result(res);
- return result;
+ DBUG_RETURN(result);
}
/*
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 1b829861b59..264140cefa8 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -59,12 +59,16 @@
#include <stdarg.h>
#include <sys/stat.h>
#include <violite.h>
-#include <regex.h> /* Our own version of lib */
+#include "my_regex.h" /* Our own version of lib */
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifndef WEXITSTATUS
-# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+# ifdef __WIN__
+# define WEXITSTATUS(stat_val) (stat_val)
+# else
+# 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)
@@ -98,6 +102,10 @@
#define DEFAULT_DELIMITER ";"
#define MAX_DELIMITER 16
+#define RESULT_OK 0
+#define RESULT_CONTENT_MISMATCH 1
+#define RESULT_LENGTH_MISMATCH 2
+
enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC,
OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH,
@@ -204,7 +212,7 @@ static int got_end_timer= FALSE;
static void timer_output(void);
static ulonglong timer_now(void);
-static regex_t ps_re; /* Holds precompiled re for valid PS statements */
+static my_regex_t ps_re; /* Holds precompiled re for valid PS statements */
static void ps_init_re(void);
static int ps_match_re(char *);
static char *ps_eprint(int);
@@ -545,7 +553,7 @@ static void close_cons()
static void close_files()
{
DBUG_ENTER("close_files");
- for (; cur_file != (file_stack-1) ; cur_file--)
+ 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)
@@ -605,7 +613,8 @@ static void die(const char *fmt, ...)
if (cur_file && cur_file != file_stack)
fprintf(stderr, "In included file \"%s\": ",
cur_file->file_name);
- fprintf(stderr, "At line %u: ", start_lineno);
+ if (start_lineno != 0)
+ fprintf(stderr, "At line %u: ", start_lineno);
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
fflush(stderr);
@@ -638,7 +647,9 @@ static void verbose_msg(const char *fmt, ...)
va_start(args, fmt);
- fprintf(stderr, "mysqltest: At line %u: ", start_lineno);
+ fprintf(stderr, "mysqltest: ");
+ if (start_lineno > 0)
+ fprintf(stderr, "At line %u: ", start_lineno);
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
va_end(args);
@@ -679,7 +690,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
DBUG_PRINT("info",("Size differs: result size: %u file size: %u",
ds->length, stat_info.st_size));
DBUG_PRINT("info",("result: '%s'", ds->str));
- DBUG_RETURN(2);
+ DBUG_RETURN(RESULT_LENGTH_MISMATCH);
}
if (!(tmp = (char*) my_malloc(stat_info.st_size + 1, MYF(MY_WME))))
die(NullS);
@@ -696,7 +707,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
res_ptr = res_ds.str;
if ((res_len = res_ds.length) != ds->length)
{
- res = 2;
+ res= RESULT_LENGTH_MISMATCH;
goto err;
}
}
@@ -706,7 +717,8 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
res_len = stat_info.st_size;
}
- res = (memcmp(res_ptr, ds->str, res_len)) ? 1 : 0;
+ res= (memcmp(res_ptr, ds->str, res_len)) ?
+ RESULT_CONTENT_MISMATCH : RESULT_OK;
err:
if (res && eval_result)
@@ -723,22 +735,23 @@ err:
static int check_result(DYNAMIC_STRING* ds, const char *fname,
my_bool require_option)
{
- int error = 0;
- int res=dyn_string_cmp(ds, fname);
+ int error= RESULT_OK;
+ int res= dyn_string_cmp(ds, fname);
+
DBUG_ENTER("check_result");
if (res && require_option)
abort_not_supported_test();
switch (res) {
- case 0:
+ case RESULT_OK:
break; /* ok */
- case 2:
+ case RESULT_LENGTH_MISMATCH:
verbose_msg("Result length mismatch");
- error = 1;
+ error= RESULT_LENGTH_MISMATCH;
break;
- case 1:
+ case RESULT_CONTENT_MISMATCH:
verbose_msg("Result content mismatch");
- error = 1;
+ error= RESULT_CONTENT_MISMATCH;
break;
default: /* impossible */
die("Unknown error code from dyn_string_cmp()");
@@ -1091,8 +1104,8 @@ static void do_exec(struct st_query *query)
(query->expected_errno[i].code.errnum == status))
{
ok= 1;
- verbose_msg("command \"%s\" failed with expected error: %d",
- cmd, status);
+ DBUG_PRINT("info", ("command \"%s\" failed with expected error: %d",
+ cmd, status));
}
}
if (!ok)
@@ -1377,9 +1390,7 @@ int do_sync_with_master2(long offset)
int rpl_parse;
if (!master_pos.file[0])
- {
- die("Line %u: Calling 'sync_with_master' without calling 'save_master_pos'", start_lineno);
- }
+ die("Calling 'sync_with_master' without calling 'save_master_pos'");
rpl_parse= mysql_rpl_parse_enabled(mysql);
mysql_disable_rpl_parse(mysql);
@@ -1389,14 +1400,13 @@ int do_sync_with_master2(long offset)
wait_for_position:
if (mysql_query(mysql, query_buf))
- die("line %u: failed in %s: %d: %s", start_lineno, query_buf,
- mysql_errno(mysql), mysql_error(mysql));
+ die("failed in %s: %d: %s", query_buf, mysql_errno(mysql),
+ mysql_error(mysql));
if (!(last_result= res= mysql_store_result(mysql)))
- die("line %u: mysql_store_result() returned NULL for '%s'", start_lineno,
- query_buf);
+ die("mysql_store_result() returned NULL for '%s'", query_buf);
if (!(row= mysql_fetch_row(res)))
- die("line %u: empty result in %s", start_lineno, query_buf);
+ die("empty result in %s", query_buf);
if (!row[0])
{
/*
@@ -1404,10 +1414,7 @@ wait_for_position:
SLAVE has been issued ?
*/
if (tries++ == 3)
- {
- die("line %u: could not sync with master ('%s' returned NULL)",
- start_lineno, query_buf);
- }
+ die("could not sync with master ('%s' returned NULL)", query_buf);
sleep(1); /* So at most we will wait 3 seconds and make 4 tries */
mysql_free_result(res);
goto wait_for_position;
@@ -1453,10 +1460,9 @@ int do_save_master_pos()
mysql_errno(mysql), mysql_error(mysql));
if (!(last_result =res = mysql_store_result(mysql)))
- die("line %u: mysql_store_result() retuned NULL for '%s'", start_lineno,
- query);
+ die("mysql_store_result() retuned NULL for '%s'", query);
if (!(row = mysql_fetch_row(res)))
- die("line %u: empty result in show master status", start_lineno);
+ die("empty result in show master status");
strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1);
master_pos.pos = strtoul(row[1], (char**) 0, 10);
mysql_free_result(res); last_result=0;
@@ -2762,7 +2768,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
fn_format(buff, argument, "", "", 4);
DBUG_ASSERT(cur_file == file_stack && cur_file->file == 0);
if (!(cur_file->file=
- my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME))))
+ 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));
break;
@@ -2868,7 +2874,7 @@ void str_to_file(const char *fname, char *str, int size)
fname=buff;
}
fn_format(buff,fname,"","",4);
-
+
if ((fd = my_open(buff, O_WRONLY | O_CREAT | O_TRUNC,
MYF(MY_WME | MY_FFNF))) < 0)
die("Could not open %s: errno = %d", buff, errno);
@@ -3149,7 +3155,7 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags)
goto end;
}
- // If we come here the query is both executed and read successfully
+ /* If we come here the query is both executed and read successfully */
if (handle_no_error(q))
{
error= 1;
@@ -3725,12 +3731,13 @@ static void ps_init_re(void)
"[[:space:]]*UPDATE[[:space:]]+MULTI[[:space:]]|"
"[[:space:]]*INSERT[[:space:]]+SELECT[[:space:]])";
- int err= regcomp(&ps_re, ps_re_str, (REG_EXTENDED | REG_ICASE | REG_NOSUB),
- &my_charset_latin1);
+ int err= my_regcomp(&ps_re, ps_re_str,
+ (REG_EXTENDED | REG_ICASE | REG_NOSUB),
+ &my_charset_latin1);
if (err)
{
char erbuf[100];
- int len= regerror(err, &ps_re, erbuf, sizeof(erbuf));
+ int len= my_regerror(err, &ps_re, erbuf, sizeof(erbuf));
fprintf(stderr, "error %s, %d/%d `%s'\n",
ps_eprint(err), len, (int)sizeof(erbuf), erbuf);
exit(1);
@@ -3740,7 +3747,7 @@ static void ps_init_re(void)
static int ps_match_re(char *stmt_str)
{
- int err= regexec(&ps_re, stmt_str, (size_t)0, NULL, 0);
+ int err= my_regexec(&ps_re, stmt_str, (size_t)0, NULL, 0);
if (err == 0)
return 1;
@@ -3749,7 +3756,7 @@ static int ps_match_re(char *stmt_str)
else
{
char erbuf[100];
- int len= regerror(err, &ps_re, erbuf, sizeof(erbuf));
+ int len= my_regerror(err, &ps_re, erbuf, sizeof(erbuf));
fprintf(stderr, "error %s, %d/%d `%s'\n",
ps_eprint(err), len, (int)sizeof(erbuf), erbuf);
exit(1);
@@ -3759,7 +3766,7 @@ static int ps_match_re(char *stmt_str)
static char *ps_eprint(int err)
{
static char epbuf[100];
- size_t len= regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf));
+ size_t len= my_regerror(REG_ITOA|err, (my_regex_t *)NULL, epbuf, sizeof(epbuf));
assert(len <= sizeof(epbuf));
return(epbuf);
}
@@ -3767,7 +3774,7 @@ static char *ps_eprint(int err)
static void ps_free_reg(void)
{
- regfree(&ps_re);
+ my_regfree(&ps_re);
}
/****************************************************************************/
@@ -3908,8 +3915,10 @@ int main(int argc, char **argv)
{
int error = 0;
struct st_query *q;
- my_bool require_file=0, q_send_flag=0, abort_flag= 0;
+ my_bool require_file=0, q_send_flag=0, abort_flag= 0,
+ query_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' */
@@ -4081,6 +4090,7 @@ int main(int argc, char **argv)
error|= run_query(&cur_con->mysql, q, QUERY_REAP|QUERY_SEND);
display_result_vertically= old_display_result_vertically;
q->last_argument= q->end;
+ query_executed= 1;
break;
}
case Q_QUERY:
@@ -4105,6 +4115,7 @@ int main(int argc, char **argv)
save_file[0]=0;
}
error |= run_query(&cur_con->mysql, q, flags);
+ query_executed= 1;
q->last_argument= q->end;
break;
}
@@ -4125,6 +4136,7 @@ int main(int argc, char **argv)
is given on this connection.
*/
error |= run_query(&cur_con->mysql, q, QUERY_SEND);
+ query_executed= 1;
q->last_argument= q->end;
break;
case Q_RESULT:
@@ -4165,6 +4177,7 @@ int main(int argc, char **argv)
break;
case Q_EXEC:
do_exec(q);
+ query_executed= 1;
break;
case Q_START_TIMER:
/* Overwrite possible earlier start of timer */
@@ -4244,12 +4257,32 @@ int main(int argc, char **argv)
parser.current_line += current_line_inc;
}
- if (result_file && ds_res.length && !error)
+ if (!query_executed && result_file && my_stat(result_file, &res_info, 0))
+ {
+ /*
+ my_stat() successful on result file. Check if we have not run a
+ single query, but we do have a result file that contains data.
+ Note that we don't care, if my_stat() fails. For example for
+ non-existing or non-readable file we assume it's fine to have
+ no query output from the test file, e.g. regarded as no error.
+ */
+ if (res_info.st_size)
+ error|= (RESULT_CONTENT_MISMATCH | RESULT_LENGTH_MISMATCH);
+ }
+ if (ds_res.length && !error)
{
- if (!record)
- error |= check_result(&ds_res, result_file, q->require_file);
+ if (result_file)
+ {
+ if (!record)
+ error |= check_result(&ds_res, result_file, q->require_file);
+ else
+ str_to_file(result_file, ds_res.str, ds_res.length);
+ }
else
- str_to_file(result_file, ds_res.str, ds_res.length);
+ {
+ /* Print the result to stdout */
+ printf("%s", ds_res.str);
+ }
}
dynstr_free(&ds_res);
diff --git a/cmd-line-utils/readline/complete.c b/cmd-line-utils/readline/complete.c
index 2196c66a54c..41ea22d815e 100644
--- a/cmd-line-utils/readline/complete.c
+++ b/cmd-line-utils/readline/complete.c
@@ -21,10 +21,18 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 500
+#endif
+
#include "config_readline.h"
#include <sys/types.h>
+
+/* To get SuSE 9.3 to define wcwidth() (in wchar.h) */
+
#include <fcntl.h>
+
#if defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif
@@ -1149,7 +1157,8 @@ compute_lcd_of_matches (match_list, matches, text)
rl_completion_found_quote &&
rl_filename_quoting_desired)
{
- dtext = (*rl_filename_dequoting_function) (text, rl_completion_quote_character);
+ dtext = (*rl_filename_dequoting_function)
+ ((char*) text, rl_completion_quote_character);
text = dtext;
}
diff --git a/cmd-line-utils/readline/display.c b/cmd-line-utils/readline/display.c
index cab76c0da81..06eaa5e4be2 100644
--- a/cmd-line-utils/readline/display.c
+++ b/cmd-line-utils/readline/display.c
@@ -21,10 +21,16 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 500
+#endif
+
#include "config_readline.h"
#include <sys/types.h>
+/* To get SuSE 9.3 to define wcwidth() (in wchar.h) */
+
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
diff --git a/cmd-line-utils/readline/mbutil.c b/cmd-line-utils/readline/mbutil.c
index c88e9485f39..284ea63aae4 100644
--- a/cmd-line-utils/readline/mbutil.c
+++ b/cmd-line-utils/readline/mbutil.c
@@ -21,9 +21,16 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 500
+#endif
+
#include "config_readline.h"
#include <sys/types.h>
+
+/* To get SuSE 9.3 to define wcwidth() (in wchar.h) */
+
#include <fcntl.h>
#include "posixjmp.h"
diff --git a/config/ac-macros/readline.m4 b/config/ac-macros/readline.m4
index 79c6479d15d..e47d0a44483 100644
--- a/config/ac-macros/readline.m4
+++ b/config/ac-macros/readline.m4
@@ -59,3 +59,42 @@ AC_DEFUN([MYSQL_CHECK_NEW_RL_INTERFACE], [
)
)
])
+
+dnl
+dnl check for availability of multibyte characters and functions
+dnl (Based on BASH_CHECK_MULTIBYTE in aclocal.m4 of readline-5.0)
+dnl
+AC_DEFUN([MYSQL_CHECK_MULTIBYTE],
+[
+AC_CHECK_HEADERS(wctype.h)
+AC_CHECK_HEADERS(wchar.h)
+AC_CHECK_HEADERS(langinfo.h)
+
+AC_CHECK_FUNC(mbsrtowcs, AC_DEFINE([HAVE_MBSRTOWCS],[],[Define if you have mbsrtowcs]))
+AC_CHECK_FUNC(mbrtowc, AC_DEFINE([HAVE_MBRTOWC],[],[Define if you have mbrtowc]))
+AC_CHECK_FUNC(mbrlen, AC_DEFINE([HAVE_MBRLEN],[],[Define if you have mbrlen]))
+AC_CHECK_FUNC(wctomb, AC_DEFINE([HAVE_WCTOMB],[],[Define if you have wctomb]))
+AC_CHECK_FUNC(wcwidth, AC_DEFINE([HAVE_WCWIDTH],[],[Define if you have wcwidth]))
+AC_CHECK_FUNC(wcsdup, AC_DEFINE([HAVE_WCSDUP],[],[Define if you check wcsdup]))
+
+AC_CACHE_CHECK([for mbstate_t], mysql_cv_have_mbstate_t,
+[AC_TRY_COMPILE([
+#include <wchar.h>], [
+ mbstate_t ps;
+ mbstate_t *psp;
+ psp = (mbstate_t *)0;
+], mysql_cv_have_mbstate_t=yes, mysql_cv_have_mbstate_t=no)])
+if test $mysql_cv_have_mbstate_t = yes; then
+ AC_DEFINE([HAVE_MBSTATE_T],[],[Define if mysql_cv_have_mbstate_t=yes])
+fi
+
+AC_CACHE_CHECK([for nl_langinfo and CODESET], mysql_cv_langinfo_codeset,
+[AC_TRY_LINK(
+[#include <langinfo.h>],
+[char* cs = nl_langinfo(CODESET);],
+mysql_cv_langinfo_codeset=yes, mysql_cv_langinfo_codeset=no)])
+if test $mysql_cv_langinfo_codeset = yes; then
+ AC_DEFINE([HAVE_LANGINFO_CODESET],[],[Define if mysql_cv_langinfo_codeset=yes])
+fi
+
+])
diff --git a/config/ac-macros/yassl.m4 b/config/ac-macros/yassl.m4
index 7af39db48be..972e4530dab 100644
--- a/config/ac-macros/yassl.m4
+++ b/config/ac-macros/yassl.m4
@@ -23,13 +23,14 @@ AC_DEFUN([MYSQL_CHECK_YASSL], [
# System specific checks
yassl_integer_extra_cxxflags=""
- case $SYSTEM_TYPE--$CXX_VERSION in
- sparc*solaris*--*Sun*C++*5.6*)
+ case $host_cpu--$CXX_VERSION in
+ sparc*--*Sun*C++*5.6*)
# Disable inlining when compiling taocrypt/src/integer.cpp
yassl_integer_extra_cxxflags="+d"
+ AC_MSG_NOTICE([disabling inlining for yassl/taocrypt/src/integer.cpp])
;;
esac
- AC_SUBST([yassl_integer_extra_cxxflags])
+ AC_SUBST([yassl_integer_extra_cxxflags])
else
yassl_dir=""
diff --git a/configure.in b/configure.in
index cba7f0a40e6..6e1ea13788b 100644
--- a/configure.in
+++ b/configure.in
@@ -1821,6 +1821,7 @@ MYSQL_HAVE_TIOCSTAT
MYSQL_STRUCT_DIRENT_D_INO
MYSQL_STRUCT_DIRENT_D_NAMLEN
MYSQL_TYPE_SIGHANDLER
+MYSQL_CHECK_MULTIBYTE
if test "$with_named_curses" = "no"
then
MYSQL_CHECK_LIB_TERMCAP
diff --git a/dbug/my_main.c b/dbug/my_main.c
index ed1c9329235..31c15aa67aa 100644
--- a/dbug/my_main.c
+++ b/dbug/my_main.c
@@ -8,6 +8,7 @@
#endif
#include <my_global.h> /* This includes dbug.h */
+#include <my_pthread.h>
int main (argc, argv)
int argc;
diff --git a/extra/Makefile.am b/extra/Makefile.am
index 457fddce673..91ec8318f08 100644
--- a/extra/Makefile.am
+++ b/extra/Makefile.am
@@ -26,7 +26,7 @@ CLEANFILES = $(BUILT_SOURCES)
DIST_SUBDIRS= yassl
# This will build mysqld_error.h and sql_state.h
-$(top_builddir)/include/mysqld_error.h: comp_err
+$(top_builddir)/include/mysqld_error.h: comp_err$(EXEEXT)
$(top_builddir)/extra/comp_err \
--charset=$(top_srcdir)/sql/share/charsets \
--out-dir=$(top_builddir)/sql/share/ \
diff --git a/extra/comp_err.c b/extra/comp_err.c
index b322be2b8ed..d0e387dcd35 100644
--- a/extra/comp_err.c
+++ b/extra/comp_err.c
@@ -131,7 +131,8 @@ static struct languages *parse_charset_string(char *str);
static struct errors *parse_error_string(char *ptr, int er_count);
static struct message *parse_message_string(struct message *new_message,
char *str);
-static struct message *find_message(struct errors *err, const char *lang);
+static struct message *find_message(struct errors *err, const char *lang,
+ my_bool no_default);
static int parse_input_file(const char *file_name, struct errors **top_error,
struct languages **top_language);
static int get_options(int *argc, char ***argv);
@@ -305,7 +306,7 @@ static int create_sys_files(struct languages *lang_head,
for (tmp_error= error_head; tmp_error; tmp_error= tmp_error->next_error)
{
/* dealing with messages */
- tmp= find_message(tmp_error, tmp_lang->lang_short_name);
+ tmp= find_message(tmp_error, tmp_lang->lang_short_name, FALSE);
if (!tmp)
{
@@ -450,6 +451,13 @@ static int parse_input_file(const char *file_name, struct errors **top_error,
current_error->er_name);
DBUG_RETURN(0);
}
+ if (find_message(current_error, current_message.lang_short_name, TRUE))
+ {
+ fprintf(stderr, "Duplicate message string for error '%s'"
+ " in language '%s'\n",
+ current_error->er_name, current_message.lang_short_name);
+ DBUG_RETURN(0);
+ }
if (insert_dynamic(&current_error->msg, (byte *) & current_message))
DBUG_RETURN(0);
continue;
@@ -556,11 +564,19 @@ static char *parse_default_language(char *str)
/*
- For given error, finds message in given language; if does not exist,
- returns english.
-*/
+ Find the message in a particular language
+
+ SYNOPSIS
+ find_message()
+ err Error to find message for
+ lang Language of message to find
+ no_default Don't return default (English) if does not exit
-static struct message *find_message(struct errors *err, const char *lang)
+ RETURN VALUE
+ Returns the message structure if one is found, or NULL if not.
+*/
+static struct message *find_message(struct errors *err, const char *lang,
+ my_bool no_default)
{
struct message *tmp, *return_val= 0;
uint i, count;
@@ -579,7 +595,7 @@ static struct message *find_message(struct errors *err, const char *lang)
return_val= tmp;
}
}
- DBUG_RETURN(return_val);
+ DBUG_RETURN(no_default ? NULL : return_val);
}
diff --git a/extra/yassl/mySTL/vector.hpp b/extra/yassl/mySTL/vector.hpp
index e7f63c37c7c..9eab91cfda8 100644
--- a/extra/yassl/mySTL/vector.hpp
+++ b/extra/yassl/mySTL/vector.hpp
@@ -45,7 +45,8 @@ struct vector_base {
vector_base() : start_(0), finish_(0), end_of_storage_(0) {}
vector_base(size_t n)
{
- start_ = static_cast<T*>(malloc(n * sizeof(T)));
+ // Don't allow malloc(0), if n is 0 use 1
+ start_ = static_cast<T*>(malloc((n ? n : 1) * sizeof(T)));
if (!start_) abort();
finish_ = start_;
end_of_storage_ = start_ + n;
diff --git a/extra/yassl/taocrypt/include/hmac.hpp b/extra/yassl/taocrypt/include/hmac.hpp
index 543366afc3a..cf029812ce2 100644
--- a/extra/yassl/taocrypt/include/hmac.hpp
+++ b/extra/yassl/taocrypt/include/hmac.hpp
@@ -56,12 +56,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/taocrypt/src/random.cpp b/extra/yassl/taocrypt/src/random.cpp
index e1e6416eb00..cf0720b11d8 100644
--- a/extra/yassl/taocrypt/src/random.cpp
+++ b/extra/yassl/taocrypt/src/random.cpp
@@ -95,7 +95,11 @@ OS_Seed::OS_Seed()
{
fd_ = open("/dev/urandom",O_RDONLY);
if (fd_ == -1)
+ {
+ fd_ = open("/dev/random",O_RDONLY);
+ if (fd_ == -1)
error_.SetError(OPEN_RAN_E);
+ }
}
diff --git a/include/my_global.h b/include/my_global.h
index 2352166fa38..a26c02a687e 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -326,7 +326,7 @@ C_MODE_END
/* Fix a bug in gcc 2.8.0 on IRIX 6.2 */
-#if SIZEOF_LONG == 4 && defined(__LONG_MAX__)
+#if SIZEOF_LONG == 4 && defined(__LONG_MAX__) && (__GNUC__ == 2 && __GNUC_MINOR__ == 8)
#undef __LONG_MAX__ /* Is a longlong value in gcc 2.8.0 ??? */
#define __LONG_MAX__ 2147483647
#endif
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 132a298bc69..057b71356db 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -144,7 +144,7 @@ extern int pthread_mutex_destroy (pthread_mutex_t *);
#define pthread_kill(A,B) raise(B)
#define pthread_exit(A) pthread_dummy()
#else
-#define pthread_mutex_init(A,B) InitializeCriticalSection(A)
+#define pthread_mutex_init(A,B) (InitializeCriticalSection(A),0)
#define pthread_mutex_lock(A) (EnterCriticalSection(A),0)
#define pthread_mutex_trylock(A) (WaitForSingleObject((A), 0) == WAIT_TIMEOUT)
#define pthread_mutex_unlock(A) LeaveCriticalSection(A)
diff --git a/include/my_sys.h b/include/my_sys.h
index 836b2a85528..422bd171eb5 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -262,6 +262,7 @@ extern char wild_many,wild_one,wild_prefix;
extern const char *charsets_dir;
extern char *defaults_extra_file;
extern const char *defaults_group_suffix;
+extern const char *defaults_file;
extern my_bool timed_mutexes;
@@ -280,7 +281,7 @@ enum loglevel {
enum cache_type
{
- READ_CACHE,WRITE_CACHE,
+ TYPE_NOT_SET= 0, READ_CACHE, WRITE_CACHE,
SEQ_READ_APPEND /* sequential read or append */,
READ_FIFO, READ_NET,WRITE_NET};
@@ -775,6 +776,7 @@ extern void my_free_lock(byte *ptr,myf flags);
extern void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
uint pre_alloc_size);
extern gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size);
+extern gptr multi_alloc_root(MEM_ROOT *mem_root, ...);
extern void free_root(MEM_ROOT *root, myf MyFLAGS);
extern void set_prealloc_root(MEM_ROOT *root, char *ptr);
extern void reset_root_defaults(MEM_ROOT *mem_root, uint block_size,
@@ -887,6 +889,9 @@ int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror,
void my_security_attr_free(SECURITY_ATTRIBUTES *sa);
+/* implemented in my_conio.c */
+char* my_cgets(char *string, unsigned long clen, unsigned long* plen);
+
#endif
#ifdef __NETWARE__
void netware_reg_user(const char *ip, const char *user,
diff --git a/include/myisam.h b/include/myisam.h
index 03194fe42ae..39cc61ad204 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -381,6 +381,20 @@ typedef struct st_sort_key_blocks /* Used when sorting */
} SORT_KEY_BLOCKS;
+/*
+ MyISAM supports several statistics collection methods. Currently statistics
+ collection method is not stored in MyISAM file and has to be specified for
+ each table analyze/repair operation in MI_CHECK::stats_method.
+*/
+
+typedef enum
+{
+ /* Treat NULLs as inequal when collecting statistics (default for 4.1/5.0) */
+ MI_STATS_METHOD_NULLS_NOT_EQUAL,
+ /* Treat NULLs as equal when collecting statistics (like 4.0 did) */
+ MI_STATS_METHOD_NULLS_EQUAL
+} enum_mi_stats_method;
+
typedef struct st_mi_check_param
{
ulonglong auto_increment_value;
@@ -411,6 +425,7 @@ typedef struct st_mi_check_param
void *thd;
const char *db_name, *table_name;
const char *op_name;
+ enum_mi_stats_method stats_method;
} MI_CHECK;
typedef struct st_sort_ft_buf
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 8dcc50e15ec..251b9e76e91 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -411,6 +411,7 @@ my_bool check_scramble(const char *reply, const char *message,
const unsigned char *hash_stage2);
void get_salt_from_password(unsigned char *res, const char *password);
void make_password_from_salt(char *to, const unsigned char *hash_stage2);
+void octet2hex(char *to, const unsigned char *str, unsigned int len);
/* end of password.c */
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
index 4db3f73d0c7..5bb97233f37 100644
--- a/libmysqld/Makefile.am
+++ b/libmysqld/Makefile.am
@@ -37,7 +37,7 @@ SUBDIRS = . examples
libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc
libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \
my_time.c
-sqlexamplessources = ha_example.cc ha_archive.cc ha_tina.cc
+sqlexamplessources = ha_example.cc ha_tina.cc
noinst_HEADERS = embedded_priv.h emb_qcache.h
@@ -60,10 +60,10 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \
sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \
unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \
- spatial.cc gstream.cc sql_help.cc tztime.cc protocol_cursor.cc \
+ spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \
sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
- parse_file.cc rpl_filter.cc sql_view.cc sql_trigger.cc my_decimal.cc \
- ha_blackhole.cc sql_partition.cc ha_partition.cc
+ parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
+ ha_blackhole.cc ha_archive.cc sql_partition.cc ha_partition.cc
libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources)
libmysqld_a_SOURCES=
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index a86d467299c..8552b1c2b8a 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -423,9 +423,9 @@ int init_embedded_server(int argc, char **argv, char **groups)
acl_error= 0;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (!(acl_error= acl_init((THD *)0, opt_noacl)) &&
+ if (!(acl_error= acl_init(opt_noacl)) &&
!opt_noacl)
- (void) grant_init((THD *)0);
+ (void) grant_init();
#endif
if (acl_error || my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
{
@@ -514,8 +514,8 @@ void *create_embedded_thd(int client_flag, char *db)
thd->db= db;
thd->db_length= db ? strip_sp(db) : 0;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- thd->db_access= DB_ACLS;
- thd->master_access= ~NO_ACCESS;
+ thd->security_ctx->db_access= DB_ACLS;
+ thd->security_ctx->master_access= ~NO_ACCESS;
#endif
thd->net.query_cache_query= 0;
@@ -532,10 +532,9 @@ err:
int check_embedded_connection(MYSQL *mysql)
{
THD *thd= (THD*)mysql->thd;
- thd->host= (char*)my_localhost;
- thd->host_or_ip= thd->host;
- thd->user= my_strdup(mysql->user, MYF(0));
- thd->priv_user= thd->user;
+ Security_context *sctx= thd->security_ctx;
+ sctx->host_or_ip= sctx->host= (char*)my_localhost;
+ sctx->priv_user= sctx->user= my_strdup(mysql->user, MYF(0));
return check_user(thd, COM_CONNECT, NULL, 0, thd->db, true);
}
@@ -543,26 +542,27 @@ int check_embedded_connection(MYSQL *mysql)
int check_embedded_connection(MYSQL *mysql)
{
THD *thd= (THD*)mysql->thd;
+ Security_context *sctx= thd->security_ctx;
int result;
char scramble_buff[SCRAMBLE_LENGTH];
int passwd_len;
if (mysql->options.client_ip)
{
- thd->host= my_strdup(mysql->options.client_ip, MYF(0));
- thd->ip= my_strdup(thd->host, MYF(0));
+ sctx->host= my_strdup(mysql->options.client_ip, MYF(0));
+ sctx->ip= my_strdup(sctx->host, MYF(0));
}
else
- thd->host= (char*)my_localhost;
- thd->host_or_ip= thd->host;
+ sctx->host= (char*)my_localhost;
+ sctx->host_or_ip= sctx->host;
- if (acl_check_host(thd->host,thd->ip))
+ if (acl_check_host(sctx->host, sctx->ip))
{
result= ER_HOST_NOT_PRIVILEGED;
goto err;
}
- thd->user= my_strdup(mysql->user, MYF(0));
+ sctx->user= my_strdup(mysql->user, MYF(0));
if (mysql->passwd && mysql->passwd[0])
{
memset(thd->scramble, 55, SCRAMBLE_LENGTH); // dummy scramble
diff --git a/man/which.2 b/man/which.2
deleted file mode 100644
index 30d5557ed01..00000000000
--- a/man/which.2
+++ /dev/null
@@ -1,54 +0,0 @@
-.TH WHICH 1 "20 December 2000"
-.SH NAME
-which - Jani please supply one.
-.SH USAGE
-which [options] [--] programname [...]
-.SH SYNOPSIS
-.B which
-.RB [ \-\-version | \-[vV] ]
-.RB [ \-\-skip\-dot ]
-.RB [ \-\-skip\-tilde ]
-.RB [ \-\-show\-dot ]
-.RB [ \-\-show\-tilde ]
-.RB [ \-\-tty\-only ]
-.RB [ \-\-all | \-a ]
-.RB [ \-\-read\-alias | \-i ]
-.RB [ \-\-skip\-alias ]
-.SH DESCRIPTION
-.TP
-.BR which
-supports by executing
-.TP
-.BR \-\-version | \-[vV]
-Print version and exit successfully.
-.TP
-.BR \-\-skip\-dot
-Skip directories in PATH that start with a dot.
-.TP
-.BR \-\-skip\-tilde
-Skip directories in PATH that start with a tilde.
-.TP
-.BR \-\-show\-dot
-Don\'t expand a dot to current directory in output.
-.TP
-.BR \-\-show\-tilde
-Output a tilde for HOME directory for non-root.
-.TP
-.BR \-\-tty\-only
-Stop processing options on the right if not on tty.
-.TP
-.BR \-\-all | \-a
-Print all matches in PATH, not just the first
-.TP
-.BR \-\-read\-alias | \-i
-Read list of aliases from stdin.
-.TP
-.BR \-\-skip\-alias
-Ignore option
-.BR --read-alias;
-don\'t read stdin.
-.SH "SEE ALSO"
-isamchk (1), isamlog (1), mysqlaccess (1), mysqladmin (1), mysqlbug (1), mysqld (1), mysqldump (1), mysqlshow (1), msql2mysql (1), perror (1), replace (1), mysqld_safe (1), which1 (1), zap (1),
-.SH AUTHOR
-Ver 1.0, distribution 3.23.29a Michael (Monty) Widenius (monty@tcx.se), TCX Datakonsult AB (http://www.tcx.se). This software comes with no warranty. Manual page by L. (Kill-9) Pedersen (kill-9@kill-9.dk), Mercurmedia Data Model Architect / system developer (http://www.mercurmedia.com)
-.\" end of man page \ No newline at end of file
diff --git a/mysql-test/include/im_check_os.inc b/mysql-test/include/im_check_os.inc
new file mode 100644
index 00000000000..9465115feb5
--- /dev/null
+++ b/mysql-test/include/im_check_os.inc
@@ -0,0 +1,7 @@
+--connect (dflt_server_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
+--connection dflt_server_con
+
+--source include/not_windows.inc
+
+--connection default
+--disconnect dflt_server_con
diff --git a/mysql-test/lib/init_db.sql b/mysql-test/lib/init_db.sql
index 37353e5974f..b366a429ab2 100644
--- a/mysql-test/lib/init_db.sql
+++ b/mysql-test/lib/init_db.sql
@@ -62,7 +62,7 @@ comment='Host privileges; Merged with database privileges';
CREATE TABLE user (
Host char(60) binary DEFAULT '' NOT NULL,
User char(16) binary DEFAULT '' NOT NULL,
- Password char(41) binary DEFAULT '' NOT NULL,
+ Password binary(41) DEFAULT '' NOT NULL,
Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl
index 250c3562227..ca984d37ecf 100644
--- a/mysql-test/lib/mtr_cases.pl
+++ b/mysql-test/lib/mtr_cases.pl
@@ -61,22 +61,6 @@ sub collect_test_cases ($) {
$elem= $tname;
$tname =~ s/\.imtest$//;
$component_id= 'im';
-
- if ( $::glob_use_embedded_server )
- {
- mtr_report(
- "Instance Manager's tests are not available in embedded mode." .
- "Test case '$tname' is skipped.");
- next;
- }
-
- unless ( $::exe_im )
- {
- mtr_report(
- "Instance Manager executable is unavailable. " .
- "Test case '$tname' is skipped.");
- next;
- }
}
# If target component is known, check that the specified test case
@@ -115,7 +99,7 @@ sub collect_test_cases ($) {
$component_id= 'im';
}
}
-
+
collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,{},
$component_id);
}
@@ -403,6 +387,34 @@ sub collect_one_test_case($$$$$$$) {
$tinfo->{'comment'}= mtr_fromfile($disabled_file);
}
+ if ( $component_id eq 'im' )
+ {
+ if ( $::glob_use_embedded_server )
+ {
+ $tinfo->{'skip'}= 1;
+
+ mtr_report(
+ "Instance Manager tests are not available in embedded mode. " .
+ "Test case '$tname' is skipped.");
+ }
+ elsif ( $::opt_ps_protocol )
+ {
+ $tinfo->{'skip'}= 1;
+
+ mtr_report(
+ "Instance Manager tests are not run with --ps-protocol. " .
+ "Test case '$tname' is skipped.");
+ }
+ elsif ( !$::exe_im )
+ {
+ $tinfo->{'skip'}= 1;
+
+ mtr_report(
+ "Instance Manager executable is unavailable." .
+ "Test case '$tname' is skipped.");
+ }
+ }
+
# We can't restart a running server that may be in use
if ( $::glob_use_running_server and
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index 5149d322f7f..eb60df4a5cb 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -680,7 +680,8 @@ sub mtr_mysqladmin_shutdown {
mtr_add_arg($args, "shutdown");
# We don't wait for termination of mysqladmin
my $pid= mtr_spawn($::exe_mysqladmin, $args,
- "", $::path_manager_log, $::path_manager_log, "");
+ "", $::path_manager_log, $::path_manager_log, "",
+ { append_log_file => 1 });
$mysql_admin_pids{$pid}= 1;
}
@@ -847,14 +848,16 @@ sub sleep_until_file_created ($$$) {
sub mtr_kill_processes ($) {
my $pids = shift;
- foreach my $sig (15,9)
+ foreach my $sig (15, 9)
{
- my $retries= 20; # FIXME 20 seconds, this is silly!
- kill($sig, @{$pids});
- while ( $retries-- and kill(0, @{$pids}) )
+ my $retries= 10;
+ while (1)
{
- mtr_debug("Sleep 1 second waiting for processes to die");
- sleep(1) # Wait one second
+ kill($sig, @{$pids});
+ last unless kill (0, @{$pids}) and $retries--;
+
+ mtr_debug("Sleep 2 second waiting for processes to die");
+ sleep(2);
}
}
}
diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl
index 9002f204602..515988ee5c7 100644
--- a/mysql-test/lib/mtr_report.pl
+++ b/mysql-test/lib/mtr_report.pl
@@ -257,11 +257,11 @@ sub mtr_print_header () {
print "\n";
if ( $::opt_timer )
{
- print "TEST RESULT TIME (ms)\n";
+ print "TEST RESULT TIME (ms)\n";
}
else
{
- print "TEST RESULT\n";
+ print "TEST RESULT\n";
}
mtr_print_line();
print "\n";
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index d1db4a65bac..101c18ec80f 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -2,37 +2,35 @@
# -*- cperl -*-
# This is a transformation of the "mysql-test-run" Bourne shell script
-# to Perl. This is just an intermediate step, the goal is to rewrite
-# the Perl script to C. The complexity of the mysql-test-run script
-# makes it a bit hard to write and debug it as a C program directly,
-# so this is considered a prototype.
+# to Perl. There are reasons this rewrite is not the prettiest Perl
+# you have seen
#
-# Because of this the Perl coding style may in some cases look a bit
-# funny. The rules used are
+# - The original script is huge and for most part uncommented,
+# not even a usage description of the flags.
#
-# - The coding style is as close as possible to the C/C++ MySQL
-# coding standard.
+# - 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.
#
-# - Where NULL is to be returned, the undefined value is used.
+# - 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.
#
-# - Regexp comparisons are simple and can be translated to strcmp
-# and other string functions. To ease this transformation matching
-# is done in the lib "lib/mtr_match.pl", i.e. regular expressions
-# should be avoided in the main program.
+# Some coding style from the original intent has been kept
#
-# - The "unless" construct is not to be used. It is the same as "if !".
-#
-# - opendir/readdir/closedir is used instead of glob()/<*>.
+# - 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
+# the C/C++ MySQL coding standard.
#
# - All lists of arguments to send to commands are Perl lists/arrays,
# not strings we append args to. Within reason, most string
# concatenation for arguments should be avoided.
#
-# - sprintf() is to be used, within reason, for all string creation.
-# This mtr_add_arg() function is also based on sprintf(), i.e. you
-# use a format string and put the variable argument in the argument
-# list.
-#
# - Functions defined in the main program are not to be prefixed,
# functions in "library files" are to be prefixed with "mtr_" (for
# Mysql-Test-Run). There are some exceptions, code that fits best in
@@ -241,8 +239,10 @@ our $opt_ps_protocol;
our $opt_sleep_time_after_restart= 1;
our $opt_sleep_time_for_delete= 10;
-our $opt_testcase_timeout= 5; # 5 min max
-our $opt_suite_timeout= 120; # 2 hours max
+our $opt_testcase_timeout;
+our $opt_suite_timeout;
+my $default_testcase_timeout= 10; # 10 min max
+my $default_suite_timeout= 120; # 2 hours max
our $opt_socket;
@@ -260,6 +260,7 @@ our $opt_user;
our $opt_user_test;
our $opt_valgrind;
+our $opt_valgrind_mysqltest;
our $opt_valgrind_all;
our $opt_valgrind_options;
@@ -473,6 +474,7 @@ sub command_line_setup () {
# Read the command line
# Note: Keep list, and the order, in sync with usage at end of this file
+ Getopt::Long::Configure("pass_through");
GetOptions(
# Control what engine/variation to run
'embedded-server' => \$opt_embedded_server,
@@ -521,8 +523,9 @@ sub command_line_setup () {
# Coverage, profiling etc
'gcov' => \$opt_gcov,
'gprof' => \$opt_gprof,
- 'valgrind' => \$opt_valgrind,
- 'valgrind-all' => \$opt_valgrind_all,
+ 'valgrind:s' => \$opt_valgrind,
+ 'valgrind-mysqltest:s' => \$opt_valgrind_mysqltest,
+ 'valgrind-all:s' => \$opt_valgrind_all,
'valgrind-options=s' => \$opt_valgrind_options,
# Misc
@@ -562,7 +565,21 @@ sub command_line_setup () {
usage("");
}
- @opt_cases= @ARGV;
+ foreach my $arg ( @ARGV )
+ {
+ if ( $arg =~ /^--skip-/ )
+ {
+ push(@opt_extra_mysqld_opt, $arg);
+ }
+ elsif ( $arg =~ /^-/ )
+ {
+ usage("Invalid option \"$arg\"");
+ }
+ else
+ {
+ push(@opt_cases, $arg);
+ }
+ }
# --------------------------------------------------------------------------
# Set the "var/" directory, as it is the base for everything else
@@ -654,11 +671,6 @@ sub command_line_setup () {
mtr_error("Coverage test needs the source - please use source dist");
}
- if ( $glob_use_embedded_server and ! $opt_source_dist )
- {
- mtr_error("Embedded server needs source tree - please use source dist");
- }
-
if ( $opt_gdb )
{
$opt_wait_timeout= 300;
@@ -700,29 +712,42 @@ sub command_line_setup () {
$opt_with_ndbcluster= 0;
}
- # FIXME
+ # The ":s" in the argument spec, means we have three different cases
+ #
+ # undefined option not set
+ # "" option set with no argument
+ # "somestring" option is name/path of valgrind executable
+
+ # Take executable path from any of them, if any
+ $opt_valgrind= $opt_valgrind_mysqltest if $opt_valgrind_mysqltest;
+ $opt_valgrind= $opt_valgrind_all if $opt_valgrind_all;
+
+ # If valgrind flag not defined, define if other valgrind flags are
+ unless ( defined $opt_valgrind )
+ {
+ $opt_valgrind= ""
+ if defined $opt_valgrind_mysqltest or defined $opt_valgrind_all;
+ }
+
+ if ( ! $opt_testcase_timeout )
+ {
+ $opt_testcase_timeout= $default_testcase_timeout;
+ $opt_testcase_timeout*= 10 if defined $opt_valgrind;
+ }
+
+ if ( ! $opt_suite_timeout )
+ {
+ $opt_suite_timeout= $default_suite_timeout;
+ $opt_suite_timeout*= 4 if defined $opt_valgrind;
+ }
- #if ( $opt_valgrind or $opt_valgrind_all )
- #{
- # VALGRIND=`which valgrind` # this will print an error if not found FIXME
- # Give good warning to the user and stop
- # if ( ! $VALGRIND )
- # {
- # print "You need to have the 'valgrind' program in your PATH to run mysql-test-run with option --valgrind. Valgrind's home page is http://valgrind.kde.org.\n"
- # exit 1
- # }
+ if ( defined $opt_valgrind )
+ {
+ $opt_sleep_time_after_restart= 10;
+ $opt_sleep_time_for_delete= 60;
# >=2.1.2 requires the --tool option, some versions write to stdout, some to stderr
- # valgrind --help 2>&1 | grep "\-\-tool" > /dev/null && VALGRIND="$VALGRIND --tool=memcheck"
- # VALGRIND="$VALGRIND --alignment=8 --leak-check=yes --num-callers=16"
- # $opt_extra_mysqld_opt.= " --skip-safemalloc --skip-bdb";
- # SLEEP_TIME_AFTER_RESTART=10
- # $opt_sleep_time_for_delete= 60
- # $glob_use_running_server= ""
- # if ( "$1"= "--valgrind-all" )
- # {
- # VALGRIND="$VALGRIND -v --show-reachable=yes"
- # }
- #}
+ # valgrind --help 2>&1 | grep "\-\-tool" > /dev/null && VALGRIND="$VALGRIND --tool=memcheck"
+ }
if ( ! $opt_user )
{
@@ -738,78 +763,96 @@ sub command_line_setup () {
# Put this into a hash, will be a C struct
- $master->[0]->{'path_myddir'}= "$opt_vardir/master-data";
- $master->[0]->{'path_myerr'}= "$opt_vardir/log/master.err";
- $master->[0]->{'path_mylog'}= "$opt_vardir/log/master.log";
- $master->[0]->{'path_mypid'}= "$opt_vardir/run/master.pid";
- $master->[0]->{'path_mysock'}= "$opt_tmpdir/master.sock";
- $master->[0]->{'path_myport'}= $opt_master_myport;
- $master->[0]->{'start_timeout'}= 400; # enough time create innodb tables
-
- $master->[0]->{'ndbcluster'}= 1; # ndbcluster not started
-
- $master->[1]->{'path_myddir'}= "$opt_vardir/master1-data";
- $master->[1]->{'path_myerr'}= "$opt_vardir/log/master1.err";
- $master->[1]->{'path_mylog'}= "$opt_vardir/log/master1.log";
- $master->[1]->{'path_mypid'}= "$opt_vardir/run/master1.pid";
- $master->[1]->{'path_mysock'}= "$opt_tmpdir/master1.sock";
- $master->[1]->{'path_myport'}= $opt_master_myport + 1;
- $master->[1]->{'start_timeout'}= 400; # enough time create innodb tables
-
- $slave->[0]->{'path_myddir'}= "$opt_vardir/slave-data";
- $slave->[0]->{'path_myerr'}= "$opt_vardir/log/slave.err";
- $slave->[0]->{'path_mylog'}= "$opt_vardir/log/slave.log";
- $slave->[0]->{'path_mypid'}= "$opt_vardir/run/slave.pid";
- $slave->[0]->{'path_mysock'}= "$opt_tmpdir/slave.sock";
- $slave->[0]->{'path_myport'}= $opt_slave_myport;
- $slave->[0]->{'start_timeout'}= 400;
-
- $slave->[1]->{'path_myddir'}= "$opt_vardir/slave1-data";
- $slave->[1]->{'path_myerr'}= "$opt_vardir/log/slave1.err";
- $slave->[1]->{'path_mylog'}= "$opt_vardir/log/slave1.log";
- $slave->[1]->{'path_mypid'}= "$opt_vardir/run/slave1.pid";
- $slave->[1]->{'path_mysock'}= "$opt_tmpdir/slave1.sock";
- $slave->[1]->{'path_myport'}= $opt_slave_myport + 1;
- $slave->[1]->{'start_timeout'}= 300;
-
- $slave->[2]->{'path_myddir'}= "$opt_vardir/slave2-data";
- $slave->[2]->{'path_myerr'}= "$opt_vardir/log/slave2.err";
- $slave->[2]->{'path_mylog'}= "$opt_vardir/log/slave2.log";
- $slave->[2]->{'path_mypid'}= "$opt_vardir/run/slave2.pid";
- $slave->[2]->{'path_mysock'}= "$opt_tmpdir/slave2.sock";
- $slave->[2]->{'path_myport'}= $opt_slave_myport + 2;
- $slave->[2]->{'start_timeout'}= 300;
-
- $instance_manager->{'path_err'}= "$opt_vardir/log/im.err";
- $instance_manager->{'path_log'}= "$opt_vardir/log/im.log";
- $instance_manager->{'path_pid'}= "$opt_vardir/run/im.pid";
- $instance_manager->{'path_sock'}= "$opt_tmpdir/im.sock";
- $instance_manager->{'port'}= $im_port;
- $instance_manager->{'start_timeout'}= $master->[0]->{'start_timeout'};
- $instance_manager->{'admin_login'}= 'im_admin';
- $instance_manager->{'admin_password'}= 'im_admin_secret';
- $instance_manager->{'admin_sha1'}= '*598D51AD2DFF7792045D6DF3DDF9AA1AF737B295';
- $instance_manager->{'password_file'}= "$opt_vardir/im.passwd";
- $instance_manager->{'defaults_file'}= "$opt_vardir/im.cnf";
-
- $instance_manager->{'instances'}->[0]->{'server_id'}= 1;
- $instance_manager->{'instances'}->[0]->{'port'}= $im_mysqld1_port;
- $instance_manager->{'instances'}->[0]->{'path_datadir'}=
- "$opt_vardir/im_mysqld_1.data";
- $instance_manager->{'instances'}->[0]->{'path_sock'}=
- "$opt_vardir/mysqld_1.sock";
- $instance_manager->{'instances'}->[0]->{'path_pid'}=
- "$opt_vardir/mysqld_1.pid";
-
- $instance_manager->{'instances'}->[1]->{'server_id'}= 2;
- $instance_manager->{'instances'}->[1]->{'port'}= $im_mysqld2_port;
- $instance_manager->{'instances'}->[1]->{'path_datadir'}=
- "$opt_vardir/im_mysqld_2.data";
- $instance_manager->{'instances'}->[1]->{'path_sock'}=
- "$opt_vardir/mysqld_2.sock";
- $instance_manager->{'instances'}->[1]->{'path_pid'}=
- "$opt_vardir/mysqld_2.pid";
- $instance_manager->{'instances'}->[1]->{'nonguarded'}= 1;
+ $master->[0]=
+ {
+ path_myddir => "$opt_vardir/master-data",
+ path_myerr => "$opt_vardir/log/master.err",
+ path_mylog => "$opt_vardir/log/master.log",
+ path_mypid => "$opt_vardir/run/master.pid",
+ path_mysock => "$opt_tmpdir/master.sock",
+ path_myport => $opt_master_myport,
+ start_timeout => 400, # enough time create innodb tables
+
+ ndbcluster => 1, # ndbcluster not started
+ };
+
+ $master->[1]=
+ {
+ path_myddir => "$opt_vardir/master1-data",
+ path_myerr => "$opt_vardir/log/master1.err",
+ path_mylog => "$opt_vardir/log/master1.log",
+ path_mypid => "$opt_vardir/run/master1.pid",
+ path_mysock => "$opt_tmpdir/master1.sock",
+ path_myport => $opt_master_myport + 1,
+ start_timeout => 400, # enough time create innodb tables
+ };
+
+ $slave->[0]=
+ {
+ path_myddir => "$opt_vardir/slave-data",
+ path_myerr => "$opt_vardir/log/slave.err",
+ path_mylog => "$opt_vardir/log/slave.log",
+ path_mypid => "$opt_vardir/run/slave.pid",
+ path_mysock => "$opt_tmpdir/slave.sock",
+ path_myport => $opt_slave_myport,
+ start_timeout => 400,
+ };
+
+ $slave->[1]=
+ {
+ path_myddir => "$opt_vardir/slave1-data",
+ path_myerr => "$opt_vardir/log/slave1.err",
+ path_mylog => "$opt_vardir/log/slave1.log",
+ path_mypid => "$opt_vardir/run/slave1.pid",
+ path_mysock => "$opt_tmpdir/slave1.sock",
+ path_myport => $opt_slave_myport + 1,
+ start_timeout => 300,
+ };
+
+ $slave->[2]=
+ {
+ path_myddir => "$opt_vardir/slave2-data",
+ path_myerr => "$opt_vardir/log/slave2.err",
+ path_mylog => "$opt_vardir/log/slave2.log",
+ path_mypid => "$opt_vardir/run/slave2.pid",
+ path_mysock => "$opt_tmpdir/slave2.sock",
+ path_myport => $opt_slave_myport + 2,
+ start_timeout => 300,
+ };
+
+ $instance_manager=
+ {
+ path_err => "$opt_vardir/log/im.err",
+ path_log => "$opt_vardir/log/im.log",
+ path_pid => "$opt_vardir/run/im.pid",
+ path_sock => "$opt_tmpdir/im.sock",
+ port => $im_port,
+ start_timeout => $master->[0]->{'start_timeout'},
+ admin_login => 'im_admin',
+ admin_password => 'im_admin_secret',
+ admin_sha1 => '*598D51AD2DFF7792045D6DF3DDF9AA1AF737B295',
+ password_file => "$opt_vardir/im.passwd",
+ defaults_file => "$opt_vardir/im.cnf",
+ };
+
+ $instance_manager->{'instances'}->[0]=
+ {
+ server_id => 1,
+ port => $im_mysqld1_port,
+ path_datadir => "$opt_vardir/im_mysqld_1.data",
+ path_sock => "$opt_vardir/mysqld_1.sock",
+ path_pid => "$opt_vardir/mysqld_1.pid",
+ };
+
+ $instance_manager->{'instances'}->[1]=
+ {
+ server_id => 2,
+ port => $im_mysqld2_port,
+ path_datadir => "$opt_vardir/im_mysqld_2.data",
+ path_sock => "$opt_vardir/mysqld_2.sock",
+ path_pid => "$opt_vardir/mysqld_2.pid",
+ nonguarded => 1,
+ };
if ( $opt_extern )
{
@@ -854,7 +897,7 @@ sub executable_setup () {
if ( $glob_use_embedded_server )
{
my $path_examples= "$glob_basedir/libmysqld/examples";
- $exe_mysqltest= mtr_exe_exists("$path_examples/mysqltest");
+ $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");
@@ -881,7 +924,6 @@ sub executable_setup () {
else
{
$path_client_bindir= mtr_path_exists("$glob_basedir/bin");
- $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest");
$exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump");
$exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow");
$exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog");
@@ -975,10 +1017,14 @@ sub environment_setup () {
# $ENV{'MYSQL_TCP_PORT'}= '@MYSQL_TCP_PORT@'; # FIXME
$ENV{'MYSQL_TCP_PORT'}= 3306;
+ $ENV{'IM_PATH_PID'}= $instance_manager->{path_pid};
+
$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 ( $glob_cygwin_perl )
{
@@ -1883,7 +1929,7 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
- if ( $opt_valgrind )
+ if ( defined $opt_valgrind )
{
mtr_add_arg($args, "%s--skip-safemalloc", $prefix);
mtr_add_arg($args, "%s--skip-bdb", $prefix);
@@ -2109,29 +2155,9 @@ sub mysqld_start ($$$$) {
mtr_init_args(\$args);
- if ( $opt_valgrind )
+ if ( defined $opt_valgrind )
{
-
- mtr_add_arg($args, "--tool=memcheck");
- mtr_add_arg($args, "--alignment=8");
- mtr_add_arg($args, "--leak-check=yes");
- mtr_add_arg($args, "--num-callers=16");
-
- if ( $opt_valgrind_all )
- {
- mtr_add_arg($args, "-v");
- mtr_add_arg($args, "--show-reachable=yes");
- }
-
- if ( $opt_valgrind_options )
- {
- # FIXME split earlier and put into @glob_valgrind_*
- mtr_add_arg($args, split(' ', $opt_valgrind_options));
- }
-
- mtr_add_arg($args, $exe);
-
- $exe= $opt_valgrind;
+ valgrind_arguments($args, \$exe);
}
mysqld_arguments($args,$type,$idx,$extra_opt,$slave_master_info);
@@ -2140,7 +2166,9 @@ sub mysqld_start ($$$$) {
{
if ( $pid= mtr_spawn($exe, $args, "",
$master->[$idx]->{'path_myerr'},
- $master->[$idx]->{'path_myerr'}, "") )
+ $master->[$idx]->{'path_myerr'},
+ "",
+ { append_log_file => 1 }) )
{
return sleep_until_file_created($master->[$idx]->{'path_mypid'},
$master->[$idx]->{'start_timeout'}, $pid);
@@ -2151,7 +2179,9 @@ sub mysqld_start ($$$$) {
{
if ( $pid= mtr_spawn($exe, $args, "",
$slave->[$idx]->{'path_myerr'},
- $slave->[$idx]->{'path_myerr'}, "") )
+ $slave->[$idx]->{'path_myerr'},
+ "",
+ { append_log_file => 1 }) )
{
return sleep_until_file_created($slave->[$idx]->{'path_mypid'},
$master->[$idx]->{'start_timeout'}, $pid);
@@ -2291,6 +2321,12 @@ sub im_stop($) {
return;
}
+ # Re-read pid from the file, since during tests Instance Manager could have
+ # been restarted, so its pid could have been changed.
+
+ $instance_manager->{'pid'} =
+ mtr_get_pid_from_file($instance_manager->{'path_pid'});
+
# Inspired from mtr_stop_mysqld_servers().
start_reap_all();
@@ -2403,6 +2439,11 @@ sub run_mysqltest ($) {
mtr_init_args(\$args);
+ if ( defined $opt_valgrind_mysqltest )
+ {
+ valgrind_arguments($args, \$exe);
+ }
+
mtr_add_arg($args, "--no-defaults");
mtr_add_arg($args, "--silent");
mtr_add_arg($args, "-v");
@@ -2448,11 +2489,6 @@ sub run_mysqltest ($) {
mtr_add_arg($args, "--big-test");
}
- if ( $opt_record )
- {
- mtr_add_arg($args, "--record");
- }
-
if ( $opt_compress )
{
mtr_add_arg($args, "--compress");
@@ -2478,9 +2514,6 @@ sub run_mysqltest ($) {
$glob_mysql_test_dir);
}
- mtr_add_arg($args, "-R");
- mtr_add_arg($args, $tinfo->{'result_file'});
-
# ----------------------------------------------------------------------
# If embedded server, we create server args to give mysqltest to pass on
# ----------------------------------------------------------------------
@@ -2495,9 +2528,51 @@ sub run_mysqltest ($) {
# ----------------------------------------------------------------------
$ENV{'MYSQL_TEST'}= "$exe_mysqltest " . join(" ", @$args);
+ # ----------------------------------------------------------------------
+ # Add arguments that should not go into the MYSQL_TEST env var
+ # ----------------------------------------------------------------------
+
+ mtr_add_arg($args, "-R");
+ mtr_add_arg($args, $tinfo->{'result_file'});
+
+ if ( $opt_record )
+ {
+ mtr_add_arg($args, "--record");
+ }
+
return mtr_run_test($exe,$args,$tinfo->{'path'},"",$path_timefile,"");
}
+
+sub valgrind_arguments {
+ my $args= shift;
+ my $exe= shift;
+
+ mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option
+ mtr_add_arg($args, "--alignment=8");
+ mtr_add_arg($args, "--leak-check=yes");
+ mtr_add_arg($args, "--num-callers=16");
+ mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir)
+ if -f "$glob_mysql_test_dir/valgrind.supp";
+
+ if ( defined $opt_valgrind_all )
+ {
+ mtr_add_arg($args, "-v");
+ mtr_add_arg($args, "--show-reachable=yes");
+ }
+
+ if ( $opt_valgrind_options )
+ {
+ # FIXME split earlier and put into @glob_valgrind_*
+ mtr_add_arg($args, split(' ', $opt_valgrind_options));
+ }
+
+ mtr_add_arg($args, $$exe);
+
+ $$exe= $opt_valgrind || "valgrind";
+}
+
+
##############################################################################
#
# Usage
@@ -2562,8 +2637,11 @@ Options for coverage, profiling etc
gcov FIXME
gprof FIXME
- valgrind FIXME
- valgrind-all FIXME
+ valgrind[=EXE] Run the "mysqltest" executable as well as the "mysqld"
+ server using valgrind, optionally specifying the
+ executable path/name
+ valgrind-mysqltest[=EXE] In addition, run the "mysqltest" executable with valgrind
+ valgrind-all[=EXE] Adds verbose flag, and --show-reachable to valgrind
valgrind-options=ARGS Extra options to give valgrind
Misc options
diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result
index d525b019c64..2bba44d36e9 100644
--- a/mysql-test/r/bdb.result
+++ b/mysql-test/r/bdb.result
@@ -1429,10 +1429,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range v v 13 NULL # Using where
explain select count(*) from t1 where v between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 13 NULL # Using where
+1 SIMPLE t1 ref v v 13 const # Using where
explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 13 NULL # Using where
+1 SIMPLE t1 ref v v 13 const # Using where
alter table t1 add unique(v);
ERROR 23000: Duplicate entry '{ ' for key 1
alter table t1 add key(v);
@@ -1622,10 +1622,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range v v 258 NULL # Using where
explain select count(*) from t1 where v between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 258 NULL # Using where
+1 SIMPLE t1 ref v v 258 const # Using where
explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 258 NULL # Using where
+1 SIMPLE t1 ref v v 258 const # Using where
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 258 const # Using where
@@ -1702,10 +1702,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range v v 33 NULL # Using where
explain select count(*) from t1 where v between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 33 NULL # Using where
+1 SIMPLE t1 ref v v 33 const # Using where
explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 33 NULL # Using where
+1 SIMPLE t1 ref v v 33 const # Using where
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 33 const # Using where
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index b02f85132aa..ea80695ad7b 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -103,8 +103,8 @@ t1 CREATE TABLE `t1` (
`c2` varchar(1) character set latin1 collate latin1_danish_ci NOT NULL default '',
`c3` varbinary(1) NOT NULL default '',
`c4` varbinary(1) NOT NULL default '',
- `c5` varbinary(4) NOT NULL default '',
- `c6` varbinary(4) NOT NULL default '',
+ `c5` varbinary(3) NOT NULL default '',
+ `c6` varbinary(3) NOT NULL default '',
`c7` decimal(2,1) NOT NULL default '0.0',
`c8` decimal(2,1) NOT NULL default '0.0',
`c9` decimal(2,1) default NULL,
@@ -152,11 +152,11 @@ SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`COALESCE(1)` int(1) NOT NULL default '0',
- `COALESCE(1.0)` decimal(2,1) NOT NULL default '0.0',
+ `COALESCE(1.0)` decimal(2,1) unsigned NOT NULL default '0.0',
`COALESCE('a')` varchar(1) NOT NULL default '',
`COALESCE(1,1.0)` decimal(2,1) NOT NULL default '0.0',
`COALESCE(1,'1')` varbinary(1) NOT NULL default '',
- `COALESCE(1.1,'1')` varbinary(4) NOT NULL default '',
+ `COALESCE(1.1,'1')` varbinary(3) NOT NULL default '',
`COALESCE('a' COLLATE latin1_bin,'b')` varchar(1) character set latin1 collate latin1_bin NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result
index 1b5bdf98afd..fa8e810cf2b 100644
--- a/mysql-test/r/cast.result
+++ b/mysql-test/r/cast.result
@@ -74,6 +74,18 @@ CAST(DATE "2004-01-22 21:45:33" AS BINARY(4))
2004
Warnings:
Warning 1292 Truncated incorrect CHAR(4) value: '2004-01-22 21:45:33'
+select CAST(0xb3 as signed);
+CAST(0xb3 as signed)
+179
+select CAST(0x8fffffffffffffff as signed);
+CAST(0x8fffffffffffffff as signed)
+-8070450532247928833
+select CAST(0xffffffffffffffff as unsigned);
+CAST(0xffffffffffffffff as unsigned)
+18446744073709551615
+select CAST(0xfffffffffffffffe as signed);
+CAST(0xfffffffffffffffe as signed)
+-2
select cast('-10a' as signed integer);
cast('-10a' as signed integer)
-10
diff --git a/mysql-test/r/ctype_ucs_binlog.result b/mysql-test/r/ctype_ucs_binlog.result
index 4267e495959..14220a7df13 100644
--- a/mysql-test/r/ctype_ucs_binlog.result
+++ b/mysql-test/r/ctype_ucs_binlog.result
@@ -17,6 +17,7 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t2 values (@v);
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
drop table t2;
diff --git a/mysql-test/r/ctype_ujis.result b/mysql-test/r/ctype_ujis.result
index 0bc101d491d..0fee6fc3456 100644
--- a/mysql-test/r/ctype_ujis.result
+++ b/mysql-test/r/ctype_ujis.result
@@ -2271,3 +2271,33 @@ select c1 from t1 where c1 like 'abcde111%' order by c1;
c1
abcde111
drop table t1;
+DROP TABLE IF EXISTS t1, t2;
+DROP PROCEDURE IF EXISTS sp1;
+set names ujis;
+set character_set_database = ujis;
+set character_set_server = ujis;
+CREATE TABLE t1(c1 char(2)) default charset = ujis;
+CREATE TABLE t2(c2 char(2)) default charset = ujis;
+INSERT INTO t1 VALUES(_ujis 0xA4A2);
+CREATE PROCEDURE sp1()
+BEGIN
+DECLARE a CHAR(1);
+DECLARE cur1 CURSOR FOR SELECT c1 FROM t1;
+OPEN cur1;
+FETCH cur1 INTO a;
+INSERT INTO t2 VALUES (a);
+CLOSE cur1;
+END|
+CALL sp1();
+SELECT c1,c2 FROM t1,t2;
+c1 c2
+¤¢ ¤¢
+SELECT hex(convert(_latin1 0xA4A2 using ujis)),hex(c2) FROM t1,t2;
+hex(convert(_latin1 0xA4A2 using ujis)) hex(c2)
+8FA2F0A1F1 A4A2
+DROP PROCEDURE sp1;
+DROP TABLE t1;
+DROP TABLE t2;
+set names default;
+set character_set_database=default;
+set character_set_server=default;
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 844750e3fed..8e10e97d49d 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -1028,6 +1028,45 @@ xxx
yyy
DROP TABLE t1;
set names utf8;
+select hex(char(1));
+hex(char(1))
+01
+select char(0xd1,0x8f);
+char(0xd1,0x8f)
+select char(0xd18f);
+char(0xd18f)
+select char(53647);
+char(53647)
+select char(0xff,0x8f);
+char(0xff,0x8f)
+ÿ
+Warnings:
+Warning 1300 Invalid utf8 character string: 'FF8F'
+set sql_mode=traditional;
+select char(0xff,0x8f);
+char(0xff,0x8f)
+NULL
+Warnings:
+Error 1300 Invalid utf8 character string: 'FF8F'
+select char(195);
+char(195)
+NULL
+Warnings:
+Error 1300 Invalid utf8 character string: 'C3'
+select char(196);
+char(196)
+NULL
+Warnings:
+Error 1300 Invalid utf8 character string: 'C4'
+select char(2557);
+char(2557)
+NULL
+Warnings:
+Error 1300 Invalid utf8 character string: 'FD'
+set names utf8;
create table t1 (a char(1)) default character set utf8;
create table t2 (a char(1)) default character set utf8;
insert into t1 values('a'),('a'),(0xE38182),(0xE38182);
diff --git a/mysql-test/r/default.result b/mysql-test/r/default.result
index 7db20c2b096..aef49af6c62 100644
--- a/mysql-test/r/default.result
+++ b/mysql-test/r/default.result
@@ -29,38 +29,6 @@ z varchar(20) binary NOT NULL DEFAULT ' ',
a1 varchar(30) binary NOT NULL DEFAULT ' ',
b1 tinyblob NULL)
ENGINE=InnoDB DEFAULT CHARACTER SET = latin1 COLLATE latin1_bin;
-SHOW CREATE TABLE t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `a` varchar(30) collate latin1_bin NOT NULL default ' ',
- `b` varchar(1) collate latin1_bin NOT NULL default ' ',
- `c` varchar(4) collate latin1_bin NOT NULL default '0000',
- `d` tinyblob,
- `e` tinyblob,
- `f` tinyblob,
- `g` tinyblob,
- `h` tinyblob,
- `i` tinyblob,
- `j` tinyblob,
- `k` tinyblob,
- `l` tinyblob,
- `m` tinyblob,
- `n` tinyblob,
- `o` tinyblob,
- `p` tinyblob,
- `q` varchar(30) collate latin1_bin NOT NULL default ' ',
- `r` varchar(30) collate latin1_bin NOT NULL default ' ',
- `s` tinyblob,
- `t` varchar(4) collate latin1_bin NOT NULL default ' ',
- `u` varchar(1) collate latin1_bin NOT NULL default ' ',
- `v` varchar(30) collate latin1_bin NOT NULL default ' ',
- `w` varchar(30) collate latin1_bin NOT NULL default ' ',
- `x` tinyblob,
- `y` varchar(5) collate latin1_bin NOT NULL default ' ',
- `z` varchar(20) collate latin1_bin NOT NULL default ' ',
- `a1` varchar(30) collate latin1_bin NOT NULL default ' ',
- `b1` tinyblob
-) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin
INSERT into t1 (b) values ('1');
SHOW WARNINGS;
Level Code Message
diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result
index 7c9d88acf90..19325731d35 100644
--- a/mysql-test/r/derived.result
+++ b/mysql-test/r/derived.result
@@ -368,3 +368,15 @@ create table t2 (a int);
select * from (select * from t1,t2) foo;
ERROR 42S21: Duplicate column name 'a'
drop table t1,t2;
+create table t1 (ID int unsigned not null auto_increment,
+DATA varchar(5) not null, primary key (ID));
+create table t2 (ID int unsigned not null auto_increment,
+DATA varchar(5) not null, FID int unsigned not null,
+primary key (ID));
+select A.* from (t1 inner join (select * from t2) as A on t1.ID = A.FID);
+ID DATA FID
+select t2.* from ((select * from t1) as A inner join t2 on A.ID = t2.FID);
+ID DATA FID
+select t2.* from (select * from t1) as A inner join t2 on A.ID = t2.FID;
+ID DATA FID
+drop table t1, t2;
diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result
index 1ec9857c8a7..e0e0bba3271 100644
--- a/mysql-test/r/federated.result
+++ b/mysql-test/r/federated.result
@@ -1457,6 +1457,32 @@ federated.t1 repair status OK
REPAIR TABLE federated.t1 USE_FRM;
Table Op Msg_type Msg_text
federated.t1 repair status OK
+DROP TABLE IF EXISTS federated.normal_table;
+CREATE TABLE federated.normal_table (
+`id` int(4) NOT NULL,
+`name` varchar(10) default NULL
+) DEFAULT CHARSET=latin1;
+DROP TABLE IF EXISTS federated.alter_me;
+CREATE TABLE federated.alter_me (
+`id` int(4) NOT NULL,
+`name` varchar(10) default NULL,
+PRIMARY KEY (`id`)
+) ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/normal_table';
+INSERT INTO federated.alter_me (id, name) VALUES (1, 'Monty');
+INSERT INTO federated.alter_me (id, name) VALUES (2, 'David');
+SELECT * FROM federated.alter_me;
+id name
+1 Monty
+2 David
+ALTER TABLE federated.alter_me MODIFY COLUMN id int(16) NOT NULL;
+ERROR HY000: Table storage engine for 'alter_me' doesn't have this option
+SELECT * FROM federated.alter_me;
+id name
+1 Monty
+2 David
+DROP TABLE federated.alter_me;
+DROP TABLE federated.normal_table;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
DROP TABLE IF EXISTS federated.t1;
diff --git a/mysql-test/r/federated_bug_13118.result b/mysql-test/r/federated_bug_13118.result
new file mode 100644
index 00000000000..cc14dae87d9
--- /dev/null
+++ b/mysql-test/r/federated_bug_13118.result
@@ -0,0 +1,39 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+stop slave;
+DROP DATABASE IF EXISTS federated;
+CREATE DATABASE federated;
+DROP DATABASE IF EXISTS federated;
+CREATE DATABASE federated;
+DROP TABLE IF EXISTS federated.bug_13118_table;
+CREATE TABLE federated.bug_13118_table (
+`foo` integer,
+`bar` integer
+);
+DROP TABLE IF EXISTS federated.t1;
+CREATE TABLE federated.t1 (
+`foo` integer,
+`bar` integer
+) ENGINE="FEDERATED"
+ CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/bug_13118_table';
+SELECT * from federated.t1;
+foo bar
+INSERT INTO federated.t1 VALUES (1,1);
+SELECT * FROM federated.t1;
+foo bar
+1 1
+INSERT INTO federated.t1 VALUES (1,1);
+SELECT * FROM federated.t1;
+foo bar
+1 1
+1 1
+DROP TABLE federated.t1;
+DROP TABLE federated.bug_13118_table;
+DROP TABLE IF EXISTS federated.t1;
+DROP DATABASE IF EXISTS federated;
+DROP TABLE IF EXISTS federated.t1;
+DROP DATABASE IF EXISTS federated;
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index 1542794798a..2b0176179ed 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -821,6 +821,142 @@ SELECT MAX(id) FROM t1 WHERE id < 3 AND a=2 AND b=6;
MAX(id)
NULL
DROP TABLE t1;
+create table t1m (a int) engine=myisam;
+create table t1i (a int) engine=innodb;
+create table t2m (a int) engine=myisam;
+create table t2i (a int) engine=innodb;
+insert into t2m values (5);
+insert into t2i values (5);
+select min(a) from t1m;
+min(a)
+NULL
+select min(7) from t1m;
+min(7)
+NULL
+select min(7) from DUAL;
+min(7)
+NULL
+explain select min(7) from t2m join t1m;
+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(7) from t2m join t1m;
+min(7)
+NULL
+select max(a) from t1m;
+max(a)
+NULL
+select max(7) from t1m;
+max(7)
+NULL
+select max(7) from DUAL;
+max(7)
+NULL
+explain select max(7) from t2m join t1m;
+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 max(7) from t2m join t1m;
+max(7)
+NULL
+select 1, min(a) from t1m where a=99;
+1 min(a)
+1 NULL
+select 1, min(a) from t1m where 1=99;
+1 min(a)
+1 NULL
+select 1, min(1) from t1m where a=99;
+1 min(1)
+select 1, min(1) from t1m where 1=99;
+1 min(1)
+1 NULL
+select 1, max(a) from t1m where a=99;
+1 max(a)
+1 NULL
+select 1, max(a) from t1m where 1=99;
+1 max(a)
+1 NULL
+select 1, max(1) from t1m where a=99;
+1 max(1)
+select 1, max(1) from t1m where 1=99;
+1 max(1)
+1 NULL
+select min(a) from t1i;
+min(a)
+NULL
+select min(7) from t1i;
+min(7)
+NULL
+select min(7) from DUAL;
+min(7)
+NULL
+explain select min(7) from t2i join t1i;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2i ALL NULL NULL NULL NULL 1
+1 SIMPLE t1i ALL NULL NULL NULL NULL 1
+select min(7) from t2i join t1i;
+min(7)
+NULL
+select max(a) from t1i;
+max(a)
+NULL
+select max(7) from t1i;
+max(7)
+NULL
+select max(7) from DUAL;
+max(7)
+NULL
+explain select max(7) from t2i join t1i;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2i ALL NULL NULL NULL NULL 1
+1 SIMPLE t1i ALL NULL NULL NULL NULL 1
+select max(7) from t2i join t1i;
+max(7)
+NULL
+select 1, min(a) from t1i where a=99;
+1 min(a)
+1 NULL
+select 1, min(a) from t1i where 1=99;
+1 min(a)
+1 NULL
+select 1, min(1) from t1i where a=99;
+1 min(1)
+1 NULL
+select 1, min(1) from t1i where 1=99;
+1 min(1)
+1 NULL
+select 1, max(a) from t1i where a=99;
+1 max(a)
+1 NULL
+select 1, max(a) from t1i where 1=99;
+1 max(a)
+1 NULL
+select 1, max(1) from t1i where a=99;
+1 max(1)
+1 NULL
+select 1, max(1) from t1i where 1=99;
+1 max(1)
+1 NULL
+explain select count(*), min(7), max(7) from t1m, t1i;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1m system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t1i ALL NULL NULL NULL NULL 1
+select count(*), min(7), max(7) from t1m, t1i;
+count(*) min(7) max(7)
+0 NULL NULL
+explain select count(*), min(7), max(7) from t1m, t2i;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1m system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t2i ALL NULL NULL NULL NULL 1
+select count(*), min(7), max(7) from t1m, t2i;
+count(*) min(7) max(7)
+0 NULL NULL
+explain select count(*), min(7), max(7) from t2m, t1i;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2m system NULL NULL NULL NULL 1
+1 SIMPLE t1i ALL NULL NULL NULL NULL 1
+select count(*), min(7), max(7) from t2m, t1i;
+count(*) min(7) max(7)
+0 NULL NULL
+drop table t1m, t1i, t2m, t2i;
create table t2 (ff double);
insert into t2 values (2.2);
select cast(sum(distinct ff) as decimal(5,2)) from t2;
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index a0868d09242..8562937f1ac 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -193,6 +193,15 @@ select * from t1 where a in (NULL, 'aa');
a
aa
drop table t1;
+create table t1 (id int, key(id));
+insert into t1 values (1),(2),(3);
+select count(*) from t1 where id not in (1);
+count(*)
+2
+select count(*) from t1 where id not in (1,2);
+count(*)
+1
+drop table t1;
CREATE TABLE t1 (a int PRIMARY KEY);
INSERT INTO t1 VALUES (44), (45), (46);
SELECT * FROM t1 WHERE a IN (45);
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 577f943ebde..3d7d693cdce 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -1011,3 +1011,9 @@ t
1000000
1
drop table t1;
+create table t1 (d decimal default null);
+insert into t1 values (null);
+select format(d, 2) from t1;
+format(d, 2)
+NULL
+drop table t1;
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index e26f32e49e5..038d0c75f74 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -1972,29 +1972,23 @@ a
b
c
d
-create table bug12672 (
+create table t4 (
pk_col int auto_increment primary key, a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
) engine=innodb;
-insert into bug12672 (a1, a2, b, c, d, dummy) select * from t1;
-create index idx12672_0 on bug12672 (a1);
-create index idx12672_1 on bug12672 (a1,a2,b,c);
-create index idx12672_2 on bug12672 (a1,a2,b);
+insert into t4 (a1, a2, b, c, d, dummy) select * from t1;
+create index idx12672_0 on t4 (a1);
+create index idx12672_1 on t4 (a1,a2,b,c);
+create index idx12672_2 on t4 (a1,a2,b);
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status Table is already up to date
-explain select distinct a1 from bug12672 where pk_col not in (1,2,3,4);
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE bug12672 range PRIMARY PRIMARY 4 NULL # Using where; Using temporary
-select distinct a1 from bug12672 where pk_col not in (1,2,3,4);
+select distinct a1 from t4 where pk_col not in (1,2,3,4);
a1
a
b
c
d
-drop table bug12672;
-drop table t1;
-drop table t2;
-drop table t3;
+drop table t1,t2,t3,t4;
create table t1 (
a varchar(30), b varchar(30), primary key(a), key(b)
) engine=innodb;
diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result
index 969cb06e9fe..7f40dfa3a36 100644
--- a/mysql-test/r/heap.result
+++ b/mysql-test/r/heap.result
@@ -379,10 +379,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL v NULL NULL NULL 271 Using where
explain select count(*) from t1 where v between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL v NULL NULL NULL 271 Using where
+1 SIMPLE t1 ref v v 13 const 10 Using where
explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL v NULL NULL NULL 271 Using where
+1 SIMPLE t1 ref v v 13 const 10 Using where
alter table t1 add unique(v);
ERROR 23000: Duplicate entry '{ ' for key 1
select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a' order by length(concat('*',v,'*',c,'*',t,'*'));
@@ -602,10 +602,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range v v 13 NULL # Using where
explain select count(*) from t1 where v between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 13 NULL # Using where
+1 SIMPLE t1 ref v v 13 const # Using where
explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 13 NULL # Using where
+1 SIMPLE t1 ref v v 13 const # Using where
alter table t1 add unique(v);
ERROR 23000: Duplicate entry '{ ' for key 1
select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a' order by length(concat('*',v,'*',c,'*',t,'*'));
diff --git a/mysql-test/r/im_daemon_life_cycle.result b/mysql-test/r/im_daemon_life_cycle.result
new file mode 100644
index 00000000000..d0a76b450fe
--- /dev/null
+++ b/mysql-test/r/im_daemon_life_cycle.result
@@ -0,0 +1,7 @@
+SHOW INSTANCES;
+instance_name status
+mysqld1 online
+mysqld2 offline
+Killing the process...
+Sleeping...
+Success: the process was restarted.
diff --git a/mysql-test/r/im_life_cycle.result b/mysql-test/r/im_life_cycle.result
new file mode 100644
index 00000000000..810953e0578
--- /dev/null
+++ b/mysql-test/r/im_life_cycle.result
@@ -0,0 +1,64 @@
+SHOW INSTANCES;
+instance_name status
+mysqld1 online
+mysqld2 offline
+SHOW INSTANCE STATUS mysqld1;
+instance_name status version
+mysqld1 online VERSION
+SHOW INSTANCE STATUS mysqld2;
+instance_name status version
+mysqld2 offline VERSION
+START INSTANCE mysqld2;
+SHOW INSTANCES;
+instance_name status
+mysqld1 online
+mysqld2 online
+SHOW INSTANCE STATUS mysqld1;
+instance_name status version
+mysqld1 online VERSION
+SHOW INSTANCE STATUS mysqld2;
+instance_name status version
+mysqld2 online VERSION
+SHOW VARIABLES LIKE 'port';
+Variable_name Value
+port 9312
+STOP INSTANCE mysqld2;
+SHOW INSTANCES;
+instance_name status
+mysqld1 online
+mysqld2 offline
+SHOW INSTANCE STATUS mysqld1;
+instance_name status version
+mysqld1 online VERSION
+SHOW INSTANCE STATUS mysqld2;
+instance_name status version
+mysqld2 offline VERSION
+START INSTANCE mysqld3;
+ERROR HY000: Bad instance name. Check that the instance with such a name exists
+START INSTANCE mysqld1;
+ERROR HY000: The instance is already started
+STOP INSTANCE mysqld3;
+ERROR HY000: Bad instance name. Check that the instance with such a name exists
+SHOW INSTANCES;
+instance_name status
+mysqld1 online
+mysqld2 offline
+Killing the process...
+Sleeping...
+Success: the process was restarted.
+SHOW INSTANCES;
+instance_name status
+mysqld1 online
+mysqld2 offline
+START INSTANCE mysqld2;
+SHOW INSTANCES;
+instance_name status
+mysqld1 online
+mysqld2 online
+Killing the process...
+Sleeping...
+Success: the process was killed.
+SHOW INSTANCES;
+instance_name status
+mysqld1 online
+mysqld2 offline
diff --git a/mysql-test/r/im_options_set.result b/mysql-test/r/im_options_set.result
new file mode 100644
index 00000000000..0d2fa699fc7
--- /dev/null
+++ b/mysql-test/r/im_options_set.result
@@ -0,0 +1,20 @@
+server_id =1
+server_id =2
+SHOW VARIABLES LIKE 'server_id';
+Variable_name Value
+server_id 1
+SET mysqld1.server_id = 11;
+server_id =11
+server_id =2
+SHOW VARIABLES LIKE 'server_id';
+Variable_name Value
+server_id 1
+SET mysqld2.server_id = 12;
+server_id =11
+server_id =12
+FLUSH INSTANCES;
+server_id =11
+server_id =12
+SHOW VARIABLES LIKE 'server_id';
+Variable_name Value
+server_id 1
diff --git a/mysql-test/r/im_options_unset.result b/mysql-test/r/im_options_unset.result
new file mode 100644
index 00000000000..834152c35d2
--- /dev/null
+++ b/mysql-test/r/im_options_unset.result
@@ -0,0 +1,15 @@
+server_id =1
+server_id =2
+SHOW VARIABLES LIKE 'server_id';
+Variable_name Value
+server_id 1
+UNSET mysqld1.server_id;
+server_id =2
+SHOW VARIABLES LIKE 'server_id';
+Variable_name Value
+server_id 1
+UNSET mysqld2.server_id;
+FLUSH INSTANCES;
+SHOW VARIABLES LIKE 'server_id';
+Variable_name Value
+server_id 1
diff --git a/mysql-test/r/im_utils.result b/mysql-test/r/im_utils.result
new file mode 100644
index 00000000000..fbfaeaebcac
--- /dev/null
+++ b/mysql-test/r/im_utils.result
@@ -0,0 +1,91 @@
+SHOW INSTANCES;
+instance_name status
+mysqld1 online
+mysqld2 offline
+SHOW INSTANCE OPTIONS mysqld1;
+option_name value
+instance_name VALUE
+mysqld-path VALUE
+socket VALUE
+pid-file VALUE
+port VALUE
+datadir VALUE
+log VALUE
+log-error VALUE
+log-slow-queries VALUE
+language VALUE
+character-sets-dir VALUE
+basedir VALUE
+server_id VALUE
+skip-stack-trace VALUE
+skip-innodb VALUE
+skip-bdb VALUE
+skip-ndbcluster VALUE
+SHOW INSTANCE OPTIONS mysqld2;
+option_name value
+instance_name VALUE
+mysqld-path VALUE
+nonguarded VALUE
+socket VALUE
+pid-file VALUE
+port VALUE
+datadir VALUE
+log VALUE
+log-error VALUE
+log-slow-queries VALUE
+language VALUE
+character-sets-dir VALUE
+basedir VALUE
+server_id VALUE
+skip-stack-trace VALUE
+skip-innodb VALUE
+skip-bdb VALUE
+skip-ndbcluster VALUE
+START INSTANCE mysqld2;
+STOP INSTANCE mysqld2;
+SHOW mysqld1 LOG FILES;
+Logfile Path File size
+ERROR LOG PATH FILE_SIZE
+GENERAL LOG PATH FILE_SIZE
+SLOW LOG PATH FILE_SIZE
+SHOW mysqld2 LOG FILES;
+Logfile Path File size
+ERROR LOG PATH FILE_SIZE
+GENERAL LOG PATH FILE_SIZE
+SLOW LOG PATH FILE_SIZE
+SHOW mysqld1 LOG ERROR 10;
+Log
+LOG_DATA
+SHOW mysqld1 LOG SLOW 10;
+Log
+LOG_DATA
+SHOW mysqld1 LOG GENERAL 10;
+Log
+LOG_DATA
+SHOW mysqld1 LOG ERROR 10, 2;
+Log
+LOG_DATA
+SHOW mysqld1 LOG SLOW 10, 2;
+Log
+LOG_DATA
+SHOW mysqld1 LOG GENERAL 10, 2;
+Log
+LOG_DATA
+SHOW mysqld2 LOG ERROR 10;
+Log
+LOG_DATA
+SHOW mysqld2 LOG SLOW 10;
+Log
+LOG_DATA
+SHOW mysqld2 LOG GENERAL 10;
+Log
+LOG_DATA
+SHOW mysqld2 LOG ERROR 10, 2;
+Log
+LOG_DATA
+SHOW mysqld2 LOG SLOW 10, 2;
+Log
+LOG_DATA
+SHOW mysqld2 LOG GENERAL 10, 2;
+Log
+LOG_DATA
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index d506aa69488..0d53180b6d6 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -1,4 +1,5 @@
-DROP TABLE IF EXISTS t0,t1,t2,t3,t5;
+DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5;
+DROP VIEW IF EXISTS v1;
show variables where variable_name like "skip_show_database";
Variable_name Value
skip_show_database OFF
@@ -361,11 +362,11 @@ show keys from v4;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
select * from information_schema.views where TABLE_NAME like "v%";
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE
-NULL test v0 select sql_no_cache `schemata`.`SCHEMA_NAME` AS `c` from `information_schema`.`schemata` NONE NO root@localhos DEFINER
-NULL test v1 select sql_no_cache `tables`.`TABLE_NAME` AS `c` from `information_schema`.`tables` where (`tables`.`TABLE_NAME` = _utf8'v1') NONE NO root@localhos DEFINER
-NULL test v2 select sql_no_cache `columns`.`COLUMN_NAME` AS `c` from `information_schema`.`columns` where (`columns`.`TABLE_NAME` = _utf8'v2') NONE NO root@localhos DEFINER
-NULL test v3 select sql_no_cache `character_sets`.`CHARACTER_SET_NAME` AS `c` from `information_schema`.`character_sets` where (`character_sets`.`CHARACTER_SET_NAME` like _utf8'latin1%') NONE NO root@localhos DEFINER
-NULL test v4 select sql_no_cache `collations`.`COLLATION_NAME` AS `c` from `information_schema`.`collations` where (`collations`.`COLLATION_NAME` like _utf8'latin1%') NONE NO root@localhos DEFINER
+NULL test v0 select sql_no_cache `schemata`.`SCHEMA_NAME` AS `c` from `information_schema`.`schemata` NONE NO root@localhost DEFINER
+NULL test v1 select sql_no_cache `tables`.`TABLE_NAME` AS `c` from `information_schema`.`tables` where (`tables`.`TABLE_NAME` = _utf8'v1') NONE NO root@localhost DEFINER
+NULL test v2 select sql_no_cache `columns`.`COLUMN_NAME` AS `c` from `information_schema`.`columns` where (`columns`.`TABLE_NAME` = _utf8'v2') NONE NO root@localhost DEFINER
+NULL test v3 select sql_no_cache `character_sets`.`CHARACTER_SET_NAME` AS `c` from `information_schema`.`character_sets` where (`character_sets`.`CHARACTER_SET_NAME` like _utf8'latin1%') NONE NO root@localhost DEFINER
+NULL test v4 select sql_no_cache `collations`.`COLLATION_NAME` AS `c` from `information_schema`.`collations` where (`collations`.`COLLATION_NAME` like _utf8'latin1%') NONE NO root@localhost DEFINER
drop view v0, v1, v2, v3, v4;
create table t1 (a int);
grant select,update,insert on t1 to mysqltest_1@localhost;
@@ -456,9 +457,9 @@ create view v2 (c) as select a from t1 WITH LOCAL CHECK OPTION;
create view v3 (c) as select a from t1 WITH CASCADED CHECK OPTION;
select * from information_schema.views;
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE
-NULL test v1 select `test`.`t1`.`a` AS `c` from `test`.`t1` CASCADED YES root@localhos DEFINER
-NULL test v2 select `test`.`t1`.`a` AS `c` from `test`.`t1` LOCAL YES root@localhos DEFINER
-NULL test v3 select `test`.`t1`.`a` AS `c` from `test`.`t1` CASCADED YES root@localhos DEFINER
+NULL test v1 select `test`.`t1`.`a` AS `c` from `test`.`t1` CASCADED YES root@localhost DEFINER
+NULL test v2 select `test`.`t1`.`a` AS `c` from `test`.`t1` LOCAL YES root@localhost DEFINER
+NULL test v3 select `test`.`t1`.`a` AS `c` from `test`.`t1` CASCADED YES root@localhost DEFINER
grant select (a) on test.t1 to joe@localhost with grant option;
select * from INFORMATION_SCHEMA.COLUMN_PRIVILEGES;
GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE
@@ -638,8 +639,8 @@ use test;
create function sub1(i int) returns int
return i+1;
create table t1(f1 int);
-create view t2 (c) as select f1 from t1;
-create view t3 (c) as select sub1(1);
+create view v2 (c) as select f1 from t1;
+create view v3 (c) as select sub1(1);
create table t4(f1 int, KEY f1_key (f1));
drop table t1;
drop function sub1;
@@ -647,29 +648,29 @@ select table_name from information_schema.views
where table_schema='test';
table_name
Warnings:
-Warning 1356 View 'test.t2' references invalid table(s) or column(s) or function(s)
-Warning 1356 View 'test.t3' references invalid table(s) or column(s) or function(s)
+Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s)
+Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s)
select table_name from information_schema.views
where table_schema='test';
table_name
Warnings:
-Warning 1356 View 'test.t2' references invalid table(s) or column(s) or function(s)
-Warning 1356 View 'test.t3' references invalid table(s) or column(s) or function(s)
+Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s)
+Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s)
select column_name from information_schema.columns
where table_schema='test';
column_name
f1
Warnings:
-Warning 1356 View 'test.t2' references invalid table(s) or column(s) or function(s)
-Warning 1356 View 'test.t3' references invalid table(s) or column(s) or function(s)
+Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s)
+Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s)
select index_name from information_schema.statistics where table_schema='test';
index_name
f1_key
select constraint_name from information_schema.table_constraints
where table_schema='test';
constraint_name
-drop view t2;
-drop view t3;
+drop view v2;
+drop view v3;
drop table t4;
select * from information_schema.table_names;
ERROR 42S02: Unknown table 'table_names' in information_schema
diff --git a/mysql-test/r/information_schema_inno.result b/mysql-test/r/information_schema_inno.result
index 9dd92baf62f..fb6584673f6 100644
--- a/mysql-test/r/information_schema_inno.result
+++ b/mysql-test/r/information_schema_inno.result
@@ -1,4 +1,4 @@
-DROP TABLE IF EXISTS t1,t2;
+DROP TABLE IF EXISTS t1,t2,t3;
CREATE TABLE t1 (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB;
CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id, id),
FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE CASCADE,
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 559e88aad46..a66259ff5f4 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1378,9 +1378,9 @@ insert into `t2`values ( 1 ) ;
create table `t3` (`id` int( 11 ) not null default '0',key `id` ( `id` ) ,constraint `t2_id_fk` foreign key ( `id` ) references `t2` (`id` )) engine = innodb;
insert into `t3`values ( 1 ) ;
delete t3,t2,t1 from t1,t2,t3 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
ERROR 42S22: Unknown column 't1.id' in 'where clause'
drop table t3,t2,t1;
@@ -1392,7 +1392,7 @@ foreign key(pid) references t1(id) on delete cascade) engine=innodb;
insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),
(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);
delete from t1 where id=0;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `t1` (`id`) ON DELETE CASCADE)
delete from t1 where id=15;
delete from t1 where id=0;
drop table t1;
@@ -1730,6 +1730,15 @@ explain select * from t1 order by a,b,c,d;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using filesort
drop table t1;
+create table t1 (a char(1), b char(1), key(a, b)) engine=innodb;
+insert into t1 values ('8', '6'), ('4', '7');
+select min(a) from t1;
+min(a)
+4
+select min(b) from t1 where a='8';
+min(b)
+6
+drop table t1;
create table t1 (x bigint unsigned not null primary key) engine=innodb;
insert into t1(x) values (0xfffffffffffffff0),(0xfffffffffffffff1);
select * from t1;
@@ -1776,7 +1785,7 @@ Variable_name Value
Innodb_rows_deleted 2070
show status like "Innodb_rows_inserted";
Variable_name Value
-Innodb_rows_inserted 31725
+Innodb_rows_inserted 31727
show status like "Innodb_rows_updated";
Variable_name Value
Innodb_rows_updated 29530
@@ -1988,10 +1997,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range v v 13 NULL # Using where; Using index
explain select count(*) from t1 where v between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 13 NULL # Using where; Using index
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 13 NULL # Using where; Using index
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
alter table t1 add unique(v);
ERROR 23000: Duplicate entry '{ ' for key 1
alter table t1 add key(v);
@@ -2179,10 +2188,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range v v 303 NULL # Using where; Using index
explain select count(*) from t1 where v between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 303 NULL # Using where; Using index
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 303 NULL # Using where; Using index
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 303 const # Using where
@@ -2259,10 +2268,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range v v 33 NULL # Using where
explain select count(*) from t1 where v between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 33 NULL # Using where
+1 SIMPLE t1 ref v v 33 const # Using where
explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 33 NULL # Using where
+1 SIMPLE t1 ref v v 33 const # Using where
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 33 const # Using where
@@ -2550,3 +2559,107 @@ FOREIGN KEY (b) REFERENCES test.t1(id)
) ENGINE=InnoDB;
Got one of the listed errors
DROP TABLE t1;
+create table t1 (col1 varchar(2000), index (col1(767)))
+character set = latin1 engine = innodb;
+create table t2 (col1 char(255), index (col1))
+character set = latin1 engine = innodb;
+create table t3 (col1 binary(255), index (col1))
+character set = latin1 engine = innodb;
+create table t4 (col1 varchar(767), index (col1))
+character set = latin1 engine = innodb;
+create table t5 (col1 varchar(767) primary key)
+character set = latin1 engine = innodb;
+create table t6 (col1 varbinary(767) primary key)
+character set = latin1 engine = innodb;
+create table t7 (col1 text, index(col1(767)))
+character set = latin1 engine = innodb;
+create table t8 (col1 blob, index(col1(767)))
+character set = latin1 engine = innodb;
+create table t9 (col1 varchar(512), col2 varchar(512), index(col1, col2))
+character set = latin1 engine = innodb;
+drop table t1, t2, t3, t4, t5, t6, t7, t8, t9;
+create table t1 (col1 varchar(768), index (col1))
+character set = latin1 engine = innodb;
+ERROR HY000: Can't create table './test/t1.frm' (errno: 139)
+create table t2 (col1 varchar(768) primary key)
+character set = latin1 engine = innodb;
+ERROR HY000: Can't create table './test/t2.frm' (errno: 139)
+create table t3 (col1 varbinary(768) primary key)
+character set = latin1 engine = innodb;
+ERROR HY000: Can't create table './test/t3.frm' (errno: 139)
+create table t4 (col1 text, index(col1(768)))
+character set = latin1 engine = innodb;
+ERROR HY000: Can't create table './test/t4.frm' (errno: 139)
+create table t5 (col1 blob, index(col1(768)))
+character set = latin1 engine = innodb;
+ERROR HY000: Can't create table './test/t5.frm' (errno: 139)
+CREATE TABLE t1
+(
+id INT PRIMARY KEY
+) ENGINE=InnoDB;
+CREATE TABLE t2
+(
+v INT,
+CONSTRAINT c1 FOREIGN KEY (v) REFERENCES t1(id)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(2);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES(1);
+DELETE FROM t1 WHERE id = 1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+DROP TABLE t1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+SET FOREIGN_KEY_CHECKS=0;
+DROP TABLE t1;
+SET FOREIGN_KEY_CHECKS=1;
+INSERT INTO t2 VALUES(3);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+DROP TABLE t2;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
+set autocommit=0;
+checksum table t1;
+Table Checksum
+test.t1 1531596814
+insert into t1 values(3);
+checksum table t1;
+Table Checksum
+test.t1 1531596814
+commit;
+checksum table t1;
+Table Checksum
+test.t1 2050879373
+commit;
+drop table t1;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
+set autocommit=1;
+checksum table t1;
+Table Checksum
+test.t1 1531596814
+set autocommit=1;
+insert into t1 values(3);
+checksum table t1;
+Table Checksum
+test.t1 2050879373
+drop table t1;
+create table t1 (col1 integer primary key, col2 integer) engine=innodb;
+insert t1 values (1,100);
+create function f1 () returns integer begin
+declare var1 int;
+select col2 into var1 from t1 where col1=1 for update;
+return var1;
+end|
+start transaction;
+select f1();
+f1()
+100
+ update t1 set col2=0 where col1=1;
+select * from t1;
+col1 col2
+1 100
+rollback;
+rollback;
+drop table t1;
+drop function f1;
diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result
index f9a25898a6f..9d514be76e8 100644
--- a/mysql-test/r/join_nested.result
+++ b/mysql-test/r/join_nested.result
@@ -1375,3 +1375,31 @@ groupid price
6 9900
DROP VIEW v1,v2;
DROP TABLE t1,t2,t3,t4;
+CREATE TABLE t1(a int);
+CREATE TABLE t2(b int);
+CREATE TABLE t3(c int, d int);
+CREATE TABLE t4(d int);
+CREATE TABLE t5(e int, f int);
+CREATE TABLE t6(f int);
+CREATE VIEW v1 AS
+SELECT e FROM t5 JOIN t6 ON t5.e=t6.f;
+CREATE VIEW v2 AS
+SELECT e FROM t5 NATURAL JOIN t6;
+SELECT t1.a FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c JOIN t4 USING(d);
+a
+SELECT t1.x FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c JOIN t4 USING(d);
+ERROR 42S22: Unknown column 't1.x' in 'field list'
+SELECT t1.a FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c NATURAL JOIN t4;
+a
+SELECT t1.x FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c NATURAL JOIN t4;
+ERROR 42S22: Unknown column 't1.x' in 'field list'
+SELECT v1.e FROM v1 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
+e
+SELECT v1.x FROM v1 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
+ERROR 42S22: Unknown column 'v1.x' in 'field list'
+SELECT v2.e FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
+e
+SELECT v2.x FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
+ERROR 42S22: Unknown column 'v2.x' in 'field list'
+DROP VIEW v1, v2;
+DROP TABLE t1, t2, t3, t4, t5, t6;
diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result
index d76fff372f5..f9d47e3533c 100644
--- a/mysql-test/r/loaddata.result
+++ b/mysql-test/r/loaddata.result
@@ -66,6 +66,17 @@ a b
3 row 3
0
drop table t1;
+SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE=NO_AUTO_VALUE_ON_ZERO;
+create table t1(id integer not null auto_increment primary key);
+insert into t1 values(0);
+select * from t1;
+id
+0
+select * from t1;
+id
+0
+SET @@SQL_MODE=@OLD_SQL_MODE;
+drop table t1;
create table t1 (a int default 100, b int, c varchar(60));
load data infile '../../std_data/rpl_loaddata.dat' into table t1 (a, @b) set b=@b+10, c=concat("b=",@b);
select * from t1;
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index d4e19201173..e028e58acf5 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -653,6 +653,32 @@ ERROR HY000: You can't specify target table 't2' for update in FROM clause
create table t3 engine=merge union=(t1, t2) select (select max(a) from t2);
ERROR HY000: You can't specify target table 't2' for update in FROM clause
drop table t1, t2;
+create table t1 (
+a double(14,4),
+b varchar(10),
+index (a,b)
+) engine=merge union=(t2,t3);
+create table t2 (
+a double(14,4),
+b varchar(10),
+index (a,b)
+) engine=myisam;
+create table t3 (
+a double(14,4),
+b varchar(10),
+index (a,b)
+) engine=myisam;
+insert into t2 values ( null, '');
+insert into t2 values ( 9999999999.999, '');
+insert into t3 select * from t2;
+select min(a), max(a) from t1;
+min(a) max(a)
+9999999999.9990 9999999999.9990
+flush tables;
+select min(a), max(a) from t1;
+min(a) max(a)
+9999999999.9990 9999999999.9990
+drop table t1, t2, t3;
create table t1 (a int,b int,c int, index (a,b,c));
create table t2 (a int,b int,c int, index (a,b,c));
create table t3 (a int,b int,c int, index (a,b,c))
diff --git a/mysql-test/r/metadata.result b/mysql-test/r/metadata.result
index 50b0b6ae294..0a170e16188 100644
--- a/mysql-test/r/metadata.result
+++ b/mysql-test/r/metadata.result
@@ -2,7 +2,7 @@ drop table if exists t1,t2;
select 1, 1.0, -1, "hello", NULL;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def 1 8 1 1 N 32897 0 63
-def 1.0 246 4 3 N 129 1 63
+def 1.0 246 3 3 N 161 1 63
def -1 8 2 2 N 32897 0 63
def hello 253 5 5 N 1 31 8
def NULL 6 0 0 Y 32896 0 63
diff --git a/mysql-test/r/multi_statement.result b/mysql-test/r/multi_statement.result
index 3a8d86bf349..ff19cbdd698 100644
--- a/mysql-test/r/multi_statement.result
+++ b/mysql-test/r/multi_statement.result
@@ -1,3 +1,4 @@
+DROP TABLE IF EXISTS t1;
select 1;
1
1
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index ce215d6a7d8..f484a937b27 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -608,6 +608,67 @@ checksum table t2;
Table Checksum
test.t2 984116287
drop table t1, t2;
+show variables like 'myisam_stats_method';
+Variable_name Value
+myisam_stats_method nulls_unequal
+create table t1 (a int, key(a));
+insert into t1 values (0),(1),(2),(3),(4);
+insert into t1 select NULL from t1;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 a 1 a A 10 NULL NULL YES BTREE
+insert into t1 values (11);
+delete from t1 where a=11;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 a 1 a A 10 NULL NULL YES BTREE
+set myisam_stats_method=nulls_equal;
+show variables like 'myisam_stats_method';
+Variable_name Value
+myisam_stats_method nulls_equal
+insert into t1 values (11);
+delete from t1 where a=11;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 a 1 a A 5 NULL NULL YES BTREE
+insert into t1 values (11);
+delete from t1 where a=11;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 a 1 a A 5 NULL NULL YES BTREE
+set myisam_stats_method=DEFAULT;
+show variables like 'myisam_stats_method';
+Variable_name Value
+myisam_stats_method nulls_unequal
+insert into t1 values (11);
+delete from t1 where a=11;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 a 1 a A 10 NULL NULL YES BTREE
+insert into t1 values (11);
+delete from t1 where a=11;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 a 1 a A 10 NULL NULL YES BTREE
+drop table t1;
set storage_engine=MyISAM;
drop table if exists t1,t2,t3;
--- Testing varchar ---
@@ -741,10 +802,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range v v 13 NULL # Using where; Using index
explain select count(*) from t1 where v between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 13 NULL # Using where; Using index
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 13 NULL # Using where; Using index
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
alter table t1 add unique(v);
ERROR 23000: Duplicate entry '{ ' for key 1
alter table t1 add key(v);
@@ -932,10 +993,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range v v 303 NULL # Using where; Using index
explain select count(*) from t1 where v between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 303 NULL # Using where; Using index
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 303 NULL # Using where; Using index
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 303 const # Using where
@@ -1012,10 +1073,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range v v 33 NULL # Using where
explain select count(*) from t1 where v between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 33 NULL # Using where
+1 SIMPLE t1 ref v v 33 const # Using where
explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range v v 33 NULL # Using where
+1 SIMPLE t1 ref v v 33 const # Using where
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 33 const # Using where
diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
index 8765e65f11b..cab3d924dd2 100644
--- a/mysql-test/r/mysqlbinlog.result
+++ b/mysql-test/r/mysqlbinlog.result
@@ -39,7 +39,8 @@ SET TIMESTAMP=1000000000;
load data LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/SQL_LOAD_MB-3-0' INTO table t1;
SET TIMESTAMP=1000000000;
load data LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/SQL_LOAD_MB-4-0' INTO table t1;
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- Broken LOAD DATA --
@@ -51,7 +52,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values ("Alas");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- --database --
@@ -59,7 +61,8 @@ ROLLBACK;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
ROLLBACK;
SET INSERT_ID=1;
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- --position --
@@ -71,7 +74,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values ("Alas");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- Remote --
@@ -101,7 +105,8 @@ SET TIMESTAMP=1000000000;
load data LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/SQL_LOAD_MB-3-2' INTO table t1;
SET TIMESTAMP=1000000000;
load data LOCAL INFILE 'MYSQL_TEST_DIR/var/tmp/SQL_LOAD_MB-4-2' INTO table t1;
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- Broken LOAD DATA --
@@ -113,7 +118,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values ("Alas");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- --database --
@@ -121,7 +127,8 @@ ROLLBACK;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
ROLLBACK;
SET INSERT_ID=1;
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- --position --
@@ -133,7 +140,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values ("Alas");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- reading stdin --
@@ -145,7 +153,8 @@ SET TIMESTAMP=1108844556;
BEGIN;
SET TIMESTAMP=1108844555;
insert t1 values (1);
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
@@ -154,6 +163,7 @@ SET TIMESTAMP=1108844556;
BEGIN;
SET TIMESTAMP=1108844555;
insert t1 values (1);
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
drop table t1, t2;
diff --git a/mysql-test/r/mysqlbinlog2.result b/mysql-test/r/mysqlbinlog2.result
index 9899fa54301..eb5fb4a87f8 100644
--- a/mysql-test/r/mysqlbinlog2.result
+++ b/mysql-test/r/mysqlbinlog2.result
@@ -39,7 +39,8 @@ insert into t1 values(null, "d");
SET INSERT_ID=5;
SET TIMESTAMP=1579609946;
insert into t1 values(null, "e");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- offset --
@@ -65,7 +66,8 @@ insert into t1 values(null, "d");
SET INSERT_ID=5;
SET TIMESTAMP=1579609946;
insert into t1 values(null, "e");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- start-position --
@@ -81,7 +83,8 @@ insert into t1 values(null, "d");
SET INSERT_ID=5;
SET TIMESTAMP=1579609946;
insert into t1 values(null, "e");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- stop-position --
@@ -103,7 +106,8 @@ insert into t1 values(null, "b");
SET INSERT_ID=3;
SET TIMESTAMP=1579609944;
insert into t1 values(null, "c");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- start-datetime --
@@ -123,7 +127,8 @@ insert into t1 values(null, "d");
SET INSERT_ID=5;
SET TIMESTAMP=1579609946;
insert into t1 values(null, "e");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- stop-datetime --
@@ -142,7 +147,8 @@ insert into t1 values(null, "a");
SET INSERT_ID=2;
SET TIMESTAMP=1579609942;
insert into t1 values(null, "b");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- Local with 2 binlogs on command line --
@@ -177,7 +183,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values(null, "f");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- offset --
@@ -210,7 +217,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values(null, "f");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- start-position --
@@ -233,7 +241,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values(null, "f");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- stop-position --
@@ -262,7 +271,8 @@ SET INSERT_ID=5;
SET TIMESTAMP=1579609946;
insert into t1 values(null, "e");
SET INSERT_ID=6;
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- start-datetime --
@@ -289,7 +299,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values(null, "f");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- stop-datetime --
@@ -308,7 +319,8 @@ insert into t1 values(null, "a");
SET INSERT_ID=2;
SET TIMESTAMP=1579609942;
insert into t1 values(null, "b");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- Remote --
@@ -336,7 +348,8 @@ insert into t1 values(null, "d");
SET INSERT_ID=5;
SET TIMESTAMP=1579609946;
insert into t1 values(null, "e");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- offset --
@@ -362,7 +375,8 @@ insert into t1 values(null, "d");
SET INSERT_ID=5;
SET TIMESTAMP=1579609946;
insert into t1 values(null, "e");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- start-position --
@@ -378,7 +392,8 @@ insert into t1 values(null, "d");
SET INSERT_ID=5;
SET TIMESTAMP=1579609946;
insert into t1 values(null, "e");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- stop-position --
@@ -400,7 +415,8 @@ insert into t1 values(null, "b");
SET INSERT_ID=3;
SET TIMESTAMP=1579609944;
insert into t1 values(null, "c");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- start-datetime --
@@ -420,7 +436,8 @@ insert into t1 values(null, "d");
SET INSERT_ID=5;
SET TIMESTAMP=1579609946;
insert into t1 values(null, "e");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- stop-datetime --
@@ -439,7 +456,8 @@ insert into t1 values(null, "a");
SET INSERT_ID=2;
SET TIMESTAMP=1579609942;
insert into t1 values(null, "b");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- Remote with 2 binlogs on command line --
@@ -474,7 +492,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values(null, "f");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- offset --
@@ -507,7 +526,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values(null, "f");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- start-position --
@@ -530,7 +550,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values(null, "f");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- stop-position --
@@ -559,7 +580,8 @@ SET INSERT_ID=5;
SET TIMESTAMP=1579609946;
insert into t1 values(null, "e");
SET INSERT_ID=6;
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- start-datetime --
@@ -586,7 +608,8 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values(null, "f");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- stop-datetime --
@@ -605,7 +628,8 @@ insert into t1 values(null, "a");
SET INSERT_ID=2;
SET TIMESTAMP=1579609942;
insert into t1 values(null, "b");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- to-last-log --
@@ -636,7 +660,8 @@ insert into t1 values(null, "e");
SET INSERT_ID=6;
SET TIMESTAMP=1579609943;
insert into t1 values(null, "f");
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- end of test --
diff --git a/mysql-test/r/mysqldump-max.result b/mysql-test/r/mysqldump-max.result
new file mode 100644
index 00000000000..699552bd514
--- /dev/null
+++ b/mysql-test/r/mysqldump-max.result
@@ -0,0 +1,266 @@
+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'
+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";
+create table t4 (id int(8), name varchar(32)) ENGINE="HEAP";
+create table t5 (id int(8), name varchar(32)) ENGINE="ARCHIVE";
+create table t6 (id int(8), name varchar(32)) ENGINE="InnoDB";
+insert into t1 values (1, 'first value');
+insert into t1 values (2, 'first value');
+insert into t1 values (3, 'first value');
+insert into t1 values (4, 'first value');
+insert into t1 values (5, 'first value');
+insert into t2 values (1, 'first value');
+insert into t2 values (2, 'first value');
+insert into t2 values (3, 'first value');
+insert into t2 values (4, 'first value');
+insert into t2 values (5, 'first value');
+insert into t3 values (1, 'first value');
+insert into t3 values (2, 'first value');
+insert into t3 values (3, 'first value');
+insert into t3 values (4, 'first value');
+insert into t3 values (5, 'first value');
+insert into t4 values (1, 'first value');
+insert into t4 values (2, 'first value');
+insert into t4 values (3, 'first value');
+insert into t4 values (4, 'first value');
+insert into t4 values (5, 'first value');
+insert into t5 values (1, 'first value');
+insert into t5 values (2, 'first value');
+insert into t5 values (3, 'first value');
+insert into t5 values (4, 'first value');
+insert into t5 values (5, 'first value');
+insert into t6 values (1, 'first value');
+insert into t6 values (2, 'first value');
+insert into t6 values (3, 'first value');
+insert into t6 values (4, 'first value');
+insert into t6 values (5, 'first value');
+select * from t1;
+id name
+1 first value
+2 first value
+3 first value
+4 first value
+5 first value
+select * from t2;
+id name
+1 first value
+2 first value
+3 first value
+4 first value
+5 first value
+select * from t3;
+id name
+1 first value
+2 first value
+3 first value
+4 first value
+5 first value
+select * from t4;
+id name
+1 first value
+2 first value
+3 first value
+4 first value
+5 first value
+select * from t5;
+id name
+1 first value
+2 first value
+3 first value
+4 first value
+5 first value
+select * from t6;
+id name
+1 first value
+2 first value
+3 first value
+4 first value
+5 first value
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET latin1 */;
+
+USE `test`;
+DROP TABLE IF EXISTS `t1`;
+CREATE TABLE `t1` (
+ `id` int(8) default NULL,
+ `name` varchar(32) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+
+/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
+INSERT DELAYED IGNORE INTO `t1` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
+/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
+DROP TABLE IF EXISTS `t2`;
+CREATE TABLE `t2` (
+ `id` int(8) default NULL,
+ `name` varchar(32) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+
+/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
+INSERT DELAYED IGNORE INTO `t2` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
+/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
+DROP TABLE IF EXISTS `t3`;
+CREATE TABLE `t3` (
+ `id` int(8) default NULL,
+ `name` varchar(32) default NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+
+
+/*!40000 ALTER TABLE `t3` DISABLE KEYS */;
+INSERT DELAYED IGNORE INTO `t3` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
+/*!40000 ALTER TABLE `t3` ENABLE KEYS */;
+DROP TABLE IF EXISTS `t4`;
+CREATE TABLE `t4` (
+ `id` int(8) default NULL,
+ `name` varchar(32) default NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+
+
+/*!40000 ALTER TABLE `t4` DISABLE KEYS */;
+INSERT DELAYED IGNORE INTO `t4` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
+/*!40000 ALTER TABLE `t4` ENABLE KEYS */;
+DROP TABLE IF EXISTS `t5`;
+CREATE TABLE `t5` (
+ `id` int(8) default NULL,
+ `name` varchar(32) default NULL
+) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
+
+
+/*!40000 ALTER TABLE `t5` DISABLE KEYS */;
+INSERT DELAYED IGNORE INTO `t5` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
+/*!40000 ALTER TABLE `t5` ENABLE KEYS */;
+DROP TABLE IF EXISTS `t6`;
+CREATE TABLE `t6` (
+ `id` int(8) default NULL,
+ `name` varchar(32) default NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+
+/*!40000 ALTER TABLE `t6` DISABLE KEYS */;
+INSERT IGNORE INTO `t6` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
+/*!40000 ALTER TABLE `t6` ENABLE KEYS */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET latin1 */;
+
+USE `test`;
+DROP TABLE IF EXISTS `t1`;
+CREATE TABLE `t1` (
+ `id` int(8) default NULL,
+ `name` varchar(32) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+
+/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
+INSERT DELAYED INTO `t1` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
+/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
+DROP TABLE IF EXISTS `t2`;
+CREATE TABLE `t2` (
+ `id` int(8) default NULL,
+ `name` varchar(32) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+
+/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
+INSERT DELAYED INTO `t2` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
+/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
+DROP TABLE IF EXISTS `t3`;
+CREATE TABLE `t3` (
+ `id` int(8) default NULL,
+ `name` varchar(32) default NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+
+
+/*!40000 ALTER TABLE `t3` DISABLE KEYS */;
+INSERT DELAYED INTO `t3` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
+/*!40000 ALTER TABLE `t3` ENABLE KEYS */;
+DROP TABLE IF EXISTS `t4`;
+CREATE TABLE `t4` (
+ `id` int(8) default NULL,
+ `name` varchar(32) default NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+
+
+/*!40000 ALTER TABLE `t4` DISABLE KEYS */;
+INSERT DELAYED INTO `t4` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
+/*!40000 ALTER TABLE `t4` ENABLE KEYS */;
+DROP TABLE IF EXISTS `t5`;
+CREATE TABLE `t5` (
+ `id` int(8) default NULL,
+ `name` varchar(32) default NULL
+) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
+
+
+/*!40000 ALTER TABLE `t5` DISABLE KEYS */;
+INSERT DELAYED INTO `t5` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
+/*!40000 ALTER TABLE `t5` ENABLE KEYS */;
+DROP TABLE IF EXISTS `t6`;
+CREATE TABLE `t6` (
+ `id` int(8) default NULL,
+ `name` varchar(32) default NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+
+/*!40000 ALTER TABLE `t6` DISABLE KEYS */;
+INSERT INTO `t6` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
+/*!40000 ALTER TABLE `t6` ENABLE KEYS */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+drop table t1;
+drop table t2;
+drop table t3;
+drop table t4;
+drop table t5;
+drop table t6;
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 48e6ded689e..9bb669fd9b8 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -614,9 +614,7 @@ CREATE TABLE `t1` (
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
-LOCK TABLES `t1` WRITE;
-INSERT IGNORE INTO `t1` VALUES (1),(2),(3),(4),(5),(6);
-UNLOCK TABLES;
+INSERT DELAYED IGNORE INTO `t1` VALUES (1),(2),(3),(4),(5),(6);
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -1737,22 +1735,65 @@ create view v1 as
select * from v3 where b in (1, 2, 3, 4, 5, 6, 7);
create view v2 as
select v3.a from v3, v1 where v1.a=v3.a and v3.b=3 limit 1;
-drop view v1, v2, v3;
-drop table t1;
-show full tables;
-Tables_in_test Table_type
-t1 BASE TABLE
-v1 VIEW
-v2 VIEW
-v3 VIEW
-show create view v1;
-View Create View
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `v3`.`a` AS `a`,`v3`.`b` AS `b`,`v3`.`c` AS `c` from `v3` where (`v3`.`b` in (1,2,3,4,5,6,7))
-select * from v1;
-a b c
-1 2 one
-2 4 two
-3 6 three
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+DROP TABLE IF EXISTS `t1`;
+CREATE TABLE `t1` (
+ `a` int(11) default NULL,
+ `b` int(11) default NULL,
+ `c` varchar(30) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+
+/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
+LOCK TABLES `t1` WRITE;
+INSERT INTO `t1` VALUES (1,2,'one'),(2,4,'two'),(3,6,'three');
+UNLOCK TABLES;
+/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
+DROP TABLE IF EXISTS `v1`;
+/*!50001 DROP VIEW IF EXISTS `v1`*/;
+/*!50001 CREATE TABLE `v1` (
+ `a` int(11) default NULL,
+ `b` int(11) default NULL,
+ `c` varchar(30) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1*/;
+DROP TABLE IF EXISTS `v2`;
+/*!50001 DROP VIEW IF EXISTS `v2`*/;
+/*!50001 CREATE TABLE `v2` (
+ `a` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1*/;
+DROP TABLE IF EXISTS `v3`;
+/*!50001 DROP VIEW IF EXISTS `v3`*/;
+/*!50001 CREATE TABLE `v3` (
+ `a` int(11) default NULL,
+ `b` int(11) default NULL,
+ `c` varchar(30) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1*/;
+/*!50001 DROP TABLE IF EXISTS `v1`*/;
+/*!50001 DROP VIEW IF EXISTS `v1`*/;
+/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `v3`.`a` AS `a`,`v3`.`b` AS `b`,`v3`.`c` AS `c` from `v3` where (`v3`.`b` in (1,2,3,4,5,6,7))*/;
+/*!50001 DROP TABLE IF EXISTS `v2`*/;
+/*!50001 DROP VIEW IF EXISTS `v2`*/;
+/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `v3`.`a` AS `a` from (`v3` join `v1`) where ((`v1`.`a` = `v3`.`a`) and (`v3`.`b` = 3)) limit 1*/;
+/*!50001 DROP TABLE IF EXISTS `v3`*/;
+/*!50001 DROP VIEW IF EXISTS `v3`*/;
+/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b`,`t1`.`c` AS `c` from `t1`*/;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
drop view v1, v2, v3;
drop table t1;
CREATE TABLE t1 (a int, b bigint default NULL);
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index 36618140306..0ad6db8c57e 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -178,6 +178,7 @@ source database
echo message echo message
mysqltest: At line 1: Empty variable
+mysqltest: At line 1: command "false" failed
mysqltest: At line 1: Missing argument in exec
MySQL
"MySQL"
@@ -299,6 +300,7 @@ mysqltest: At line 1: First argument to dec must be a variable (start with $)
mysqltest: At line 1: End of line junk detected: "1000"
mysqltest: At line 1: Missing arguments to system, nothing to do!
mysqltest: At line 1: Missing arguments to system, nothing to do!
+mysqltest: At line 1: system command 'false' failed
test
test2
test3
@@ -342,6 +344,10 @@ 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"
+Output from mysqltest-x.inc
+Output from mysqltest-x.inc
+Output from mysqltest-x.inc
+mysqltest: Could not open ./non_existing_file.inc: errno = 2
failing_statement;
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 'failing_statement' at line 1
failing_statement;
diff --git a/mysql-test/r/ndb_alter_table.result b/mysql-test/r/ndb_alter_table.result
index 0d9837e76c4..e766a25b111 100644
--- a/mysql-test/r/ndb_alter_table.result
+++ b/mysql-test/r/ndb_alter_table.result
@@ -200,3 +200,119 @@ a
drop table t4;
show tables;
Tables_in_test
+create table t1 (
+ai bigint auto_increment,
+c001 int(11) not null,
+c002 int(11) not null,
+c003 int(11) not null,
+c004 int(11) not null,
+c005 int(11) not null,
+c006 int(11) not null,
+c007 int(11) not null,
+c008 int(11) not null,
+c009 int(11) not null,
+c010 int(11) not null,
+c011 int(11) not null,
+c012 int(11) not null,
+c013 int(11) not null,
+c014 int(11) not null,
+c015 int(11) not null,
+c016 int(11) not null,
+c017 int(11) not null,
+c018 int(11) not null,
+c019 int(11) not null,
+c020 int(11) not null,
+c021 int(11) not null,
+c022 int(11) not null,
+c023 int(11) not null,
+c024 int(11) not null,
+c025 int(11) not null,
+c026 int(11) not null,
+c027 int(11) not null,
+c028 int(11) not null,
+c029 int(11) not null,
+c030 int(11) not null,
+c031 int(11) not null,
+c032 int(11) not null,
+c033 int(11) not null,
+c034 int(11) not null,
+c035 int(11) not null,
+c036 int(11) not null,
+c037 int(11) not null,
+c038 int(11) not null,
+c039 int(11) not null,
+c040 int(11) not null,
+c041 int(11) not null,
+c042 int(11) not null,
+c043 int(11) not null,
+c044 int(11) not null,
+c045 int(11) not null,
+c046 int(11) not null,
+c047 int(11) not null,
+c048 int(11) not null,
+c049 int(11) not null,
+c050 int(11) not null,
+c051 int(11) not null,
+c052 int(11) not null,
+c053 int(11) not null,
+c054 int(11) not null,
+c055 int(11) not null,
+c056 int(11) not null,
+c057 int(11) not null,
+c058 int(11) not null,
+c059 int(11) not null,
+c060 int(11) not null,
+c061 int(11) not null,
+c062 int(11) not null,
+c063 int(11) not null,
+c064 int(11) not null,
+c065 int(11) not null,
+c066 int(11) not null,
+c067 int(11) not null,
+c068 int(11) not null,
+c069 int(11) not null,
+c070 int(11) not null,
+c071 int(11) not null,
+c072 int(11) not null,
+c073 int(11) not null,
+c074 int(11) not null,
+c075 int(11) not null,
+c076 int(11) not null,
+c077 int(11) not null,
+c078 int(11) not null,
+c079 int(11) not null,
+c080 int(11) not null,
+c081 int(11) not null,
+c082 int(11) not null,
+c083 int(11) not null,
+c084 int(11) not null,
+c085 int(11) not null,
+c086 int(11) not null,
+c087 int(11) not null,
+c088 int(11) not null,
+c089 int(11) not null,
+c090 int(11) not null,
+c091 int(11) not null,
+c092 int(11) not null,
+c093 int(11) not null,
+c094 int(11) not null,
+c095 int(11) not null,
+c096 int(11) not null,
+c097 int(11) not null,
+c098 int(11) not null,
+c099 int(11) not null,
+c100 int(11) not null,
+c101 int(11) not null,
+c102 int(11) not null,
+c103 int(11) not null,
+c104 int(11) not null,
+c105 int(11) not null,
+c106 int(11) not null,
+c107 int(11) not null,
+c108 int(11) not null,
+c109 int(11) not null,
+primary key (ai),
+unique key tx1 (c002, c003, c004, c005)) engine=ndb;
+create index tx2
+on t1 (c010, c011, c012, c013);
+drop table t1;
diff --git a/mysql-test/r/ndb_config.result b/mysql-test/r/ndb_config.result
index c2557f85c0b..629d37f1e5e 100644
--- a/mysql-test/r/ndb_config.result
+++ b/mysql-test/r/ndb_config.result
@@ -3,3 +3,5 @@ ndbd,1,localhost ndbd,2,localhost ndb_mgmd,3,localhost mysqld,4, mysqld,5, mysql
1 localhost 41943040 12582912
2 localhost 41943040 12582912
1 2
+ndbd,1,localhost ndbd,2,localhost ndb_mgmd,3,localhost mysqld,4, mysqld,5, mysqld,6, mysqld,7,
+ndbd,1,localhost,52428800,26214400 ndbd,2,localhost,52428800,36700160 ndbd,3,localhost,52428800,52428800 ndbd,4,localhost,52428800,52428800 ndb_mgmd,5,localhost,, mysqld,6,localhost,,
diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result
index 7fb1e1b4df4..d41d1b74ca7 100644
--- a/mysql-test/r/ps_1general.result
+++ b/mysql-test/r/ps_1general.result
@@ -323,22 +323,17 @@ execute stmt4;
Engine Support Comment
MyISAM YES/NO Default engine as of MySQL 3.23 with great performance
MEMORY YES/NO Hash based, stored in memory, useful for temporary tables
-HEAP YES/NO Alias for MEMORY
-MERGE YES/NO Collection of identical MyISAM tables
-MRG_MYISAM YES/NO Alias for MERGE
-ISAM YES/NO Obsolete storage engine, now replaced by MyISAM
-MRG_ISAM YES/NO Obsolete storage engine, now replaced by MERGE
InnoDB YES/NO Supports transactions, row-level locking, and foreign keys
-INNOBASE YES/NO Alias for INNODB
-BDB YES/NO Supports transactions and page-level locking
-BERKELEYDB YES/NO Alias for BDB
-NDBCLUSTER YES/NO Clustered, fault-tolerant, memory-based tables
-NDB YES/NO Alias for NDBCLUSTER
+BerkeleyDB YES/NO Supports transactions and page-level locking
+BLACKHOLE YES/NO /dev/null storage engine (anything you write to it disappears)
EXAMPLE YES/NO Example storage engine
ARCHIVE YES/NO Archive storage engine
CSV YES/NO CSV storage engine
+ndbcluster YES/NO Clustered, fault-tolerant, memory-based tables
FEDERATED YES/NO Federated MySQL storage engine
-BLACKHOLE YES/NO /dev/null storage engine (anything you write to it disappears)
+MRG_MYISAM YES/NO Collection of identical MyISAM tables
+binlog YES/NO This is a meta storage engine to represent the binlog in a transaction
+ISAM YES/NO Obsolete storage engine
drop table if exists t5;
prepare stmt1 from ' drop table if exists t5 ' ;
execute stmt1 ;
diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result
index 16ead200933..c839c8a65b9 100644
--- a/mysql-test/r/ps_2myisam.result
+++ b/mysql-test/r/ps_2myisam.result
@@ -1775,7 +1775,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) NOT NULL default '0.0',
+ `const02` decimal(2,1) unsigned NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1805,7 +1805,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 4 3 N 1 1 63
+def test t5 t5 const02 const02 246 3 3 N 33 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result
index 9ab5a79f755..81d6180e41f 100644
--- a/mysql-test/r/ps_3innodb.result
+++ b/mysql-test/r/ps_3innodb.result
@@ -1758,7 +1758,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) NOT NULL default '0.0',
+ `const02` decimal(2,1) unsigned NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1788,7 +1788,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 4 3 N 1 1 63
+def test t5 t5 const02 const02 246 3 3 N 33 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result
index 8336a5bf99b..931e6b7c86c 100644
--- a/mysql-test/r/ps_4heap.result
+++ b/mysql-test/r/ps_4heap.result
@@ -1759,7 +1759,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) NOT NULL default '0.0',
+ `const02` decimal(2,1) unsigned NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1789,7 +1789,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 4 3 N 1 1 63
+def test t5 t5 const02 const02 246 3 3 N 33 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result
index f341247a417..3b9244c251f 100644
--- a/mysql-test/r/ps_5merge.result
+++ b/mysql-test/r/ps_5merge.result
@@ -1695,7 +1695,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) NOT NULL default '0.0',
+ `const02` decimal(2,1) unsigned NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1725,7 +1725,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 4 3 N 1 1 63
+def test t5 t5 const02 const02 246 3 3 N 33 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
@@ -4707,7 +4707,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) NOT NULL default '0.0',
+ `const02` decimal(2,1) unsigned NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -4737,7 +4737,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 4 3 N 1 1 63
+def test t5 t5 const02 const02 246 3 3 N 33 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result
index fe4536827e6..643e12f7e2d 100644
--- a/mysql-test/r/ps_6bdb.result
+++ b/mysql-test/r/ps_6bdb.result
@@ -1758,7 +1758,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) NOT NULL default '0.0',
+ `const02` decimal(2,1) unsigned NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1788,7 +1788,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 4 3 N 1 1 63
+def test t5 t5 const02 const02 246 3 3 N 33 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result
index c4cb92bdc02..9fbe67f581b 100644
--- a/mysql-test/r/ps_7ndb.result
+++ b/mysql-test/r/ps_7ndb.result
@@ -1758,7 +1758,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) NOT NULL default '0.0',
+ `const02` decimal(2,1) unsigned NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1788,7 +1788,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 4 3 N 1 1 63
+def test t5 t5 const02 const02 246 3 3 N 33 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index f490c2e1383..69c150fc0b7 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1,4 +1,4 @@
-drop table if exists t1, t2;
+drop table if exists t1, t2, t3;
CREATE TABLE t1 (
event_date date DEFAULT '0000-00-00' NOT NULL,
type int(11) DEFAULT '0' NOT NULL,
@@ -768,3 +768,45 @@ SELECT * FROM t1;
a
2
DROP TABLE t1;
+create table t1 (a int, b int, primary key(a,b));
+create view v1 as select a, b from t1;
+INSERT INTO `t1` VALUES
+(0,0),(1,0),(2,0),(3,0),(4,0),(5,1),(6,1),(7,1),(8,1),(9,1),(10,2),(11,2),(12,2)
+,(13,2),(14,2),(15,3),(16,3),(17,3),(18,3),(19,3);
+explain select * from t1 where a in (3,4) and b in (1,2,3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
+explain select * from v1 where a in (3,4) and b in (1,2,3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
+explain select * from t1 where a between 3 and 4 and b between 1 and 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
+explain select * from v1 where a between 3 and 4 and b between 1 and 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
+drop view v1;
+drop table t1;
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a varchar(10), filler char(200), key(a)) charset=binary;
+insert into t1 values ('a','');
+insert into t1 values ('a ','');
+insert into t1 values ('a ', '');
+insert into t1 select concat('a', 1000 + A.a + 10 * (B.a + 10 * C.a)), ''
+ from t3 A, t3 B, t3 C;
+create table t2 (a varchar(10), filler char(200), key(a));
+insert into t2 select * from t1;
+explain select * from t1 where a between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 13 NULL # Using where
+explain select * from t1 where a = 'a' or a='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 13 NULL # Using where
+explain select * from t2 where a between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref a a 13 const # Using where
+explain select * from t2 where a = 'a' or a='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref a a 13 const # Using where
+drop table t1,t2,t3;
diff --git a/mysql-test/r/rpl_charset.result b/mysql-test/r/rpl_charset.result
index b27acc0972e..28f694a3933 100644
--- a/mysql-test/r/rpl_charset.result
+++ b/mysql-test/r/rpl_charset.result
@@ -246,7 +246,8 @@ CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255));
SET TIMESTAMP=1000000000;
SET @@session.character_set_client=7,@@session.collation_connection=51,@@session.collation_server=30;
INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ');
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
drop table t1;
create table `t1` (
diff --git a/mysql-test/r/rpl_multi_delete.result b/mysql-test/r/rpl_multi_delete.result
index e94a4e7947e..d2c68eee62e 100644
--- a/mysql-test/r/rpl_multi_delete.result
+++ b/mysql-test/r/rpl_multi_delete.result
@@ -19,4 +19,13 @@ a
select * from t2;
a
1
+delete from t1;
+delete from t2;
+insert into t1 values(1);
+insert into t2 values(1);
+DELETE t1.*, t2.* from t1, t2;
+select * from t1;
+a
+select * from t2;
+a
drop table t1,t2;
diff --git a/mysql-test/r/rpl_multi_delete2.result b/mysql-test/r/rpl_multi_delete2.result
index c6c088111fc..73db9f62eb4 100644
--- a/mysql-test/r/rpl_multi_delete2.result
+++ b/mysql-test/r/rpl_multi_delete2.result
@@ -4,6 +4,26 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+set sql_log_bin=0;
+create database mysqltest_from;
+set sql_log_bin=1;
+create database mysqltest_to;
+use mysqltest_from;
+drop table if exists a;
+CREATE TABLE a (i INT);
+INSERT INTO a VALUES(1);
+DELETE alias FROM a alias WHERE alias.i=1;
+SELECT * FROM a;
+i
+insert into a values(2),(3);
+delete a alias FROM a alias where alias.i=2;
+select * from a;
+i
+3
+use mysqltest_to;
+select * from a;
+i
+3
create table t1 (a int);
create table t2 (a int);
insert into t1 values (1);
@@ -15,7 +35,10 @@ select * from t2;
a
1
select * from t1;
-ERROR 42S02: Table 'test.t1' doesn't exist
+ERROR 42S02: Table 'mysqltest_to.t1' doesn't exist
select * from t2;
-ERROR 42S02: Table 'test.t2' doesn't exist
-drop table t1,t2;
+ERROR 42S02: Table 'mysqltest_to.t2' doesn't exist
+set sql_log_bin=0;
+drop database mysqltest_from;
+set sql_log_bin=1;
+drop database mysqltest_to;
diff --git a/mysql-test/r/rpl_multi_update.result b/mysql-test/r/rpl_multi_update.result
index 34f99746c7d..04cb1bc7460 100644
--- a/mysql-test/r/rpl_multi_update.result
+++ b/mysql-test/r/rpl_multi_update.result
@@ -24,3 +24,16 @@ a b
1 0
2 1
UPDATE t1, t2 SET t1.b = t2.b WHERE t1.a = t2.a;
+delete from t1;
+delete from t2;
+insert into t1 values(1,1);
+insert into t2 values(1,1);
+update t1 set a=2;
+UPDATE t1, t2 SET t1.a = t2.a;
+select * from t1;
+a b
+1 1
+select * from t2;
+a b
+1 1
+drop table t1, t2;
diff --git a/mysql-test/r/rpl_sp.result b/mysql-test/r/rpl_sp.result
index 394f93f2ea0..b1f564a0791 100644
--- a/mysql-test/r/rpl_sp.result
+++ b/mysql-test/r/rpl_sp.result
@@ -121,7 +121,7 @@ call foo4();
Got one of the listed errors
show warnings;
Level Code Message
-Error 1142 INSERT command denied to user 'zedjzlcsjhd'@'localhost' for table 't1'
+Error 1142 INSERT command denied to user 'zedjzlcsjhd'@'127.0.0.1' for table 't1'
Warning 1417 A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes
alter procedure foo4 sql security invoker;
call foo4();
diff --git a/mysql-test/r/rpl_timezone.result b/mysql-test/r/rpl_timezone.result
index 85637638f99..64d05aa787e 100644
--- a/mysql-test/r/rpl_timezone.result
+++ b/mysql-test/r/rpl_timezone.result
@@ -63,7 +63,8 @@ delete from t1;
SET TIMESTAMP=100000000;
SET @@session.time_zone='Europe/Moscow';
insert into t1 values ('20040101000000'), ('20040611093902');
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
delete from t1;
set time_zone='UTC';
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index d7de9b6509b..3e4f29d7a01 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -2620,6 +2620,15 @@ select found_rows();
found_rows()
1
DROP TABLE t1;
+create table t1(f1 int, f2 int);
+create table t2(f3 int);
+select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,1));
+f1
+select f1 from t1,t2 where f1=f2 and (f1,NULL) = ((1,1));
+f1
+select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,NULL));
+f1
+drop table t1,t2;
CREATE TABLE t1 ( city char(30) );
INSERT INTO t1 VALUES ('London');
INSERT INTO t1 VALUES ('Paris');
@@ -2943,3 +2952,112 @@ select * from t1 join t2 join t4 using (c);
c a b
1 1 1
drop table t1, t2, t3, t4;
+create table t1(x int, y int);
+create table t2(x int, y int);
+create table t3(x int, primary key(x));
+insert into t1 values (1, 1), (2, 1), (3, 1), (4, 3), (5, 6), (6, 6);
+insert into t2 values (1, 1), (2, 1), (3, 3), (4, 6), (5, 6);
+insert into t3 values (1), (2), (3), (4), (5);
+select t1.x, t3.x from t1, t2, t3 where t1.x = t2.x and t3.x >= t1.y and t3.x <= t2.y;
+x x
+1 1
+2 1
+3 1
+3 2
+3 3
+4 3
+4 4
+4 5
+drop table t1,t2,t3;
+create table t1 (id char(16) not null default '', primary key (id));
+insert into t1 values ('100'),('101'),('102');
+create table t2 (id char(16) default null);
+insert into t2 values (1);
+create view v1 as select t1.id from t1;
+create view v2 as select t2.id from t2;
+create view v3 as select (t1.id+2) as id from t1 natural left join t2;
+select t1.id from t1 left join v2 using (id);
+id
+100
+101
+102
+select t1.id from v2 right join t1 using (id);
+id
+100
+101
+102
+select t1.id from t1 left join v3 using (id);
+id
+100
+101
+102
+select * from t1 left join v2 using (id);
+id
+100
+101
+102
+select * from v2 right join t1 using (id);
+id
+100
+101
+102
+select * from t1 left join v3 using (id);
+id
+100
+101
+102
+select v1.id from v1 left join v2 using (id);
+id
+100
+101
+102
+select v1.id from v2 right join v1 using (id);
+id
+100
+101
+102
+select v1.id from v1 left join v3 using (id);
+id
+100
+101
+102
+select * from v1 left join v2 using (id);
+id
+100
+101
+102
+select * from v2 right join v1 using (id);
+id
+100
+101
+102
+select * from v1 left join v3 using (id);
+id
+100
+101
+102
+drop table t1, t2;
+drop view v1, v2, v3;
+create table a (
+id int(11) not null default '0'
+) engine=myisam default charset=latin1;
+insert into a values (123),(191),(192);
+create table b (
+id char(16) character set utf8 not null default ''
+) engine=myisam default charset=latin1;
+insert into b values ('58013'),('58014'),('58015'),('58016');
+create table c (
+a_id int(11) not null default '0',
+b_id char(16) character set utf8 default null
+) engine=myisam default charset=latin1;
+insert into c values
+(123,null),(123,null),(123,null),(123,null),(123,null),(123,'58013');
+select count(*)
+from a inner join (c left join b on b.id = c.b_id) on a.id = c.a_id;
+count(*)
+6
+select count(*)
+from a inner join (b right join c on b.id = c.b_id) on a.id = c.a_id;
+count(*)
+6
+drop table a, b, c;
diff --git a/mysql-test/r/skip_name_resolve.result b/mysql-test/r/skip_name_resolve.result
index d8d873699a5..a969c5c9ae0 100644
--- a/mysql-test/r/skip_name_resolve.result
+++ b/mysql-test/r/skip_name_resolve.result
@@ -5,3 +5,10 @@ GRANT USAGE ON *.* TO 'mysqltest_1'@'127.0.0.1/255.255.255.255'
GRANT ALL PRIVILEGES ON `test`.* TO 'mysqltest_1'@'127.0.0.1/255.255.255.255'
REVOKE ALL ON test.* FROM mysqltest_1@'127.0.0.1/255.255.255.255';
DROP USER mysqltest_1@'127.0.0.1/255.255.255.255';
+select user();
+user()
+#
+show processlist;
+Id User Host db Command Time State Info
+# root # test Sleep # NULL
+# root # test Query # NULL show processlist
diff --git a/mysql-test/r/sp-big.result b/mysql-test/r/sp-big.result
index 004ff586aab..1f0b6b34651 100644
--- a/mysql-test/r/sp-big.result
+++ b/mysql-test/r/sp-big.result
@@ -13,3 +13,49 @@ select @value;
3
drop procedure test.longprocedure;
drop table t1;
+create table t1 (f1 char(100) , f2 mediumint , f3 int , f4 real, f5 numeric);
+insert into t1 (f1, f2, f3, f4, f5) values
+("This is a test case for for Bug#9819", 1, 2, 3.0, 4.598);
+Warnings:
+Note 1265 Data truncated for column 'f5' at row 1
+create table t2 like t1;
+select count(*) from t1;
+count(*)
+256
+select count(*) from t2;
+count(*)
+0
+create procedure p1()
+begin
+declare done integer default 0;
+declare vf1 char(100) ;
+declare vf2 mediumint;
+declare vf3 int ;
+declare vf4 real ;
+declare vf5 numeric ;
+declare cur1 cursor for select f1,f2,f3,f4,f5 from t1;
+declare continue handler for sqlstate '02000' set done = 1;
+open cur1;
+while done <> 1 do
+fetch cur1 into vf1, vf2, vf3, vf4, vf5;
+if not done then
+insert into t2 values (vf1, vf2, vf3, vf4, vf5);
+end if;
+end while;
+close cur1;
+end|
+call p1();
+select count(*) from t1;
+count(*)
+256
+select count(*) from t2;
+count(*)
+256
+select f1 from t1 limit 1;
+f1
+This is a test case for for Bug#9819
+select f1 from t2 limit 1;
+f1
+This is a test case for for Bug#9819
+drop procedure p1;
+drop table t1, t2;
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index aedaaad9398..1b8cde6d3db 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -3206,6 +3206,18 @@ set f1= concat( 'hello', f1 );
return f1;
end|
drop function bug9048|
+drop function if exists bug12812|
+create function bug12812() returns char(2)
+begin
+return 'ok';
+end;
+create user user_bug12812@localhost IDENTIFIED BY 'ABC'|
+SELECT test.bug12812()|
+ERROR 42000: execute command denied to user 'user_bug12812'@'localhost' for routine 'test.bug12812'
+CREATE VIEW v1 AS SELECT test.bug12812()|
+ERROR 42000: execute command denied to user 'user_bug12812'@'localhost' for routine 'test.bug12812'
+DROP USER user_bug12812@localhost|
+drop function bug12812|
drop procedure if exists bug12849_1|
create procedure bug12849_1(inout x char) select x into x|
set @var='a'|
@@ -3348,4 +3360,79 @@ call bug12979_2()|
internal_var
NULL
drop procedure bug12979_2|
+drop table if exists t3|
+drop procedure if exists bug6127|
+create table t3 (s1 int unique)|
+set @sm=@@sql_mode|
+set sql_mode='traditional'|
+create procedure bug6127()
+begin
+declare continue handler for sqlstate '23000'
+ begin
+declare continue handler for sqlstate '22003'
+ insert into t3 values (0);
+insert into t3 values (1000000000000000);
+end;
+insert into t3 values (1);
+insert into t3 values (1);
+end|
+call bug6127()|
+select * from t3|
+s1
+0
+1
+call bug6127()|
+ERROR 23000: Duplicate entry '0' for key 1
+select * from t3|
+s1
+0
+1
+set sql_mode=@sm|
+drop table t3|
+drop procedure bug6127|
+drop procedure if exists bug12589_1|
+drop procedure if exists bug12589_2|
+drop procedure if exists bug12589_3|
+create procedure bug12589_1()
+begin
+declare spv1 decimal(3,3);
+set spv1= 123.456;
+set spv1 = 'test';
+create temporary table tm1 as select spv1;
+show create table tm1;
+drop temporary table tm1;
+end|
+create procedure bug12589_2()
+begin
+declare spv1 decimal(6,3);
+set spv1= 123.456;
+create temporary table tm1 as select spv1;
+show create table tm1;
+drop temporary table tm1;
+end|
+create procedure bug12589_3()
+begin
+declare spv1 decimal(6,3);
+set spv1= -123.456;
+create temporary table tm1 as select spv1;
+show create table tm1;
+drop temporary table tm1;
+end|
+call bug12589_1()|
+Table Create Table
+tm1 CREATE TEMPORARY TABLE `tm1` (
+ `spv1` decimal(1,0) unsigned default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Warnings:
+Warning 1292 Truncated incorrect DECIMAL value: 'test'
+call bug12589_2()|
+Table Create Table
+tm1 CREATE TEMPORARY TABLE `tm1` (
+ `spv1` decimal(6,3) unsigned default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+call bug12589_3()|
+Table Create Table
+tm1 CREATE TEMPORARY TABLE `tm1` (
+ `spv1` decimal(6,3) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1,t2;
diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result
index 6ceb1cda888..83099623e23 100644
--- a/mysql-test/r/sql_mode.result
+++ b/mysql-test/r/sql_mode.result
@@ -65,7 +65,7 @@ sql_mode NO_FIELD_OPTIONS,MYSQL323,MYSQL40,HIGH_NOT_PRECEDENCE
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` int(11) NOT NULL auto_increment,
+ `a` int(11) NOT NULL,
`pseudo` varchar(35) NOT NULL default '',
`email` varchar(60) NOT NULL default '',
PRIMARY KEY (`a`),
@@ -79,8 +79,8 @@ show create table t1;
Table Create Table
t1 CREATE TABLE "t1" (
"a" int(11) NOT NULL,
- "pseudo" varchar(35) NOT NULL default '',
- "email" varchar(60) NOT NULL default '',
+ "pseudo" varchar(35) character set latin2 NOT NULL default '',
+ "email" varchar(60) character set latin2 NOT NULL default '',
PRIMARY KEY ("a"),
UNIQUE KEY "email" ("email")
)
@@ -140,6 +140,26 @@ t1 CREATE TABLE `t1` (
drop table t1 ;
set @@SQL_MODE=NULL;
ERROR 42000: Variable 'sql_mode' can't be set to the value of 'NULL'
+set session sql_mode=ansi;
+create table t1
+(f1 integer auto_increment primary key,
+f2 timestamp default current_timestamp on update current_timestamp);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE "t1" (
+ "f1" int(11) NOT NULL auto_increment,
+ "f2" timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY ("f1")
+)
+set session sql_mode=no_field_options;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f1` int(11) NOT NULL,
+ `f2` timestamp NOT NULL default CURRENT_TIMESTAMP,
+ PRIMARY KEY (`f1`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE='';
show local variables like 'SQL_MODE';
Variable_name Value
diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result
index d2872878cb9..f68c4805d72 100644
--- a/mysql-test/r/system_mysql_db.result
+++ b/mysql-test/r/system_mysql_db.result
@@ -73,7 +73,7 @@ Table Create Table
user CREATE TABLE `user` (
`Host` char(60) collate utf8_bin NOT NULL default '',
`User` char(16) collate utf8_bin NOT NULL default '',
- `Password` char(41) collate utf8_bin NOT NULL default '',
+ `Password` binary(41) NOT NULL default '',
`Select_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Insert_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Update_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
diff --git a/mysql-test/r/temp_table.result b/mysql-test/r/temp_table.result
index 726861bb525..82479504b10 100644
--- a/mysql-test/r/temp_table.result
+++ b/mysql-test/r/temp_table.result
@@ -1,4 +1,5 @@
drop table if exists t1,t2;
+drop view if exists v1;
CREATE TABLE t1 (c int not null, d char (10) not null);
insert into t1 values(1,""),(2,"a"),(3,"b");
CREATE TEMPORARY TABLE t1 (a int not null, b char (10) not null);
@@ -99,32 +100,32 @@ Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_tables 2
drop table t1;
-create temporary table t1 as select 'This is temp. table' A;
-create view t1 as select 'This is view' A;
-select * from t1;
+create temporary table v1 as select 'This is temp. table' A;
+create view v1 as select 'This is view' A;
+select * from v1;
A
This is temp. table
-show create table t1;
+show create table v1;
Table Create Table
-t1 CREATE TEMPORARY TABLE `t1` (
+v1 CREATE TEMPORARY TABLE `v1` (
`A` varchar(19) NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
-show create view t1;
+show create view v1;
View Create View
-t1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `t1` AS select _latin1'This is view' AS `A`
-drop view t1;
-select * from t1;
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'This is view' AS `A`
+drop view v1;
+select * from v1;
A
This is temp. table
-create view t1 as select 'This is view again' A;
-select * from t1;
+create view v1 as select 'This is view again' A;
+select * from v1;
A
This is temp. table
-drop table t1;
-select * from t1;
+drop table v1;
+select * from v1;
A
This is view again
-drop view t1;
+drop view v1;
create table t1 (a int, b int, index(a), index(b));
create table t2 (c int auto_increment, d varchar(255), primary key (c));
insert into t1 values (3,1),(3,2);
diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result
index 5988b4f745e..0213dbaffde 100644
--- a/mysql-test/r/type_bit.result
+++ b/mysql-test/r/type_bit.result
@@ -553,3 +553,13 @@ sum(a1) b1+0 b2+0
2 0 0
4 2 2
8 1 1
+select 1 from t1 join t2 on b1 = b2 group by b1 order by 1;
+1
+1
+1
+1
+select b1+0,sum(b1), sum(b2) from t1 join t2 on b1 = b2 group by b1 order by 1;
+b1+0 sum(b1) sum(b2)
+0 0 0
+1 4 4
+2 2 2
diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
index 15f9b839994..d7f5f9fa328 100644
--- a/mysql-test/r/type_decimal.result
+++ b/mysql-test/r/type_decimal.result
@@ -476,7 +476,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
CREATE TABLE t1 (a_dec DECIMAL(-1,1));
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 '-1,1))' at line 1
CREATE TABLE t1 (a_dec DECIMAL(0,11));
-ERROR 42000: Scale may not be larger than the precision (column 'a_dec').
+ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'a_dec').
create table t1(a decimal(7,3));
insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000');
select * from t1;
@@ -672,6 +672,17 @@ a
9999.999
0000.000
drop table t1;
+create table t1(a decimal(10,5), b decimal(10,1));
+insert into t1 values(123.12345, 123.12345);
+Warnings:
+Note 1265 Data truncated for column 'b' at row 1
+update t1 set b=a;
+Warnings:
+Note 1265 Data truncated for column 'b' at row 1
+select * from t1;
+a b
+123.12345 123.1
+drop table t1;
CREATE TABLE t1
(EMPNUM CHAR(3) NOT NULL,
HOURS DECIMAL(5));
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index d243985332e..6b124caac14 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -225,3 +225,7 @@ select * from t1 where reckey=1.09E2;
reckey recdesc
109 Has 109 as key
drop table t1;
+create table t1 (s1 float(0,2));
+ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 's1').
+create table t1 (s1 float(1,2));
+ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 's1').
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index d821339a229..be5e29ab662 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -68,10 +68,10 @@ NULL 1.1 NULL NULL NULL 1
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `nullif(1.1, 1.1)` decimal(2,1) default NULL,
- `nullif(1.1, 1.2)` decimal(2,1) default NULL,
- `nullif(1.1, 0.11e1)` decimal(2,1) default NULL,
- `nullif(1.0, 1)` decimal(2,1) default NULL,
+ `nullif(1.1, 1.1)` decimal(2,1) unsigned default NULL,
+ `nullif(1.1, 1.2)` decimal(2,1) unsigned default NULL,
+ `nullif(1.1, 0.11e1)` decimal(2,1) unsigned default NULL,
+ `nullif(1.0, 1)` decimal(2,1) unsigned default NULL,
`nullif(1, 1.0)` int(1) default NULL,
`nullif(1, 1.1)` int(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
@@ -174,9 +174,9 @@ create table t1 select round(15.4,-1), truncate(-5678.123451,-3), abs(-1.1), -(-
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `round(15.4,-1)` decimal(3,0) NOT NULL default '0',
+ `round(15.4,-1)` decimal(3,0) unsigned NOT NULL default '0',
`truncate(-5678.123451,-3)` decimal(4,0) NOT NULL default '0',
- `abs(-1.1)` decimal(3,1) NOT NULL default '0.0',
+ `abs(-1.1)` decimal(2,1) NOT NULL default '0.0',
`-(-1.1)` decimal(2,1) NOT NULL default '0.0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
@@ -781,7 +781,7 @@ create table t1 as select 0.5;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `0.5` decimal(2,1) NOT NULL default '0.0'
+ `0.5` decimal(2,1) unsigned NOT NULL default '0.0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
select round(1.5),round(2.5);
@@ -936,7 +936,7 @@ ERROR 42000: Too big scale 31 specified for column 'sl'. Maximum is 30.
create table t1 (sl decimal(0,38));
ERROR 42000: Too big scale 38 specified for column 'sl'. Maximum is 30.
create table t1 (sl decimal(0,30));
-ERROR 42000: Scale may not be larger than the precision (column 'sl').
+ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'sl').
create table t1 (sl decimal(5, 5));
show create table t1;
Table Create Table
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index eb129e32983..042dfb5ad8d 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -780,21 +780,6 @@ t1 CREATE TABLE `t1` (
`b` longblob
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1,t2;
-create table t1 (d decimal(10,1));
-create table t2 (d decimal(10,9));
-insert into t1 values ("100000000.0");
-insert into t2 values ("1.23456780");
-create table t3 select * from t2 union select * from t1;
-select * from t3;
-d
-1.234567800
-100000000.000000000
-show create table t3;
-Table Create Table
-t3 CREATE TABLE `t3` (
- `d` decimal(18,9) default NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-drop table t1,t2,t3;
create table t1 select 1 union select -1;
select * from t1;
1
diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result
index 42fb8064044..9ca6370dff6 100644
--- a/mysql-test/r/update.result
+++ b/mysql-test/r/update.result
@@ -251,3 +251,15 @@ f1 f2
1 1
2 2
drop table t1,t2;
+create table t1(f1 int);
+select DATABASE();
+DATABASE()
+test
+update t1 set f1=1 where count(*)=1;
+ERROR HY000: Invalid use of group function
+select DATABASE();
+DATABASE()
+test
+delete from t1 where count(*)=1;
+ERROR HY000: Invalid use of group function
+drop table t1;
diff --git a/mysql-test/r/user_var-binlog.result b/mysql-test/r/user_var-binlog.result
index 0e9692523ef..17ac8809d52 100644
--- a/mysql-test/r/user_var-binlog.result
+++ b/mysql-test/r/user_var-binlog.result
@@ -27,6 +27,7 @@ SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`;
SET @`var2`:=_latin1 0x61 COLLATE `latin1_swedish_ci`;
SET TIMESTAMP=10000;
insert into t1 values (@var1),(@var2);
-ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
drop table t1;
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index 265f353ae3c..30ebeb462df 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -147,7 +147,7 @@ Variable_name Value
storage_engine MEMORY
show global variables like 'storage_engine';
Variable_name Value
-storage_engine MERGE
+storage_engine MRG_MYISAM
set GLOBAL query_cache_size=100000;
set GLOBAL myisam_max_sort_file_size=2000000;
show global variables like 'myisam_max_sort_file_size';
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index a40d776000d..e52ec950c8c 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -845,6 +845,15 @@ select * from v1;
cast(1 as char(3))
1
drop view v1;
+create table t1 (a int);
+create view v1 as select a from t1;
+create database seconddb;
+rename table v1 to seconddb.v1;
+ERROR HY000: Changing schema from 'test' to 'seconddb' is not allowed.
+rename table v1 to v2;
+drop table t1;
+drop view v2;
+drop database seconddb;
create view v1 as select 'a',1;
create view v2 as select * from v1 union all select * from v1;
create view v3 as select * from v2 where 1 = (select `1` from v2);
@@ -2253,3 +2262,39 @@ WEEKDAY(date)
1
DROP TABLE t1;
DROP VIEW v1, v2, v3;
+CREATE TABLE t1 ( a int, b int );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+CREATE VIEW v1 AS SELECT a,b FROM t1;
+SELECT t1.a FROM t1 GROUP BY t1.a HAVING a > 1;
+a
+2
+3
+SELECT v1.a FROM v1 GROUP BY v1.a HAVING a > 1;
+a
+2
+3
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1 ( a int, b int );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+CREATE VIEW v1 AS SELECT a,b FROM t1;
+SELECT t1.a FROM t1 GROUP BY t1.a HAVING t1.a > 1;
+a
+2
+3
+SELECT v1.a FROM v1 GROUP BY v1.a HAVING v1.a > 1;
+a
+2
+3
+SELECT t_1.a FROM t1 AS t_1 GROUP BY t_1.a HAVING t_1.a IN (1,2,3);
+a
+1
+2
+3
+SELECT v_1.a FROM v1 AS v_1 GROUP BY v_1.a HAVING v_1.a IN (1,2,3);
+a
+1
+2
+3
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/r/view_query_cache.result b/mysql-test/r/view_query_cache.result
index e6c2c0152f3..944e1db34c9 100644
--- a/mysql-test/r/view_query_cache.result
+++ b/mysql-test/r/view_query_cache.result
@@ -123,4 +123,13 @@ select * from v3;
a b
drop view v3;
drop table t1, t2;
+create table t1(f1 int);
+insert into t1 values(1),(2),(3);
+create view v1 as select * from t1;
+set query_cache_wlock_invalidate=1;
+lock tables v1 read /*!32311 local */;
+unlock tables;
+set query_cache_wlock_invalidate=default;
+drop view v1;
+drop table t1;
set GLOBAL query_cache_size=default;
diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result
index f3d7e151628..5fb03d2378e 100644
--- a/mysql-test/r/xa.result
+++ b/mysql-test/r/xa.result
@@ -9,10 +9,10 @@ select * from t1;
a
xa start 'test2';
xa start 'test-bad';
-ERROR XAE07: XAER_RMFAIL: The command cannot be executed in the ACTIVE state
+ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state
insert t1 values (20);
xa prepare 'test2';
-ERROR XAE07: XAER_RMFAIL: The command cannot be executed in the ACTIVE state
+ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state
xa end 'test2';
xa prepare 'test2';
xa commit 'test2';
@@ -21,13 +21,23 @@ a
20
xa start 'testa','testb';
insert t1 values (30);
+commit;
+ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state
xa end 'testa','testb';
+begin;
+ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the IDLE state
+create table t2 (a int);
+ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the IDLE state
xa start 'testa','testb';
ERROR XAE08: XAER_DUPID: The XID already exists
+xa start 'testa','testb', 123;
+ERROR XAE08: XAER_DUPID: The XID already exists
xa start 0x7465737462, 0x2030405060, 0xb;
insert t1 values (40);
xa end 'testb',' 0@P`',11;
xa prepare 'testb',0x2030405060,11;
+start transaction;
+ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the PREPARED state
xa recover;
formatID gtrid_length bqual_length data
11 5 5 testb 0@P`
diff --git a/mysql-test/std_data/ndb_config_mycnf1.cnf b/mysql-test/std_data/ndb_config_mycnf1.cnf
new file mode 100644
index 00000000000..c680bfd8fa3
--- /dev/null
+++ b/mysql-test/std_data/ndb_config_mycnf1.cnf
@@ -0,0 +1,15 @@
+[cluster_config]
+NoOfReplicas=1
+DataMemory=50M
+
+[cluster_config.jonas]
+IndexMemory=50M
+ndbd = localhost,localhost,localhost,localhost
+ndb_mgmd = localhost
+mysqld = localhost
+
+[cluster_config.ndbd.1]
+DataMemory=25M
+
+[cluster_config.ndbd.2.jonas]
+DataMemory=35M
diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test
index 2049c17580e..6220b4cbae7 100644
--- a/mysql-test/t/cast.test
+++ b/mysql-test/t/cast.test
@@ -27,6 +27,10 @@ select CONVERT(DATE "2004-01-22 21:45:33",CHAR);
select CONVERT(DATE "2004-01-22 21:45:33",CHAR(4));
select CONVERT(DATE "2004-01-22 21:45:33",BINARY(4));
select CAST(DATE "2004-01-22 21:45:33" AS BINARY(4));
+select CAST(0xb3 as signed);
+select CAST(0x8fffffffffffffff as signed);
+select CAST(0xffffffffffffffff as unsigned);
+select CAST(0xfffffffffffffffe as signed);
select cast('-10a' as signed integer);
select cast('a10' as unsigned integer);
select 10+'a';
diff --git a/mysql-test/t/ctype_ujis.test b/mysql-test/t/ctype_ujis.test
index 88386500c9f..7730fd0db6d 100644
--- a/mysql-test/t/ctype_ujis.test
+++ b/mysql-test/t/ctype_ujis.test
@@ -1151,3 +1151,45 @@ SET collation_connection='ujis_bin';
-- source include/ctype_innodb_like.inc
# End of 4.1 tests
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+DROP PROCEDURE IF EXISTS sp1;
+--enable_warnings
+
+set names ujis;
+set character_set_database = ujis;
+set character_set_server = ujis;
+
+CREATE TABLE t1(c1 char(2)) default charset = ujis;
+CREATE TABLE t2(c2 char(2)) default charset = ujis;
+
+INSERT INTO t1 VALUES(_ujis 0xA4A2);
+
+DELIMITER |;
+CREATE PROCEDURE sp1()
+BEGIN
+ DECLARE a CHAR(1);
+ DECLARE cur1 CURSOR FOR SELECT c1 FROM t1;
+ OPEN cur1;
+ FETCH cur1 INTO a;
+ INSERT INTO t2 VALUES (a);
+ CLOSE cur1;
+END|
+DELIMITER ;|
+CALL sp1();
+
+#The data in t1 and t2 should be the same but different
+SELECT c1,c2 FROM t1,t2;
+
+#Since the result of hex(convert(_latin1 0xA4A2 using ujis))
+#equals to hex(c2), it seems that the value which was inserted
+#by using cursor is interpreted as latin1 character set
+SELECT hex(convert(_latin1 0xA4A2 using ujis)),hex(c2) FROM t1,t2;
+
+DROP PROCEDURE sp1;
+DROP TABLE t1;
+DROP TABLE t2;
+
+set names default;
+set character_set_database=default;
+set character_set_server=default;
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 3a89da3a41e..b009e13874f 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -865,6 +865,24 @@ SELECT DISTINCT id FROM t1 ORDER BY id;
DROP TABLE t1;
#
+# Bugs#10504: Character set does not support traditional mode
+#
+set names utf8;
+# correct value
+select hex(char(1));
+select char(0xd1,0x8f);
+select char(0xd18f);
+select char(53647);
+# incorrect value: return with warning
+select char(0xff,0x8f);
+# incorrect value in strict mode: return NULL with "Error" level warning
+set sql_mode=traditional;
+select char(0xff,0x8f);
+select char(195);
+select char(196);
+select char(2557);
+
+#
# Bug#12891: UNION doesn't return DISTINCT result for multi-byte characters
#
set names utf8;
diff --git a/mysql-test/t/default.test b/mysql-test/t/default.test
index 42620a27b66..b5522394d2d 100644
--- a/mysql-test/t/default.test
+++ b/mysql-test/t/default.test
@@ -40,7 +40,6 @@ CREATE TABLE t1 (a varchar(30) binary NOT NULL DEFAULT ' ',
ENGINE=InnoDB DEFAULT CHARACTER SET = latin1 COLLATE latin1_bin;
--enable_warnings
-SHOW CREATE TABLE t1;
INSERT into t1 (b) values ('1');
SHOW WARNINGS;
SELECT * from t1;
diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test
index f52e12849e4..33b06e9bc11 100644
--- a/mysql-test/t/derived.test
+++ b/mysql-test/t/derived.test
@@ -258,4 +258,17 @@ create table t2 (a int);
select * from (select * from t1,t2) foo;
drop table t1,t2;
+#
+# Bug#10586 - query works with 4.1.8, but not with 4.1.11
+#
+create table t1 (ID int unsigned not null auto_increment,
+ DATA varchar(5) not null, primary key (ID));
+create table t2 (ID int unsigned not null auto_increment,
+ DATA varchar(5) not null, FID int unsigned not null,
+ primary key (ID));
+select A.* from (t1 inner join (select * from t2) as A on t1.ID = A.FID);
+select t2.* from ((select * from t1) as A inner join t2 on A.ID = t2.FID);
+select t2.* from (select * from t1) as A inner join t2 on A.ID = t2.FID;
+drop table t1, t2;
+
# End of 4.1 tests
diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test
index 28091676dd7..c401468a940 100644
--- a/mysql-test/t/federated.test
+++ b/mysql-test/t/federated.test
@@ -1137,11 +1137,53 @@ ORDER BY federated.t1.country_id;
DROP TABLE federated.countries;
-# optimize and repair tests
+#BEGIN optimize and repair tests
OPTIMIZE TABLE federated.t1;
REPAIR TABLE federated.t1;
REPAIR TABLE federated.t1 QUICK;
REPAIR TABLE federated.t1 EXTENDED;
REPAIR TABLE federated.t1 USE_FRM;
+#END optimize and repair tests
+
+
+# BEGIN ALTER TEST
+connection slave;
+--disable_warnings
+DROP TABLE IF EXISTS federated.normal_table;
+--enable_warnings
+
+CREATE TABLE federated.normal_table (
+ `id` int(4) NOT NULL,
+ `name` varchar(10) default NULL
+ ) DEFAULT CHARSET=latin1;
+
+connection master;
+--disable_warnings
+DROP TABLE IF EXISTS federated.alter_me;
+--enable_warnings
+
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval CREATE TABLE federated.alter_me (
+ `id` int(4) NOT NULL,
+ `name` varchar(10) default NULL,
+ PRIMARY KEY (`id`)
+ ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1
+ CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/normal_table';
+
+INSERT INTO federated.alter_me (id, name) VALUES (1, 'Monty');
+INSERT INTO federated.alter_me (id, name) VALUES (2, 'David');
+
+SELECT * FROM federated.alter_me;
+
+--error 1031
+ALTER TABLE federated.alter_me MODIFY COLUMN id int(16) NOT NULL;
+
+SELECT * FROM federated.alter_me;
+
+DROP TABLE federated.alter_me;
+connection slave;
+DROP TABLE federated.normal_table;
+# END ALTER TEST
+
source include/federated_cleanup.inc;
diff --git a/mysql-test/t/federated_bug_13118.test b/mysql-test/t/federated_bug_13118.test
new file mode 100644
index 00000000000..deec79becd2
--- /dev/null
+++ b/mysql-test/t/federated_bug_13118.test
@@ -0,0 +1,42 @@
+source include/federated.inc;
+
+
+connection slave;
+--disable_warnings
+DROP TABLE IF EXISTS federated.bug_13118_table;
+--enable_warnings
+
+CREATE TABLE federated.bug_13118_table (
+ `foo` integer,
+ `bar` integer
+ );
+
+
+connection master;
+--disable_warnings
+DROP TABLE IF EXISTS federated.t1;
+--enable_warnings
+
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval CREATE TABLE federated.t1 (
+ `foo` integer,
+ `bar` integer
+ ) ENGINE="FEDERATED"
+ CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/bug_13118_table';
+
+SELECT * from federated.t1;
+
+INSERT INTO federated.t1 VALUES (1,1);
+SELECT * FROM federated.t1;
+
+INSERT INTO federated.t1 VALUES (1,1);
+SELECT * FROM federated.t1;
+
+
+DROP TABLE federated.t1;
+connection slave;
+DROP TABLE federated.bug_13118_table;
+
+
+source include/federated_cleanup.inc;
+
diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test
index fb9470c16dd..19596c1b55a 100644
--- a/mysql-test/t/func_group.test
+++ b/mysql-test/t/func_group.test
@@ -539,6 +539,75 @@ INSERT INTO t1 VALUES
SELECT MAX(id) FROM t1 WHERE id < 3 AND a=2 AND b=6;
DROP TABLE t1;
+#
+# Bug #12882 min/max inconsistent on empty table
+#
+
+create table t1m (a int) engine=myisam;
+create table t1i (a int) engine=innodb;
+create table t2m (a int) engine=myisam;
+create table t2i (a int) engine=innodb;
+insert into t2m values (5);
+insert into t2i values (5);
+
+# test with MyISAM
+select min(a) from t1m;
+select min(7) from t1m;
+select min(7) from DUAL;
+explain select min(7) from t2m join t1m;
+select min(7) from t2m join t1m;
+
+select max(a) from t1m;
+select max(7) from t1m;
+select max(7) from DUAL;
+explain select max(7) from t2m join t1m;
+select max(7) from t2m join t1m;
+
+select 1, min(a) from t1m where a=99;
+select 1, min(a) from t1m where 1=99;
+select 1, min(1) from t1m where a=99;
+select 1, min(1) from t1m where 1=99;
+
+select 1, max(a) from t1m where a=99;
+select 1, max(a) from t1m where 1=99;
+select 1, max(1) from t1m where a=99;
+select 1, max(1) from t1m where 1=99;
+
+# test with InnoDB
+select min(a) from t1i;
+select min(7) from t1i;
+select min(7) from DUAL;
+explain select min(7) from t2i join t1i;
+select min(7) from t2i join t1i;
+
+select max(a) from t1i;
+select max(7) from t1i;
+select max(7) from DUAL;
+explain select max(7) from t2i join t1i;
+select max(7) from t2i join t1i;
+
+select 1, min(a) from t1i where a=99;
+select 1, min(a) from t1i where 1=99;
+select 1, min(1) from t1i where a=99;
+select 1, min(1) from t1i where 1=99;
+
+select 1, max(a) from t1i where a=99;
+select 1, max(a) from t1i where 1=99;
+select 1, max(1) from t1i where a=99;
+select 1, max(1) from t1i where 1=99;
+
+# mixed MyISAM/InnoDB test
+explain select count(*), min(7), max(7) from t1m, t1i;
+select count(*), min(7), max(7) from t1m, t1i;
+
+explain select count(*), min(7), max(7) from t1m, t2i;
+select count(*), min(7), max(7) from t1m, t2i;
+
+explain select count(*), min(7), max(7) from t2m, t1i;
+select count(*), min(7), max(7) from t2m, t1i;
+
+drop table t1m, t1i, t2m, t2i;
+
# End of 4.1 tests
#
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index 7bf737402ef..dd4edd8ca48 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -102,6 +102,13 @@ insert into t1 values ('aa'), ('bb');
select * from t1 where a in (NULL, 'aa');
drop table t1;
+# BUG#13419
+create table t1 (id int, key(id));
+insert into t1 values (1),(2),(3);
+select count(*) from t1 where id not in (1);
+select count(*) from t1 where id not in (1,2);
+drop table t1;
+
# End of 4.1 tests
#
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index 4a6c98c8d7f..5f32b7b2b49 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -665,3 +665,13 @@ select rpad(i, 7, ' ') as t from t1;
drop table t1;
# End of 4.1 tests
+
+#
+# Bug #13361: SELECT FORMAT(<decimal field with null>, 2) crashes
+#
+create table t1 (d decimal default null);
+insert into t1 values (null);
+select format(d, 2) from t1;
+drop table t1;
+
+# End of 5.0 tests
diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test
index da3fdec80d2..3d751f4a571 100644
--- a/mysql-test/t/group_min_max.test
+++ b/mysql-test/t/group_min_max.test
@@ -655,26 +655,21 @@ select distinct a1 from t1 where a2 = 'b';
# Bug #12672: primary key implcitly included in every innodb index
#
-create table bug12672 (
+--disable_warnings
+create table t4 (
pk_col int auto_increment primary key, a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
) engine=innodb;
+--enable_warnings
+insert into t4 (a1, a2, b, c, d, dummy) select * from t1;
-insert into bug12672 (a1, a2, b, c, d, dummy) select * from t1;
-
-create index idx12672_0 on bug12672 (a1);
-create index idx12672_1 on bug12672 (a1,a2,b,c);
-create index idx12672_2 on bug12672 (a1,a2,b);
+create index idx12672_0 on t4 (a1);
+create index idx12672_1 on t4 (a1,a2,b,c);
+create index idx12672_2 on t4 (a1,a2,b);
analyze table t1;
---replace_column 9 #
-explain select distinct a1 from bug12672 where pk_col not in (1,2,3,4);
-select distinct a1 from bug12672 where pk_col not in (1,2,3,4);
-
-drop table bug12672;
+select distinct a1 from t4 where pk_col not in (1,2,3,4);
-drop table t1;
-drop table t2;
-drop table t3;
+drop table t1,t2,t3,t4;
#
# Bug #6142: a problem with the empty innodb table
diff --git a/mysql-test/t/im_daemon_life_cycle-im.opt b/mysql-test/t/im_daemon_life_cycle-im.opt
new file mode 100644
index 00000000000..6bfd9a24107
--- /dev/null
+++ b/mysql-test/t/im_daemon_life_cycle-im.opt
@@ -0,0 +1,2 @@
+--run-as-service
+--log=$MYSQL_TEST_DIR/var/log/im.log
diff --git a/mysql-test/t/im_daemon_life_cycle.imtest b/mysql-test/t/im_daemon_life_cycle.imtest
new file mode 100644
index 00000000000..87388d7c1e6
--- /dev/null
+++ b/mysql-test/t/im_daemon_life_cycle.imtest
@@ -0,0 +1,15 @@
+###########################################################################
+#
+# This file contains test for (1.2) test suite.
+#
+# Consult WL#2789 for more information.
+#
+###########################################################################
+
+--source include/im_check_os.inc
+
+###########################################################################
+
+SHOW INSTANCES;
+
+--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted
diff --git a/mysql-test/t/im_life_cycle.imtest b/mysql-test/t/im_life_cycle.imtest
new file mode 100644
index 00000000000..fff57e16eab
--- /dev/null
+++ b/mysql-test/t/im_life_cycle.imtest
@@ -0,0 +1,141 @@
+###########################################################################
+#
+# This file contains test for (1.1) test suite.
+#
+# Consult WL#2789 for more information.
+#
+###########################################################################
+
+--source include/im_check_os.inc
+
+###########################################################################
+#
+# 1.1.1. Check that Instance Manager is able:
+# - to read definitions of two mysqld-instances;
+# - to start the first instance;
+# - to understand 'nonguarded' option and keep the second instance down;
+#
+###########################################################################
+
+SHOW INSTANCES;
+--replace_column 3 VERSION
+SHOW INSTANCE STATUS mysqld1;
+--replace_column 3 VERSION
+SHOW INSTANCE STATUS mysqld2;
+
+###########################################################################
+#
+# 1.1.2. Check 'START INSTANCE' command:
+# - start the second instance;
+# - check that it is reported as online;
+# - execute some SQL-statement on mysqld2 to ensure that it is really up and
+# running;
+#
+###########################################################################
+
+START INSTANCE mysqld2;
+# FIXME
+--sleep 3
+
+SHOW INSTANCES;
+--replace_column 3 VERSION
+SHOW INSTANCE STATUS mysqld1;
+--replace_column 3 VERSION
+SHOW INSTANCE STATUS mysqld2;
+
+--connect (mysql_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
+--connection mysql_con
+
+SHOW VARIABLES LIKE 'port';
+
+--connection default
+--disconnect mysql_con
+
+###########################################################################
+#
+# 1.1.3. Check 'STOP INSTANCE' command:
+# - stop the second instance;
+# - check that it is reported as offline;
+# - TODO: try to execute some SQL-statement to ensure that it is really down;
+#
+###########################################################################
+
+STOP INSTANCE mysqld2;
+# FIXME
+--sleep 3
+
+SHOW INSTANCES;
+--replace_column 3 VERSION
+SHOW INSTANCE STATUS mysqld1;
+--replace_column 3 VERSION
+SHOW INSTANCE STATUS mysqld2;
+
+###########################################################################
+#
+# 1.1.4. Check that Instance Manager reports correct errors for 'START
+# INSTANCE' command:
+# - if the client tries to start unregistered instance;
+# - if the client tries to start already started instance;
+# - if the client submits invalid arguments;
+#
+###########################################################################
+
+--error 3000
+START INSTANCE mysqld3;
+
+--error 3002
+START INSTANCE mysqld1;
+
+# FIXME TODO
+# BUG#12813: START/STOP INSTANCE commands accept a list as argument
+# START INSTANCE mysqld1, mysqld2;
+
+###########################################################################
+#
+# 1.1.5. Check that Instance Manager reports correct errors for 'STOP INSTANCE'
+# command:
+# - if the client tries to start unregistered instance;
+# - if the client tries to start already stopped instance;
+# - if the client submits invalid arguments;
+#
+###########################################################################
+
+--error 3000
+STOP INSTANCE mysqld3;
+
+# TODO: IM should be fixed.
+# BUG#12673: Instance Manager allows to stop the instance many times
+# --error 3002
+# STOP INSTANCE mysqld2;
+
+# FIXME TODO
+# BUG#12813: START/STOP INSTANCE commands accept a list as argument
+# STOP INSTANCE mysqld1, mysqld2;
+
+###########################################################################
+#
+# 1.1.6. Check that Instance Manager is able to restart guarded instances.
+#
+###########################################################################
+
+SHOW INSTANCES;
+
+--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_MYSQLD1_PATH_PID restarted
+
+###########################################################################
+#
+# 1.1.7. Check that Instance Manager does not restart non-guarded instance.
+#
+###########################################################################
+
+SHOW INSTANCES;
+
+START INSTANCE mysqld2;
+# FIXME
+--sleep 3
+
+SHOW INSTANCES;
+
+--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_MYSQLD2_PATH_PID killed
+
+SHOW INSTANCES;
diff --git a/mysql-test/t/im_options_set.imtest b/mysql-test/t/im_options_set.imtest
new file mode 100644
index 00000000000..785c6d05fef
--- /dev/null
+++ b/mysql-test/t/im_options_set.imtest
@@ -0,0 +1,142 @@
+###########################################################################
+#
+# This file contains test for (3) test suite.
+#
+# Consult WL#2789 for more information.
+#
+###########################################################################
+
+#
+# Check the options-management commands:
+# - SET;
+# - FLUSH INSTANCES;
+#
+# Let's test the commands on the option 'server_id'. It's expected that
+# originally the instances have the following server ids:
+# - mysqld1: 1
+# - mysqld2: 2
+#
+# 1. SET <instance_id>.server_id= SERVER_ID); where SERVER_ID is 11 or 12.
+# 1.1. check that the configuration file has been updated (i.e. contains
+# server_id=SERVER_ID for the instance);
+# 1.2. (for mysqld1) check that the running instance has not been affected:
+# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
+# returns zero;
+# 1.3. check that internal cache of Instance Manager has not been affected
+# (i.e. SHOW INSTANCE OPTIONS <instance> does not contain updated value).
+#
+# 2. FLUSH INSTANCES;
+# 2.1. check that the configuration file has not been updated;
+# 2.2. (for mysqld1) check that the running instance has not been affected:
+# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
+# returns zero value;
+# 2.3. check that internal cache of Instance Manager has been updated (i.e.
+# SHOW INSTANCE OPTIONS <instance> contains 'server_id=SERVER_ID' line).
+#
+# 3. Restore options.
+#
+
+###########################################################################
+
+--source include/im_check_os.inc
+
+###########################################################################
+#
+# 0. Check starting conditions.
+#
+###########################################################################
+
+# - check the configuration file;
+
+--exec grep server_id $MYSQL_TEST_DIR/var/im.cnf ;
+
+# - check the running instances.
+
+--connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
+
+--connection mysql1_con
+
+SHOW VARIABLES LIKE 'server_id';
+
+--connection default
+
+# - check the internal cache.
+# TODO: we should check only server_id option here.
+
+# SHOW INSTANCE OPTIONS mysqld1;
+# SHOW INSTANCE OPTIONS mysqld2;
+
+###########################################################################
+#
+# 1. SET <instance_id>.server_id= SERVER_ID); where SERVER_ID is 11 or 12.
+#
+###########################################################################
+
+# * mysqld1
+
+SET mysqld1.server_id = 11;
+
+# - check that the configuration file has been updated (i.e. contains
+# server_id=SERVER_ID for the instance);
+
+--exec grep server_id $MYSQL_TEST_DIR/var/im.cnf ;
+
+# - (for mysqld1) check that the running instance has not been affected:
+# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
+# returns zero;
+
+--connection mysql1_con
+
+SHOW VARIABLES LIKE 'server_id';
+
+--connection default
+
+# - check that internal cache of Instance Manager has not been affected
+# (i.e. SHOW INSTANCE OPTIONS <instance> does not contain updated value).
+# TODO: we should check only server_id option here.
+
+# SHOW INSTANCE OPTIONS mysqld1;
+
+# * mysqld2
+
+SET mysqld2.server_id = 12;
+
+# - check that the configuration file has been updated (i.e. contains
+# server_id=SERVER_ID for the instance);
+
+--exec grep server_id $MYSQL_TEST_DIR/var/im.cnf ;
+
+# - check that internal cache of Instance Manager has not been affected
+# (i.e. SHOW INSTANCE OPTIONS <instance> does not contain updated value).
+# TODO: we should check only server_id option here.
+
+# SHOW INSTANCE OPTIONS mysqld2;
+
+###########################################################################
+#
+# 2. FLUSH INSTANCES;
+#
+###########################################################################
+
+FLUSH INSTANCES;
+
+# - check that the configuration file has not been updated;
+
+--exec grep server_id $MYSQL_TEST_DIR/var/im.cnf ;
+
+# - (for mysqld1) check that the running instance has not been affected:
+# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
+# returns zero value;
+
+--connection mysql1_con
+
+SHOW VARIABLES LIKE 'server_id';
+
+--connection default
+
+# - check that internal cache of Instance Manager has been updated (i.e.
+# SHOW INSTANCE OPTIONS <instance> contains 'server_id=' line).
+# TODO: we should check only server_id option here.
+
+# SHOW INSTANCE OPTIONS mysqld1;
+# SHOW INSTANCE OPTIONS mysqld2;
diff --git a/mysql-test/t/im_options_unset.imtest b/mysql-test/t/im_options_unset.imtest
new file mode 100644
index 00000000000..74ec42ac3f9
--- /dev/null
+++ b/mysql-test/t/im_options_unset.imtest
@@ -0,0 +1,150 @@
+###########################################################################
+#
+# This file contains test for (3) test suite.
+#
+# Consult WL#2789 for more information.
+#
+###########################################################################
+
+#
+# Check the options-management commands:
+# - UNSET;
+# - FLUSH INSTANCES;
+#
+# Let's test the commands on the option 'server_id'. It's expected that
+# originally the instances have the following server ids:
+# - mysqld1: 1
+# - mysqld2: 2
+#
+# The test case:
+#
+# 1. UNSET <instance_id>.server_id;
+#
+# Do the step for both instances.
+#
+# 1.1. check that the configuration file has been updated (i.e. does not
+# contain 'server_id=' line for the instance);
+# 1.2. (for mysqld1) check that the running instance has not been affected:
+# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
+# returns non-zero value;
+# 1.3. check that internal cache of Instance Manager is not affected (i.e.
+# SHOW INSTANCE OPTIONS <instance> contains non-zero value for server_id);
+#
+# 2. FLUSH INSTANCES;
+#
+# Do the step for both instances.
+#
+# 2.1. check that the configuration file has not been updated (i.e. does not
+# contain 'server_id=' for the instance);
+# 2.2. (for mysqld1) check that the running instance has not been affected:
+# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
+# returns non-zero value;
+# 2.3. check that internal cache of Instance Manager has been updated (i.e.
+# SHOW INSTANCE OPTIONS <instance> does not contain 'server_id=' line).
+#
+
+###########################################################################
+
+--source include/im_check_os.inc
+
+###########################################################################
+#
+# 0. Check starting conditions.
+#
+###########################################################################
+
+# - check the configuration file;
+
+--exec grep server_id $MYSQL_TEST_DIR/var/im.cnf ;
+
+# - check the running instances.
+
+--connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
+
+--connection mysql1_con
+
+SHOW VARIABLES LIKE 'server_id';
+
+--connection default
+
+# - check the internal cache.
+# TODO: we should check only server_id option here.
+
+# SHOW INSTANCE OPTIONS mysqld1;
+# SHOW INSTANCE OPTIONS mysqld2;
+
+###########################################################################
+#
+# 1. UNSET <instance_id>.server_id;
+#
+###########################################################################
+
+# * mysqld1
+
+UNSET mysqld1.server_id;
+
+# - check that the configuration file has been updated (i.e. does not
+# contain 'server_id=' line for the instance);
+
+--exec grep server_id $MYSQL_TEST_DIR/var/im.cnf ;
+
+# - check that the running instance has not been affected: connect to the
+# instance and check that 'SHOW VARIABLES LIKE 'server_id'' returns non-zero
+# value;
+
+--connection mysql1_con
+
+SHOW VARIABLES LIKE 'server_id';
+
+--connection default
+
+# - check that internal cache of Instance Manager is not affected (i.e. SHOW
+# INSTANCE OPTIONS <instance> contains non-zero value for server_id);
+# TODO: we should check only server_id option here.
+
+# SHOW INSTANCE OPTIONS mysqld1;
+
+# * mysqld2
+
+UNSET mysqld2.server_id;
+
+# - check that the configuration file has been updated (i.e. does not
+# contain 'server_id=' line for the instance);
+
+--exec grep server_id $MYSQL_TEST_DIR/var/im.cnf || true;
+
+# - check that internal cache of Instance Manager is not affected (i.e. SHOW
+# INSTANCE OPTIONS <instance> contains non-zero value for server_id);
+# TODO: we should check only server_id option here.
+
+# SHOW INSTANCE OPTIONS mysqld2;
+
+###########################################################################
+#
+# 2. FLUSH INSTANCES;
+#
+###########################################################################
+
+FLUSH INSTANCES;
+
+# - check that the configuration file has not been updated (i.e. does not
+# contain 'server_id=' for the instance);
+
+--exec grep server_id $MYSQL_TEST_DIR/var/im.cnf || true;
+
+# - (for mysqld1) check that the running instance has not been affected:
+# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
+# returns non-zero value;
+
+--connection mysql1_con
+
+SHOW VARIABLES LIKE 'server_id';
+
+--connection default
+
+# - check that internal cache of Instance Manager has been updated (i.e.
+# SHOW INSTANCE OPTIONS <instance> does not contain 'server_id=' line).
+# TODO: we should check only server_id option here.
+
+# SHOW INSTANCE OPTIONS mysqld1;
+# SHOW INSTANCE OPTIONS mysqld2;
diff --git a/mysql-test/t/im_utils.imtest b/mysql-test/t/im_utils.imtest
new file mode 100644
index 00000000000..dc6fb93c4ff
--- /dev/null
+++ b/mysql-test/t/im_utils.imtest
@@ -0,0 +1,115 @@
+###########################################################################
+#
+# This file contains test for (2) test suite.
+#
+# Consult WL#2789 for more information.
+#
+###########################################################################
+
+--source include/im_check_os.inc
+
+###########################################################################
+
+#
+# Check starting conditions. This test case assumes that:
+# - two mysqld-instances are registered;
+# - the first instance is online;
+# - the second instance is offline;
+#
+
+SHOW INSTANCES;
+
+#
+# Check 'SHOW INSTANCE OPTIONS' command:
+# - check that options of both offline and online instances are accessible;
+# - since configuration of an mysqld-instance contains directories, we should
+# completely ignore the second column (values) in order to make the test
+# case produce the same results on different installations;
+# TODO: ignore values of only directory-specific options.
+#
+
+--replace_column 2 VALUE
+SHOW INSTANCE OPTIONS mysqld1;
+
+--replace_column 2 VALUE
+SHOW INSTANCE OPTIONS mysqld2;
+
+#
+# Before checking log files, we should start the second instance (mysqld2) to
+# give it a chance to create log files.
+#
+
+START INSTANCE mysqld2;
+
+# FIXME
+-- sleep 3
+
+STOP INSTANCE mysqld2;
+
+#
+# Check 'SHOW LOG FILES' command:
+# - check that log files of both offline and online instances are accessible;
+# - since placement of the log files is installation-specific, we should
+# ignore it in comparisson;
+# - also, we should ignore log file size, since it may depend on the version
+# being tested;
+#
+
+--replace_column 2 PATH 3 FILE_SIZE
+SHOW mysqld1 LOG FILES;
+
+--replace_column 2 PATH 3 FILE_SIZE
+SHOW mysqld2 LOG FILES;
+
+#
+# Check 'SHOW LOG' command:
+# - check that all three kinds of logs are available for both offline and
+# online instances;
+# - we should ignore the value, because it is very specific and depends on
+# many factors; we only check that Instance Manager is able to provide log
+# files.
+#
+
+# mysqld1 (online) w/o the optional argument.
+
+--replace_column 1 LOG_DATA
+SHOW mysqld1 LOG ERROR 10;
+
+--replace_column 1 LOG_DATA
+SHOW mysqld1 LOG SLOW 10;
+
+--replace_column 1 LOG_DATA
+SHOW mysqld1 LOG GENERAL 10;
+
+# mysqld1 (online) with the optional argument.
+
+--replace_column 1 LOG_DATA
+SHOW mysqld1 LOG ERROR 10, 2;
+
+--replace_column 1 LOG_DATA
+SHOW mysqld1 LOG SLOW 10, 2;
+
+--replace_column 1 LOG_DATA
+SHOW mysqld1 LOG GENERAL 10, 2;
+
+# mysqld2 (offline) w/o the optional argument.
+
+--replace_column 1 LOG_DATA
+SHOW mysqld2 LOG ERROR 10;
+
+--replace_column 1 LOG_DATA
+SHOW mysqld2 LOG SLOW 10;
+
+--replace_column 1 LOG_DATA
+SHOW mysqld2 LOG GENERAL 10;
+
+# mysqld2 (offline) with the optional argument.
+
+--replace_column 1 LOG_DATA
+SHOW mysqld2 LOG ERROR 10, 2;
+
+--replace_column 1 LOG_DATA
+SHOW mysqld2 LOG SLOW 10, 2;
+
+--replace_column 1 LOG_DATA
+SHOW mysqld2 LOG GENERAL 10, 2;
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index 51cca0a3db1..f351d315680 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -5,7 +5,8 @@
# show databases
--disable_warnings
-DROP TABLE IF EXISTS t0,t1,t2,t3,t5;
+DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5;
+DROP VIEW IF EXISTS v1;
--enable_warnings
@@ -364,8 +365,8 @@ use test;
create function sub1(i int) returns int
return i+1;
create table t1(f1 int);
-create view t2 (c) as select f1 from t1;
-create view t3 (c) as select sub1(1);
+create view v2 (c) as select f1 from t1;
+create view v3 (c) as select sub1(1);
create table t4(f1 int, KEY f1_key (f1));
drop table t1;
drop function sub1;
@@ -378,8 +379,8 @@ where table_schema='test';
select index_name from information_schema.statistics where table_schema='test';
select constraint_name from information_schema.table_constraints
where table_schema='test';
-drop view t2;
-drop view t3;
+drop view v2;
+drop view v3;
drop table t4;
#
diff --git a/mysql-test/t/information_schema_inno.test b/mysql-test/t/information_schema_inno.test
index dd7015bfd9a..9cd64a54ad9 100644
--- a/mysql-test/t/information_schema_inno.test
+++ b/mysql-test/t/information_schema_inno.test
@@ -1,6 +1,6 @@
-- source include/have_innodb.inc
--disable_warnings
-DROP TABLE IF EXISTS t1,t2;
+DROP TABLE IF EXISTS t1,t2,t3;
--enable_warnings
#
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index beec3b0f8c7..5a45b3524ac 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -978,9 +978,9 @@ create table `t2` (`id` int( 11 ) not null default '0',unique key `id` ( `id` )
insert into `t2`values ( 1 ) ;
create table `t3` (`id` int( 11 ) not null default '0',key `id` ( `id` ) ,constraint `t2_id_fk` foreign key ( `id` ) references `t2` (`id` )) engine = innodb;
insert into `t3`values ( 1 ) ;
---error 1217
+--error 1451
delete t3,t2,t1 from t1,t2,t3 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
---error 1217
+--error 1451
update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
--error 1054
update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
@@ -996,7 +996,7 @@ create table t1(
foreign key(pid) references t1(id) on delete cascade) engine=innodb;
insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),
(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);
--- error 1217
+-- error 1451
delete from t1 where id=0;
delete from t1 where id=15;
delete from t1 where id=0;
@@ -1259,6 +1259,16 @@ select * from t1 order by a,b,c,d;
explain select * from t1 order by a,b,c,d;
drop table t1;
+#
+# BUG#11039,#13218 Wrong key length in min()
+#
+
+create table t1 (a char(1), b char(1), key(a, b)) engine=innodb;
+insert into t1 values ('8', '6'), ('4', '7');
+select min(a) from t1;
+select min(b) from t1 where a='8';
+drop table t1;
+
# End of 4.1 tests
#
@@ -1473,3 +1483,155 @@ CREATE TEMPORARY TABLE t2
FOREIGN KEY (b) REFERENCES test.t1(id)
) ENGINE=InnoDB;
DROP TABLE t1;
+
+#
+# Test that index column max sizes are checked (bug #13315)
+#
+
+# prefix index
+create table t1 (col1 varchar(2000), index (col1(767)))
+ character set = latin1 engine = innodb;
+
+# normal indexes
+create table t2 (col1 char(255), index (col1))
+ character set = latin1 engine = innodb;
+create table t3 (col1 binary(255), index (col1))
+ character set = latin1 engine = innodb;
+create table t4 (col1 varchar(767), index (col1))
+ character set = latin1 engine = innodb;
+create table t5 (col1 varchar(767) primary key)
+ character set = latin1 engine = innodb;
+create table t6 (col1 varbinary(767) primary key)
+ character set = latin1 engine = innodb;
+create table t7 (col1 text, index(col1(767)))
+ character set = latin1 engine = innodb;
+create table t8 (col1 blob, index(col1(767)))
+ character set = latin1 engine = innodb;
+
+# multi-column indexes are allowed to be longer
+create table t9 (col1 varchar(512), col2 varchar(512), index(col1, col2))
+ character set = latin1 engine = innodb;
+
+drop table t1, t2, t3, t4, t5, t6, t7, t8, t9;
+
+--error 1005
+create table t1 (col1 varchar(768), index (col1))
+ character set = latin1 engine = innodb;
+--error 1005
+create table t2 (col1 varchar(768) primary key)
+ character set = latin1 engine = innodb;
+--error 1005
+create table t3 (col1 varbinary(768) primary key)
+ character set = latin1 engine = innodb;
+--error 1005
+create table t4 (col1 text, index(col1(768)))
+ character set = latin1 engine = innodb;
+--error 1005
+create table t5 (col1 blob, index(col1(768)))
+ character set = latin1 engine = innodb;
+
+#
+# Test improved foreign key error messages (bug #3443)
+#
+
+CREATE TABLE t1
+(
+ id INT PRIMARY KEY
+) ENGINE=InnoDB;
+
+CREATE TABLE t2
+(
+ v INT,
+ CONSTRAINT c1 FOREIGN KEY (v) REFERENCES t1(id)
+) ENGINE=InnoDB;
+
+--error 1452
+INSERT INTO t2 VALUES(2);
+
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES(1);
+
+--error 1451
+DELETE FROM t1 WHERE id = 1;
+
+--error 1217
+DROP TABLE t1;
+
+SET FOREIGN_KEY_CHECKS=0;
+DROP TABLE t1;
+SET FOREIGN_KEY_CHECKS=1;
+
+--error 1452
+INSERT INTO t2 VALUES(3);
+
+DROP TABLE t2;
+#
+# Test that checksum table uses a consistent read Bug #12669
+#
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
+set autocommit=0;
+checksum table t1;
+connection b;
+insert into t1 values(3);
+connection a;
+#
+# Here checksum should not see insert
+#
+checksum table t1;
+connection a;
+commit;
+checksum table t1;
+commit;
+drop table t1;
+#
+# autocommit = 1
+#
+connection a;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
+set autocommit=1;
+checksum table t1;
+connection b;
+set autocommit=1;
+insert into t1 values(3);
+connection a;
+#
+# Here checksum sees insert
+#
+checksum table t1;
+drop table t1;
+
+#
+# BUG#11238 - in prelocking mode SELECT .. FOR UPDATE is changed to
+# non-blocking SELECT
+#
+create table t1 (col1 integer primary key, col2 integer) engine=innodb;
+insert t1 values (1,100);
+delimiter |;
+create function f1 () returns integer begin
+declare var1 int;
+select col2 into var1 from t1 where col1=1 for update;
+return var1;
+end|
+delimiter ;|
+start transaction;
+select f1();
+connection b;
+send update t1 set col2=0 where col1=1;
+connection default;
+select * from t1;
+connection a;
+rollback;
+connection b;
+reap;
+rollback;
+connection default;
+drop table t1;
+drop function f1;
+disconnect a;
+disconnect b;
+
diff --git a/mysql-test/t/join_nested.test b/mysql-test/t/join_nested.test
index 482c7f9f8b9..0592ec3152f 100644
--- a/mysql-test/t/join_nested.test
+++ b/mysql-test/t/join_nested.test
@@ -801,3 +801,34 @@ SELECT * FROM
DROP VIEW v1,v2;
DROP TABLE t1,t2,t3,t4;
+
+#
+# Bug #13545: problem with NATURAL/USING joins.
+#
+
+CREATE TABLE t1(a int);
+CREATE TABLE t2(b int);
+CREATE TABLE t3(c int, d int);
+CREATE TABLE t4(d int);
+CREATE TABLE t5(e int, f int);
+CREATE TABLE t6(f int);
+CREATE VIEW v1 AS
+ SELECT e FROM t5 JOIN t6 ON t5.e=t6.f;
+CREATE VIEW v2 AS
+ SELECT e FROM t5 NATURAL JOIN t6;
+
+SELECT t1.a FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c JOIN t4 USING(d);
+--error 1054
+SELECT t1.x FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c JOIN t4 USING(d);
+SELECT t1.a FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c NATURAL JOIN t4;
+--error 1054
+SELECT t1.x FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c NATURAL JOIN t4;
+SELECT v1.e FROM v1 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
+--error 1054
+SELECT v1.x FROM v1 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
+SELECT v2.e FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
+--error 1054
+SELECT v2.x FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
+
+DROP VIEW v1, v2;
+DROP TABLE t1, t2, t3, t4, t5, t6;
diff --git a/mysql-test/t/kill_n_check.sh b/mysql-test/t/kill_n_check.sh
new file mode 100755
index 00000000000..7fe30c4774c
--- /dev/null
+++ b/mysql-test/t/kill_n_check.sh
@@ -0,0 +1,66 @@
+#!/bin/sh
+
+if [ $# -ne 2 ]; then
+ echo "Usage: kill_n_check.sh <pid file path> killed|restarted"
+ exit 0
+fi
+
+pid_path="$1"
+expected_result="$2"
+
+if [ -z "$pid_path" -o ! -r "$pid_path" ]; then
+ echo "Error: invalid PID path ($pid_path) or PID file does not exist."
+ exit 0
+fi
+
+if [ "$expected_result" != "killed" -a \
+ "$expected_result" != "restarted" ]; then
+ echo "Error: expected result must be either 'killed' or 'restarted'."
+ exit 0
+fi
+
+# echo "PID path: '$pid_path'"
+
+original_pid=`cat "$pid_path"`
+
+# echo "Original PID: $original_pid"
+
+echo "Killing the process..."
+
+kill -9 $original_pid
+
+echo "Sleeping..."
+
+sleep 3
+
+new_pid=""
+
+[ -r "$pid_path" ] && new_pid=`cat "$pid_path"`
+
+# echo "New PID: $new_pid"
+
+if [ "$expected_result" == "restarted" ]; then
+
+ if [ -z "$new_pid" ]; then
+ echo "Error: the process was killed."
+ exit 0
+ fi
+
+ if [ "$original_pid" -eq "$new_pid" ]; then
+ echo "Error: the process was not restarted."
+ exit 0
+ fi
+
+ echo "Success: the process was restarted."
+ exit 0
+
+else # $expected_result == killed
+
+ if [ "$new_pid" -a "$new_pid" -ne "$original_pid" ]; then
+ echo "Error: the process was restarted."
+ exit 0
+ fi
+
+ echo "Success: the process was killed."
+ exit 0
+fi
diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test
index fe6828916a3..cd3a8f0fd92 100644
--- a/mysql-test/t/loaddata.test
+++ b/mysql-test/t/loaddata.test
@@ -31,6 +31,34 @@ load data infile '../../std_data/loaddata4.dat' into table t1 fields terminated
select * from t1;
drop table t1;
+
+#
+# Bug #12053 LOAD DATA INFILE ignores NO_AUTO_VALUE_ON_ZERO setting
+#
+SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE=NO_AUTO_VALUE_ON_ZERO;
+create table t1(id integer not null auto_increment primary key);
+insert into t1 values(0);
+disable_query_log;
+eval SELECT * INTO OUTFILE '$MYSQL_TEST_DIR/var/tmp/t1' from t1;
+delete from t1;
+eval load data infile '$MYSQL_TEST_DIR/var/tmp/t1' into table t1;
+enable_query_log;
+select * from t1;
+--exec rm $MYSQL_TEST_DIR/var/tmp/t1
+
+disable_query_log;
+eval SELECT * INTO OUTFILE '$MYSQL_TEST_DIR/var/tmp/t1'
+FIELDS TERMINATED BY '' OPTIONALLY ENCLOSED BY '' LINES TERMINATED BY '\r\n'
+FROM t1;
+delete from t1;
+eval load data infile '$MYSQL_TEST_DIR/var/tmp/t1' into table t1
+FIELDS TERMINATED BY '' OPTIONALLY ENCLOSED BY '' LINES TERMINATED BY '\r\n';
+enable_query_log;
+select * from t1;
+--exec rm $MYSQL_TEST_DIR/var/tmp/t1
+SET @@SQL_MODE=@OLD_SQL_MODE;
+drop table t1;
+
# End of 4.1 tests
#
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index 7d708243a10..ff05867b7c1 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -288,6 +288,38 @@ create table t3 engine=merge union=(t1, t2) select * from t2;
create table t3 engine=merge union=(t1, t2) select (select max(a) from t2);
drop table t1, t2;
+#
+# Bug#9112 - Merge table with composite index producing invalid results with some queries
+# This test case will fail only without the bugfix and some
+# non-deterministic circumstances. It depends on properly initialized
+# "un-initialized" memory. At the time it happens with a standard
+# non-debug build. But there is no guarantee that this will be always so.
+#
+create table t1 (
+ a double(14,4),
+ b varchar(10),
+ index (a,b)
+) engine=merge union=(t2,t3);
+
+create table t2 (
+ a double(14,4),
+ b varchar(10),
+ index (a,b)
+) engine=myisam;
+
+create table t3 (
+ a double(14,4),
+ b varchar(10),
+ index (a,b)
+) engine=myisam;
+
+insert into t2 values ( null, '');
+insert into t2 values ( 9999999999.999, '');
+insert into t3 select * from t2;
+select min(a), max(a) from t1;
+flush tables;
+select min(a), max(a) from t1;
+drop table t1, t2, t3;
# BUG#6699 : no sorting on 'ref' retrieval
create table t1 (a int,b int,c int, index (a,b,c));
create table t2 (a int,b int,c int, index (a,b,c));
diff --git a/mysql-test/t/multi_statement.test b/mysql-test/t/multi_statement.test
index eb8d867f3f0..785aa749f5e 100644
--- a/mysql-test/t/multi_statement.test
+++ b/mysql-test/t/multi_statement.test
@@ -1,6 +1,10 @@
# PS doesn't support multi-statements
--disable_ps_protocol
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
select 1;
delimiter ||||;
select 2;
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index eeac2971788..73afcab5e27 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -578,6 +578,59 @@ checksum table t1;
# The above should give the same number as the following.
checksum table t2;
drop table t1, t2;
+
+#
+# BUG#12232: New myisam_stats_method variable.
+#
+
+show variables like 'myisam_stats_method';
+
+create table t1 (a int, key(a));
+insert into t1 values (0),(1),(2),(3),(4);
+insert into t1 select NULL from t1;
+
+# default: NULLs considered inequal
+analyze table t1;
+show index from t1;
+insert into t1 values (11);
+delete from t1 where a=11;
+check table t1;
+show index from t1;
+
+# Set nulls to be equal:
+set myisam_stats_method=nulls_equal;
+show variables like 'myisam_stats_method';
+insert into t1 values (11);
+delete from t1 where a=11;
+
+analyze table t1;
+show index from t1;
+
+insert into t1 values (11);
+delete from t1 where a=11;
+
+check table t1;
+show index from t1;
+
+# Set nulls back to be equal
+set myisam_stats_method=DEFAULT;
+show variables like 'myisam_stats_method';
+insert into t1 values (11);
+delete from t1 where a=11;
+
+analyze table t1;
+show index from t1;
+
+insert into t1 values (11);
+delete from t1 where a=11;
+
+check table t1;
+show index from t1;
+
+drop table t1;
+
+# End of 4.1 tests
+
#
# Test varchar
#
@@ -700,4 +753,3 @@ create table t3 (c1 int) engine=myisam pack_keys=default;
create table t4 (c1 int) engine=myisam pack_keys=2;
drop table t1, t2, t3;
-# End of 4.1 tests
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index c1d9813ea39..0b031ea1be8 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -19,16 +19,16 @@ insert into t1 values(1);
--disable_query_log
# Test delimiter : supplied on the command line
select "Test delimiter : from command line" as " ";
---exec $MYSQL test --delimiter=':' -e 'select * from t1:'
+--exec $MYSQL test --delimiter=":" -e "select * from t1:"
# Test delimiter :; supplied on the command line
select "Test delimiter :; from command line" as " ";
---exec $MYSQL test --delimiter=':;' -e 'select * from t1:;'
+--exec $MYSQL test --delimiter=":;" -e "select * from t1:;"
# Test 'go' command (vertical output) \G
select "Test 'go' command(vertical output) \G" as " ";
---exec $MYSQL test -e 'select * from t1\G'
+--exec $MYSQL test -e "select * from t1\G"
# Test 'go' command \g
select "Test 'go' command \g" as " ";
---exec $MYSQL test -e 'select * from t1\g'
+--exec $MYSQL test -e "select * from t1\g"
--enable_query_log
drop table t1;
@@ -37,7 +37,7 @@ drop table t1;
#
create table t1(a int);
lock tables t1 write;
---exec $MYSQL -e 'use test; select database();'
+--exec $MYSQL -e "use test; select database();"
unlock tables;
drop table t1;
diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test
index e5bd8c554cb..61d7d9994ba 100644
--- a/mysql-test/t/mysqlbinlog.test
+++ b/mysql-test/t/mysqlbinlog.test
@@ -102,10 +102,10 @@ select "--- --position --" as "";
select "--- reading stdin --" as "";
--enable_query_log
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
---exec cat $MYSQL_TEST_DIR/std_data/trunc_binlog.000001 | $MYSQL_BINLOG --short-form -
+--exec $MYSQL_BINLOG --short-form - < $MYSQL_TEST_DIR/std_data/trunc_binlog.000001
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
---exec cat $MYSQL_TEST_DIR/std_data/trunc_binlog.000001 | $MYSQL_BINLOG --short-form --position=79 -
+--exec $MYSQL_BINLOG --short-form --position=79 - < $MYSQL_TEST_DIR/std_data/trunc_binlog.000001
# clean up
drop table t1, t2;
diff --git a/mysql-test/t/mysqldump-max.test b/mysql-test/t/mysqldump-max.test
new file mode 100644
index 00000000000..fbea84808b4
--- /dev/null
+++ b/mysql-test/t/mysqldump-max.test
@@ -0,0 +1,73 @@
+# Embedded server doesn't support external clients
+--source include/not_embedded.inc
+--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
+
+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";
+create table t4 (id int(8), name varchar(32)) ENGINE="HEAP";
+create table t5 (id int(8), name varchar(32)) ENGINE="ARCHIVE";
+create table t6 (id int(8), name varchar(32)) ENGINE="InnoDB";
+
+insert into t1 values (1, 'first value');
+insert into t1 values (2, 'first value');
+insert into t1 values (3, 'first value');
+insert into t1 values (4, 'first value');
+insert into t1 values (5, 'first value');
+
+insert into t2 values (1, 'first value');
+insert into t2 values (2, 'first value');
+insert into t2 values (3, 'first value');
+insert into t2 values (4, 'first value');
+insert into t2 values (5, 'first value');
+
+insert into t3 values (1, 'first value');
+insert into t3 values (2, 'first value');
+insert into t3 values (3, 'first value');
+insert into t3 values (4, 'first value');
+insert into t3 values (5, 'first value');
+
+insert into t4 values (1, 'first value');
+insert into t4 values (2, 'first value');
+insert into t4 values (3, 'first value');
+insert into t4 values (4, 'first value');
+insert into t4 values (5, 'first value');
+
+insert into t5 values (1, 'first value');
+insert into t5 values (2, 'first value');
+insert into t5 values (3, 'first value');
+insert into t5 values (4, 'first value');
+insert into t5 values (5, 'first value');
+
+insert into t6 values (1, 'first value');
+insert into t6 values (2, 'first value');
+insert into t6 values (3, 'first value');
+insert into t6 values (4, 'first value');
+insert into t6 values (5, 'first value');
+
+select * from t1;
+select * from t2;
+select * from t3;
+select * from t4;
+select * from t5;
+select * from t6;
+
+--exec $MYSQL_DUMP --skip-comments --delayed-insert --insert-ignore --databases test
+--exec $MYSQL_DUMP --skip-comments --delayed-insert --databases test
+
+drop table t1;
+drop table t2;
+drop table t3;
+drop table t4;
+drop table t5;
+drop table t6;
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 2ce4b1071e2..7dafac2bde5 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -142,7 +142,7 @@ drop table t1;
--exec $MYSQL_DUMP --skip-comments --databases test
create database mysqldump_test_db character set latin2 collate latin2_bin;
---exec $MYSQL_DUMP --skip-comments --databases mysqldump_test_db;
+--exec $MYSQL_DUMP --skip-comments --databases mysqldump_test_db
drop database mysqldump_test_db;
#
@@ -758,17 +758,7 @@ select * from v3 where b in (1, 2, 3, 4, 5, 6, 7);
create view v2 as
select v3.a from v3, v1 where v1.a=v3.a and v3.b=3 limit 1;
---exec $MYSQL_DUMP test > var/tmp/bug10927.sql
-drop view v1, v2, v3;
-drop table t1;
---exec $MYSQL test < var/tmp/bug10927.sql
-
-# Without dropping the original tables in between
---exec $MYSQL_DUMP test > var/tmp/bug10927.sql
---exec $MYSQL test < var/tmp/bug10927.sql
-show full tables;
-show create view v1;
-select * from v1;
+--exec $MYSQL_DUMP --skip-comments test
drop view v1, v2, v3;
drop table t1;
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index c903749839d..11fbb023963 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -428,9 +428,8 @@ echo ;
# ----------------------------------------------------------------------------
# Illegal use of exec
-# Disabled, some shells prints the failed command regardless of pipes
-#--error 1
-#--exec echo "--exec ';' 2> /dev/null" | $MYSQL_TEST 2>&1
+--error 1
+--exec echo "--exec false" | $MYSQL_TEST 2>&1
--error 1
--exec echo "--exec " | $MYSQL_TEST 2>&1
@@ -677,9 +676,8 @@ system echo "hej" > /dev/null;
--exec echo "system;" | $MYSQL_TEST 2>&1
--error 1
--exec echo "system $NONEXISTSINFVAREABLI;" | $MYSQL_TEST 2>&1
-# Disabled, some shells prints the failed command regardless of pipes
-#--error 1
-#--exec echo "system NonExistsinfComamdn 2> /dev/null;" | $MYSQL_TEST 2>&1
+--error 1
+--exec echo "system false;" | $MYSQL_TEST 2>&1
--disable_abort_on_error
system NonExistsinfComamdn;
@@ -814,11 +812,11 @@ select "a" as col1, "c" as col2;
# ----------------------------------------------------------------------------
# -x <file_name>, use the file specified after -x as the test file
-#--exec $MYSQL_TEST < $MYSQL_TEST_DIR/include/mysqltest-x.inc 2>&1
-#--exec $MYSQL_TEST -x $MYSQL_TEST_DIR/include/mysqltest-x.inc 2>&1
-#--exec $MYSQL_TEST --result_file=$MYSQL_TEST_DIR/include/mysqltest-x.inc 2>&1
-#--error 1
-#--exec $MYSQL_TEST -x non_existing_file.inc 2>&1
+--exec $MYSQL_TEST < $MYSQL_TEST_DIR/include/mysqltest-x.inc
+--exec $MYSQL_TEST -x $MYSQL_TEST_DIR/include/mysqltest-x.inc
+--exec $MYSQL_TEST --test_file=$MYSQL_TEST_DIR/include/mysqltest-x.inc
+--error 1
+--exec $MYSQL_TEST -x non_existing_file.inc 2>&1
# ----------------------------------------------------------------------------
diff --git a/mysql-test/t/ndb_alter_table.test b/mysql-test/t/ndb_alter_table.test
index 0f7b0bb7edc..357f658a296 100644
--- a/mysql-test/t/ndb_alter_table.test
+++ b/mysql-test/t/ndb_alter_table.test
@@ -203,5 +203,124 @@ drop table t4;
show tables;
connection server1;
+create table t1 (
+ai bigint auto_increment,
+c001 int(11) not null,
+c002 int(11) not null,
+c003 int(11) not null,
+c004 int(11) not null,
+c005 int(11) not null,
+c006 int(11) not null,
+c007 int(11) not null,
+c008 int(11) not null,
+c009 int(11) not null,
+c010 int(11) not null,
+c011 int(11) not null,
+c012 int(11) not null,
+c013 int(11) not null,
+c014 int(11) not null,
+c015 int(11) not null,
+c016 int(11) not null,
+c017 int(11) not null,
+c018 int(11) not null,
+c019 int(11) not null,
+c020 int(11) not null,
+c021 int(11) not null,
+c022 int(11) not null,
+c023 int(11) not null,
+c024 int(11) not null,
+c025 int(11) not null,
+c026 int(11) not null,
+c027 int(11) not null,
+c028 int(11) not null,
+c029 int(11) not null,
+c030 int(11) not null,
+c031 int(11) not null,
+c032 int(11) not null,
+c033 int(11) not null,
+c034 int(11) not null,
+c035 int(11) not null,
+c036 int(11) not null,
+c037 int(11) not null,
+c038 int(11) not null,
+c039 int(11) not null,
+c040 int(11) not null,
+c041 int(11) not null,
+c042 int(11) not null,
+c043 int(11) not null,
+c044 int(11) not null,
+c045 int(11) not null,
+c046 int(11) not null,
+c047 int(11) not null,
+c048 int(11) not null,
+c049 int(11) not null,
+c050 int(11) not null,
+c051 int(11) not null,
+c052 int(11) not null,
+c053 int(11) not null,
+c054 int(11) not null,
+c055 int(11) not null,
+c056 int(11) not null,
+c057 int(11) not null,
+c058 int(11) not null,
+c059 int(11) not null,
+c060 int(11) not null,
+c061 int(11) not null,
+c062 int(11) not null,
+c063 int(11) not null,
+c064 int(11) not null,
+c065 int(11) not null,
+c066 int(11) not null,
+c067 int(11) not null,
+c068 int(11) not null,
+c069 int(11) not null,
+c070 int(11) not null,
+c071 int(11) not null,
+c072 int(11) not null,
+c073 int(11) not null,
+c074 int(11) not null,
+c075 int(11) not null,
+c076 int(11) not null,
+c077 int(11) not null,
+c078 int(11) not null,
+c079 int(11) not null,
+c080 int(11) not null,
+c081 int(11) not null,
+c082 int(11) not null,
+c083 int(11) not null,
+c084 int(11) not null,
+c085 int(11) not null,
+c086 int(11) not null,
+c087 int(11) not null,
+c088 int(11) not null,
+c089 int(11) not null,
+c090 int(11) not null,
+c091 int(11) not null,
+c092 int(11) not null,
+c093 int(11) not null,
+c094 int(11) not null,
+c095 int(11) not null,
+c096 int(11) not null,
+c097 int(11) not null,
+c098 int(11) not null,
+c099 int(11) not null,
+c100 int(11) not null,
+c101 int(11) not null,
+c102 int(11) not null,
+c103 int(11) not null,
+c104 int(11) not null,
+c105 int(11) not null,
+c106 int(11) not null,
+c107 int(11) not null,
+c108 int(11) not null,
+c109 int(11) not null,
+primary key (ai),
+unique key tx1 (c002, c003, c004, c005)) engine=ndb;
+
+create index tx2
+on t1 (c010, c011, c012, c013);
+
+drop table t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/ndb_config.test b/mysql-test/t/ndb_config.test
index ab3063af672..9d1c107472f 100644
--- a/mysql-test/t/ndb_config.test
+++ b/mysql-test/t/ndb_config.test
@@ -6,5 +6,8 @@
--exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=nodeid,host,DataMemory,IndexMemory --type=ndbd 2> /dev/null
--exec $NDB_TOOLS_DIR/ndb_config --no-defaults -r \\n -f " " --query=nodeid,host,DataMemory,IndexMemory --type=ndbd 2> /dev/null
--exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=nodeid --type=ndbd --host=localhost 2> /dev/null
+--exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=type,nodeid,host --config-file=$NDB_BACKUP_DIR/config.ini 2> /dev/null
# End of 4.1 tests
+
+--exec $NDB_TOOLS_DIR/ndb_config --defaults-group-suffix=.jonas --defaults-file=$MYSQL_TEST_DIR/std_data/ndb_config_mycnf1.cnf --query=type,nodeid,host,IndexMemory,DataMemory --mycnf 2> /dev/null
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index bbe5798e7e5..11c5e8d7bc5 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -3,7 +3,7 @@
#
--disable_warnings
-drop table if exists t1, t2;
+drop table if exists t1, t2, t3;
--enable_warnings
CREATE TABLE t1 (
@@ -578,3 +578,51 @@ DELETE FROM t1 WHERE NOT(a <=> 2);
SELECT * FROM t1;
DROP TABLE t1;
+
+#
+# BUG#13317: range optimization doesn't work for IN over VIEW.
+#
+create table t1 (a int, b int, primary key(a,b));
+create view v1 as select a, b from t1;
+
+INSERT INTO `t1` VALUES
+(0,0),(1,0),(2,0),(3,0),(4,0),(5,1),(6,1),(7,1),(8,1),(9,1),(10,2),(11,2),(12,2)
+,(13,2),(14,2),(15,3),(16,3),(17,3),(18,3),(19,3);
+
+--replace_column 9 #
+explain select * from t1 where a in (3,4) and b in (1,2,3);
+--replace_column 9 #
+explain select * from v1 where a in (3,4) and b in (1,2,3);
+--replace_column 9 #
+explain select * from t1 where a between 3 and 4 and b between 1 and 2;
+--replace_column 9 #
+explain select * from v1 where a between 3 and 4 and b between 1 and 2;
+
+drop view v1;
+drop table t1;
+
+# BUG#13455:
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1 (a varchar(10), filler char(200), key(a)) charset=binary;
+insert into t1 values ('a','');
+insert into t1 values ('a ','');
+insert into t1 values ('a ', '');
+insert into t1 select concat('a', 1000 + A.a + 10 * (B.a + 10 * C.a)), ''
+ from t3 A, t3 B, t3 C;
+
+create table t2 (a varchar(10), filler char(200), key(a));
+insert into t2 select * from t1;
+
+--replace_column 9 #
+explain select * from t1 where a between 'a' and 'a ';
+--replace_column 9 #
+explain select * from t1 where a = 'a' or a='a ';
+
+--replace_column 9 #
+explain select * from t2 where a between 'a' and 'a ';
+--replace_column 9 #
+explain select * from t2 where a = 'a' or a='a ';
+
+drop table t1,t2,t3;
diff --git a/mysql-test/t/rpl_multi_delete.test b/mysql-test/t/rpl_multi_delete.test
index 2fd7b820b1a..4a8c0ab6912 100644
--- a/mysql-test/t/rpl_multi_delete.test
+++ b/mysql-test/t/rpl_multi_delete.test
@@ -16,10 +16,26 @@ sync_with_master;
select * from t1;
select * from t2;
+# End of 4.1 tests
+
+# Check if deleting 0 rows is binlogged (BUG#13348)
+
connection master;
-drop table t1,t2;
-save_master_pos;
-connection slave;
-sync_with_master;
+delete from t1;
+delete from t2;
-# End of 4.1 tests
+sync_slave_with_master;
+# force a difference to see if master's multi-DELETE will correct it
+insert into t1 values(1);
+insert into t2 values(1);
+
+connection master;
+DELETE t1.*, t2.* from t1, t2;
+
+sync_slave_with_master;
+select * from t1;
+select * from t2;
+
+connection master;
+drop table t1,t2;
+sync_slave_with_master;
diff --git a/mysql-test/t/rpl_multi_delete2-slave.opt b/mysql-test/t/rpl_multi_delete2-slave.opt
index b828d03fafb..0febb2891b1 100644
--- a/mysql-test/t/rpl_multi_delete2-slave.opt
+++ b/mysql-test/t/rpl_multi_delete2-slave.opt
@@ -1 +1 @@
---replicate-wild-ignore-table=test.%
+"--replicate-rewrite-db=mysqltest_from->mysqltest_to" --replicate-do-table=mysqltest_to.a
diff --git a/mysql-test/t/rpl_multi_delete2.test b/mysql-test/t/rpl_multi_delete2.test
index 62d95a3a90f..c50311de363 100644
--- a/mysql-test/t/rpl_multi_delete2.test
+++ b/mysql-test/t/rpl_multi_delete2.test
@@ -1,4 +1,41 @@
+#multi delete replication bugs
+
+
source include/master-slave.inc;
+
+#BUG#11139 - improper wild-table and table rules
+#checking for multi deletes with an alias
+
+connection master;
+set sql_log_bin=0;
+create database mysqltest_from;
+set sql_log_bin=1;
+
+connection slave;
+create database mysqltest_to;
+
+
+connection master;
+use mysqltest_from;
+--disable_warnings
+drop table if exists a;
+--enable_warnings
+CREATE TABLE a (i INT);
+INSERT INTO a VALUES(1);
+DELETE alias FROM a alias WHERE alias.i=1;
+SELECT * FROM a;
+insert into a values(2),(3);
+delete a alias FROM a alias where alias.i=2;
+select * from a;
+save_master_pos;
+connection slave;
+
+use mysqltest_to;
+sync_with_master;
+select * from a;
+
+# BUG#3461
+connection master;
create table t1 (a int);
create table t2 (a int);
@@ -19,7 +56,13 @@ select * from t1;
error 1146;
select * from t2;
+# cleanup
connection master;
-drop table t1,t2;
+set sql_log_bin=0;
+drop database mysqltest_from;
+set sql_log_bin=1;
+connection slave;
+drop database mysqltest_to;
# End of 4.1 tests
+
diff --git a/mysql-test/t/rpl_multi_update.test b/mysql-test/t/rpl_multi_update.test
index dd75edb3055..f6a960434ad 100644
--- a/mysql-test/t/rpl_multi_update.test
+++ b/mysql-test/t/rpl_multi_update.test
@@ -24,3 +24,26 @@ connection slave;
sync_with_master;
# End of 4.1 tests
+
+# Check if updating 0 rows is binlogged (BUG#13348)
+
+connection master;
+delete from t1;
+delete from t2;
+insert into t1 values(1,1);
+insert into t2 values(1,1);
+
+sync_slave_with_master;
+# force a difference to see if master's multi-UPDATE will correct it
+update t1 set a=2;
+
+connection master;
+UPDATE t1, t2 SET t1.a = t2.a;
+
+sync_slave_with_master;
+select * from t1;
+select * from t2;
+
+connection master;
+drop table t1, t2;
+sync_slave_with_master;
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 61242b3d96e..f7de7239292 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -2181,6 +2181,16 @@ select found_rows();
DROP TABLE t1;
+#
+# Bug #13356 assertion failed in resolve_const_item()
+#
+create table t1(f1 int, f2 int);
+create table t2(f3 int);
+select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,1));
+select f1 from t1,t2 where f1=f2 and (f1,NULL) = ((1,1));
+select f1 from t1,t2 where f1=f2 and (f1,f2) = ((1,NULL));
+drop table t1,t2;
+
# End of 4.1 tests
#
@@ -2523,3 +2533,79 @@ select * from t1, t2 join t3 on (t2.b = t3.b and t1.a = t3.a);
select * from t1 join t2 join t3 join t4 on (t1.a = t4.c and t2.b = t4.c);
select * from t1 join t2 join t4 using (c);
drop table t1, t2, t3, t4;
+
+#
+# Bug #12291 Table wasn't reinited for index scan after sequential scan
+#
+create table t1(x int, y int);
+create table t2(x int, y int);
+create table t3(x int, primary key(x));
+insert into t1 values (1, 1), (2, 1), (3, 1), (4, 3), (5, 6), (6, 6);
+insert into t2 values (1, 1), (2, 1), (3, 3), (4, 6), (5, 6);
+insert into t3 values (1), (2), (3), (4), (5);
+select t1.x, t3.x from t1, t2, t3 where t1.x = t2.x and t3.x >= t1.y and t3.x <= t2.y;
+drop table t1,t2,t3;
+
+#
+# Bug #13127 LEFT JOIN against a VIEW returns NULL instead of correct value
+#
+
+create table t1 (id char(16) not null default '', primary key (id));
+insert into t1 values ('100'),('101'),('102');
+create table t2 (id char(16) default null);
+insert into t2 values (1);
+create view v1 as select t1.id from t1;
+create view v2 as select t2.id from t2;
+create view v3 as select (t1.id+2) as id from t1 natural left join t2;
+
+# all queries must return the same result
+select t1.id from t1 left join v2 using (id);
+select t1.id from v2 right join t1 using (id);
+select t1.id from t1 left join v3 using (id);
+select * from t1 left join v2 using (id);
+select * from v2 right join t1 using (id);
+select * from t1 left join v3 using (id);
+
+select v1.id from v1 left join v2 using (id);
+select v1.id from v2 right join v1 using (id);
+select v1.id from v1 left join v3 using (id);
+select * from v1 left join v2 using (id);
+select * from v2 right join v1 using (id);
+select * from v1 left join v3 using (id);
+
+drop table t1, t2;
+drop view v1, v2, v3;
+
+#
+# Bug #13597 Column in ON condition not resolved if references a table in
+# nested right join.
+#
+
+create table a (
+ id int(11) not null default '0'
+) engine=myisam default charset=latin1;
+
+insert into a values (123),(191),(192);
+
+create table b (
+ id char(16) character set utf8 not null default ''
+) engine=myisam default charset=latin1;
+
+insert into b values ('58013'),('58014'),('58015'),('58016');
+
+create table c (
+ a_id int(11) not null default '0',
+ b_id char(16) character set utf8 default null
+) engine=myisam default charset=latin1;
+
+insert into c values
+(123,null),(123,null),(123,null),(123,null),(123,null),(123,'58013');
+
+-- both queries are equivalent
+select count(*)
+from a inner join (c left join b on b.id = c.b_id) on a.id = c.a_id;
+
+select count(*)
+from a inner join (b right join c on b.id = c.b_id) on a.id = c.a_id;
+
+drop table a, b, c;
diff --git a/mysql-test/t/skip_name_resolve.test b/mysql-test/t/skip_name_resolve.test
index 02339ca14c5..b67869692d2 100644
--- a/mysql-test/t/skip_name_resolve.test
+++ b/mysql-test/t/skip_name_resolve.test
@@ -8,3 +8,13 @@ REVOKE ALL ON test.* FROM mysqltest_1@'127.0.0.1/255.255.255.255';
DROP USER mysqltest_1@'127.0.0.1/255.255.255.255';
# End of 4.1 tests
+
+# Bug #13407 "Remote connecting crashes server".
+# Server crashed when one used USER() function in connection for which
+# was impossible to obtain peer hostname.
+connect (con1, 127.0.0.1, root, , test, $MASTER_MYPORT, );
+--replace_column 1 #
+select user();
+--replace_column 1 # 6 # 3 #
+show processlist;
+connection default;
diff --git a/mysql-test/t/sp-big.test b/mysql-test/t/sp-big.test
index 769d77dbef9..389a6f04504 100644
--- a/mysql-test/t/sp-big.test
+++ b/mysql-test/t/sp-big.test
@@ -31,3 +31,52 @@ call test.longprocedure(@value); select @value;
drop procedure test.longprocedure;
drop table t1;
+#
+# Bug #9819 "Cursors: Mysql Server Crash while fetching from table with 5
+# million records.":
+# To really test the bug, increase the number of loop iterations ($1).
+# For 4 millions set $1 to 22.
+create table t1 (f1 char(100) , f2 mediumint , f3 int , f4 real, f5 numeric);
+insert into t1 (f1, f2, f3, f4, f5) values
+("This is a test case for for Bug#9819", 1, 2, 3.0, 4.598);
+create table t2 like t1;
+let $1=8;
+--disable_query_log
+--disable_result_log
+while ($1)
+{
+ eval insert into t1 select * from t1;
+ dec $1;
+}
+--enable_result_log
+--enable_query_log
+select count(*) from t1;
+select count(*) from t2;
+delimiter |;
+create procedure p1()
+begin
+ declare done integer default 0;
+ declare vf1 char(100) ;
+ declare vf2 mediumint;
+ declare vf3 int ;
+ declare vf4 real ;
+ declare vf5 numeric ;
+ declare cur1 cursor for select f1,f2,f3,f4,f5 from t1;
+ declare continue handler for sqlstate '02000' set done = 1;
+ open cur1;
+ while done <> 1 do
+ fetch cur1 into vf1, vf2, vf3, vf4, vf5;
+ if not done then
+ insert into t2 values (vf1, vf2, vf3, vf4, vf5);
+ end if;
+ end while;
+ close cur1;
+end|
+delimiter ;|
+call p1();
+select count(*) from t1;
+select count(*) from t2;
+select f1 from t1 limit 1;
+select f1 from t2 limit 1;
+drop procedure p1;
+drop table t1, t2;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index b6a8eb6518a..e16e7456056 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -4038,6 +4038,27 @@ end|
drop function bug9048|
#
+# BUG#12812 create view calling a function works without execute right
+# on function
+--disable_warnings
+drop function if exists bug12812|
+--enable_warnings
+create function bug12812() returns char(2)
+begin
+ return 'ok';
+end;
+create user user_bug12812@localhost IDENTIFIED BY 'ABC'|
+--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
+connect (test_user_12812,localhost,user_bug12812,ABC,test)|
+--error 1370
+SELECT test.bug12812()|
+--error 1370
+CREATE VIEW v1 AS SELECT test.bug12812()|
+# Cleanup
+connection default|
+disconnect test_user_12812|
+DROP USER user_bug12812@localhost|
+drop function bug12812|
# Bug #12849 Stored Procedure: Crash on procedure call with CHAR type
# 'INOUT' parameter
#
@@ -4208,6 +4229,93 @@ drop procedure bug12979_2|
#
+# BUG#6127: Stored procedure handlers within handlers don't work
+#
+--disable_warnings
+drop table if exists t3|
+drop procedure if exists bug6127|
+--enable_warnings
+create table t3 (s1 int unique)|
+
+set @sm=@@sql_mode|
+set sql_mode='traditional'|
+
+create procedure bug6127()
+begin
+ declare continue handler for sqlstate '23000'
+ begin
+ declare continue handler for sqlstate '22003'
+ insert into t3 values (0);
+
+ insert into t3 values (1000000000000000);
+ end;
+
+ insert into t3 values (1);
+ insert into t3 values (1);
+end|
+
+call bug6127()|
+select * from t3|
+--error ER_DUP_ENTRY
+call bug6127()|
+select * from t3|
+set sql_mode=@sm|
+drop table t3|
+drop procedure bug6127|
+
+
+#
+# BUG#12589: Assert when creating temp. table from decimal stored procedure
+# variable
+#
+--disable_warnings
+drop procedure if exists bug12589_1|
+drop procedure if exists bug12589_2|
+drop procedure if exists bug12589_3|
+--enable_warnings
+create procedure bug12589_1()
+begin
+ declare spv1 decimal(3,3);
+ set spv1= 123.456;
+
+ set spv1 = 'test';
+ create temporary table tm1 as select spv1;
+ show create table tm1;
+ drop temporary table tm1;
+end|
+
+create procedure bug12589_2()
+begin
+ declare spv1 decimal(6,3);
+ set spv1= 123.456;
+
+ create temporary table tm1 as select spv1;
+ show create table tm1;
+ drop temporary table tm1;
+end|
+
+create procedure bug12589_3()
+begin
+ declare spv1 decimal(6,3);
+ set spv1= -123.456;
+
+ create temporary table tm1 as select spv1;
+ show create table tm1;
+ drop temporary table tm1;
+end|
+
+# Note: The type of the field will match the value, not the declared
+# type of the variable. (This is a type checking issue which
+# might be changed later.)
+
+# Warning expected from "set spv1 = 'test'", the value is set to decimal "0".
+call bug12589_1()|
+# No warnings here
+call bug12589_2()|
+call bug12589_3()|
+
+
+#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
diff --git a/mysql-test/t/sql_mode.test b/mysql-test/t/sql_mode.test
index 10db520cd12..b11afe9e59d 100644
--- a/mysql-test/t/sql_mode.test
+++ b/mysql-test/t/sql_mode.test
@@ -86,6 +86,18 @@ drop table t1 ;
--error 1231
set @@SQL_MODE=NULL;
+#
+# Bug #797: in sql_mode=ANSI, show create table ignores auto_increment
+#
+set session sql_mode=ansi;
+create table t1
+(f1 integer auto_increment primary key,
+ f2 timestamp default current_timestamp on update current_timestamp);
+show create table t1;
+set session sql_mode=no_field_options;
+show create table t1;
+drop table t1;
+
# End of 4.1 tests
#
diff --git a/mysql-test/t/temp_table.test b/mysql-test/t/temp_table.test
index 9a7678ed712..6b3991c9c78 100644
--- a/mysql-test/t/temp_table.test
+++ b/mysql-test/t/temp_table.test
@@ -4,6 +4,7 @@
--disable_warnings
drop table if exists t1,t2;
+drop view if exists v1;
--enable_warnings
CREATE TABLE t1 (c int not null, d char (10) not null);
@@ -91,18 +92,18 @@ show status like "created_tmp%tables";
drop table t1;
# Fix for BUG#8921: Check that temporary table is ingored by view commands.
-create temporary table t1 as select 'This is temp. table' A;
-create view t1 as select 'This is view' A;
-select * from t1;
-show create table t1;
-show create view t1;
-drop view t1;
-select * from t1;
-create view t1 as select 'This is view again' A;
-select * from t1;
-drop table t1;
-select * from t1;
-drop view t1;
+create temporary table v1 as select 'This is temp. table' A;
+create view v1 as select 'This is view' A;
+select * from v1;
+show create table v1;
+show create view v1;
+drop view v1;
+select * from v1;
+create view v1 as select 'This is view again' A;
+select * from v1;
+drop table v1;
+select * from v1;
+drop view v1;
# Bug #8497: tmpdir with extra slashes would cause failures
#
diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test
index 6906cfc2808..0c45dea21bb 100644
--- a/mysql-test/t/type_bit.test
+++ b/mysql-test/t/type_bit.test
@@ -224,3 +224,5 @@ select a1, a2, b1+0, b2+0 from t1 join t2 on a1 = a2;
select a1, a2, b1+0, b2+0 from t1 join t2 on a1 = a2 order by a1;
select a1, a2, b1+0, b2+0 from t1 join t2 on b1 = b2;
select sum(a1), b1+0, b2+0 from t1 join t2 on b1 = b2 group by b1 order by 1;
+select 1 from t1 join t2 on b1 = b2 group by b1 order by 1;
+select b1+0,sum(b1), sum(b2) from t1 join t2 on b1 = b2 group by b1 order by 1;
diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test
index 44032fde46f..1f6310cb819 100644
--- a/mysql-test/t/type_decimal.test
+++ b/mysql-test/t/type_decimal.test
@@ -268,6 +268,16 @@ insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000
select * from t1;
drop table t1;
+#
+# Bug #7589: a problem with update from column
+#
+
+create table t1(a decimal(10,5), b decimal(10,1));
+insert into t1 values(123.12345, 123.12345);
+update t1 set b=a;
+select * from t1;
+drop table t1;
+
# End of 4.1 tests
#
diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test
index c0f1854d5b2..cf2a2676ab0 100644
--- a/mysql-test/t/type_float.test
+++ b/mysql-test/t/type_float.test
@@ -147,3 +147,12 @@ select * from t1 where reckey=1.09E2;
drop table t1;
# End of 4.1 tests
+
+#
+# bug #12694 (float(m,d) specifications)
+#
+
+--error 1427
+create table t1 (s1 float(0,2));
+--error 1427
+create table t1 (s1 float(1,2));
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index d4b0c1746af..daa83ef0fa4 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -443,14 +443,6 @@ create table t1 SELECT b from t2 UNION select tx from t2;
select * from t1;
show create table t1;
drop table t1,t2;
-create table t1 (d decimal(10,1));
-create table t2 (d decimal(10,9));
-insert into t1 values ("100000000.0");
-insert into t2 values ("1.23456780");
-create table t3 select * from t2 union select * from t1;
-select * from t3;
-show create table t3;
-drop table t1,t2,t3;
create table t1 select 1 union select -1;
select * from t1;
show create table t1;
diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test
index dd6c36d8414..3822d1fe4e7 100644
--- a/mysql-test/t/update.test
+++ b/mysql-test/t/update.test
@@ -215,4 +215,16 @@ UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1);
select * from t1;
drop table t1,t2;
+#
+# Bug #13180 sometimes server accepts sum func in update/delete where condition
+#
+create table t1(f1 int);
+select DATABASE();
+--error 1111
+update t1 set f1=1 where count(*)=1;
+select DATABASE();
+--error 1111
+delete from t1 where count(*)=1;
+drop table t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 59ec47821f6..15c8cccf69c 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -786,6 +786,19 @@ select * from v1;
drop view v1;
#
+# renaming views
+#
+create table t1 (a int);
+create view v1 as select a from t1;
+create database seconddb;
+-- error 1450
+rename table v1 to seconddb.v1;
+rename table v1 to v2;
+drop table t1;
+drop view v2;
+drop database seconddb;
+
+#
# bug handling from VIEWs
#
create view v1 as select 'a',1;
@@ -2030,6 +2043,7 @@ drop view v1;
drop table t1;
# BUG#12941
#
+--disable_warnings
create table t1 (
r_object_id char(16) NOT NULL,
group_name varchar(32) NOT NULL
@@ -2040,6 +2054,7 @@ create table t2 (
i_position int(11) NOT NULL,
users_names varchar(32) default NULL
) Engine = InnoDB;
+--enable_warnings
create view v1 as select r_object_id, group_name from t1;
create view v2 as select r_object_id, i_position, users_names from t2;
@@ -2124,3 +2139,31 @@ SELECT * FROM v3;
DROP TABLE t1;
DROP VIEW v1, v2, v3;
+
+#
+# Bug #13411: crash when using non-qualified view column in HAVING clause
+#
+
+CREATE TABLE t1 ( a int, b int );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+CREATE VIEW v1 AS SELECT a,b FROM t1;
+SELECT t1.a FROM t1 GROUP BY t1.a HAVING a > 1;
+SELECT v1.a FROM v1 GROUP BY v1.a HAVING a > 1;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+#
+# Bug #13410: failed name resolution for qualified view column in HAVING
+#
+
+CREATE TABLE t1 ( a int, b int );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+CREATE VIEW v1 AS SELECT a,b FROM t1;
+SELECT t1.a FROM t1 GROUP BY t1.a HAVING t1.a > 1;
+SELECT v1.a FROM v1 GROUP BY v1.a HAVING v1.a > 1;
+SELECT t_1.a FROM t1 AS t_1 GROUP BY t_1.a HAVING t_1.a IN (1,2,3);
+SELECT v_1.a FROM v1 AS v_1 GROUP BY v_1.a HAVING v_1.a IN (1,2,3);
+
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/t/view_query_cache.test b/mysql-test/t/view_query_cache.test
index bca111a5ed1..81994407641 100644
--- a/mysql-test/t/view_query_cache.test
+++ b/mysql-test/t/view_query_cache.test
@@ -84,4 +84,16 @@ select * from v3;
drop view v3;
drop table t1, t2;
+#
+# Bug #13424 locking view with query cache enabled crashes server
+#
+create table t1(f1 int);
+insert into t1 values(1),(2),(3);
+create view v1 as select * from t1;
+set query_cache_wlock_invalidate=1;
+lock tables v1 read /*!32311 local */;
+unlock tables;
+set query_cache_wlock_invalidate=default;
+drop view v1;
+drop table t1;
set GLOBAL query_cache_size=default;
diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test
index 1347fd05415..92405bac137 100644
--- a/mysql-test/t/xa.test
+++ b/mysql-test/t/xa.test
@@ -26,13 +26,24 @@ select * from t1;
xa start 'testa','testb';
insert t1 values (30);
+
+--error 1399
+commit;
+
xa end 'testa','testb';
+--error 1399
+begin;
+--error 1399
+create table t2 (a int);
+
connect (con1,localhost,,,);
connection con1;
--error 1440
xa start 'testa','testb';
+--error 1440
+xa start 'testa','testb', 123;
# gtrid [ , bqual [ , formatID ] ]
xa start 0x7465737462, 0x2030405060, 0xb;
@@ -40,6 +51,9 @@ insert t1 values (40);
xa end 'testb',' 0@P`',11;
xa prepare 'testb',0x2030405060,11;
+--error 1399
+start transaction;
+
xa recover;
# uncomment the line below when binlog will be able to prepare
diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp
index 26f3477140b..7737810653d 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -52,6 +52,16 @@
}
{
+ pthread pthread_key_create
+ Memcheck:Leak
+ fun:malloc
+ fun:*
+ fun:*
+ fun:pthread_key_create
+ fun:my_thread_global_init
+}
+
+{
pthread strstr uninit
Memcheck:Cond
fun:strstr
@@ -127,8 +137,18 @@
{
libz deflate
Memcheck:Cond
- obj:/usr/lib/libz.so.*
- obj:/usr/lib/libz.so.*
+ obj:*/libz.so.*
+ obj:*/libz.so.*
fun:deflate
fun:compress2
}
+
+{
+ libz deflate2
+ Memcheck:Cond
+ obj:*/libz.so.*
+ obj:*/libz.so.*
+ fun:deflate
+ obj:*/libz.so.*
+ fun:gzflush
+}
diff --git a/mysys/default.c b/mysys/default.c
index bca3ec0fed3..edd02402a2a 100644
--- a/mysys/default.c
+++ b/mysys/default.c
@@ -42,6 +42,7 @@
#include <winbase.h>
#endif
+const char *defaults_file=0;
const char *defaults_group_suffix=0;
char *defaults_extra_file=0;
@@ -138,8 +139,11 @@ int my_search_option_files(const char *conf_file, int *argc, char ***argv,
defaults_group_suffix= getenv(STRINGIFY_ARG(DEFAULT_GROUP_SUFFIX_ENV));
if (forced_extra_defaults)
- defaults_extra_file= forced_extra_defaults;
+ defaults_extra_file= (char *) forced_extra_defaults;
+ if (forced_default_file)
+ defaults_file= forced_default_file;
+
/*
We can only handle 'defaults-group-suffix' if we are called from
load_defaults() as otherwise we can't know the type of 'func_ctx'
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index b000af19aa0..63f5dc964da 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -165,7 +165,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
(ulong) info, (int) type, (ulong) seek_offset));
info->file= file;
- info->type= 0; /* Don't set it until mutex are created */
+ info->type= TYPE_NOT_SET; /* Don't set it until mutex are created */
info->pos_in_file= seek_offset;
info->pre_close = info->pre_read = info->post_read = 0;
info->arg = 0;
@@ -1246,7 +1246,7 @@ int end_io_cache(IO_CACHE *info)
if (info->type == SEQ_READ_APPEND)
{
/* Destroy allocated mutex */
- info->type=0;
+ info->type= TYPE_NOT_SET;
#ifdef THREAD
pthread_mutex_destroy(&info->append_buffer_lock);
#endif
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index a86b6a2f1f4..69410e9faaa 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -161,10 +161,12 @@ KEY_CACHE *dflt_key_cache= &dflt_key_cache_var;
#define FLUSH_CACHE 2000 /* sort this many blocks at once */
static int flush_all_key_blocks(KEY_CACHE *keycache);
+#ifdef THREAD
static void link_into_queue(KEYCACHE_WQUEUE *wqueue,
struct st_my_thread_var *thread);
static void unlink_from_queue(KEYCACHE_WQUEUE *wqueue,
struct st_my_thread_var *thread);
+#endif
static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block);
static void test_key_cache(KEY_CACHE *keycache,
const char *where, my_bool lock);
@@ -215,6 +217,7 @@ static void keycache_debug_print _VARARGS((const char *fmt,...));
#endif /* defined(KEYCACHE_DEBUG_LOG) && defined(KEYCACHE_DEBUG) */
#if defined(KEYCACHE_DEBUG) || !defined(DBUG_OFF)
+#ifdef THREAD
static long keycache_thread_id;
#define KEYCACHE_THREAD_TRACE(l) \
KEYCACHE_DBUG_PRINT(l,("|thread %ld",keycache_thread_id))
@@ -226,6 +229,11 @@ static long keycache_thread_id;
#define KEYCACHE_THREAD_TRACE_END(l) \
KEYCACHE_DBUG_PRINT(l,("]thread %ld",keycache_thread_id))
+#else /* THREAD */
+#define KEYCACHE_THREAD_TRACE(l) KEYCACHE_DBUG_PRINT(l,(""))
+#define KEYCACHE_THREAD_TRACE_BEGIN(l) KEYCACHE_DBUG_PRINT(l,(""))
+#define KEYCACHE_THREAD_TRACE_END(l) KEYCACHE_DBUG_PRINT(l,(""))
+#endif /* THREAD */
#else
#define KEYCACHE_THREAD_TRACE_BEGIN(l)
#define KEYCACHE_THREAD_TRACE_END(l)
@@ -492,6 +500,7 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
keycache_pthread_mutex_lock(&keycache->cache_lock);
+#ifdef THREAD
wqueue= &keycache->resize_queue;
thread= my_thread_var;
link_into_queue(wqueue, thread);
@@ -500,6 +509,7 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
{
keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock);
}
+#endif
keycache->resize_in_flush= 1;
if (flush_all_key_blocks(keycache))
@@ -512,12 +522,16 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
}
keycache->resize_in_flush= 0;
keycache->can_be_used= 0;
+#ifdef THREAD
while (keycache->cnt_for_resize_op)
{
KEYCACHE_DBUG_PRINT("resize_key_cache: wait",
("suspend thread %ld", thread->id));
keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock);
}
+#else
+ KEYCACHE_DBUG_ASSERT(keycache->cnt_for_resize_op == 0);
+#endif
end_key_cache(keycache, 0); /* Don't free mutex */
/* The following will work even if use_mem is 0 */
@@ -525,6 +539,7 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
division_limit, age_threshold);
finish:
+#ifdef THREAD
unlink_from_queue(wqueue, thread);
/* Signal for the next resize request to proceeed if any */
if (wqueue->last_thread)
@@ -533,6 +548,7 @@ finish:
("thread %ld", wqueue->last_thread->next->id));
keycache_pthread_cond_signal(&wqueue->last_thread->next->suspend);
}
+#endif
keycache_pthread_mutex_unlock(&keycache->cache_lock);
return blocks;
}
@@ -553,6 +569,7 @@ static inline void inc_counter_for_resize_op(KEY_CACHE *keycache)
*/
static inline void dec_counter_for_resize_op(KEY_CACHE *keycache)
{
+#ifdef THREAD
struct st_my_thread_var *last_thread;
if (!--keycache->cnt_for_resize_op &&
(last_thread= keycache->resize_queue.last_thread))
@@ -561,6 +578,9 @@ static inline void dec_counter_for_resize_op(KEY_CACHE *keycache)
("thread %ld", last_thread->next->id));
keycache_pthread_cond_signal(&last_thread->next->suspend);
}
+#else
+ keycache->cnt_for_resize_op--;
+#endif
}
/*
@@ -650,6 +670,7 @@ void end_key_cache(KEY_CACHE *keycache, my_bool cleanup)
} /* end_key_cache */
+#ifdef THREAD
/*
Link a thread into double-linked queue of waiting threads.
@@ -786,6 +807,7 @@ static void release_queue(KEYCACHE_WQUEUE *wqueue)
while (thread != last);
wqueue->last_thread= NULL;
}
+#endif
/*
@@ -893,6 +915,7 @@ static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot,
BLOCK_LINK **pins;
KEYCACHE_DBUG_ASSERT(! (block->hash_link && block->hash_link->requests));
+#ifdef THREAD
if (!hot && keycache->waiting_for_block.last_thread)
{
/* Signal that in the LRU warm sub-chain an available block has appeared */
@@ -929,6 +952,10 @@ static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot,
#endif
return;
}
+#else /* THREAD */
+ KEYCACHE_DBUG_ASSERT(! (!hot && keycache->waiting_for_block.last_thread));
+ /* Condition not transformed using DeMorgan, to keep the text identical */
+#endif /* THREAD */
pins= hot ? &keycache->used_ins : &keycache->used_last;
ins= *pins;
if (ins)
@@ -1101,6 +1128,7 @@ static inline void remove_reader(BLOCK_LINK *block)
static inline void wait_for_readers(KEY_CACHE *keycache, BLOCK_LINK *block)
{
+#ifdef THREAD
struct st_my_thread_var *thread= my_thread_var;
while (block->hash_link->requests)
{
@@ -1111,6 +1139,9 @@ static inline void wait_for_readers(KEY_CACHE *keycache, BLOCK_LINK *block)
keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock);
block->condvar= NULL;
}
+#else
+ KEYCACHE_DBUG_ASSERT(block->hash_link->requests == 0);
+#endif
}
@@ -1140,6 +1171,7 @@ static void unlink_hash(KEY_CACHE *keycache, HASH_LINK *hash_link)
if ((*hash_link->prev= hash_link->next))
hash_link->next->prev= hash_link->prev;
hash_link->block= NULL;
+#ifdef THREAD
if (keycache->waiting_for_hash_link.last_thread)
{
/* Signal that a free hash link has appeared */
@@ -1175,6 +1207,9 @@ static void unlink_hash(KEY_CACHE *keycache, HASH_LINK *hash_link)
hash_link);
return;
}
+#else /* THREAD */
+ KEYCACHE_DBUG_ASSERT(! (keycache->waiting_for_hash_link.last_thread));
+#endif /* THREAD */
hash_link->next= keycache->free_hash_list;
keycache->free_hash_list= hash_link;
}
@@ -1240,6 +1275,7 @@ restart:
}
else
{
+#ifdef THREAD
/* Wait for a free hash link */
struct st_my_thread_var *thread= my_thread_var;
KEYCACHE_DBUG_PRINT("get_hash_link", ("waiting"));
@@ -1252,6 +1288,9 @@ restart:
keycache_pthread_cond_wait(&thread->suspend,
&keycache->cache_lock);
thread->opt_info= NULL;
+#else
+ KEYCACHE_DBUG_ASSERT(0);
+#endif
goto restart;
}
hash_link->file= file;
@@ -1363,6 +1402,7 @@ restart:
/* Wait intil the page is flushed on disk */
hash_link->requests--;
{
+#ifdef THREAD
struct st_my_thread_var *thread= my_thread_var;
add_to_queue(&block->wqueue[COND_FOR_SAVED], thread);
do
@@ -1373,6 +1413,16 @@ restart:
&keycache->cache_lock);
}
while(thread->next);
+#else
+ KEYCACHE_DBUG_ASSERT(0);
+ /*
+ Given the use of "resize_in_flush", it seems impossible
+ that this whole branch is ever entered in single-threaded case
+ because "(wrmode && keycache->resize_in_flush)" cannot be true.
+ TODO: Check this, and then put the whole branch into the
+ "#ifdef THREAD" guard.
+ */
+#endif
}
/* Invalidate page in the block if it has not been done yet */
if (block->status)
@@ -1401,6 +1451,7 @@ restart:
KEYCACHE_DBUG_PRINT("find_key_block",
("request waiting for old page to be saved"));
{
+#ifdef THREAD
struct st_my_thread_var *thread= my_thread_var;
/* Put the request into the queue of those waiting for the old page */
add_to_queue(&block->wqueue[COND_FOR_SAVED], thread);
@@ -1413,6 +1464,10 @@ restart:
&keycache->cache_lock);
}
while(thread->next);
+#else
+ KEYCACHE_DBUG_ASSERT(0);
+ /* No parallel requests in single-threaded case */
+#endif
}
KEYCACHE_DBUG_PRINT("find_key_block",
("request for old page resubmitted"));
@@ -1471,6 +1526,7 @@ restart:
all of them must get the same block
*/
+#ifdef THREAD
if (! keycache->used_last)
{
struct st_my_thread_var *thread= my_thread_var;
@@ -1486,6 +1542,9 @@ restart:
while (thread->next);
thread->opt_info= NULL;
}
+#else
+ KEYCACHE_DBUG_ASSERT(keycache->used_last);
+#endif
block= hash_link->block;
if (! block)
{
@@ -1674,6 +1733,7 @@ static void read_block(KEY_CACHE *keycache,
KEYCACHE_DBUG_PRINT("read_block",
("secondary request waiting for new page to be read"));
{
+#ifdef THREAD
struct st_my_thread_var *thread= my_thread_var;
/* Put the request into a queue and wait until it can be processed */
add_to_queue(&block->wqueue[COND_FOR_REQUESTED], thread);
@@ -1685,6 +1745,10 @@ static void read_block(KEY_CACHE *keycache,
&keycache->cache_lock);
}
while (thread->next);
+#else
+ KEYCACHE_DBUG_ASSERT(0);
+ /* No parallel requests in single-threaded case */
+#endif
}
KEYCACHE_DBUG_PRINT("read_block",
("secondary request: new page in cache"));
@@ -1822,7 +1886,7 @@ byte *key_cache_read(KEY_CACHE *keycache,
#ifndef THREAD
/* This is only true if we where able to read everything in one block */
if (return_buffer)
- return (block->buffer);
+ DBUG_RETURN(block->buffer);
#endif
buff+= read_length;
filepos+= read_length+offset;
@@ -2398,6 +2462,7 @@ restart:
#endif
block= first_in_switch;
{
+#ifdef THREAD
struct st_my_thread_var *thread= my_thread_var;
add_to_queue(&block->wqueue[COND_FOR_SAVED], thread);
do
@@ -2408,6 +2473,10 @@ restart:
&keycache->cache_lock);
}
while (thread->next);
+#else
+ KEYCACHE_DBUG_ASSERT(0);
+ /* No parallel requests in single-threaded case */
+#endif
}
#if defined(KEYCACHE_DEBUG)
cnt++;
@@ -2574,7 +2643,6 @@ static void test_key_cache(KEY_CACHE *keycache __attribute__((unused)),
static void keycache_dump(KEY_CACHE *keycache)
{
FILE *keycache_dump_file=fopen(KEYCACHE_DUMP_FILE, "w");
- struct st_my_thread_var *thread_var= my_thread_var;
struct st_my_thread_var *last;
struct st_my_thread_var *thread;
BLOCK_LINK *block;
diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c
index fd5a4908572..d5346d530c3 100644
--- a/mysys/my_alloc.c
+++ b/mysys/my_alloc.c
@@ -221,6 +221,57 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
#endif
}
+
+/*
+ Allocate many pointers at the same time.
+
+ DESCRIPTION
+ ptr1, ptr2, etc all point into big allocated memory area.
+
+ SYNOPSIS
+ multi_alloc_root()
+ root Memory root
+ ptr1, length1 Multiple arguments terminated by a NULL pointer
+ ptr2, length2 ...
+ ...
+ NULL
+
+ RETURN VALUE
+ A pointer to the beginning of the allocated memory block
+ in case of success or NULL if out of memory.
+*/
+
+gptr multi_alloc_root(MEM_ROOT *root, ...)
+{
+ va_list args;
+ char **ptr, *start, *res;
+ uint tot_length, length;
+ DBUG_ENTER("multi_alloc_root");
+
+ va_start(args, root);
+ tot_length= 0;
+ while ((ptr= va_arg(args, char **)))
+ {
+ length= va_arg(args, uint);
+ tot_length+= ALIGN_SIZE(length);
+ }
+ va_end(args);
+
+ if (!(start= (char*) alloc_root(root, tot_length)))
+ DBUG_RETURN(0); /* purecov: inspected */
+
+ va_start(args, root);
+ res= start;
+ while ((ptr= va_arg(args, char **)))
+ {
+ *ptr= res;
+ length= va_arg(args, uint);
+ res+= ALIGN_SIZE(length);
+ }
+ va_end(args);
+ DBUG_RETURN((gptr) start);
+}
+
#define TRASH_MEM(X) TRASH(((char*)(X) + ((X)->size-(X)->left)), (X)->left)
/* Mark all data in blocks free for reusage */
diff --git a/mysys/my_conio.c b/mysys/my_conio.c
new file mode 100644
index 00000000000..e381f9f23ef
--- /dev/null
+++ b/mysys/my_conio.c
@@ -0,0 +1,217 @@
+/* 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"
+
+#ifdef __WIN__
+
+static HANDLE my_coninpfh= 0; /* console input */
+
+/*
+ functions my_pthread_auto_mutex_lock & my_pthread_auto_mutex_free
+ are experimental at this moment, they are intended to bring
+ ability of protecting code sections without necessity to explicitly
+ initialize synchronization object in one of threads
+
+ if found useful they are to be exported in mysys
+*/
+
+/*
+ int my_pthread_auto_mutex_lock(HANDLE* ph, const char* name,
+ int id, int time)
+
+ NOTES
+ creates a mutex with given name and tries to lock it time msec.
+ mutex name is appended with id to allow system wide or process wide
+ locks. Handle to created mutex returned in ph argument.
+
+ RETURN
+ 0 thread owns mutex
+ <>0 error
+
+*/
+static
+int my_pthread_auto_mutex_lock(HANDLE* ph, const char* name, int id, int time)
+{
+ int res;
+ char tname[FN_REFLEN];
+
+ sprintf(tname, "%s-%08X", name, id);
+
+ *ph= CreateMutex(NULL, FALSE, tname);
+ if (*ph == NULL)
+ return GetLastError();
+
+ res= WaitForSingleObject(*ph, time);
+
+ if (res == WAIT_TIMEOUT)
+ return ERROR_SEM_TIMEOUT;
+
+ if (res == WAIT_FAILED)
+ return GetLastError();
+
+ return 0;
+}
+
+/*
+ int my_pthread_auto_mutex_free(HANDLE* ph)
+
+
+ NOTES
+ releases a mutex.
+
+ RETURN
+ 0 thread released mutex
+ <>0 error
+
+*/
+static
+int my_pthread_auto_mutex_free(HANDLE* ph)
+{
+ if (*ph)
+ {
+ ReleaseMutex(*ph);
+ CloseHandle(*ph);
+ *ph= NULL;
+ }
+
+ return 0;
+}
+
+
+#define pthread_auto_mutex_decl(name) \
+ HANDLE __h##name= NULL;
+
+#define pthread_auto_mutex_lock(name, proc, time) \
+ my_pthread_auto_mutex_lock(&__h##name, #name, (proc), (time))
+
+#define pthread_auto_mutex_free(name) \
+ my_pthread_auto_mutex_free(&__h##name)
+
+
+/*
+ char* my_cgets(char *string, unsigned long clen, unsigned long* plen)
+
+ NOTES
+ Replaces _cgets from libc to support input of more than 255 chars.
+ Reads from the console via ReadConsole into buffer which
+ should be at least clen characters.
+ Actual length of string returned in plen.
+
+ WARNING
+ my_cgets() does NOT check the pushback character buffer (i.e., _chbuf).
+ Thus, my_cgets() will not return any character that is pushed back by
+ the _ungetch() call.
+
+ RETURN
+ string pointer ok
+ NULL Error
+
+*/
+char* my_cgets(char *buffer, unsigned long clen, unsigned long* plen)
+{
+ ULONG state;
+ char *result;
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+ pthread_auto_mutex_decl(my_conio_cs);
+
+ /* lock the console for the current process*/
+ if (pthread_auto_mutex_lock(my_conio_cs, GetCurrentProcessId(), INFINITE))
+ {
+ /* can not lock console */
+ pthread_auto_mutex_free(my_conio_cs);
+ return NULL;
+ }
+
+ /* init console input */
+ if (my_coninpfh == 0)
+ {
+ /* same handle will be used until process termination */
+ my_coninpfh= CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, 0, NULL);
+ }
+
+ if (my_coninpfh == INVALID_HANDLE_VALUE)
+ {
+ /* unlock the console */
+ pthread_auto_mutex_free(my_conio_cs);
+ return(NULL);
+ }
+
+ GetConsoleMode((HANDLE)my_coninpfh, &state);
+ SetConsoleMode((HANDLE)my_coninpfh, ENABLE_LINE_INPUT |
+ ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT);
+
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
+
+ /*
+ there is no known way to determine allowed buffer size for input
+ though it is known it should not be more than 64K
+ so we cut 64K and try first size of screen buffer
+ if it is still to large we cut half of it and try again
+ later we may want to cycle from min(clen, 65535) to allowed size
+ with small decrement to determine exact allowed buffer
+ */
+ clen= min(clen, 65535);
+ do
+ {
+ clen= min(clen, (unsigned long)csbi.dwSize.X*csbi.dwSize.Y);
+ if (!ReadConsole((HANDLE)my_coninpfh, (LPVOID)buffer, clen - 1, plen, NULL))
+ {
+ result= NULL;
+ clen>>= 1;
+ }
+ else
+ {
+ result= buffer;
+ break;
+ }
+ }
+ while (GetLastError() == ERROR_NOT_ENOUGH_MEMORY);
+
+
+ if (result != NULL)
+ {
+ if (buffer[*plen - 2] == '\r')
+ {
+ *plen= *plen - 2;
+ }
+ else
+ {
+ if (buffer[*plen - 1] == '\r')
+ {
+ char tmp[3];
+ int tmplen= sizeof(tmp);
+
+ *plen= *plen - 1;
+ /* read /n left in the buffer */
+ ReadConsole((HANDLE)my_coninpfh, (LPVOID)tmp, tmplen, &tmplen, NULL);
+ }
+ }
+ buffer[*plen]= '\0';
+ }
+
+ SetConsoleMode((HANDLE)my_coninpfh, state);
+ /* unlock the console */
+ pthread_auto_mutex_free(my_conio_cs);
+
+ return result;
+}
+
+#endif /* __WIN__ */
diff --git a/mysys/my_init.c b/mysys/my_init.c
index abb1ad27f7b..f28f47e090e 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -127,11 +127,23 @@ my_bool my_init(void)
void my_end(int infoflag)
{
- FILE *info_file;
- if (!(info_file=DBUG_FILE))
- info_file=stderr;
- DBUG_PRINT("info",("Shutting down"));
- if (infoflag & MY_CHECK_ERROR || info_file != stderr)
+ /*
+ this code is suboptimal to workaround a bug in
+ Sun CC: Sun C++ 5.6 2004/06/02 for x86, and should not be
+ optimized until this compiler is not in use anymore
+ */
+ FILE *info_file= DBUG_FILE;
+ my_bool print_info= (info_file != stderr);
+ DBUG_ENTER("my_end");
+ if (!info_file)
+ {
+ info_file= stderr;
+ print_info= 0;
+ }
+
+ DBUG_PRINT("info",("Shutting down: print_info: %d", print_info));
+ if ((infoflag & MY_CHECK_ERROR) || print_info)
+
{ /* Test if some file is left open */
if (my_file_opened | my_stream_opened)
{
@@ -141,7 +153,8 @@ void my_end(int infoflag)
}
}
my_once_free();
- if (infoflag & MY_GIVE_INFO || info_file != stderr)
+
+ if ((infoflag & MY_GIVE_INFO) || print_info)
{
#ifdef HAVE_GETRUSAGE
struct rusage rus;
diff --git a/ndb/tools/ndb_size.pl b/ndb/tools/ndb_size.pl
new file mode 100644
index 00000000000..64a20423636
--- /dev/null
+++ b/ndb/tools/ndb_size.pl
@@ -0,0 +1,263 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+use DBI;
+use POSIX;
+use HTML::Template;
+
+# MySQL Cluster size estimator
+# ----------------------------
+#
+# (C)2005 MySQL AB
+#
+#
+# The purpose of this tool is to work out storage requirements
+# from an existing MySQL database.
+#
+# This involves connecting to a mysql server and throwing a bunch
+# of queries at it.
+#
+# We currently estimate sizes for: 4.1, 5.0 and 5.1 to various amounts
+# of accurracy.
+#
+# There is no warranty.
+#
+# BUGS
+# ----
+# - enum/set is 0 byte storage! Woah - efficient!
+# - some float stores come out weird (when there's a comma e.g. 'float(4,1)')
+# - no disk data values
+# - computes the storage requirements of views (and probably MERGE)
+# - ignores character sets.
+
+my $template = HTML::Template->new(filename => 'ndb_size.tmpl',
+ die_on_bad_params => 0);
+
+my $dbh;
+
+{
+ my $database= $ARGV[0];
+ my $hostname= $ARGV[1];
+ my $port= $ARGV[2];
+ my $user= $ARGV[3];
+ my $password= $ARGV[4];
+ my $dsn = "DBI:mysql:database=$database;host=$hostname;port=$port";
+ $dbh= DBI->connect($dsn, $user, $password);
+ $template->param(db => $database);
+ $template->param(dsn => $dsn);
+}
+
+my @releases = ({rel=>'4.1'},{rel=>'5.0'},{rel=>'5.1'});
+$template->param(releases => \@releases);
+
+my $tables = $dbh->selectall_arrayref("show tables");
+
+my @table_size;
+
+sub align {
+ my($to,@unaligned) = @_;
+ my @aligned;
+ foreach my $x (@unaligned) {
+ push @aligned, $to * POSIX::floor(($x+$to-1)/$to);
+ }
+ return @aligned;
+}
+
+foreach(@{$tables})
+{
+ my $table= @{$_}[0];
+ my @columns;
+ my $info= $dbh->selectall_hashref("describe ".$dbh->quote($table),"Field");
+ my @count = $dbh->selectrow_array("select count(*) from "
+ .$dbh->quote($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);
+
+ foreach(keys %$info)
+ {
+ my @realsize = (0,0,0);
+ my $type;
+ my $size;
+ my $name= $_;
+
+ if($$info{$_}{Type} =~ /^(.*?)\((\d+)\)/)
+ {
+ $type= $1;
+ $size= $2;
+ }
+ else
+ {
+ $type= $$info{$_}{Type};
+ }
+
+ if($type =~ /tinyint/)
+ {@realsize=(1,1,1)}
+ elsif($type =~ /smallint/)
+ {@realsize=(2,2,2)}
+ elsif($type =~ /mediumint/)
+ {@realsize=(3,3,3)}
+ elsif($type =~ /bigint/)
+ {@realsize=(8,8,8)}
+ elsif($type =~ /int/)
+ {@realsize=(4,4,4)}
+ elsif($type =~ /float/)
+ {
+ if($size<=24)
+ {@realsize=(4,4,4)}
+ else
+ {@realsize=(8,8,8)}
+ }
+ elsif($type =~ /double/ || $type =~ /real/)
+ {@realsize=(8,8,8)}
+ elsif($type =~ /bit/)
+ {
+ my $a=($size+7)/8;
+ @realsize = ($a,$a,$a);
+ }
+ elsif($type =~ /datetime/)
+ {@realsize=(8,8,8)}
+ elsif($type =~ /timestamp/)
+ {@realsize=(4,4,4)}
+ elsif($type =~ /date/ || $type =~ /time/)
+ {@realsize=(3,3,3)}
+ elsif($type =~ /year/)
+ {@realsize=(1,1,1)}
+ elsif($type =~ /varchar/ || $type =~ /varbinary/)
+ {
+ my $fixed= 1+$size;
+ my @dynamic=$dbh->selectrow_array("select avg(length("
+ .$dbh->quote($name)
+ .")) from ".$dbh->quote($table));
+ $dynamic[0]=0 if !$dynamic[0];
+ @realsize= ($fixed,$fixed,ceil($dynamic[0]));
+ }
+ elsif($type =~ /binary/ || $type =~ /char/)
+ {@realsize=($size,$size,$size)}
+ elsif($type =~ /text/ || $type =~ /blob/)
+ {@realsize=(256,256,1)} # FIXME check if 5.1 is correct
+
+ @realsize= align(4,@realsize);
+
+ $totalsize[$_]+=$realsize[$_] foreach 0..$#totalsize;
+
+ my @realout;
+ push @realout,{val=>$_} foreach @realsize;
+
+ push @columns, {
+ name=>$name,
+ type=>$type,
+ size=>$size,
+ key=>$$info{$_}{Key},
+ datamemory=>\@realout,
+ };
+
+ $columnsize{$name}= \@realsize; # used for index calculations
+ }
+
+ # And now... the IndexMemory usage.
+ #
+ # 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 "$dbh->quote($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})) {
+ $indexes{PRIMARY}= {
+ type=>'BTREE',
+ unique=>1,
+ comment=>'Hidden pkey created by NDB',
+ columns=>['HIDDEN_NDB_PKEY'],
+ };
+ push @columns, {
+ name=>'HIDDEN_NDB_PKEY',
+ type=>'bigint',
+ size=>8,
+ key=>'PRI',
+ datamemory=>[{val=>8},{val=>8},{val=>8}],
+ };
+ $columnsize{'HIDDEN_NDB_PKEY'}= [8,8,8];
+ }
+
+ my @IndexDataMemory= ({val=>0},{val=>0},{val=>0});
+ my @RowIndexMemory= ({val=>0},{val=>0},{val=>0});
+
+ 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});
+ push @indexes, {
+ name=>$index,
+ type=>$indexes{$index}{type},
+ columns=>join(',',@{$indexes{$index}{columns}}),
+ indexmemory=>\@im,
+ datamemory=>\@dm,
+ };
+ $IndexDataMemory[$_]{val}+=$dm[$_]{val} foreach 0..2;
+ $RowIndexMemory[$_]{val}+=$im[$_]{val} foreach 0..2;
+ }
+
+ # total size + 16 bytes overhead
+ my @TotalDataMemory;
+ $TotalDataMemory[$_]{val}=$IndexDataMemory[$_]{val}+$totalsize[$_]+16 foreach 0..2;
+
+ my @RowDataMemory;
+ push @RowDataMemory,{val=>$_} foreach @totalsize;
+
+ my @RowPerPage;
+ push @RowPerPage,{val=>(floor((32768-128)/$TotalDataMemory[$_]{val}))} foreach 0..$#TotalDataMemory;
+
+ my @RowPerIndexPage;
+ push @RowPerIndexPage,{val=>(floor(8192/$RowIndexMemory[$_]{val}))} foreach 0..$#TotalDataMemory;
+
+ my @DataMemory;
+ push @DataMemory,{val=>ceil(($count[0]/($RowPerPage[$_]{val})))*32} foreach 0..$#RowPerPage;
+
+ my @IndexMemory;
+ push @IndexMemory,{val=>ceil(($count[0]/($RowPerIndexPage[$_]{val})))*8} foreach 0..$#RowPerPage;
+
+ my $count= $count[0];
+ my @counts;
+ $counts[$_]{val}= $count foreach 0..$#releases;
+
+ push @table_size, {
+ table=>$table,
+ indexes=>\@indexes,
+ columns=>\@columns,
+ count=>\@counts,
+ RowDataMemory=>\@RowDataMemory,
+ releases=>\@releases,
+ IndexDataMemory=>\@IndexDataMemory,
+ TotalDataMemory=>\@TotalDataMemory,
+ RowPerPage=>\@RowPerPage,
+ DataMemory=>\@DataMemory,
+ RowIndexMemory=>\@RowIndexMemory,
+ RowPerIndexPage=>\@RowPerIndexPage,
+ IndexMemory=>\@IndexMemory,
+
+ };
+}
+
+$template->param(tables => \@table_size);
+print $template->output;
diff --git a/ndb/tools/ndb_size.tmpl b/ndb/tools/ndb_size.tmpl
new file mode 100644
index 00000000000..d83d5d2c6af
--- /dev/null
+++ b/ndb/tools/ndb_size.tmpl
@@ -0,0 +1,175 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8"/>
+ <meta name="keywords" content="MySQL Cluster" />
+ <title>MySQL Cluster size estimate for <TMPL_VAR NAME="db" ESCAPE="HTML"></title>
+<style type="text/css">
+table { border-collapse: collapse }
+td,th { border: 1px solid black }
+</style>
+ </head>
+<body>
+<h1>MySQL Cluster analysis for <TMPL_VAR NAME="db" escape="html"></h1>
+<p>This is an automated analysis of the <TMPL_VAR NAME="DSN" escape="html"> database for migration into <a href="http://www.mysql.com/">MySQL</a> Cluster. No warranty is made to the accuracy of the information.</p>
+
+<p>This information should be valid for MySQL 4.1</p>
+
+<ul>
+<TMPL_LOOP NAME="tables">
+<li><TMPL_VAR NAME="table"></li>
+</TMPL_LOOP>
+</ul>
+
+<hr/>
+
+<TMPL_LOOP NAME="tables">
+<h2><TMPL_VAR NAME="table"></h2>
+<table>
+ <tr>
+ <th>Column</th>
+ <th>Type</th>
+ <th>Size</th>
+ <th>Key</th>
+ <TMPL_LOOP NAME=releases>
+ <th><TMPL_VAR NAME=rel> NDB Size</th>
+ </TMPL_LOOP>
+ </tr>
+ <TMPL_LOOP NAME="columns">
+ <tr>
+ <td><TMPL_VAR NAME=name></td>
+ <td><TMPL_VAR NAME=type></td>
+ <td><TMPL_VAR NAME=size></td>
+ <td><TMPL_VAR NAME=key></td>
+ <TMPL_LOOP NAME=datamemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+ </tr>
+ </TMPL_LOOP>
+</table>
+
+<p>&nbsp;</p>
+
+<h3>Indexes</h3>
+
+<p>We assume that indexes are ORDERED (not created USING HASH). If order is not required, 10 bytes of data memory can be saved per row if the index is created USING HASH</p>
+<table>
+<tr>
+ <th>Index</th>
+ <th>Type</th>
+ <th>Columns</th>
+ <TMPL_LOOP NAME=releases>
+ <th><TMPL_VAR NAME=rel> IdxMem</th>
+ </TMPL_LOOP>
+ <TMPL_LOOP NAME=releases>
+ <th><TMPL_VAR NAME=rel> DatMem</th>
+ </TMPL_LOOP>
+</tr>
+<TMPL_LOOP NAME="indexes">
+ <tr>
+ <td><TMPL_VAR NAME=name></td>
+ <td><TMPL_VAR NAME=type></td>
+ <td><TMPL_VAR NAME=columns></td>
+ <TMPL_LOOP NAME=indexmemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+ <TMPL_LOOP NAME=datamemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+ </tr>
+</TMPL_LOOP>
+</table>
+
+<h3>DataMemory Usage</h3>
+<table>
+<tr>
+ <th>&nbsp;</th>
+ <TMPL_LOOP NAME=releases>
+ <th><TMPL_VAR NAME=rel></th>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Row Overhead</th>
+ <TMPL_LOOP NAME=releases>
+ <td>16</td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Column DataMemory/Row</th>
+ <TMPL_LOOP NAME=RowDataMemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Index DataMemory/Row</th>
+ <TMPL_LOOP NAME=IndexDataMemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Total DataMemory/Row</th>
+ <TMPL_LOOP NAME=TotalDataMemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Rows per 32kb page</th>
+ <TMPL_LOOP NAME=RowPerPage>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Current number of rows</th>
+ <TMPL_LOOP NAME=count>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Total DataMemory (kb)</th>
+ <TMPL_LOOP NAME=DataMemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+</table>
+
+<h3>IndexMemory Usage</h3>
+<table>
+<tr>
+ <th>&nbsp;</th>
+ <TMPL_LOOP NAME=releases>
+ <th><TMPL_VAR NAME=rel></th>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>IndexMemory/Row</th>
+ <TMPL_LOOP NAME=RowIndexMemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Rows per 8kb page</th>
+ <TMPL_LOOP NAME=RowPerIndexPage>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Current number of rows</th>
+ <TMPL_LOOP NAME=count>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+<tr>
+ <th>Total IndexMemory (kb)</th>
+ <TMPL_LOOP NAME=IndexMemory>
+ <td><TMPL_VAR NAME=val></td>
+ </TMPL_LOOP>
+</tr>
+</table>
+
+<hr/>
+</TMPL_LOOP>
+
+<p>This is the output of ndb_size.pl.</p>
+</body>
+</html>
+
diff --git a/os2/MySQL-Source.icc b/os2/MySQL-Source.icc
index de0ac75ec9c..342cb6c96b9 100644
--- a/os2/MySQL-Source.icc
+++ b/os2/MySQL-Source.icc
@@ -12,7 +12,7 @@ group client_global_pch =
'm_ctype.h', 'mysqld_error.h',
'my_list.h', 'my_sys.h', 'my_net.h',
'myisam.h', 'myisampack.h', '.\myisam\myisamdef.h',
- '.\regex\regex.h'
+ '.\regex\my_regex.h'
group server_global_pch =
'os2.h',
@@ -38,7 +38,7 @@ group server_global_pch =
'my_tree.h', '..\mysys\my_static.h', 'netdb.h',
'thr_alarm.h', 'heap.h', '..\myisam\fulltext.h',
'..\myisam\ftdefs.h', 'myisammrg.h',
- '.\regex\regex.h'
+ '.\regex\my_regex.h'
group server_pch =
'ha_heap.h', 'ha_myisammrg.h', 'opt_ft.h',
diff --git a/regex/Makefile.am b/regex/Makefile.am
index 3b161287d36..7e8478e8123 100644
--- a/regex/Makefile.am
+++ b/regex/Makefile.am
@@ -18,7 +18,7 @@
INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
noinst_LIBRARIES = libregex.a
LDADD= libregex.a $(top_builddir)/strings/libmystrings.a
-noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c regex.h
+noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c my_regex.h
libregex_a_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c
noinst_PROGRAMS = re
re_SOURCES = split.c debug.c main.c
diff --git a/regex/debug.c b/regex/debug.c
index bdd3e00d5a7..271b09bb27a 100644
--- a/regex/debug.c
+++ b/regex/debug.c
@@ -2,7 +2,8 @@
#include <m_ctype.h>
#include <m_string.h>
#include <sys/types.h>
-#include <regex.h>
+
+#include "my_regex.h"
#include "utils.h"
#include "regex2.h"
#include "debug.ih"
@@ -15,7 +16,7 @@
*/
void
regprint(r, d)
-regex_t *r;
+my_regex_t *r;
FILE *d;
{
register struct re_guts *g = r->re_g;
diff --git a/regex/debug.ih b/regex/debug.ih
index 0d91e170437..1e1fb11177c 100644
--- a/regex/debug.ih
+++ b/regex/debug.ih
@@ -4,7 +4,7 @@ extern "C" {
#endif
/* === debug.c === */
-void regprint(regex_t *r, FILE *d);
+void regprint(my_regex_t *r, FILE *d);
static void s_print(CHARSET_INFO *charset, register struct re_guts *g, FILE *d);
static char *regchar(CHARSET_INFO *charset, int ch,char *buf);
diff --git a/regex/engine.c b/regex/engine.c
index c4c4efe7e2f..1968ca61a96 100644
--- a/regex/engine.c
+++ b/regex/engine.c
@@ -32,7 +32,7 @@
struct match {
struct re_guts *g;
int eflags;
- regmatch_t *pmatch; /* [nsub+1] (0 element unused) */
+ my_regmatch_t *pmatch; /* [nsub+1] (0 element unused) */
char *offp; /* offsets work from here */
char *beginp; /* start of string -- virtual NUL precedes */
char *endp; /* end of string -- virtual NUL here */
@@ -68,7 +68,7 @@ CHARSET_INFO *charset;
register struct re_guts *g;
char *str;
size_t nmatch;
-regmatch_t pmatch[];
+my_regmatch_t pmatch[];
int eflags;
{
register char *endp;
@@ -148,8 +148,8 @@ int eflags;
/* oh my, he wants the subexpressions... */
if (m->pmatch == NULL)
- m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) *
- sizeof(regmatch_t));
+ m->pmatch = (my_regmatch_t *)malloc((m->g->nsub + 1) *
+ sizeof(my_regmatch_t));
if (m->pmatch == NULL) {
if (m->lastpos != NULL)
free((char *)m->lastpos);
diff --git a/regex/engine.ih b/regex/engine.ih
index 7cfcb39fb2d..a9e98abef00 100644
--- a/regex/engine.ih
+++ b/regex/engine.ih
@@ -4,7 +4,7 @@ extern "C" {
#endif
/* === engine.c === */
-static int matcher(CHARSET_INFO *charset,register struct re_guts *g, char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
+static int matcher(CHARSET_INFO *charset,register struct re_guts *g, char *string, size_t nmatch, my_regmatch_t pmatch[], int eflags);
static char *dissect(CHARSET_INFO *charset,register struct match *m, char *start, char *stop, sopno startst, sopno stopst);
static char *backref(CHARSET_INFO *charset, register struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev);
static char *fast(CHARSET_INFO *charset, register struct match *m, char *start, char *stop, sopno startst, sopno stopst);
diff --git a/regex/main.c b/regex/main.c
index 8fe16d74eee..fa97ca89047 100644
--- a/regex/main.c
+++ b/regex/main.c
@@ -1,9 +1,9 @@
#include <my_global.h>
#include <m_string.h>
#include <sys/types.h>
-#include <regex.h>
#include <assert.h>
+#include "my_regex.h"
#include "main.ih"
char *progname;
@@ -27,9 +27,9 @@ int main(argc, argv)
int argc;
char *argv[];
{
- regex_t re;
+ my_regex_t re;
# define NS 10
- regmatch_t subs[NS];
+ my_regmatch_t subs[NS];
char erbuf[100];
int err;
size_t len;
@@ -74,9 +74,9 @@ char *argv[];
exit(status);
}
- err = regcomp(&re, argv[optind++], copts, &my_charset_latin1);
+ err = my_regcomp(&re, argv[optind++], copts, &my_charset_latin1);
if (err) {
- len = regerror(err, &re, erbuf, sizeof(erbuf));
+ len = my_regerror(err, &re, erbuf, sizeof(erbuf));
fprintf(stderr, "error %s, %d/%d `%s'\n",
eprint(err), (int) len, (int) sizeof(erbuf), erbuf);
exit(status);
@@ -84,7 +84,7 @@ char *argv[];
regprint(&re, stdout);
if (optind >= argc) {
- regfree(&re);
+ my_regfree(&re);
exit(status);
}
@@ -92,9 +92,9 @@ char *argv[];
subs[0].rm_so = startoff;
subs[0].rm_eo = strlen(argv[optind]) - endoff;
}
- err = regexec(&re, argv[optind], (size_t)NS, subs, eopts);
+ err = my_regexec(&re, argv[optind], (size_t)NS, subs, eopts);
if (err) {
- len = regerror(err, &re, erbuf, sizeof(erbuf));
+ len = my_regerror(err, &re, erbuf, sizeof(erbuf));
fprintf(stderr, "error %s, %d/%d `%s'\n",
eprint(err), (int) len, (int) sizeof(erbuf), erbuf);
exit(status);
@@ -136,7 +136,7 @@ FILE *in;
const char *badpat = "invalid regular expression";
# define SHORT 10
const char *bpname = "REG_BADPAT";
- regex_t re;
+ my_regex_t re;
while (fgets(inbuf, sizeof(inbuf), in) != NULL) {
line++;
@@ -163,27 +163,27 @@ FILE *in;
options('c', f[1]) &~ REG_EXTENDED);
}
- ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf));
+ ne = my_regerror(REG_BADPAT, (my_regex_t *)NULL, erbuf, sizeof(erbuf));
if (strcmp(erbuf, badpat) != 0 || ne != strlen(badpat)+1) {
fprintf(stderr, "end: regerror() test gave `%s' not `%s'\n",
erbuf, badpat);
status = 1;
}
- ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, (size_t)SHORT);
+ ne = my_regerror(REG_BADPAT, (my_regex_t *)NULL, erbuf, (size_t)SHORT);
if (strncmp(erbuf, badpat, SHORT-1) != 0 || erbuf[SHORT-1] != '\0' ||
ne != strlen(badpat)+1) {
fprintf(stderr, "end: regerror() short test gave `%s' not `%.*s'\n",
erbuf, SHORT-1, badpat);
status = 1;
}
- ne = regerror(REG_ITOA|REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf));
+ ne = my_regerror(REG_ITOA|REG_BADPAT, (my_regex_t *)NULL, erbuf, sizeof(erbuf));
if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname)+1) {
fprintf(stderr, "end: regerror() ITOA test gave `%s' not `%s'\n",
erbuf, bpname);
status = 1;
}
re.re_endp = bpname;
- ne = regerror(REG_ATOI, &re, erbuf, sizeof(erbuf));
+ ne = my_regerror(REG_ATOI, &re, erbuf, sizeof(erbuf));
if (atoi(erbuf) != (int)REG_BADPAT) {
fprintf(stderr, "end: regerror() ATOI test gave `%s' not `%ld'\n",
erbuf, (long)REG_BADPAT);
@@ -208,9 +208,9 @@ char *f3;
char *f4;
int opts; /* may not match f1 */
{
- regex_t re;
+ my_regex_t re;
# define NSUBS 10
- regmatch_t subs[NSUBS];
+ my_regmatch_t subs[NSUBS];
# define NSHOULD 15
char *should[NSHOULD];
int nshould;
@@ -226,10 +226,10 @@ int opts; /* may not match f1 */
strcpy(f0copy, f0);
re.re_endp = (opts&REG_PEND) ? f0copy + strlen(f0copy) : NULL;
fixstr(f0copy);
- err = regcomp(&re, f0copy, opts, &my_charset_latin1);
+ err = my_regcomp(&re, f0copy, opts, &my_charset_latin1);
if (err != 0 && (!opt('C', f1) || err != efind(f2))) {
/* unexpected error or wrong error */
- len = regerror(err, &re, erbuf, sizeof(erbuf));
+ len = my_regerror(err, &re, erbuf, sizeof(erbuf));
fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n",
line, type, eprint(err), len,
(int) sizeof(erbuf), erbuf);
@@ -243,7 +243,7 @@ int opts; /* may not match f1 */
}
if (err != 0) {
- regfree(&re);
+ my_regfree(&re);
return;
}
@@ -256,11 +256,11 @@ int opts; /* may not match f1 */
subs[0].rm_so = strchr(f2, '(') - f2 + 1;
subs[0].rm_eo = strchr(f2, ')') - f2;
}
- err = regexec(&re, f2copy, NSUBS, subs, options('e', f1));
+ err = my_regexec(&re, f2copy, NSUBS, subs, options('e', f1));
if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) {
/* unexpected error or wrong error */
- len = regerror(err, &re, erbuf, sizeof(erbuf));
+ len = my_regerror(err, &re, erbuf, sizeof(erbuf));
fprintf(stderr, "%d: %s exec error %s, %d/%d `%s'\n",
line, type, eprint(err), len,
(int) sizeof(erbuf), erbuf);
@@ -282,7 +282,7 @@ int opts; /* may not match f1 */
}
if (err != 0 || f4 == NULL) {
- regfree(&re);
+ my_regfree(&re);
return;
}
@@ -303,7 +303,7 @@ int opts; /* may not match f1 */
}
}
- regfree(&re);
+ my_regfree(&re);
}
/*
@@ -404,7 +404,7 @@ register char *p;
char * /* NULL or complaint */
check(str, sub, should)
char *str;
-regmatch_t sub;
+my_regmatch_t sub;
char *should;
{
register int len;
@@ -485,7 +485,7 @@ int err;
static char epbuf[100];
size_t len;
- len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf));
+ len = my_regerror(REG_ITOA|err, (my_regex_t *)NULL, epbuf, sizeof(epbuf));
assert(len <= sizeof(epbuf));
return(epbuf);
}
@@ -499,11 +499,11 @@ efind(name)
char *name;
{
static char efbuf[100];
- regex_t re;
+ my_regex_t re;
sprintf(efbuf, "REG_%s", name);
assert(strlen(efbuf) < sizeof(efbuf));
re.re_endp = efbuf;
- (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf));
+ (void) my_regerror(REG_ATOI, &re, efbuf, sizeof(efbuf));
return(atoi(efbuf));
}
diff --git a/regex/main.ih b/regex/main.ih
index 4b16e676ad3..f0104cc18c0 100644
--- a/regex/main.ih
+++ b/regex/main.ih
@@ -9,7 +9,7 @@ void rx_try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts);
int options(int type, char *s);
int opt(int c, char *s);
void fixstr(register char *p);
-char *check(char *str, regmatch_t sub, char *should);
+char *check(char *str, my_regmatch_t sub, char *should);
static char *eprint(int err);
static int efind(char *name);
diff --git a/regex/regex.h b/regex/my_regex.h
index e0fb0c77dc9..0d1cedf5430 100644
--- a/regex/regex.h
+++ b/regex/my_regex.h
@@ -20,15 +20,15 @@ typedef struct {
const char *re_endp; /* end pointer for REG_PEND */
struct re_guts *re_g; /* none of your business :-) */
CHARSET_INFO *charset; /* For ctype things */
-} regex_t;
+} my_regex_t;
typedef struct {
regoff_t rm_so; /* start of match */
regoff_t rm_eo; /* end of match */
-} regmatch_t;
+} my_regmatch_t;
/* === regcomp.c === */
-extern int regcomp(regex_t *, const char *, int, CHARSET_INFO *charset);
+extern int my_regcomp(my_regex_t *, const char *, int, CHARSET_INFO *charset);
#define REG_BASIC 0000
#define REG_EXTENDED 0001
#define REG_ICASE 0002
@@ -58,11 +58,11 @@ extern int regcomp(regex_t *, const char *, int, CHARSET_INFO *charset);
#define REG_INVARG 16
#define REG_ATOI 255 /* convert name to number (!) */
#define REG_ITOA 0400 /* convert number to name (!) */
-extern size_t regerror(int, const regex_t *, char *, size_t);
+extern size_t my_regerror(int, const my_regex_t *, char *, size_t);
/* === regexec.c === */
-extern int regexec(const regex_t *, const char *, size_t, regmatch_t [], int);
+extern int my_regexec(const my_regex_t *, const char *, size_t, my_regmatch_t [], int);
#define REG_NOTBOL 00001
#define REG_NOTEOL 00002
#define REG_STARTEND 00004
@@ -72,12 +72,12 @@ extern int regexec(const regex_t *, const char *, size_t, regmatch_t [], int);
/* === regfree.c === */
-extern void regfree(regex_t *);
+extern void my_regfree(my_regex_t *);
/* === reginit.c === */
-extern void regex_init(CHARSET_INFO *cs); /* Should be called for multithread progs */
-extern void regex_end(void); /* If one wants a clean end */
+extern void my_regex_init(CHARSET_INFO *cs); /* Should be called for multithread progs */
+extern void my_regex_end(void); /* If one wants a clean end */
#ifdef __cplusplus
}
diff --git a/regex/regcomp.c b/regex/regcomp.c
index 998b39379aa..9cba56a97dd 100644
--- a/regex/regcomp.c
+++ b/regex/regcomp.c
@@ -1,11 +1,11 @@
#include <my_global.h>
#include <m_string.h>
#include <m_ctype.h>
-#include <regex.h>
#ifdef __WIN__
#include <limits.h>
#endif
+#include "my_regex.h"
#include "utils.h"
#include "regex2.h"
@@ -100,8 +100,8 @@ static int never = 0; /* for use in asserts; shuts lint up */
= #define REG_DUMP 0200
*/
int /* 0 success, otherwise REG_something */
-regcomp(preg, pattern, cflags, charset)
-regex_t *preg;
+my_regcomp(preg, pattern, cflags, charset)
+my_regex_t *preg;
const char *pattern;
int cflags;
CHARSET_INFO *charset;
@@ -117,7 +117,7 @@ CHARSET_INFO *charset;
# define GOODFLAGS(f) ((f)&~REG_DUMP)
#endif
- regex_init(charset); /* Init cclass if neaded */
+ my_regex_init(charset); /* Init cclass if neaded */
preg->charset=charset;
cflags = GOODFLAGS(cflags);
if ((cflags&REG_EXTENDED) && (cflags&REG_NOSPEC))
@@ -199,7 +199,7 @@ CHARSET_INFO *charset;
/* win or lose, we're done */
if (p->error != 0) /* lose */
- regfree(preg);
+ my_regfree(preg);
return(p->error);
}
diff --git a/regex/regerror.c b/regex/regerror.c
index 9caa5b95a4c..489f2e35abb 100644
--- a/regex/regerror.c
+++ b/regex/regerror.c
@@ -1,8 +1,8 @@
#include <my_global.h>
#include <m_string.h>
#include <m_ctype.h>
-#include <regex.h>
+#include "my_regex.h"
#include "utils.h"
#include "regerror.ih"
@@ -56,7 +56,7 @@ static struct rerr {
*/
/* ARGSUSED */
size_t
-regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
+my_regerror(int errcode, const my_regex_t *preg, char *errbuf, size_t errbuf_size)
{
register struct rerr *r;
register size_t len;
@@ -101,7 +101,7 @@ regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
*/
static char *
regatoi(preg, localbuf)
-const regex_t *preg;
+const my_regex_t *preg;
char *localbuf;
{
register struct rerr *r;
diff --git a/regex/regerror.ih b/regex/regerror.ih
index 2cb668c24f0..a4d048022f8 100644
--- a/regex/regerror.ih
+++ b/regex/regerror.ih
@@ -4,7 +4,7 @@ extern "C" {
#endif
/* === regerror.c === */
-static char *regatoi(const regex_t *preg, char *localbuf);
+static char *regatoi(const my_regex_t *preg, char *localbuf);
#ifdef __cplusplus
}
diff --git a/regex/regexec.c b/regex/regexec.c
index 723289bd0ad..b7ad83ba883 100644
--- a/regex/regexec.c
+++ b/regex/regexec.c
@@ -8,11 +8,10 @@
#include <my_global.h>
#include <m_string.h>
#include <m_ctype.h>
-#include <regex.h>
#ifdef __WIN__
#include <limits.h>
#endif
-
+#include "my_regex.h"
#include "utils.h"
#include "regex2.h"
@@ -110,11 +109,11 @@ static int nope = 0; /* for use in asserts; shuts lint up */
* have been prototyped.
*/
int /* 0 success, REG_NOMATCH failure */
-regexec(preg, str, nmatch, pmatch, eflags)
-const regex_t *preg;
+my_regexec(preg, str, nmatch, pmatch, eflags)
+const my_regex_t *preg;
const char *str;
size_t nmatch;
-regmatch_t pmatch[];
+my_regmatch_t pmatch[];
int eflags;
{
register struct re_guts *g = preg->re_g;
diff --git a/regex/regfree.c b/regex/regfree.c
index 6ab50735075..f764fcdf84e 100644
--- a/regex/regfree.c
+++ b/regex/regfree.c
@@ -2,7 +2,7 @@
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
-#include <regex.h>
+#include "my_regex.h"
#include "utils.h"
#include "regex2.h"
@@ -12,8 +12,8 @@
= extern void regfree(regex_t *);
*/
void
-regfree(preg)
-regex_t *preg;
+my_regfree(preg)
+my_regex_t *preg;
{
register struct re_guts *g;
diff --git a/regex/reginit.c b/regex/reginit.c
index 74ad3dc6de4..f0b53e64be3 100644
--- a/regex/reginit.c
+++ b/regex/reginit.c
@@ -7,7 +7,7 @@
static bool regex_inited=0;
-void regex_init(CHARSET_INFO *cs)
+void my_regex_init(CHARSET_INFO *cs)
{
char buff[CCLASS_LAST][256];
int count[CCLASS_LAST];
@@ -67,7 +67,7 @@ void regex_init(CHARSET_INFO *cs)
return;
}
-void regex_end()
+void my_regex_end()
{
if (regex_inited)
{
diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh
index fbdbd998138..9c2ae9c42f2 100644
--- a/scripts/make_binary_distribution.sh
+++ b/scripts/make_binary_distribution.sh
@@ -169,7 +169,8 @@ for i in \
libmysql_r/.libs/libmysqlclient_r.so* libmysql_r/libmysqlclient_r.* \
mysys/libmysys.a strings/libmystrings.a dbug/libdbug.a \
libmysqld/.libs/libmysqld.a libmysqld/.libs/libmysqld.so* \
- libmysqld/libmysqld.a netware/libmysql.imp
+ libmysqld/libmysqld.a netware/libmysql.imp \
+ zlib/.libs/libz.a
do
if [ -f $i ]
then
diff --git a/scripts/mysql_config.sh b/scripts/mysql_config.sh
index 16e50c044ca..5b35c0190a5 100644
--- a/scripts/mysql_config.sh
+++ b/scripts/mysql_config.sh
@@ -101,13 +101,16 @@ libs_r="$ldflags -L$pkglibdir -lmysqlclient_r @ZLIB_DEPS@ @LIBS@ @openssl_libs@"
libs_r=`echo "$libs_r" | sed -e 's; \+; ;g' | sed -e 's;^ *;;' | sed -e 's; *\$;;'`
cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
include="-I$pkgincludedir"
-embedded_libs="$ldflags -L$pkglibdir -lmysqld @LIBS@ @WRAPLIBS@ @innodb_system_libs@ $client_libs"
+embedded_libs="$ldflags -L$pkglibdir -lmysqld @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @innodb_system_libs@"
embedded_libs=`echo "$embedded_libs" | sed -e 's; \+; ;g' | sed -e 's;^ *;;' | sed -e 's; *\$;;'`
# Remove some options that a client doesn't have to care about
+# FIXME until we have a --cxxflags, we need to remove -Xa
+# and -xstrconst to make --cflags usable for Sun Forte C++
for remove in DDBUG_OFF DSAFEMALLOC USAFEMALLOC DSAFE_MUTEX \
DPEDANTIC_SAFEMALLOC DUNIV_MUST_NOT_INLINE DFORCE_INIT_OF_VARS \
- DEXTRA_DEBUG DHAVE_purify 'O[0-9]' 'W[-A-Za-z]*'
+ DEXTRA_DEBUG DHAVE_purify 'O[0-9]' 'W[-A-Za-z]*' \
+ Xa xstrconst
do
# The first option we might strip will always have a space before it because
# we set -I$pkgincludedir as the first option
@@ -120,13 +123,13 @@ usage () {
Usage: $0 [OPTIONS]
Options:
--cflags [$cflags]
- --include [$include]
+ --include [$include]
--libs [$libs]
--libs_r [$libs_r]
--socket [$socket]
--port [$port]
--version [$version]
- --libmysqld-libs [$embedded_libs]
+ --libmysqld-libs [$embedded_libs]
EOF
exit 1
}
@@ -136,13 +139,13 @@ if test $# -le 0; then usage; fi
while test $# -gt 0; do
case $1 in
--cflags) echo "$cflags" ;;
- --include) echo "$include" ;;
+ --include) echo "$include" ;;
--libs) echo "$libs" ;;
--libs_r) echo "$libs_r" ;;
--socket) echo "$socket" ;;
--port) echo "$port" ;;
--version) echo "$version" ;;
- --embedded-libs | --embedded | --libmysqld-libs) echo "$embedded_libs" ;;
+ --embedded-libs | --embedded | --libmysqld-libs) echo "$embedded_libs" ;;
*) usage ;;
esac
diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh
index 383f8b80dc8..babf3a1c83f 100644
--- a/scripts/mysql_create_system_tables.sh
+++ b/scripts/mysql_create_system_tables.sh
@@ -123,7 +123,7 @@ then
c_u="$c_u CREATE TABLE user ("
c_u="$c_u Host char(60) binary DEFAULT '' NOT NULL,"
c_u="$c_u User char(16) binary DEFAULT '' NOT NULL,"
- c_u="$c_u Password char(41) binary DEFAULT '' NOT NULL,"
+ c_u="$c_u Password binary(41) DEFAULT '' NOT NULL,"
c_u="$c_u Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
c_u="$c_u Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
c_u="$c_u Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh
index d080b68b268..073964d4bde 100644
--- a/scripts/mysql_fix_privilege_tables.sh
+++ b/scripts/mysql_fix_privilege_tables.sh
@@ -97,9 +97,11 @@ fi
# Find where 'mysql' command is located
+dirname=`dirname "$0"`
+
if test -z "$bindir"
then
- for i in @bindir@ $basedir/bin client
+ for i in @bindir@ $basedir/bin "$dirname/../client"
do
if test -f $i/mysql
then
@@ -109,6 +111,13 @@ then
done
fi
+if test -z "$bindir"
+then
+ echo "Could not find MySQL command-line client (mysql)."
+ echo "Please use --basedir to specify the directory where MySQL is installed."
+ exit 1
+fi
+
cmd="$bindir/mysql --no-defaults --force --user=$user --host=$host"
if test ! -z "$password" ; then
cmd="$cmd --password=$password"
@@ -128,7 +137,7 @@ fi
# Find where first mysql_fix_privilege_tables.sql is located
for i in $basedir/support-files $basedir/share $basedir/share/mysql \
- $basedir/scripts $pkgdatadir . ./scripts
+ $basedir/scripts $pkgdatadir . "$dirname"
do
if test -f $i/$file
then
diff --git a/scripts/mysql_fix_privilege_tables.sql b/scripts/mysql_fix_privilege_tables.sql
index 328839345aa..2248e0a84fd 100644
--- a/scripts/mysql_fix_privilege_tables.sql
+++ b/scripts/mysql_fix_privilege_tables.sql
@@ -155,9 +155,9 @@ alter table columns_priv comment='Column privileges';
ALTER TABLE user
MODIFY Host char(60) NOT NULL default '',
MODIFY User char(16) NOT NULL default '',
- MODIFY Password char(41) NOT NULL default '',
ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;
ALTER TABLE user
+ MODIFY Password binary(41) NOT NULL default '',
MODIFY Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
MODIFY Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
MODIFY Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh
index 098cd894916..b2b85018d7a 100644
--- a/scripts/mysqld_multi.sh
+++ b/scripts/mysqld_multi.sh
@@ -4,7 +4,7 @@ use Getopt::Long;
use POSIX qw(strftime);
$|=1;
-$VER="2.14";
+$VER="2.15";
$opt_config_file = undef();
$opt_example = 0;
@@ -326,7 +326,6 @@ sub start_mysqlds()
}
else
{
- $options[$j]=~ s/;/\\;/g;
$options[$j]= quote_opt_arg($options[$j]);
$tmp.= " $options[$j]";
}
diff --git a/server-tools/instance-manager/buffer.cc b/server-tools/instance-manager/buffer.cc
index 26df401c3c5..8039ab24481 100644
--- a/server-tools/instance-manager/buffer.cc
+++ b/server-tools/instance-manager/buffer.cc
@@ -14,13 +14,15 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
#pragma implementation
#endif
#include "buffer.h"
#include <m_string.h>
+const uint Buffer::BUFFER_INITIAL_SIZE= 4096;
+const uint Buffer::MAX_BUFFER_SIZE= 16777216;
/*
Puts the given string to the buffer.
diff --git a/server-tools/instance-manager/buffer.h b/server-tools/instance-manager/buffer.h
index e63d725f508..afc71320ecb 100644
--- a/server-tools/instance-manager/buffer.h
+++ b/server-tools/instance-manager/buffer.h
@@ -19,7 +19,7 @@
#include <my_global.h>
#include <my_sys.h>
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
@@ -33,9 +33,9 @@
class Buffer
{
private:
- enum { BUFFER_INITIAL_SIZE= 4096 };
+ static const uint BUFFER_INITIAL_SIZE;
/* maximum buffer size is 16Mb */
- enum { MAX_BUFFER_SIZE= 16777216 };
+ static const uint MAX_BUFFER_SIZE;
size_t buffer_size;
/* Error flag. Triggered if we get an error of some kind */
int error;
diff --git a/server-tools/instance-manager/command.cc b/server-tools/instance-manager/command.cc
index 73dd49ef8b8..f76366d5661 100644
--- a/server-tools/instance-manager/command.cc
+++ b/server-tools/instance-manager/command.cc
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
#pragma implementation
#endif
diff --git a/server-tools/instance-manager/command.h b/server-tools/instance-manager/command.h
index 8ae4e33b92f..82ded800e65 100644
--- a/server-tools/instance-manager/command.h
+++ b/server-tools/instance-manager/command.h
@@ -16,7 +16,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
diff --git a/server-tools/instance-manager/commands.cc b/server-tools/instance-manager/commands.cc
index 1cf888eab45..b4dd1b469f1 100644
--- a/server-tools/instance-manager/commands.cc
+++ b/server-tools/instance-manager/commands.cc
@@ -695,9 +695,9 @@ Set_option::Set_option(Instance_map *instance_map_arg,
int Set_option::correct_file(int skip)
{
- int error;
- const static int mysys_to_im_error[]= { 0, ER_OUT_OF_RESOURCES,
+ static const int mysys_to_im_error[]= { 0, ER_OUT_OF_RESOURCES,
ER_ACCESS_OPTION_FILE };
+ int error;
error= modify_defaults_file(Options::config_file, option,
option_value, instance_name, skip);
diff --git a/server-tools/instance-manager/guardian.cc b/server-tools/instance-manager/guardian.cc
index 17f4204185a..a4c0cef41b3 100644
--- a/server-tools/instance-manager/guardian.cc
+++ b/server-tools/instance-manager/guardian.cc
@@ -15,7 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
#pragma implementation
#endif
diff --git a/server-tools/instance-manager/guardian.h b/server-tools/instance-manager/guardian.h
index 758c4a3f3bc..16180e72dc9 100644
--- a/server-tools/instance-manager/guardian.h
+++ b/server-tools/instance-manager/guardian.h
@@ -22,7 +22,7 @@
#include <my_sys.h>
#include <my_list.h>
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc
index 5e1c3d2ea9f..0c3c1aee5b4 100644
--- a/server-tools/instance-manager/instance.cc
+++ b/server-tools/instance-manager/instance.cc
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
#pragma implementation
#endif
diff --git a/server-tools/instance-manager/instance.h b/server-tools/instance-manager/instance.h
index 003cbca8cef..adb66991685 100644
--- a/server-tools/instance-manager/instance.h
+++ b/server-tools/instance-manager/instance.h
@@ -19,7 +19,7 @@
#include <my_global.h>
#include "instance_options.h"
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
diff --git a/server-tools/instance-manager/instance_map.cc b/server-tools/instance-manager/instance_map.cc
index b3a207ae79f..611eda457f2 100644
--- a/server-tools/instance-manager/instance_map.cc
+++ b/server-tools/instance-manager/instance_map.cc
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
#pragma implementation
#endif
diff --git a/server-tools/instance-manager/instance_map.h b/server-tools/instance-manager/instance_map.h
index 47037e0d433..51971db4c2f 100644
--- a/server-tools/instance-manager/instance_map.h
+++ b/server-tools/instance-manager/instance_map.h
@@ -24,7 +24,7 @@
#include <my_sys.h>
#include <hash.h>
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc
index 70950a91015..25609f489af 100644
--- a/server-tools/instance-manager/instance_options.cc
+++ b/server-tools/instance-manager/instance_options.cc
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
#pragma implementation
#endif
@@ -469,7 +469,7 @@ int Instance_options::add_option(const char* option)
case SAVE_WHOLE:
*(selected_options->value)= tmp;
return 0;
- defaut:
+ default:
break;
}
}
diff --git a/server-tools/instance-manager/instance_options.h b/server-tools/instance-manager/instance_options.h
index dc62d277a43..dae1c2695d1 100644
--- a/server-tools/instance-manager/instance_options.h
+++ b/server-tools/instance-manager/instance_options.h
@@ -21,7 +21,7 @@
#include "parse.h"
#include "portability.h"
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
diff --git a/server-tools/instance-manager/listener.cc b/server-tools/instance-manager/listener.cc
index 374946d3b73..a1c1a743c24 100644
--- a/server-tools/instance-manager/listener.cc
+++ b/server-tools/instance-manager/listener.cc
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
#pragma implementation
#endif
diff --git a/server-tools/instance-manager/listener.h b/server-tools/instance-manager/listener.h
index 67a090c3aa2..3f5a80f1f53 100644
--- a/server-tools/instance-manager/listener.h
+++ b/server-tools/instance-manager/listener.h
@@ -16,7 +16,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
diff --git a/server-tools/instance-manager/mysql_connection.cc b/server-tools/instance-manager/mysql_connection.cc
index dfa12f6f6e2..4a32e95450e 100644
--- a/server-tools/instance-manager/mysql_connection.cc
+++ b/server-tools/instance-manager/mysql_connection.cc
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
#pragma interface
#endif
diff --git a/server-tools/instance-manager/mysql_connection.h b/server-tools/instance-manager/mysql_connection.h
index e0109ce234f..2ff55d81e57 100644
--- a/server-tools/instance-manager/mysql_connection.h
+++ b/server-tools/instance-manager/mysql_connection.h
@@ -16,7 +16,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
diff --git a/server-tools/instance-manager/mysqlmanager.vcproj b/server-tools/instance-manager/mysqlmanager.vcproj
index a5ef7cb21e3..ef8b2dd017e 100644
--- a/server-tools/instance-manager/mysqlmanager.vcproj
+++ b/server-tools/instance-manager/mysqlmanager.vcproj
@@ -12,7 +12,7 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Debug"
+ OutputDirectory="../../client_debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
@@ -63,7 +63,7 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Release"
+ OutputDirectory="../../client_release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
diff --git a/server-tools/instance-manager/options.cc b/server-tools/instance-manager/options.cc
index 74ccade3a2c..b16fcabae01 100644
--- a/server-tools/instance-manager/options.cc
+++ b/server-tools/instance-manager/options.cc
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
#pragma implementation
#endif
diff --git a/server-tools/instance-manager/options.h b/server-tools/instance-manager/options.h
index a5cd049decf..3a60de2bb39 100644
--- a/server-tools/instance-manager/options.h
+++ b/server-tools/instance-manager/options.h
@@ -16,7 +16,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
diff --git a/server-tools/instance-manager/parse_output.cc b/server-tools/instance-manager/parse_output.cc
index 4ec9a71bfd2..b5af3cb83a7 100644
--- a/server-tools/instance-manager/parse_output.cc
+++ b/server-tools/instance-manager/parse_output.cc
@@ -107,7 +107,6 @@ int parse_output_and_get_value(const char *command, const char *word,
}
}
-pclose:
/* we are not interested in the termination status */
pclose(output);
diff --git a/server-tools/instance-manager/portability.h b/server-tools/instance-manager/portability.h
index c2b4e8b7467..2bdeff71a72 100644
--- a/server-tools/instance-manager/portability.h
+++ b/server-tools/instance-manager/portability.h
@@ -1,6 +1,10 @@
#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_PORTABILITY_H
#define INCLUDES_MYSQL_INSTANCE_MANAGER_PORTABILITY_H
+#if defined(_SCO_DS) && !defined(SHUT_RDWR)
+#define SHUT_RDWR 2
+#endif
+
#ifdef __WIN__
#define vsnprintf _vsnprintf
diff --git a/server-tools/instance-manager/protocol.cc b/server-tools/instance-manager/protocol.cc
index cd1be805b6b..73e07f993ae 100644
--- a/server-tools/instance-manager/protocol.cc
+++ b/server-tools/instance-manager/protocol.cc
@@ -23,6 +23,7 @@
static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */
+static const char ERROR_PACKET_CODE= (char) 255;
int net_send_ok(struct st_net *net, unsigned long connection_id,
@@ -74,7 +75,6 @@ int net_send_error(struct st_net *net, uint sql_errno)
MYSQL_ERRMSG_SIZE]; // message
char *pos= buff;
- enum { ERROR_PACKET_CODE= 255 };
*pos++= ERROR_PACKET_CODE;
int2store(pos, sql_errno);
pos+= 2;
@@ -95,7 +95,6 @@ int net_send_error_323(struct st_net *net, uint sql_errno)
MYSQL_ERRMSG_SIZE]; // message
char *pos= buff;
- enum { ERROR_PACKET_CODE= 255 };
*pos++= ERROR_PACKET_CODE;
int2store(pos, sql_errno);
pos+= 2;
@@ -148,14 +147,14 @@ int store_to_protocol_packet(Buffer *buf, const char *string, uint *position)
int send_eof(struct st_net *net)
{
- char buff[1 + /* eof packet code */
- 2 + /* warning count */
- 2]; /* server status */
+ uchar buff[1 + /* eof packet code */
+ 2 + /* warning count */
+ 2]; /* server status */
buff[0]=254;
int2store(buff+1, 0);
int2store(buff+3, 0);
- return my_net_write(net, buff, sizeof buff);
+ return my_net_write(net, (char*) buff, sizeof buff);
}
int send_fields(struct st_net *net, LIST *fields)
@@ -195,7 +194,7 @@ int send_fields(struct st_net *net, LIST *fields)
int2store(send_buff.buffer + position, 1); /* charsetnr */
int4store(send_buff.buffer + position + 2,
field->length); /* field length */
- send_buff.buffer[position+6]= FIELD_TYPE_STRING; /* type */
+ send_buff.buffer[position+6]= (char) FIELD_TYPE_STRING; /* type */
int2store(send_buff.buffer + position + 7, 0); /* flags */
send_buff.buffer[position + 9]= (char) 0; /* decimals */
send_buff.buffer[position + 10]= 0;
diff --git a/server-tools/instance-manager/thread_registry.cc b/server-tools/instance-manager/thread_registry.cc
index a7384c0fa13..fe665f410e5 100644
--- a/server-tools/instance-manager/thread_registry.cc
+++ b/server-tools/instance-manager/thread_registry.cc
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
#pragma implementation
#endif
diff --git a/server-tools/instance-manager/thread_registry.h b/server-tools/instance-manager/thread_registry.h
index 28899810f23..a1075e719d6 100644
--- a/server-tools/instance-manager/thread_registry.h
+++ b/server-tools/instance-manager/thread_registry.h
@@ -50,7 +50,7 @@
in manner, similar to ``quit'' signals.
*/
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
diff --git a/server-tools/instance-manager/user_map.cc b/server-tools/instance-manager/user_map.cc
index d13eb681d05..d901d1ca5ec 100644
--- a/server-tools/instance-manager/user_map.cc
+++ b/server-tools/instance-manager/user_map.cc
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
#pragma interface
#endif
@@ -66,7 +66,8 @@ int User::init(const char *line)
*/
if (password[strlen(password)-2] == '\r')
line_ending_len= 2;
- if (strlen(password) != SCRAMBLED_PASSWORD_CHAR_LENGTH + line_ending_len)
+ if (strlen(password) != (uint) (SCRAMBLED_PASSWORD_CHAR_LENGTH +
+ line_ending_len))
goto err;
memcpy(user, name_begin, user_length);
diff --git a/server-tools/instance-manager/user_map.h b/server-tools/instance-manager/user_map.h
index 4c86edd93d9..a57174a37c3 100644
--- a/server-tools/instance-manager/user_map.h
+++ b/server-tools/instance-manager/user_map.h
@@ -16,7 +16,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
diff --git a/sql/Makefile.am b/sql/Makefile.am
index e90be7630fa..ada462f5e09 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -61,8 +61,8 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
tztime.h my_decimal.h\
sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
parse_file.h sql_view.h sql_trigger.h \
- sql_array.h \
- examples/ha_example.h examples/ha_archive.h \
+ sql_array.h sql_cursor.h \
+ examples/ha_example.h ha_archive.h \
examples/ha_tina.h ha_blackhole.h \
ha_federated.h ha_partition.h
mysqld_SOURCES = sql_lex.cc sql_handler.cc \
@@ -95,11 +95,11 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
client.c sql_client.cc mini_client_errors.c pack.c\
stacktrace.c repl_failsafe.h repl_failsafe.cc \
sql_olap.cc sql_view.cc \
- gstream.cc spatial.cc sql_help.cc protocol_cursor.cc \
+ gstream.cc spatial.cc sql_help.cc sql_cursor.cc \
tztime.cc my_time.c my_decimal.cc\
sp_head.cc sp_pcontext.cc sp_rcontext.cc sp.cc \
sp_cache.cc parse_file.cc sql_trigger.cc \
- examples/ha_example.cc examples/ha_archive.cc \
+ examples/ha_example.cc ha_archive.cc \
examples/ha_tina.cc ha_blackhole.cc \
ha_partition.cc sql_partition.cc \
ha_federated.cc
diff --git a/sql/examples/ha_example.cc b/sql/examples/ha_example.cc
index dfc2fa7a260..d340b9289ec 100644
--- a/sql/examples/ha_example.cc
+++ b/sql/examples/ha_example.cc
@@ -73,8 +73,12 @@
#include "ha_example.h"
-static handlerton example_hton= {
- "CSV",
+handlerton example_hton= {
+ "EXAMPLE",
+ SHOW_OPTION_YES,
+ "Example storage engine",
+ DB_TYPE_EXAMPLE_DB,
+ NULL, /* We do need to write one! */
0, /* slot */
0, /* savepoint size. */
NULL, /* close_connection */
@@ -90,7 +94,7 @@ static handlerton example_hton= {
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
- HTON_NO_FLAGS
+ HTON_CAN_RECREATE
};
/* Variables for example share methods */
diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc
index a611466ca1d..2c193f4ce84 100644
--- a/sql/examples/ha_tina.cc
+++ b/sql/examples/ha_tina.cc
@@ -58,8 +58,12 @@ pthread_mutex_t tina_mutex;
static HASH tina_open_tables;
static int tina_init= 0;
-static handlerton tina_hton= {
+handlerton tina_hton= {
"CSV",
+ SHOW_OPTION_YES,
+ "CSV storage engine",
+ DB_TYPE_CSV_DB,
+ NULL, /* One needs to be written! */
0, /* slot */
0, /* savepoint size. */
NULL, /* close_connection */
@@ -75,7 +79,7 @@ static handlerton tina_hton= {
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
- HTON_NO_FLAGS
+ HTON_CAN_RECREATE
};
/*****************************************************************************
@@ -243,6 +247,16 @@ static int free_share(TINA_SHARE *share)
DBUG_RETURN(result_code);
}
+bool tina_end()
+{
+ if (tina_init)
+ {
+ hash_free(&tina_open_tables);
+ VOID(pthread_mutex_destroy(&tina_mutex));
+ }
+ tina_init= 0;
+ return FALSE;
+}
/*
Finds the end of a line.
@@ -873,19 +887,7 @@ THR_LOCK_DATA **ha_tina::store_lock(THD *thd,
return to;
}
-/*
- Range optimizer calls this.
- I need to update the information on this.
-*/
-ha_rows ha_tina::records_in_range(uint inx, key_range *min_key,
- key_range *max_key)
-{
- DBUG_ENTER("ha_tina::records_in_range ");
- DBUG_RETURN(records); // Good guess
-}
-
-
-/*
+/*
Create a table. You do not want to leave the table open after a call to
this (the database will call ::open() if it needs to).
*/
diff --git a/sql/examples/ha_tina.h b/sql/examples/ha_tina.h
index 43479c7c11c..0ac90a05812 100644
--- a/sql/examples/ha_tina.h
+++ b/sql/examples/ha_tina.h
@@ -83,11 +83,6 @@ public:
*/
virtual double scan_time() { return (double) (records+deleted) / 20.0+10; }
/* The next method will never be called */
- virtual double read_time(uint index, uint ranges, ha_rows rows)
- {
- DBUG_ASSERT(0);
- return((double) rows / 20.0+1);
- }
virtual bool fast_key_read() { return 1;}
/*
TODO: return actual upper bound of number of records in the table.
@@ -119,10 +114,6 @@ public:
int reset(void);
int external_lock(THD *thd, int lock_type);
int delete_all_rows(void);
- ha_rows records_in_range(uint inx, key_range *min_key,
- key_range *max_key);
-// int delete_table(const char *from);
-// int rename_table(const char * from, const char * to);
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
@@ -133,3 +124,6 @@ public:
int find_current_row(byte *buf);
int chain_append();
};
+
+bool tina_end();
+
diff --git a/sql/field.cc b/sql/field.cc
index 779dae20220..d334dc1ab53 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -3440,7 +3440,7 @@ int Field_long::store(longlong nr, bool unsigned_val)
else
{
if (nr < 0 && unsigned_val)
- nr= INT_MAX32+1; // Generate overflow
+ nr= ((longlong) INT_MAX32) + 1; // Generate overflow
if (nr < (longlong) INT_MIN32)
{
res=(int32) INT_MIN32;
diff --git a/sql/examples/ha_archive.cc b/sql/ha_archive.cc
index 85104405024..59c56e80cc3 100644
--- a/sql/examples/ha_archive.cc
+++ b/sql/ha_archive.cc
@@ -18,7 +18,7 @@
#pragma implementation // gcc: Class implementation
#endif
-#include "../mysql_priv.h"
+#include "mysql_priv.h"
#ifdef HAVE_ARCHIVE_DB
#include "ha_archive.h"
@@ -116,7 +116,7 @@
*/
/* If the archive storage engine has been inited */
-static bool archive_inited= 0;
+static bool archive_inited= FALSE;
/* Variables for archive share methods */
pthread_mutex_t archive_mutex;
static HASH archive_open_tables;
@@ -136,8 +136,12 @@ static HASH archive_open_tables;
#define ARCHIVE_CHECK_HEADER 254 // The number we use to determine corruption
/* dummy handlerton - only to have something to return from archive_db_init */
-static handlerton archive_hton = {
- "archive",
+handlerton archive_hton = {
+ "ARCHIVE",
+ SHOW_OPTION_YES,
+ "Archive storage engine",
+ DB_TYPE_ARCHIVE_DB,
+ archive_db_init,
0, /* slot */
0, /* savepoint size. */
NULL, /* close_connection */
@@ -176,18 +180,28 @@ static byte* archive_get_key(ARCHIVE_SHARE *share,uint *length,
void
RETURN
- &archive_hton OK
- 0 Error
+ FALSE OK
+ TRUE Error
*/
-handlerton *archive_db_init()
+bool archive_db_init()
{
- archive_inited= 1;
- VOID(pthread_mutex_init(&archive_mutex, MY_MUTEX_INIT_FAST));
+ DBUG_ENTER("archive_db_init");
+ if (pthread_mutex_init(&archive_mutex, MY_MUTEX_INIT_FAST))
+ goto error;
if (hash_init(&archive_open_tables, system_charset_info, 32, 0, 0,
(hash_get_key) archive_get_key, 0, 0))
- return 0;
- return &archive_hton;
+ {
+ VOID(pthread_mutex_destroy(&archive_mutex));
+ }
+ else
+ {
+ archive_inited= TRUE;
+ DBUG_RETURN(FALSE);
+ }
+error:
+ have_archive_db= SHOW_OPTION_DISABLED; // If we couldn't use handler
+ DBUG_RETURN(TRUE);
}
/*
diff --git a/sql/examples/ha_archive.h b/sql/ha_archive.h
index e2d8aa49add..849b5b5bd6c 100644
--- a/sql/examples/ha_archive.h
+++ b/sql/ha_archive.h
@@ -105,6 +105,6 @@ public:
enum thr_lock_type lock_type);
};
-handlerton *archive_db_init(void);
+bool archive_db_init(void);
bool archive_db_end(void);
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 5bead36600b..3312b60e6c4 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -108,8 +108,12 @@ static int berkeley_close_connection(THD *thd);
static int berkeley_commit(THD *thd, bool all);
static int berkeley_rollback(THD *thd, bool all);
-static handlerton berkeley_hton = {
+handlerton berkeley_hton = {
"BerkeleyDB",
+ SHOW_OPTION_YES,
+ "Supports transactions and page-level locking",
+ DB_TYPE_BERKELEY_DB,
+ berkeley_init,
0, /* slot */
0, /* savepoint size */
berkeley_close_connection,
@@ -136,10 +140,13 @@ typedef struct st_berkeley_trx_data {
/* General functions */
-handlerton *berkeley_init(void)
+bool berkeley_init(void)
{
DBUG_ENTER("berkeley_init");
+ if (have_berkeley_db != SHOW_OPTION_YES)
+ goto error;
+
if (!berkeley_tmpdir)
berkeley_tmpdir=mysql_tmpdir;
if (!berkeley_home)
@@ -165,7 +172,7 @@ handlerton *berkeley_init(void)
berkeley_log_file_size= max(berkeley_log_file_size, 10*1024*1024L);
if (db_env_create(&db_env,0))
- DBUG_RETURN(0);
+ goto error;
db_env->set_errcall(db_env,berkeley_print_error);
db_env->set_errpfx(db_env,"bdb");
db_env->set_noticecall(db_env, berkeley_noticecall);
@@ -195,13 +202,16 @@ handlerton *berkeley_init(void)
{
db_env->close(db_env,0);
db_env=0;
- DBUG_RETURN(0);
+ goto error;
}
(void) hash_init(&bdb_open_tables,system_charset_info,32,0,0,
(hash_get_key) bdb_get_key,0,0);
pthread_mutex_init(&bdb_mutex,MY_MUTEX_INIT_FAST);
- DBUG_RETURN(&berkeley_hton);
+ DBUG_RETURN(FALSE);
+error:
+ have_berkeley_db= SHOW_OPTION_DISABLED; // If we couldn't use handler
+ DBUG_RETURN(TRUE);
}
@@ -1897,7 +1907,7 @@ int ha_berkeley::external_lock(THD *thd, int lock_type)
Under LOCK TABLES, each used tables will force a call to start_stmt.
*/
-int ha_berkeley::start_stmt(THD *thd)
+int ha_berkeley::start_stmt(THD *thd, thr_lock_type lock_type)
{
int error=0;
DBUG_ENTER("ha_berkeley::start_stmt");
diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h
index aab76accefa..95ff64a082a 100644
--- a/sql/ha_berkeley.h
+++ b/sql/ha_berkeley.h
@@ -124,7 +124,7 @@ class ha_berkeley: public handler
int extra(enum ha_extra_function operation);
int reset(void);
int external_lock(THD *thd, int lock_type);
- int start_stmt(THD *thd);
+ int start_stmt(THD *thd, thr_lock_type lock_type);
void position(byte *record);
int analyze(THD* thd,HA_CHECK_OPT* check_opt);
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
@@ -162,7 +162,7 @@ extern char *berkeley_home, *berkeley_tmpdir, *berkeley_logdir;
extern long berkeley_lock_scan_time;
extern TYPELIB berkeley_lock_typelib;
-handlerton *berkeley_init(void);
+bool berkeley_init(void);
bool berkeley_end(void);
bool berkeley_flush_logs(void);
int berkeley_show_logs(Protocol *protocol);
diff --git a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc
index a287d6e446b..2505919af39 100644
--- a/sql/ha_blackhole.cc
+++ b/sql/ha_blackhole.cc
@@ -26,8 +26,12 @@
/* Blackhole storage engine handlerton */
-static handlerton blackhole_hton= {
+handlerton blackhole_hton= {
"BLACKHOLE",
+ SHOW_OPTION_YES,
+ "/dev/null storage engine (anything you write to it disappears)",
+ DB_TYPE_BLACKHOLE_DB,
+ NULL,
0, /* slot */
0, /* savepoint size. */
NULL, /* close_connection */
@@ -43,7 +47,7 @@ static handlerton blackhole_hton= {
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
- HTON_NO_FLAGS
+ HTON_CAN_RECREATE
};
/*****************************************************************************
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc
index fa027ce71b5..66c2431844d 100644
--- a/sql/ha_federated.cc
+++ b/sql/ha_federated.cc
@@ -363,6 +363,33 @@ pthread_mutex_t federated_mutex; // This is the mutex we use to
static int federated_init= FALSE; // Variable for checking the
// init state of hash
+/* Federated storage engine handlerton */
+
+handlerton federated_hton= {
+ "FEDERATED",
+ SHOW_OPTION_YES,
+ "Federated MySQL storage engine",
+ DB_TYPE_FEDERATED_DB,
+ federated_db_init,
+ 0, /* slot */
+ 0, /* savepoint size. */
+ NULL, /* close_connection */
+ NULL, /* savepoint */
+ NULL, /* rollback to savepoint */
+ NULL, /* release savepoint */
+ NULL, /* commit */
+ NULL, /* rollback */
+ NULL, /* prepare */
+ NULL, /* recover */
+ NULL, /* commit_by_xid */
+ NULL, /* rollback_by_xid */
+ NULL, /* create_cursor_read_view */
+ NULL, /* set_cursor_read_view */
+ NULL, /* close_cursor_read_view */
+ HTON_ALTER_NOT_SUPPORTED
+};
+
+
/* Function we use in the creation of our hash to get key. */
static byte *federated_get_key(FEDERATED_SHARE *share, uint *length,
@@ -386,10 +413,22 @@ static byte *federated_get_key(FEDERATED_SHARE *share, uint *length,
bool federated_db_init()
{
- federated_init= 1;
- VOID(pthread_mutex_init(&federated_mutex, MY_MUTEX_INIT_FAST));
- return (hash_init(&federated_open_tables, system_charset_info, 32, 0, 0,
- (hash_get_key) federated_get_key, 0, 0));
+ DBUG_ENTER("federated_db_init");
+ if (pthread_mutex_init(&federated_mutex, MY_MUTEX_INIT_FAST))
+ goto error;
+ if (hash_init(&federated_open_tables, system_charset_info, 32, 0, 0,
+ (hash_get_key) federated_get_key, 0, 0))
+ {
+ VOID(pthread_mutex_destroy(&federated_mutex));
+ }
+ else
+ {
+ federated_init= TRUE;
+ DBUG_RETURN(FALSE);
+ }
+error:
+ have_federated_db= SHOW_OPTION_DISABLED; // If we couldn't use handler
+ DBUG_RETURN(TRUE);
}
@@ -588,12 +627,15 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table,
DBUG_ENTER("ha_federated::parse_url");
share->port= 0;
+ share->socket= 0;
DBUG_PRINT("info", ("Length %d \n", table->s->connect_string.length));
DBUG_PRINT("info", ("String %.*s \n", table->s->connect_string.length,
table->s->connect_string.str));
- share->scheme= my_strdup_with_length(table->s->connect_string.str,
- table->s->connect_string.length+1,
- MYF(0));
+ share->scheme= my_strdup_with_length((const byte*)table->s->
+ connect_string.str,
+ table->s->connect_string.length,
+ MYF(0));
+
// Add a null for later termination of table name
share->scheme[table->s->connect_string.length]= 0;
DBUG_PRINT("info",("parse_url alloced share->scheme %lx", share->scheme));
@@ -691,29 +733,6 @@ error:
}
-/* Federated storage engine handlerton */
-
-static handlerton federated_hton= {
- "FEDERATED",
- 0, /* slot */
- 0, /* savepoint size. */
- NULL, /* close_connection */
- NULL, /* savepoint */
- NULL, /* rollback to savepoint */
- NULL, /* release savepoint */
- NULL, /* commit */
- NULL, /* rollback */
- NULL, /* prepare */
- NULL, /* recover */
- NULL, /* commit_by_xid */
- NULL, /* rollback_by_xid */
- NULL, /* create_cursor_read_view */
- NULL, /* set_cursor_read_view */
- NULL, /* close_cursor_read_view */
- HTON_NO_FLAGS
-};
-
-
/*****************************************************************************
** FEDERATED tables
*****************************************************************************/
@@ -1374,13 +1393,9 @@ static int free_share(FEDERATED_SHARE *share)
if (!--share->use_count)
{
- if (share->scheme)
- {
- my_free((gptr) share->scheme, MYF(0));
- share->scheme= 0;
- }
-
hash_delete(&federated_open_tables, (byte*) share);
+ my_free((gptr) share->scheme, MYF(MY_ALLOW_ZERO_PTR));
+ share->scheme= 0;
thr_lock_delete(&share->lock);
VOID(pthread_mutex_destroy(&share->mutex));
my_free((gptr) share, MYF(0));
@@ -2601,7 +2616,8 @@ int ha_federated::stash_remote_error()
{
DBUG_ENTER("ha_federated::stash_remote_error()");
remote_error_number= mysql_errno(mysql);
- snprintf(remote_error_buf, FEDERATED_QUERY_BUFFER_SIZE, mysql_error(mysql));
+ my_snprintf(remote_error_buf, FEDERATED_QUERY_BUFFER_SIZE,
+ mysql_error(mysql));
DBUG_RETURN(HA_FEDERATED_ERROR_WITH_REMOTE_SYSTEM);
}
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index 01e693978db..ab13f03825d 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -23,8 +23,12 @@
#include <myisampack.h>
#include "ha_heap.h"
-static handlerton heap_hton= {
+handlerton heap_hton= {
"MEMORY",
+ SHOW_OPTION_YES,
+ "Hash based, stored in memory, useful for temporary tables",
+ DB_TYPE_HEAP,
+ NULL,
0, /* slot */
0, /* savepoint size. */
NULL, /* close_connection */
@@ -40,7 +44,7 @@ static handlerton heap_hton= {
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
- HTON_NO_FLAGS
+ HTON_CAN_RECREATE
};
/*****************************************************************************
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 638bda49002..dc019bc7a3a 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -206,8 +206,12 @@ static int innobase_rollback_to_savepoint(THD* thd, void *savepoint);
static int innobase_savepoint(THD* thd, void *savepoint);
static int innobase_release_savepoint(THD* thd, void *savepoint);
-static handlerton innobase_hton = {
+handlerton innobase_hton = {
"InnoDB",
+ SHOW_OPTION_YES,
+ "Supports transactions, row-level locking, and foreign keys",
+ DB_TYPE_INNODB,
+ innobase_init,
0, /* slot */
sizeof(trx_named_savept_t), /* savepoint size. TODO: use it */
innobase_close_connection,
@@ -563,25 +567,29 @@ innobase_mysql_print_thd(
use the default max length */
{
const THD* thd;
+ const Security_context *sctx;
const char* s;
thd = (const THD*) input_thd;
+ /* We probably want to have original user as part of debug output. */
+ sctx = &thd->main_security_ctx;
+
fprintf(f, "MySQL thread id %lu, query id %lu",
thd->thread_id, (ulong) thd->query_id);
- if (thd->host) {
+ if (sctx->host) {
putc(' ', f);
- fputs(thd->host, f);
+ fputs(sctx->host, f);
}
- if (thd->ip) {
+ if (sctx->ip) {
putc(' ', f);
- fputs(thd->ip, f);
+ fputs(sctx->ip, f);
}
- if (thd->user) {
+ if (sctx->user) {
putc(' ', f);
- fputs(thd->user, f);
+ fputs(sctx->user, f);
}
if ((s = thd->proc_info)) {
@@ -1184,10 +1192,10 @@ ha_innobase::init_table_handle_for_HANDLER(void)
/*************************************************************************
Opens an InnoDB database. */
-handlerton*
+bool
innobase_init(void)
/*===============*/
- /* out: TRUE if error */
+ /* out: &innobase_hton, or NULL on error */
{
static char current_dir[3]; /* Set if using current lib */
int err;
@@ -1196,6 +1204,9 @@ innobase_init(void)
DBUG_ENTER("innobase_init");
+ if (have_innodb != SHOW_OPTION_YES)
+ goto error;
+
ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
os_innodb_umask = (ulint)my_umask;
@@ -1248,7 +1259,7 @@ innobase_init(void)
copy of it: */
internal_innobase_data_file_path = my_strdup(innobase_data_file_path,
- MYF(MY_WME));
+ MYF(MY_FAE));
ret = (bool) srv_parse_data_file_paths_and_sizes(
internal_innobase_data_file_path,
@@ -1263,7 +1274,7 @@ innobase_init(void)
"InnoDB: syntax error in innodb_data_file_path");
my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR));
- DBUG_RETURN(0);
+ goto error;
}
/* -------------- Log files ---------------------------*/
@@ -1294,7 +1305,7 @@ innobase_init(void)
my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR));
- DBUG_RETURN(0);
+ goto error;
}
/* --------------------------------------------------*/
@@ -1382,7 +1393,7 @@ innobase_init(void)
if (err != DB_SUCCESS) {
my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR));
- DBUG_RETURN(0);
+ goto error;
}
(void) hash_init(&innobase_open_tables,system_charset_info, 32, 0, 0,
@@ -1409,7 +1420,10 @@ innobase_init(void)
glob_mi.pos = trx_sys_mysql_master_log_pos;
}
*/
- DBUG_RETURN(&innobase_hton);
+ DBUG_RETURN(FALSE);
+error:
+ have_innodb= SHOW_OPTION_DISABLED; // If we couldn't use handler
+ DBUG_RETURN(TRUE);
}
/***********************************************************************
@@ -2112,7 +2126,7 @@ innobase_rollback_to_savepoint(
/* TODO: use provided savepoint data area to store savepoint data */
- longlong2str((ulonglong)savepoint, name, 36);
+ longlong2str((ulint)savepoint, name, 36);
error = (int) trx_rollback_to_savepoint_for_mysql(trx, name,
&mysql_binlog_cache_pos);
@@ -2141,7 +2155,7 @@ innobase_release_savepoint(
/* TODO: use provided savepoint data area to store savepoint data */
- longlong2str((ulonglong)savepoint, name, 36);
+ longlong2str((ulint)savepoint, name, 36);
error = (int) trx_release_savepoint_for_mysql(trx, name);
@@ -2182,7 +2196,7 @@ innobase_savepoint(
/* TODO: use provided savepoint data area to store savepoint data */
char name[64];
- longlong2str((ulonglong)savepoint,name,36);
+ longlong2str((ulint)savepoint,name,36);
error = (int) trx_savepoint_for_mysql(trx, name, (ib_longlong)0);
@@ -2382,7 +2396,7 @@ ha_innobase::open(
"how you can resolve the problem.\n",
norm_name);
free_share(share);
- my_free((char*) upd_buff, MYF(0));
+ my_free((gptr) upd_buff, MYF(0));
my_errno = ENOENT;
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
@@ -2400,7 +2414,7 @@ ha_innobase::open(
"how you can resolve the problem.\n",
norm_name);
free_share(share);
- my_free((char*) upd_buff, MYF(0));
+ my_free((gptr) upd_buff, MYF(0));
my_errno = ENOENT;
dict_table_decrement_handle_count(ib_table);
@@ -2488,13 +2502,13 @@ Closes a handle to an InnoDB table. */
int
ha_innobase::close(void)
/*====================*/
- /* out: error number */
+ /* out: 0 */
{
DBUG_ENTER("ha_innobase::close");
row_prebuilt_free((row_prebuilt_t*) innobase_prebuilt);
- my_free((char*) upd_buff, MYF(0));
+ my_free((gptr) upd_buff, MYF(0));
free_share(share);
/* Tell InnoDB server that there might be work for
@@ -4490,7 +4504,8 @@ create_index(
ulint is_unsigned;
ulint i;
ulint j;
-
+ ulint* field_lengths;
+
DBUG_ENTER("create_index");
key = form->key_info + key_num;
@@ -4512,6 +4527,10 @@ create_index(
index = dict_mem_index_create((char*) table_name, key->name, 0,
ind_type, n_fields);
+
+ field_lengths = (ulint*) my_malloc(sizeof(ulint) * n_fields,
+ MYF(MY_FAE));
+
for (i = 0; i < n_fields; i++) {
key_part = key->key_part + i;
@@ -4566,6 +4585,8 @@ create_index(
prefix_len = 0;
}
+ field_lengths[i] = key_part->length;
+
/* We assume all fields should be sorted in ascending
order, hence the '0': */
@@ -4574,10 +4595,12 @@ create_index(
0, prefix_len);
}
- error = row_create_index_for_mysql(index, trx);
+ error = row_create_index_for_mysql(index, trx, field_lengths);
error = convert_error_code_to_mysql(error, NULL);
+ my_free((gptr) field_lengths, MYF(0));
+
DBUG_RETURN(error);
}
@@ -4600,7 +4623,7 @@ create_clustered_index_when_no_primary(
index = dict_mem_index_create((char*) table_name,
(char*) "GEN_CLUST_INDEX",
0, DICT_CLUSTERED, 0);
- error = row_create_index_for_mysql(index, trx);
+ error = row_create_index_for_mysql(index, trx, NULL);
error = convert_error_code_to_mysql(error, NULL);
@@ -5136,7 +5159,7 @@ ha_innobase::records_in_range(
mysql_byte* key_val_buff2 = (mysql_byte*) my_malloc(
table->s->reclength
+ table->s->max_key_length + 100,
- MYF(MY_WME));
+ MYF(MY_FAE));
ulint buff2_len = table->s->reclength
+ table->s->max_key_length + 100;
dtuple_t* range_start;
@@ -5195,7 +5218,7 @@ ha_innobase::records_in_range(
dtuple_free_for_mysql(heap1);
dtuple_free_for_mysql(heap2);
- my_free((char*) key_val_buff2, MYF(0));
+ my_free((gptr) key_val_buff2, MYF(0));
prebuilt->trx->op_info = (char*)"";
@@ -5989,7 +6012,8 @@ int
ha_innobase::start_stmt(
/*====================*/
/* out: 0 or error code */
- THD* thd) /* in: handle to the user thread */
+ THD* thd, /* in: handle to the user thread */
+ thr_lock_type lock_type)
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
trx_t* trx;
@@ -6030,7 +6054,7 @@ ha_innobase::start_stmt(
} else {
if (trx->isolation_level != TRX_ISO_SERIALIZABLE
&& thd->lex->sql_command == SQLCOM_SELECT
- && thd->lex->lock_option == TL_READ) {
+ && lock_type == TL_READ) {
/* For other than temporary tables, we obtain
no lock for consistent read (plain SELECT). */
@@ -6063,6 +6087,8 @@ ha_innobase::start_stmt(
}
}
+ trx->detailed_error[0] = '\0';
+
/* Set the MySQL flag to mark that there is an active transaction */
if (trx->active_trans == 0) {
@@ -6136,6 +6162,8 @@ ha_innobase::external_lock(
if (lock_type != F_UNLCK) {
/* MySQL is setting a new table lock */
+ trx->detailed_error[0] = '\0';
+
/* Set the MySQL flag to mark that there is an active
transaction */
if (trx->active_trans == 0) {
@@ -6673,6 +6701,11 @@ ha_innobase::store_lock(
prebuilt->select_lock_type = LOCK_NONE;
prebuilt->stored_select_lock_type = LOCK_NONE;
+ } else if (thd->lex->sql_command == SQLCOM_CHECKSUM) {
+ /* Use consistent read for checksum table */
+
+ prebuilt->select_lock_type = LOCK_NONE;
+ prebuilt->stored_select_lock_type = LOCK_NONE;
} else {
prebuilt->select_lock_type = LOCK_S;
prebuilt->stored_select_lock_type = LOCK_S;
@@ -6939,6 +6972,18 @@ ha_innobase::reset_auto_increment(ulonglong value)
DBUG_RETURN(0);
}
+/* See comment in handler.cc */
+bool
+ha_innobase::get_error_message(int error, String *buf)
+{
+ trx_t* trx = check_trx_exists(current_thd);
+
+ buf->copy(trx->detailed_error, strlen(trx->detailed_error),
+ system_charset_info);
+
+ return FALSE;
+}
+
/***********************************************************************
Compares two 'refs'. A 'ref' is the (internal) primary key value of the row.
If there is no explicitly declared non-null unique key or a primary key, then
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index 595ab5ccde2..d687e8bf160 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -150,7 +150,7 @@ class ha_innobase: public handler
int extra(enum ha_extra_function operation);
int external_lock(THD *thd, int lock_type);
int transactional_table_lock(THD *thd, int lock_type);
- int start_stmt(THD *thd);
+ int start_stmt(THD *thd, thr_lock_type lock_type);
int ha_retrieve_all_cols()
{
@@ -184,6 +184,8 @@ class ha_innobase: public handler
void init_table_handle_for_HANDLER();
ulonglong get_auto_increment();
int reset_auto_increment(ulonglong value);
+
+ virtual bool get_error_message(int error, String *buf);
uint8 table_cache_type() { return HA_CACHE_TBL_ASKTRANSACT; }
/*
@@ -251,7 +253,7 @@ extern ulong srv_commit_concurrency;
extern TYPELIB innobase_lock_typelib;
-handlerton *innobase_init(void);
+bool innobase_init(void);
bool innobase_end(void);
bool innobase_flush_logs(void);
uint innobase_get_free_space(void);
@@ -356,4 +358,4 @@ restored to a transaction read view. */
void
innobase_set_cursor_view(
/*=====================*/
- void* curview); /* in: Consistent read view to be closed */
+ void* curview); /* in: Consistent read view to be set */
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 715ee3da8b9..689dbf2fc24 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -39,6 +39,12 @@ const char *myisam_recover_names[] =
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
myisam_recover_names, NULL};
+const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
+ NullS};
+TYPELIB myisam_stats_method_typelib= {
+ array_elements(myisam_stats_method_names) - 1, "",
+ myisam_stats_method_names, NULL};
+
/*****************************************************************************
** MyISAM tables
@@ -46,8 +52,12 @@ TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"",
/* MyISAM handlerton */
-static handlerton myisam_hton= {
+handlerton myisam_hton= {
"MyISAM",
+ SHOW_OPTION_YES,
+ "Default engine as of MySQL 3.23 with great performance",
+ DB_TYPE_MYISAM,
+ NULL,
0, /* slot */
0, /* savepoint size. */
NULL, /* close_connection */
@@ -67,7 +77,7 @@ static handlerton myisam_hton= {
MyISAM doesn't support transactions and doesn't have
transaction-dependent context: cursors can survive a commit.
*/
- HTON_NO_FLAGS
+ HTON_CAN_RECREATE
};
// collect errors printed by mi_check routines
@@ -324,6 +334,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
param.db_name= table->s->db;
param.table_name= table->alias;
param.testflag = check_opt->flags | T_CHECK | T_SILENT;
+ param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
if (!(table->db_stat & HA_READ_ONLY))
param.testflag|= T_STATISTICS;
@@ -413,6 +424,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt)
param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
T_DONT_CHECK_CHECKSUM);
param.using_global_keycache = 1;
+ param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
if (!(share->state.changed & STATE_NOT_ANALYZED))
return HA_ADMIN_ALREADY_DONE;
@@ -967,6 +979,7 @@ int ha_myisam::enable_indexes(uint mode)
T_CREATE_MISSING_KEYS);
param.myf_rw&= ~MY_WAIT_IF_FULL;
param.sort_buffer_length= thd->variables.myisam_sort_buff_size;
+ param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
param.tmpdir=&mysql_tmpdir_list;
if ((error= (repair(thd,param,0) != HA_ADMIN_OK)) && param.retry_repair)
{
@@ -1694,7 +1707,7 @@ int ha_myisam::ft_read(byte * buf)
uint ha_myisam::checksum() const
{
- return (uint)file->s->state.checksum;
+ return (uint)file->state->checksum;
}
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index 388ecfb331f..cdea97bcea3 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -34,8 +34,12 @@
/* MyISAM MERGE handlerton */
-static handlerton myisammrg_hton= {
- "MRG_MyISAM",
+handlerton myisammrg_hton= {
+ "MRG_MYISAM",
+ SHOW_OPTION_YES,
+ "Collection of identical MyISAM tables",
+ DB_TYPE_MRG_MYISAM,
+ NULL,
0, /* slot */
0, /* savepoint size. */
NULL, /* close_connection */
@@ -51,7 +55,7 @@ static handlerton myisammrg_hton= {
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
- HTON_NO_FLAGS
+ HTON_CAN_RECREATE
};
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index c7d281a1ba0..490d00c55d0 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -51,8 +51,12 @@ static int ndbcluster_close_connection(THD *thd);
static int ndbcluster_commit(THD *thd, bool all);
static int ndbcluster_rollback(THD *thd, bool all);
-static handlerton ndbcluster_hton = {
+handlerton ndbcluster_hton = {
"ndbcluster",
+ SHOW_OPTION_YES,
+ "Clustered, fault-tolerant, memory-based tables",
+ DB_TYPE_NDBCLUSTER,
+ ndbcluster_init,
0, /* slot */
0, /* savepoint size */
ndbcluster_close_connection,
@@ -1239,7 +1243,8 @@ inline ulong ha_ndbcluster::index_flags(uint idx_no, uint part,
DBUG_ENTER("ha_ndbcluster::index_flags");
DBUG_PRINT("info", ("idx_no: %d", idx_no));
DBUG_ASSERT(get_index_type_from_table(idx_no) < index_flags_size);
- DBUG_RETURN(index_type_flags[get_index_type_from_table(idx_no)]);
+ DBUG_RETURN(index_type_flags[get_index_type_from_table(idx_no)] |
+ HA_KEY_SCAN_NOT_ROR);
}
static void shrink_varchar(Field* field, const byte* & ptr, char* buf)
@@ -3390,7 +3395,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
startTransaction for each transaction/statement.
*/
-int ha_ndbcluster::start_stmt(THD *thd)
+int ha_ndbcluster::start_stmt(THD *thd, thr_lock_type lock_type)
{
int error=0;
DBUG_ENTER("start_stmt");
@@ -4701,11 +4706,14 @@ static int connect_callback()
return 0;
}
-handlerton *
-ndbcluster_init()
+bool ndbcluster_init()
{
int res;
DBUG_ENTER("ndbcluster_init");
+
+ if (have_ndbcluster != SHOW_OPTION_YES)
+ goto ndbcluster_init_error;
+
// Set connectstring if specified
if (opt_ndbcluster_connectstring != 0)
DBUG_PRINT("connectstring", ("%s", opt_ndbcluster_connectstring));
@@ -4786,16 +4794,17 @@ ndbcluster_init()
}
ndbcluster_inited= 1;
- DBUG_RETURN(&ndbcluster_hton);
+ DBUG_RETURN(FALSE);
- ndbcluster_init_error:
+ndbcluster_init_error:
if (g_ndb)
delete g_ndb;
g_ndb= NULL;
if (g_ndb_cluster_connection)
delete g_ndb_cluster_connection;
g_ndb_cluster_connection= NULL;
- DBUG_RETURN(NULL);
+ have_ndbcluster= SHOW_OPTION_DISABLED; // If we couldn't use handler
+ DBUG_RETURN(TRUE);
}
@@ -7472,6 +7481,50 @@ ha_ndbcluster::generate_scan_filter(Ndb_cond_stack *ndb_cond_stack,
DBUG_RETURN(0);
}
+int
+ndbcluster_show_status(THD* thd)
+{
+ Protocol *protocol= thd->protocol;
+
+ DBUG_ENTER("ndbcluster_show_status");
+
+ if (have_ndbcluster != SHOW_OPTION_YES)
+ {
+ my_message(ER_NOT_SUPPORTED_YET,
+ "Cannot call SHOW NDBCLUSTER STATUS because skip-ndbcluster is defined",
+ MYF(0));
+ DBUG_RETURN(TRUE);
+ }
+
+ List<Item> field_list;
+ field_list.push_back(new Item_empty_string("free_list", 255));
+ field_list.push_back(new Item_return_int("created", 10,MYSQL_TYPE_LONG));
+ field_list.push_back(new Item_return_int("free", 10,MYSQL_TYPE_LONG));
+ field_list.push_back(new Item_return_int("sizeof", 10,MYSQL_TYPE_LONG));
+
+ if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+ DBUG_RETURN(TRUE);
+
+ if (get_thd_ndb(thd) && get_thd_ndb(thd)->ndb)
+ {
+ Ndb* ndb= (get_thd_ndb(thd))->ndb;
+ Ndb::Free_list_usage tmp; tmp.m_name= 0;
+ while (ndb->get_free_list_usage(&tmp))
+ {
+ protocol->prepare_for_resend();
+
+ protocol->store(tmp.m_name, &my_charset_bin);
+ protocol->store((uint)tmp.m_created);
+ protocol->store((uint)tmp.m_free);
+ protocol->store((uint)tmp.m_sizeof);
+ if (protocol->write())
+ DBUG_RETURN(TRUE);
+ }
+ }
+ send_eof(thd);
+
+ DBUG_RETURN(FALSE);
+}
/*
Create a table in NDB Cluster
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 0d99e9c1220..4530e5f1977 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -510,7 +510,7 @@ class ha_ndbcluster: public handler
int extra(enum ha_extra_function operation);
int extra_opt(enum ha_extra_function operation, ulong cache_size);
int external_lock(THD *thd, int lock_type);
- int start_stmt(THD *thd);
+ int start_stmt(THD *thd, thr_lock_type lock_type);
const char * table_type() const;
const char ** bas_ext() const;
ulong table_flags(void) const;
@@ -746,7 +746,7 @@ private:
extern struct show_var_st ndb_status_variables[];
-handlerton *ndbcluster_init(void);
+bool ndbcluster_init(void);
bool ndbcluster_end(void);
int ndbcluster_discover(THD* thd, const char* dbname, const char* name,
@@ -758,3 +758,5 @@ int ndbcluster_table_exists_in_engine(THD* thd,
int ndbcluster_drop_database(const char* path);
void ndbcluster_print_error(int error, const NdbOperation *error_op);
+
+int ndbcluster_show_status(THD*);
diff --git a/sql/handler.cc b/sql/handler.cc
index 8c8904b1df0..5b07c9e9c24 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -25,42 +25,110 @@
#include "ha_heap.h"
#include "ha_myisam.h"
#include "ha_myisammrg.h"
+
+
+/*
+ We have dummy hanldertons in case the handler has not been compiled
+ in. This will be removed in 5.1.
+*/
#ifdef HAVE_BERKELEY_DB
#include "ha_berkeley.h"
+extern handlerton berkeley_hton;
+#else
+handlerton berkeley_hton = { "BerkeleyDB", SHOW_OPTION_NO,
+ "Supports transactions and page-level locking", DB_TYPE_BERKELEY_DB, NULL,
+ 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, HTON_NO_FLAGS };
#endif
#ifdef HAVE_BLACKHOLE_DB
#include "ha_blackhole.h"
+extern handlerton blackhole_hton;
+#else
+handlerton blackhole_hton = { "BLACKHOLE", SHOW_OPTION_NO,
+ "/dev/null storage engine (anything you write to it disappears)",
+ DB_TYPE_BLACKHOLE_DB, NULL, 0, 0, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ HTON_NO_FLAGS };
#endif
#ifdef HAVE_EXAMPLE_DB
#include "examples/ha_example.h"
+extern handlerton example_hton;
+#else
+handlerton example_hton = { "EXAMPLE", SHOW_OPTION_NO,
+ "Example storage engine",
+ DB_TYPE_EXAMPLE_DB, NULL, 0, 0, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ HTON_NO_FLAGS };
#endif
#ifdef HAVE_PARTITION_DB
#include "ha_partition.h"
#endif
#ifdef HAVE_ARCHIVE_DB
-#include "examples/ha_archive.h"
+#include "ha_archive.h"
+extern handlerton archive_hton;
+#else
+handlerton archive_hton = { "ARCHIVE", SHOW_OPTION_NO,
+ "Archive storage engine", DB_TYPE_ARCHIVE_DB, NULL, 0, 0, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ HTON_NO_FLAGS };
#endif
#ifdef HAVE_CSV_DB
#include "examples/ha_tina.h"
+extern handlerton tina_hton;
+#else
+handlerton tina_hton = { "CSV", SHOW_OPTION_NO, "CSV storage engine",
+ DB_TYPE_CSV_DB, NULL, 0, 0, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ HTON_NO_FLAGS };
#endif
#ifdef HAVE_INNOBASE_DB
#include "ha_innodb.h"
+extern handlerton innobase_hton;
+#else
+handlerton innobase_hton = { "InnoDB", SHOW_OPTION_NO,
+ "Supports transactions, row-level locking, and foreign keys",
+ DB_TYPE_INNODB, NULL, 0, 0, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ HTON_NO_FLAGS };
#endif
#ifdef HAVE_NDBCLUSTER_DB
#include "ha_ndbcluster.h"
+extern handlerton ndbcluster_hton;
+#else
+handlerton ndbcluster_hton = { "ndbcluster", SHOW_OPTION_NO,
+ "Clustered, fault-tolerant, memory-based tables",
+ DB_TYPE_NDBCLUSTER, NULL, 0, 0, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ HTON_NO_FLAGS };
#endif
#ifdef HAVE_FEDERATED_DB
#include "ha_federated.h"
+extern handlerton federated_hton;
+#else
+handlerton federated_hton = { "FEDERATED", SHOW_OPTION_NO,
+ "Federated MySQL storage engine", DB_TYPE_FEDERATED_DB, NULL, 0, 0, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ HTON_NO_FLAGS };
#endif
#include <myisampack.h>
#include <errno.h>
- /* static functions defined in this file */
+extern handlerton myisam_hton;
+extern handlerton myisammrg_hton;
+extern handlerton heap_hton;
+extern handlerton binlog_hton;
-static SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES;
+/*
+ Obsolete
+*/
+handlerton isam_hton = { "ISAM", SHOW_OPTION_NO, "Obsolete storage engine",
+ DB_TYPE_ISAM, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, HTON_NO_FLAGS };
-/* list of all available storage engines (of their handlertons) */
-handlerton *handlertons[MAX_HA]={0};
+
+/* static functions defined in this file */
+
+static SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES;
/* number of entries in handlertons[] */
ulong total_ha;
@@ -69,46 +137,35 @@ ulong total_ha_2pc;
/* size of savepoint storage area (see ha_init) */
ulong savepoint_alloc_size;
-struct show_table_type_st sys_table_types[]=
-{
- {"MyISAM", &have_yes,
- "Default engine as of MySQL 3.23 with great performance", DB_TYPE_MYISAM},
- {"MEMORY", &have_yes,
- "Hash based, stored in memory, useful for temporary tables", DB_TYPE_HEAP},
- {"HEAP", &have_yes,
- "Alias for MEMORY", DB_TYPE_HEAP},
- {"MERGE", &have_yes,
- "Collection of identical MyISAM tables", DB_TYPE_MRG_MYISAM},
- {"MRG_MYISAM",&have_yes,
- "Alias for MERGE", DB_TYPE_MRG_MYISAM},
- {"ISAM", &have_isam,
- "Obsolete storage engine, now replaced by MyISAM", DB_TYPE_ISAM},
- {"MRG_ISAM", &have_isam,
- "Obsolete storage engine, now replaced by MERGE", DB_TYPE_MRG_ISAM},
- {"InnoDB", &have_innodb,
- "Supports transactions, row-level locking, and foreign keys", DB_TYPE_INNODB},
- {"INNOBASE", &have_innodb,
- "Alias for INNODB", DB_TYPE_INNODB},
- {"BDB", &have_berkeley_db,
- "Supports transactions and page-level locking", DB_TYPE_BERKELEY_DB},
- {"BERKELEYDB",&have_berkeley_db,
- "Alias for BDB", DB_TYPE_BERKELEY_DB},
- {"NDBCLUSTER", &have_ndbcluster,
- "Clustered, fault-tolerant, memory-based tables", DB_TYPE_NDBCLUSTER},
- {"NDB", &have_ndbcluster,
- "Alias for NDBCLUSTER", DB_TYPE_NDBCLUSTER},
- {"EXAMPLE",&have_example_db,
- "Example storage engine", DB_TYPE_EXAMPLE_DB},
- {"ARCHIVE",&have_archive_db,
- "Archive storage engine", DB_TYPE_ARCHIVE_DB},
- {"CSV",&have_csv_db,
- "CSV storage engine", DB_TYPE_CSV_DB},
- {"FEDERATED",&have_federated_db,
- "Federated MySQL storage engine", DB_TYPE_FEDERATED_DB},
- {"BLACKHOLE",&have_blackhole_db,
- "/dev/null storage engine (anything you write to it disappears)",
- DB_TYPE_BLACKHOLE_DB},
- {NullS, NULL, NullS, DB_TYPE_UNKNOWN}
+/*
+ This array is used for processing compiled in engines.
+*/
+handlerton *sys_table_types[]=
+{
+ &myisam_hton,
+ &heap_hton,
+ &innobase_hton,
+ &berkeley_hton,
+ &blackhole_hton,
+ &example_hton,
+ &archive_hton,
+ &tina_hton,
+ &ndbcluster_hton,
+ &federated_hton,
+ &myisammrg_hton,
+ &binlog_hton,
+ &isam_hton,
+ NULL
+};
+
+struct show_table_alias_st sys_table_aliases[]=
+{
+ {"INNOBASE", "InnoDB"},
+ {"NDB", "NDBCLUSTER"},
+ {"BDB", "BERKELEYDB"},
+ {"HEAP", "MEMORY"},
+ {"MERGE", "MRG_MYISAM"},
+ {NullS, NullS}
};
const char *ha_row_type[] = {
@@ -127,46 +184,78 @@ uint known_extensions_id= 0;
enum db_type ha_resolve_by_name(const char *name, uint namelen)
{
THD *thd= current_thd;
- if (thd && !my_strcasecmp(&my_charset_latin1, name, "DEFAULT")) {
+ show_table_alias_st *table_alias;
+ handlerton **types;
+ const char *ptr= name;
+
+ if (thd && !my_strcasecmp(&my_charset_latin1, ptr, "DEFAULT"))
return (enum db_type) thd->variables.table_type;
+
+retest:
+ for (types= sys_table_types; *types; types++)
+ {
+ if (!my_strcasecmp(&my_charset_latin1, ptr, (*types)->name))
+ return (enum db_type) (*types)->db_type;
}
- show_table_type_st *types;
- for (types= sys_table_types; types->type; types++)
+ /*
+ We check for the historical aliases.
+ */
+ for (table_alias= sys_table_aliases; table_alias->type; table_alias++)
{
- if (!my_strcasecmp(&my_charset_latin1, name, types->type))
- return (enum db_type) types->db_type;
+ if (!my_strcasecmp(&my_charset_latin1, ptr, table_alias->alias))
+ {
+ ptr= table_alias->type;
+ goto retest;
+ }
}
+
return DB_TYPE_UNKNOWN;
}
-
const char *ha_get_storage_engine(enum db_type db_type)
{
- show_table_type_st *types;
- for (types= sys_table_types; types->type; types++)
+ handlerton **types;
+ for (types= sys_table_types; *types; types++)
{
- if (db_type == types->db_type)
- return types->type;
+ if (db_type == (*types)->db_type)
+ return (*types)->name;
}
return "none";
}
+bool ha_check_storage_engine_flag(enum db_type db_type, uint32 flag)
+{
+ handlerton **types;
+ for (types= sys_table_types; *types; types++)
+ {
+ if (db_type == (*types)->db_type)
+ {
+ if ((*types)->flags & flag)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ }
+
+ return FALSE;
+}
+
my_bool ha_storage_engine_is_enabled(enum db_type database_type)
{
- show_table_type_st *types;
- for (types= sys_table_types; types->type; types++)
+ handlerton **types;
+ for (types= sys_table_types; *types; types++)
{
- if ((database_type == types->db_type) &&
- (*types->value == SHOW_OPTION_YES))
+ if ((database_type == (*types)->db_type) &&
+ ((*types)->state == SHOW_OPTION_YES))
return TRUE;
}
return FALSE;
}
- /* Use other database handler if databasehandler is not incompiled */
+/* Use other database handler if databasehandler is not compiled in */
enum db_type ha_checktype(THD *thd, enum db_type database_type,
bool no_substitute, bool report_error)
@@ -372,8 +461,8 @@ static int ha_init_errors(void)
SETMSG(HA_ERR_READ_ONLY_TRANSACTION, ER(ER_READ_ONLY_TRANSACTION));
SETMSG(HA_ERR_LOCK_DEADLOCK, ER(ER_LOCK_DEADLOCK));
SETMSG(HA_ERR_CANNOT_ADD_FOREIGN, ER(ER_CANNOT_ADD_FOREIGN));
- SETMSG(HA_ERR_NO_REFERENCED_ROW, ER(ER_NO_REFERENCED_ROW));
- SETMSG(HA_ERR_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED));
+ SETMSG(HA_ERR_NO_REFERENCED_ROW, ER(ER_NO_REFERENCED_ROW_2));
+ SETMSG(HA_ERR_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED_2));
SETMSG(HA_ERR_NO_SAVEPOINT, "No savepoint with that name");
SETMSG(HA_ERR_NON_UNIQUE_BLOCK_SIZE, "Non unique key block size");
SETMSG(HA_ERR_NO_SUCH_TABLE, "No such table: '%.64s'");
@@ -422,81 +511,24 @@ static inline void ha_was_inited_ok(handlerton **ht)
int ha_init()
{
int error= 0;
- handlerton **ht= handlertons;
+ handlerton **types;
+ show_table_alias_st *table_alias;
total_ha= savepoint_alloc_size= 0;
if (ha_init_errors())
return 1;
- if (opt_bin_log)
- {
- if (!(*ht= binlog_init())) // Always succeed
- {
- mysql_bin_log.close(LOG_CLOSE_INDEX); // Never used
- opt_bin_log= 0; // Never used
- error= 1; // Never used
- }
- else
- ha_was_inited_ok(ht++);
- }
-#ifdef HAVE_BERKELEY_DB
- if (have_berkeley_db == SHOW_OPTION_YES)
- {
- if (!(*ht= berkeley_init()))
- {
- have_berkeley_db= SHOW_OPTION_DISABLED; // If we couldn't use handler
- error= 1;
- }
- else
- ha_was_inited_ok(ht++);
- }
-#endif
-#ifdef HAVE_INNOBASE_DB
- if (have_innodb == SHOW_OPTION_YES)
- {
- if (!(*ht= innobase_init()))
- {
- have_innodb= SHOW_OPTION_DISABLED; // If we couldn't use handler
- error= 1;
- }
- else
- ha_was_inited_ok(ht++);
- }
-#endif
-#ifdef HAVE_NDBCLUSTER_DB
- if (have_ndbcluster == SHOW_OPTION_YES)
- {
- if (!(*ht= ndbcluster_init()))
- {
- have_ndbcluster= SHOW_OPTION_DISABLED;
- error= 1;
- }
- else
- ha_was_inited_ok(ht++);
- }
-#endif
-#ifdef HAVE_FEDERATED_DB
- if (have_federated_db == SHOW_OPTION_YES)
- {
- if (federated_db_init())
- {
- have_federated_db= SHOW_OPTION_DISABLED;
- error= 1;
- }
- }
-#endif
-#ifdef HAVE_ARCHIVE_DB
- if (have_archive_db == SHOW_OPTION_YES)
+ /*
+ We now initialize everything here.
+ */
+ for (types= sys_table_types; *types; types++)
{
- if (!(*ht= archive_db_init()))
- {
- have_archive_db= SHOW_OPTION_DISABLED;
- error= 1;
- }
+ if (!(*types)->init || !(*types)->init())
+ ha_was_inited_ok(types);
else
- ha_was_inited_ok(ht++);
+ (*types)->state= SHOW_OPTION_DISABLED;
}
-#endif
+
DBUG_ASSERT(total_ha < MAX_HA);
/*
Check if there is a transaction-capable storage engine besides the
@@ -544,6 +576,10 @@ int ha_panic(enum ha_panic_function flag)
if (have_archive_db == SHOW_OPTION_YES)
error|= archive_db_end();
#endif
+#ifdef HAVE_CSV_DB
+ if (have_csv_db == SHOW_OPTION_YES)
+ error|= tina_end();
+#endif
if (ha_finish_errors())
error= 1;
return error;
@@ -564,9 +600,10 @@ void ha_drop_database(char* path)
/* don't bother to rollback here, it's done already */
void ha_close_connection(THD* thd)
{
- for (uint i=0; i < total_ha; i++)
- if (thd->ha_data[i])
- (*handlertons[i]->close_connection)(thd);
+ handlerton **types;
+ for (types= sys_table_types; *types; types++)
+ if (thd->ha_data[(*types)->slot])
+ (*types)->close_connection(thd);
}
/* ========================================================================
@@ -877,13 +914,13 @@ int ha_autocommit_or_rollback(THD *thd, int error)
int ha_commit_or_rollback_by_xid(XID *xid, bool commit)
{
- handlerton **ht= handlertons, **end_ht=ht+total_ha;
+ handlerton **types;
int res= 1;
- for ( ; ht < end_ht ; ht++)
- if ((*ht)->recover)
+ for (types= sys_table_types; *types; types++)
+ if ((*types)->state == SHOW_OPTION_YES && (*types)->recover)
res= res &&
- (*(commit ? (*ht)->commit_by_xid : (*ht)->rollback_by_xid))(xid);
+ (*(commit ? (*types)->commit_by_xid : (*types)->rollback_by_xid))(xid);
return res;
}
@@ -962,7 +999,7 @@ static char* xid_to_str(char *buf, XID *xid)
int ha_recover(HASH *commit_list)
{
int len, got, found_foreign_xids=0, found_my_xids=0;
- handlerton **ht= handlertons, **end_ht=ht+total_ha;
+ handlerton **types;
XID *list=0;
bool dry_run=(commit_list==0 && tc_heuristic_recover==0);
DBUG_ENTER("ha_recover");
@@ -998,14 +1035,14 @@ int ha_recover(HASH *commit_list)
DBUG_RETURN(1);
}
- for ( ; ht < end_ht ; ht++)
+ for (types= sys_table_types; *types; types++)
{
- if (!(*ht)->recover)
+ if ((*types)->state != SHOW_OPTION_YES || !(*types)->recover)
continue;
- while ((got=(*(*ht)->recover)(list, len)) > 0 )
+ while ((got=(*(*types)->recover)(list, len)) > 0 )
{
sql_print_information("Found %d prepared transaction(s) in %s",
- got, (*ht)->name);
+ got, (*types)->name);
for (int i=0; i < got; i ++)
{
my_xid x=list[i].get_my_xid();
@@ -1033,7 +1070,7 @@ int ha_recover(HASH *commit_list)
char buf[XIDDATASIZE*4+6]; // see xid_to_str
sql_print_information("commit xid %s", xid_to_str(buf, list+i));
#endif
- (*(*ht)->commit_by_xid)(list+i);
+ (*(*types)->commit_by_xid)(list+i);
}
else
{
@@ -1041,7 +1078,7 @@ int ha_recover(HASH *commit_list)
char buf[XIDDATASIZE*4+6]; // see xid_to_str
sql_print_information("rollback xid %s", xid_to_str(buf, list+i));
#endif
- (*(*ht)->rollback_by_xid)(list+i);
+ (*(*types)->rollback_by_xid)(list+i);
}
}
if (got < len)
@@ -1401,11 +1438,9 @@ int handler::ha_open(const char *name, int mode, int test_if_locked)
table->db_stat|=HA_READ_ONLY;
(void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
- if (!alloc_root_inited(&table->mem_root)) // If temporary table
- ref=(byte*) sql_alloc(ALIGN_SIZE(ref_length)*2);
- else
- ref=(byte*) alloc_root(&table->mem_root, ALIGN_SIZE(ref_length)*2);
- if (!ref)
+ DBUG_ASSERT(alloc_root_inited(&table->mem_root));
+
+ if (!(ref= (byte*) alloc_root(&table->mem_root, ALIGN_SIZE(ref_length)*2)))
{
close();
error=HA_ERR_OUT_OF_MEM;
@@ -1870,11 +1905,19 @@ void handler::print_error(int error, myf errflag)
textno=ER_CANNOT_ADD_FOREIGN;
break;
case HA_ERR_ROW_IS_REFERENCED:
- textno=ER_ROW_IS_REFERENCED;
- break;
+ {
+ String str;
+ get_error_message(error, &str);
+ my_error(ER_ROW_IS_REFERENCED_2, MYF(0), str.c_ptr_safe());
+ DBUG_VOID_RETURN;
+ }
case HA_ERR_NO_REFERENCED_ROW:
- textno=ER_NO_REFERENCED_ROW;
- break;
+ {
+ String str;
+ get_error_message(error, &str);
+ my_error(ER_NO_REFERENCED_ROW_2, MYF(0), str.c_ptr_safe());
+ DBUG_VOID_RETURN;
+ }
case HA_ERR_TABLE_DEF_CHANGED:
textno=ER_TABLE_DEF_CHANGED;
break;
@@ -2585,7 +2628,7 @@ TYPELIB *ha_known_exts(void)
{
if (!known_extensions.type_names || mysys_usage_id != known_extensions_id)
{
- show_table_type_st *types;
+ handlerton **types;
List<char> found_exts;
List_iterator_fast<char> it(found_exts);
const char **ext, *old_ext;
@@ -2593,11 +2636,11 @@ TYPELIB *ha_known_exts(void)
known_extensions_id= mysys_usage_id;
found_exts.push_back((char*) triggers_file_ext);
found_exts.push_back((char*) trigname_file_ext);
- for (types= sys_table_types; types->type; types++)
+ for (types= sys_table_types; *types; types++)
{
- if (*types->value == SHOW_OPTION_YES)
+ if ((*types)->state == SHOW_OPTION_YES)
{
- handler *file= get_new_handler(0,(enum db_type) types->db_type);
+ handler *file= get_new_handler(0,(enum db_type) (*types)->db_type);
for (ext= file->bas_ext(); *ext; ext++)
{
while ((old_ext= it++))
diff --git a/sql/handler.h b/sql/handler.h
index bd935da2a80..2347c03ae2d 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -107,6 +107,13 @@
#define HA_ONLINE_ADD_EMPTY_PARTITION 1
#define HA_ONLINE_DROP_PARTITION 2
+/*
+ Index scan will not return records in rowid order. Not guaranteed to be
+ set for unordered (e.g. HASH) indexes.
+*/
+#define HA_KEY_SCAN_NOT_ROR 128
+
+
/* operations for disable/enable indexes */
#define HA_KEY_SWITCH_NONUNIQ 0
#define HA_KEY_SWITCH_ALL 1
@@ -187,13 +194,6 @@ enum db_type
DB_TYPE_DEFAULT // Must be last
};
-struct show_table_type_st {
- const char *type;
- SHOW_COMP_OPTION *value;
- const char *comment;
- enum db_type db_type;
-};
-
enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT };
@@ -241,7 +241,7 @@ struct xid_t {
char data[XIDDATASIZE]; // not \0-terminated !
bool eq(struct xid_t *xid)
- { return !memcmp(this, xid, length()); }
+ { return eq(xid->gtrid_length, xid->bqual_length, xid->data); }
bool eq(long g, long b, const char *d)
{ return g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); }
void set(struct xid_t *xid)
@@ -289,6 +289,14 @@ struct xid_t {
return sizeof(formatID)+sizeof(gtrid_length)+sizeof(bqual_length)+
gtrid_length+bqual_length;
}
+ byte *key()
+ {
+ return (byte *)&gtrid_length;
+ }
+ uint key_length()
+ {
+ return sizeof(gtrid_length)+sizeof(bqual_length)+gtrid_length+bqual_length;
+ }
};
typedef struct xid_t XID;
@@ -317,6 +325,27 @@ typedef struct
storage engine name as it should be printed to a user
*/
const char *name;
+
+ /*
+ Historical marker for if the engine is available of not
+ */
+ SHOW_COMP_OPTION state;
+
+ /*
+ A comment used by SHOW to describe an engine.
+ */
+ const char *comment;
+
+ /*
+ Historical number used for frm file to determine the correct storage engine.
+ This is going away and new engines will just use "name" for this.
+ */
+ enum db_type db_type;
+ /*
+ Method that initizlizes a storage engine
+ */
+ bool (*init)();
+
/*
each storage engine has it's own memory area (actually a pointer)
in the thd, for storing per-connection information.
@@ -376,9 +405,16 @@ typedef struct
uint32 flags; /* global handler flags */
} handlerton;
+struct show_table_alias_st {
+ const char *alias;
+ const char *type;
+};
+
/* Possible flags of a handlerton */
-#define HTON_NO_FLAGS 0
-#define HTON_CLOSE_CURSORS_AT_COMMIT 1
+#define HTON_NO_FLAGS 0
+#define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
+#define HTON_ALTER_NOT_SUPPORTED (1 << 1)
+#define HTON_CAN_RECREATE (1 << 2)
typedef struct st_thd_trans
{
@@ -1121,7 +1157,7 @@ public:
{ return extra(operation); }
virtual int external_lock(THD *thd, int lock_type) { return 0; }
virtual void unlock_row() {}
- virtual int start_stmt(THD *thd) {return 0;}
+ virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
/*
This is called to delete all rows in a table
If the handler don't support this, then this function will
@@ -1338,10 +1374,10 @@ public:
/* Some extern variables used with handlers */
-extern struct show_table_type_st sys_table_types[];
+extern handlerton *sys_table_types[];
extern const char *ha_row_type[];
extern TYPELIB tx_isolation_typelib;
-extern handlerton *handlertons[MAX_HA];
+extern TYPELIB myisam_stats_method_typelib;
extern ulong total_ha, total_ha_2pc;
/* Wrapper functions */
@@ -1350,18 +1386,13 @@ extern ulong total_ha, total_ha_2pc;
#define ha_commit(thd) (ha_commit_trans((thd), TRUE))
#define ha_rollback(thd) (ha_rollback_trans((thd), TRUE))
-#define ha_supports_generate(T) (T != DB_TYPE_INNODB && \
- T != DB_TYPE_BERKELEY_DB && \
- T != DB_TYPE_ARCHIVE_DB && \
- T != DB_TYPE_FEDERATED_DB && \
- T != DB_TYPE_NDBCLUSTER)
-
/* lookups */
enum db_type ha_resolve_by_name(const char *name, uint namelen);
const char *ha_get_storage_engine(enum db_type db_type);
handler *get_new_handler(TABLE *table, enum db_type db_type);
enum db_type ha_checktype(THD *thd, enum db_type database_type,
bool no_substitute, bool report_error);
+bool ha_check_storage_engine_flag(enum db_type db_type, uint32 flag);
/* basic stuff */
int ha_init(void);
diff --git a/sql/item.cc b/sql/item.cc
index 60ea00e1b89..5caac05f6ca 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -904,6 +904,7 @@ bool Item_splocal::fix_fields(THD *, Item **)
DBUG_ASSERT(it->fixed);
max_length= it->max_length;
decimals= it->decimals;
+ unsigned_flag= it->unsigned_flag;
fixed= 1;
return FALSE;
}
@@ -1687,7 +1688,7 @@ bool Item_field::eq(const Item *item, bool binary_cmp) const
return 0;
Item_field *item_field= (Item_field*) item;
- if (item_field->field)
+ if (item_field->field && field)
return item_field->field == field;
/*
We may come here when we are trying to find a function in a GROUP BY
@@ -1701,10 +1702,10 @@ bool Item_field::eq(const Item *item, bool binary_cmp) const
*/
return (!my_strcasecmp(system_charset_info, item_field->name,
field_name) &&
- (!item_field->table_name ||
+ (!item_field->table_name || !table_name ||
(!my_strcasecmp(table_alias_charset, item_field->table_name,
table_name) &&
- (!item_field->db_name ||
+ (!item_field->db_name || !db_name ||
(item_field->db_name && !strcmp(item_field->db_name,
db_name))))));
}
@@ -1804,6 +1805,7 @@ Item_decimal::Item_decimal(const char *str_arg, uint length,
name= (char*) str_arg;
decimals= (uint8) decimal_value.frac;
fixed= 1;
+ unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
decimals, unsigned_flag);
}
@@ -1813,6 +1815,7 @@ Item_decimal::Item_decimal(longlong val, bool unsig)
int2my_decimal(E_DEC_FATAL_ERROR, val, unsig, &decimal_value);
decimals= (uint8) decimal_value.frac;
fixed= 1;
+ unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
decimals, unsigned_flag);
}
@@ -1823,6 +1826,7 @@ Item_decimal::Item_decimal(double val, int precision, int scale)
double2my_decimal(E_DEC_FATAL_ERROR, val, &decimal_value);
decimals= (uint8) decimal_value.frac;
fixed= 1;
+ unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
decimals, unsigned_flag);
}
@@ -1835,6 +1839,7 @@ Item_decimal::Item_decimal(const char *str, const my_decimal *val_arg,
name= (char*) str;
decimals= (uint8) decimal_par;
max_length= length;
+ unsigned_flag= !decimal_value.sign();
fixed= 1;
}
@@ -1844,8 +1849,9 @@ Item_decimal::Item_decimal(my_decimal *value_par)
my_decimal2decimal(value_par, &decimal_value);
decimals= (uint8) decimal_value.frac;
fixed= 1;
+ unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
- decimals, !decimal_value.sign());
+ decimals, unsigned_flag);
}
@@ -1855,8 +1861,9 @@ Item_decimal::Item_decimal(const char *bin, int precision, int scale)
&decimal_value, precision, scale);
decimals= (uint8) decimal_value.frac;
fixed= 1;
+ unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(precision, decimals,
- !decimal_value.sign());
+ unsigned_flag);
}
@@ -2966,7 +2973,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
const char *field_name;
ORDER *found_group= NULL;
int found_match_degree= 0;
- Item_field *cur_field;
+ Item_ident *cur_field;
int cur_match_degree= 0;
if (find_item->type() == Item::FIELD_ITEM ||
@@ -2983,9 +2990,9 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
for (ORDER *cur_group= group_list ; cur_group ; cur_group= cur_group->next)
{
- if ((*(cur_group->item))->type() == Item::FIELD_ITEM)
+ if ((*(cur_group->item))->real_item()->type() == Item::FIELD_ITEM)
{
- cur_field= (Item_field*) *cur_group->item;
+ cur_field= (Item_ident*) *cur_group->item;
cur_match_degree= 0;
DBUG_ASSERT(cur_field->field_name != 0);
@@ -3448,8 +3455,8 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
VIEW_ANY_ACL)))
{
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
- "ANY", thd->priv_user, thd->host_or_ip,
- field_name, tab);
+ "ANY", thd->security_ctx->priv_user,
+ thd->security_ctx->host_or_ip, field_name, tab);
goto error;
}
}
@@ -5232,6 +5239,36 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
(Item*) new Item_int(name, result, length));
break;
}
+ case ROW_RESULT:
+ {
+ new_item= 0;
+ /*
+ If item and comp_item are both Item_rows and have same number of cols
+ then process items in Item_row one by one. If Item_row contain nulls
+ substitute it by Item_null. Otherwise just return.
+ */
+ if (item->result_type() == comp_item->result_type() &&
+ ((Item_row*)item)->cols() == ((Item_row*)comp_item)->cols())
+ {
+ Item_row *item_row= (Item_row*)item,*comp_item_row= (Item_row*)comp_item;
+ if (item_row->null_inside())
+ new_item= (Item*) new Item_null(name);
+ else
+ {
+ int i= item_row->cols() - 1;
+ for (; i >= 0; i--)
+ {
+ if (item_row->maybe_null && item_row->el(i)->is_null())
+ {
+ new_item= (Item*) new Item_null(name);
+ break;
+ }
+ resolve_const_item(thd, item_row->addr(i), comp_item_row->el(i));
+ }
+ }
+ }
+ break;
+ }
case REAL_RESULT:
{ // It must REAL_RESULT
double result= item->val_real();
@@ -5252,7 +5289,6 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
(Item*) new Item_decimal(name, result, length, decimals));
break;
}
- case ROW_RESULT:
default:
DBUG_ASSERT(0);
}
diff --git a/sql/item.h b/sql/item.h
index 381ba98e193..a8f013f60d4 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -164,6 +164,7 @@ struct Hybrid_type_traits
virtual my_decimal *val_decimal(Hybrid_type *val, my_decimal *buf) const;
virtual String *val_str(Hybrid_type *val, String *buf, uint8 decimals) const;
static const Hybrid_type_traits *instance();
+ Hybrid_type_traits() {};
};
@@ -185,6 +186,7 @@ struct Hybrid_type_traits_decimal: public Hybrid_type_traits
{ return &val->dec_buf[val->used_dec_buf_no]; }
virtual String *val_str(Hybrid_type *val, String *buf, uint8 decimals) const;
static const Hybrid_type_traits_decimal *instance();
+ Hybrid_type_traits_decimal() {};
};
@@ -215,6 +217,7 @@ struct Hybrid_type_traits_integer: public Hybrid_type_traits
virtual String *val_str(Hybrid_type *val, String *buf, uint8 decimals) const
{ buf->set(val->integer, &my_charset_bin); return buf;}
static const Hybrid_type_traits_integer *instance();
+ Hybrid_type_traits_integer() {};
};
@@ -1502,6 +1505,7 @@ public:
my_decimal *val_decimal(my_decimal *);
int save_in_field(Field *field, bool no_conversions);
enum Item_result result_type () const { return STRING_RESULT; }
+ enum Item_result cast_to_int_type() const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
// to prevent drop fixed flag (no need parent cleanup call)
void cleanup() {}
@@ -1618,7 +1622,7 @@ public:
}
Item *real_item()
{
- return (*ref)->real_item();
+ return (ref && *ref) ? (*ref)->real_item() : this;
}
bool walk(Item_processor processor, byte *arg)
{ return (*ref)->walk(processor, arg); }
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 48839abcb10..85ba8ff794d 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -3072,14 +3072,14 @@ Item_func_regex::fix_fields(THD *thd, Item **ref)
return FALSE;
}
int error;
- if ((error= regcomp(&preg,res->c_ptr(),
- ((cmp_collation.collation->state &
- (MY_CS_BINSORT | MY_CS_CSSORT)) ?
- REG_EXTENDED | REG_NOSUB :
- REG_EXTENDED | REG_NOSUB | REG_ICASE),
- cmp_collation.collation)))
+ if ((error= my_regcomp(&preg,res->c_ptr(),
+ ((cmp_collation.collation->state &
+ (MY_CS_BINSORT | MY_CS_CSSORT)) ?
+ REG_EXTENDED | REG_NOSUB :
+ REG_EXTENDED | REG_NOSUB | REG_ICASE),
+ cmp_collation.collation)))
{
- (void) regerror(error,&preg,buff,sizeof(buff));
+ (void) my_regerror(error,&preg,buff,sizeof(buff));
my_error(ER_REGEXP_ERROR, MYF(0), buff);
return TRUE;
}
@@ -3121,15 +3121,15 @@ longlong Item_func_regex::val_int()
prev_regexp.copy(*res2);
if (regex_compiled)
{
- regfree(&preg);
+ my_regfree(&preg);
regex_compiled=0;
}
- if (regcomp(&preg,res2->c_ptr_safe(),
- ((cmp_collation.collation->state &
- (MY_CS_BINSORT | MY_CS_CSSORT)) ?
- REG_EXTENDED | REG_NOSUB :
- REG_EXTENDED | REG_NOSUB | REG_ICASE),
- cmp_collation.collation))
+ if (my_regcomp(&preg,res2->c_ptr_safe(),
+ ((cmp_collation.collation->state &
+ (MY_CS_BINSORT | MY_CS_CSSORT)) ?
+ REG_EXTENDED | REG_NOSUB :
+ REG_EXTENDED | REG_NOSUB | REG_ICASE),
+ cmp_collation.collation))
{
null_value=1;
return 0;
@@ -3138,7 +3138,7 @@ longlong Item_func_regex::val_int()
}
}
null_value=0;
- return regexec(&preg,res->c_ptr(),0,(regmatch_t*) 0,0) ? 0 : 1;
+ return my_regexec(&preg,res->c_ptr(),0,(my_regmatch_t*) 0,0) ? 0 : 1;
}
@@ -3148,7 +3148,7 @@ void Item_func_regex::cleanup()
Item_bool_func::cleanup();
if (regex_compiled)
{
- regfree(&preg);
+ my_regfree(&preg);
regex_compiled=0;
}
DBUG_VOID_RETURN;
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 09a0fa8c357..aa50593abf4 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1002,11 +1002,11 @@ public:
#ifdef USE_REGEX
-#include <regex.h>
+#include "my_regex.h"
class Item_func_regex :public Item_bool_func
{
- regex_t preg;
+ my_regex_t preg;
bool regex_compiled;
bool regex_is_const;
String prev_regexp;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 518fb011e0f..f07460f2a05 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -4711,27 +4711,11 @@ Item_func_sp::execute(Item **itp)
THD *thd= current_thd;
int res= -1;
Sub_statement_state statement_state;
+ Security_context *save_ctx;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- st_sp_security_context save_ctx;
-#endif
-
- if (! m_sp && ! (m_sp= sp_find_function(thd, m_name, TRUE)))
- {
- my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
+ if (find_and_check_access(thd, EXECUTE_ACL, &save_ctx))
goto error;
- }
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (check_routine_access(thd, EXECUTE_ACL,
- m_sp->m_db.str, m_sp->m_name.str, 0, 0))
- goto error;
- sp_change_security_context(thd, m_sp, &save_ctx);
- if (save_ctx.changed &&
- check_routine_access(thd, EXECUTE_ACL,
- m_sp->m_db.str, m_sp->m_name.str, 0, 0))
- goto error_check_ctx;
-#endif
/*
Disable the binlogging if this is not a SELECT statement. If this is a
SELECT, leave binlogging on, so execute_function() code writes the
@@ -4740,7 +4724,7 @@ Item_func_sp::execute(Item **itp)
thd->reset_sub_statement_state(&statement_state, SUB_STMT_FUNCTION);
res= m_sp->execute_function(thd, args, arg_count, itp);
thd->restore_sub_statement_state(&statement_state);
-
+
if (res && mysql_bin_log.is_open() &&
(m_sp->m_chistics->daccess == SP_CONTAINS_SQL ||
m_sp->m_chistics->daccess == SP_MODIFIES_SQL_DATA))
@@ -4749,8 +4733,7 @@ Item_func_sp::execute(Item **itp)
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
#ifndef NO_EMBEDDED_ACCESS_CHECKS
-error_check_ctx:
- sp_restore_security_context(thd, m_sp, &save_ctx);
+ sp_restore_security_context(thd, save_ctx);
#endif
error:
@@ -4857,3 +4840,79 @@ Item_func_sp::tmp_table_field(TABLE *t_arg)
DBUG_RETURN(res);
}
+
+
+/*
+ Find the function and chack access rigths to the function
+
+ SYNOPSIS
+ find_and_check_access()
+ thd thread handler
+ want_access requested access
+ backup backup of security context or 0
+
+ RETURN
+ FALSE Access granted
+ TRUE Requested access can't be granted or function doesn't exists
+
+ NOTES
+ Checks if requested access to function can be granted to user.
+ If function isn't found yet, it searches function first.
+ If function can't be found or user don't have requested access
+ error is raised.
+ If security context sp_ctx is provided and access can be granted then
+ switch back to previous context isn't performed.
+ In case of access error or if context is not provided then
+ find_and_check_access() switches back to previous security context.
+*/
+
+bool
+Item_func_sp::find_and_check_access(THD *thd, ulong want_access,
+ Security_context **backup)
+{
+ bool res;
+ Security_context *local_save,
+ **save= (backup ? backup : &local_save);
+ res= TRUE;
+ if (! m_sp && ! (m_sp= sp_find_function(thd, m_name, TRUE)))
+ {
+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
+ goto error;
+ }
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ if (check_routine_access(thd, want_access,
+ m_sp->m_db.str, m_sp->m_name.str, 0, FALSE))
+ {
+ goto error;
+ }
+
+ sp_change_security_context(thd, m_sp, save);
+ if (*save &&
+ check_routine_access(thd, want_access,
+ m_sp->m_db.str, m_sp->m_name.str, 0, FALSE))
+ {
+ goto error_check_ctx;
+ }
+ res= FALSE;
+error_check_ctx:
+ if (*save && (res || !backup))
+ sp_restore_security_context(thd, local_save);
+error:
+#else
+ res= 0;
+error:
+#endif
+ return res;
+}
+
+bool
+Item_func_sp::fix_fields(THD *thd, Item **ref)
+{
+ bool res;
+ DBUG_ASSERT(fixed == 0);
+ res= Item_func::fix_fields(thd, ref);
+ if (!res && find_and_check_access(thd, EXECUTE_ACL, NULL))
+ res= 1;
+ return res;
+}
diff --git a/sql/item_func.h b/sql/item_func.h
index 019abb0c072..223144a5d51 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -55,7 +55,7 @@ public:
NOT_FUNC, NOT_ALL_FUNC,
NOW_FUNC, TRIG_COND_FUNC,
GUSERVAR_FUNC, COLLATE_FUNC,
- EXTRACT_FUNC, CHAR_TYPECAST_FUNC };
+ EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP };
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
OPTIMIZE_EQUAL };
enum Type type() const { return FUNC_ITEM; }
@@ -1286,9 +1286,6 @@ public:
{
ft_handler->please->close_search(ft_handler);
ft_handler=0;
- if (join_key)
- table->file->ft_handler=0;
- table->fulltext_searched=0;
}
concat= 0;
DBUG_VOID_RETURN;
@@ -1365,6 +1362,7 @@ public:
class sp_head;
class sp_name;
+struct st_sp_security_context;
class Item_func_sp :public Item_func
{
@@ -1434,7 +1432,11 @@ public:
{ context= (Name_resolution_context *)cntx; return FALSE; }
void fix_length_and_dec();
+ bool find_and_check_access(THD * thd, ulong want_access,
+ Security_context **backup);
+ virtual enum Functype functype() const { return FUNC_SP; }
+ bool fix_fields(THD *thd, Item **ref);
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 4fd33c06095..018afac3812 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -473,7 +473,8 @@ String *Item_func_des_decrypt::val_str(String *str)
{
uint key_number=(uint) (*res)[0] & 127;
// Check if automatic key and that we have privilege to uncompress using it
- if (!(current_thd->master_access & SUPER_ACL) || key_number > 9)
+ if (!(current_thd->security_ctx->master_access & SUPER_ACL) ||
+ key_number > 9)
goto error;
VOID(pthread_mutex_lock(&LOCK_des_key_file));
@@ -1601,13 +1602,13 @@ String *Item_func_user::val_str(String *str)
if (is_current)
{
- user= thd->priv_user;
- host= thd->priv_host;
+ user= thd->security_ctx->priv_user;
+ host= thd->security_ctx->priv_host;
}
else
{
- user= thd->user;
- host= thd->host_or_ip;
+ user= thd->main_security_ctx.user;
+ host= thd->main_security_ctx.host_or_ip;
}
// For system threads (e.g. replication SQL thread) user may be empty
@@ -1732,6 +1733,8 @@ String *Item_func_format::val_str(String *str)
{
my_decimal dec_val, rnd_dec, *res;
res= args[0]->val_decimal(&dec_val);
+ if ((null_value=args[0]->null_value))
+ return 0; /* purecov: inspected */
my_decimal_round(E_DEC_FATAL_ERROR, res, decimals, false, &rnd_dec);
my_decimal2string(E_DEC_FATAL_ERROR, &rnd_dec, 0, 0, 0, str);
str_length= str->length();
@@ -1980,6 +1983,33 @@ b1: str->append((char)(num>>8));
}
str->set_charset(collation.collation);
str->realloc(str->length()); // Add end 0 (for Purify)
+
+ /* Check whether we got a well-formed string */
+ CHARSET_INFO *cs= collation.collation;
+ int well_formed_error;
+ uint wlen= cs->cset->well_formed_len(cs,
+ str->ptr(), str->ptr() + str->length(),
+ str->length(), &well_formed_error);
+ if (wlen < str->length())
+ {
+ THD *thd= current_thd;
+ char hexbuf[7];
+ enum MYSQL_ERROR::enum_warning_level level;
+ uint diff= str->length() - wlen;
+ set_if_smaller(diff, 3);
+ octet2hex(hexbuf, (const uchar*) str->ptr() + wlen, diff);
+ if (thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))
+ {
+ level= MYSQL_ERROR::WARN_LEVEL_ERROR;
+ null_value= 1;
+ str= 0;
+ }
+ else
+ level= MYSQL_ERROR::WARN_LEVEL_WARN;
+ push_warning_printf(thd, level, ER_INVALID_CHARACTER_STRING,
+ ER(ER_INVALID_CHARACTER_STRING), cs->csname, hexbuf);
+ }
return str;
}
@@ -2518,7 +2548,7 @@ String *Item_load_file::val_str(String *str)
if (!(file_name= args[0]->val_str(str))
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- || !(current_thd->master_access & FILE_ACL)
+ || !(current_thd->security_ctx->master_access & FILE_ACL)
#endif
)
goto err;
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index aead2d67c2c..0e30bbd8a96 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1468,7 +1468,7 @@ int subselect_single_select_engine::prepare()
int subselect_union_engine::prepare()
{
- return unit->prepare(thd, result, SELECT_NO_UNLOCK, "");
+ return unit->prepare(thd, result, SELECT_NO_UNLOCK);
}
int subselect_uniquesubquery_engine::prepare()
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 880ab4c8cb1..b56d99cf245 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -545,6 +545,7 @@ struct Hybrid_type_traits_fast_decimal: public
val->traits->div(val, u);
}
static const Hybrid_type_traits_fast_decimal *instance();
+ Hybrid_type_traits_fast_decimal() {};
};
static const Hybrid_type_traits_fast_decimal fast_decimal_traits_instance;
@@ -1367,8 +1368,8 @@ void Item_sum_hybrid::cleanup()
void Item_sum_hybrid::no_rows_in_result()
{
- Item_sum::no_rows_in_result();
was_values= FALSE;
+ clear();
}
diff --git a/sql/log.cc b/sql/log.cc
index 9d9f500fe80..0dc0b4d1682 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -39,6 +39,7 @@ ulong sync_binlog_counter= 0;
static bool test_if_number(const char *str,
long *res, bool allow_wildcards);
+static bool binlog_init();
static int binlog_close_connection(THD *thd);
static int binlog_savepoint_set(THD *thd, void *sv);
static int binlog_savepoint_rollback(THD *thd, void *sv);
@@ -46,8 +47,12 @@ static int binlog_commit(THD *thd, bool all);
static int binlog_rollback(THD *thd, bool all);
static int binlog_prepare(THD *thd, bool all);
-static handlerton binlog_hton = {
+handlerton binlog_hton = {
"binlog",
+ SHOW_OPTION_YES,
+ "This is a meta storage engine to represent the binlog in a transaction",
+ DB_TYPE_UNKNOWN, /* IGNORE for now */
+ binlog_init,
0,
sizeof(my_off_t), /* savepoint size = binlog offset */
binlog_close_connection,
@@ -72,9 +77,9 @@ static handlerton binlog_hton = {
should be moved here.
*/
-handlerton *binlog_init()
+bool binlog_init()
{
- return &binlog_hton;
+ return false;
}
static int binlog_close_connection(THD *thd)
@@ -1477,7 +1482,7 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
{ // Normal thread
if ((thd->options & OPTION_LOG_OFF)
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- && (thd->master_access & SUPER_ACL)
+ && (thd->security_ctx->master_access & SUPER_ACL)
#endif
)
{
@@ -1852,7 +1857,9 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
if (commit_event->write(&log_file))
goto err;
+#ifndef DBUG_OFF
DBUG_skip_commit:
+#endif
if (flush_and_sync())
goto err;
DBUG_EXECUTE_IF("half_binlogged_transaction", abort(););
@@ -1917,6 +1924,7 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
}
if (!(specialflag & SPECIAL_SHORT_LOG_FORMAT) || query_start_arg)
{
+ Security_context *sctx= thd->security_ctx;
current_time=time(NULL);
if (current_time != last_time)
{
@@ -1937,10 +1945,12 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
tmp_errno=errno;
}
if (my_b_printf(&log_file, "# User@Host: %s[%s] @ %s [%s]\n",
- thd->priv_user ? thd->priv_user : "",
- thd->user ? thd->user : "",
- thd->host ? thd->host : "",
- thd->ip ? thd->ip : "") == (uint) -1)
+ sctx->priv_user ?
+ sctx->priv_user : "",
+ sctx->user ? sctx->user : "",
+ sctx->host ? sctx->host : "",
+ sctx->ip ? sctx->ip : "") ==
+ (uint) -1)
tmp_errno=errno;
}
if (query_start_arg)
@@ -2792,7 +2802,7 @@ void TC_LOG_MMAP::close()
case 3:
my_free((gptr)pages, MYF(0));
case 2:
- my_munmap(data, (size_t)file_length);
+ my_munmap((byte*)data, (size_t)file_length);
case 1:
my_close(fd, MYF(0));
}
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index b15b1682d69..d46d0bd1e81 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -284,7 +284,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
/* Flag set if setup_tables already done */
#define OPTION_SETUP_TABLES_DONE (1L << 30) // intern
/* If not set then the thread will ignore all warnings with level notes. */
-#define OPTION_SQL_NOTES (1L << 31) // THD, user
+#define OPTION_SQL_NOTES (1UL << 31) // THD, user
/*
Force the used temporary table to be a MyISAM table (because we will use
fulltext functions when reading from it.
@@ -491,6 +491,7 @@ typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
#include "protocol.h"
#include "sql_udf.h"
class user_var_entry;
+class Security_context;
enum enum_var_type
{
OPT_DEFAULT= 0, OPT_SESSION, OPT_GLOBAL
@@ -522,7 +523,7 @@ bool delete_precheck(THD *thd, TABLE_LIST *tables);
bool insert_precheck(THD *thd, TABLE_LIST *tables);
bool create_table_precheck(THD *thd, TABLE_LIST *tables,
TABLE_LIST *create_table);
-bool default_view_definer(THD *thd, st_lex_user *definer);
+bool default_view_definer(Security_context *sctx, st_lex_user *definer);
enum enum_mysql_completiontype {
@@ -1097,7 +1098,6 @@ bool fn_format_relative_to_data_home(my_string to, const char *name,
const char *dir, const char *extension);
File open_binlog(IO_CACHE *log, const char *log_file_name,
const char **errmsg);
-handlerton *binlog_init();
/* mysqld.cc */
extern void yyerror(const char*);
@@ -1182,12 +1182,13 @@ extern my_bool relay_log_purge, opt_innodb_safe_binlog, opt_innodb;
extern uint test_flags,select_errors,ha_open_options;
extern uint protocol_version, mysqld_port, dropping_tables;
extern uint delay_key_write_options, lower_case_table_names;
-extern bool opt_endinfo, using_udf_functions, locked_in_memory;
+extern bool opt_endinfo, using_udf_functions;
+extern my_bool locked_in_memory;
extern bool opt_using_transactions, mysqld_embedded;
extern bool using_update_log, opt_large_files, server_id_supplied;
extern bool opt_log, opt_update_log, opt_bin_log, opt_slow_log, opt_error_log;
extern bool opt_disable_networking, opt_skip_show_db;
-extern bool opt_character_set_client_handshake;
+extern my_bool opt_character_set_client_handshake;
extern bool volatile abort_loop, shutdown_in_progress, grant_option;
extern bool mysql_proc_table_exists;
extern uint volatile thread_count, thread_running, global_read_lock;
@@ -1202,7 +1203,7 @@ extern my_bool sp_automatic_privileges, opt_noacl;
extern my_bool opt_old_style_user_limits, trust_routine_creators;
extern uint opt_crash_binlog_innodb;
extern char *shared_memory_base_name, *mysqld_unix_port;
-extern bool opt_enable_shared_memory;
+extern my_bool opt_enable_shared_memory;
extern char *default_tz_name;
extern my_bool opt_large_pages;
extern uint opt_large_page_size;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 81657a7657f..e79bce9cd9e 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -295,7 +295,7 @@ bool opt_large_files= sizeof(my_off_t) > 4;
/*
Used with --help for detailed option
*/
-static bool opt_help= 0, opt_verbose= 0;
+static my_bool opt_help= 0, opt_verbose= 0;
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
{{&Arg_comparator::compare_string, &Arg_comparator::compare_e_string},
@@ -339,9 +339,10 @@ static my_bool opt_sync_bdb_logs;
bool opt_log, opt_update_log, opt_bin_log, opt_slow_log;
bool opt_error_log= IF_WIN(1,0);
bool opt_disable_networking=0, opt_skip_show_db=0;
-bool opt_character_set_client_handshake= 1;
+my_bool opt_character_set_client_handshake= 1;
bool server_id_supplied = 0;
-bool opt_endinfo,using_udf_functions, locked_in_memory;
+bool opt_endinfo,using_udf_functions;
+my_bool locked_in_memory;
bool opt_using_transactions, using_update_log;
bool volatile abort_loop;
bool volatile shutdown_in_progress, grant_option;
@@ -439,6 +440,7 @@ char server_version[SERVER_VERSION_LENGTH];
char *mysqld_unix_port, *opt_mysql_tmpdir;
const char **errmesg; /* Error messages */
const char *myisam_recover_options_str="OFF";
+const char *myisam_stats_method_str="nulls_unequal";
/* name of reference on left espression in rewritten IN subquery */
const char *in_left_expr_name= "<left expr>";
/* name of additional condition */
@@ -577,7 +579,7 @@ Query_cache query_cache;
#endif
#ifdef HAVE_SMEM
char *shared_memory_base_name= default_shared_memory_base_name;
-bool opt_enable_shared_memory;
+my_bool opt_enable_shared_memory;
HANDLE smem_event_connect_request= 0;
#endif
@@ -782,7 +784,9 @@ static void close_connections(void)
{
if (global_system_variables.log_warnings)
sql_print_warning(ER(ER_FORCING_CLOSE),my_progname,
- tmp->thread_id,tmp->user ? tmp->user : "");
+ tmp->thread_id,
+ (tmp->main_security_ctx.user ?
+ tmp->main_security_ctx.user : ""));
close_connection(tmp,0,0);
}
#endif
@@ -1098,7 +1102,7 @@ void clean_up(bool print_message)
my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR));
#endif /* HAVE_OPENSSL */
#ifdef USE_REGEX
- regex_end();
+ my_regex_end();
#endif
if (print_message && errmesg)
@@ -2605,7 +2609,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
set_var_init();
mysys_uses_curses=0;
#ifdef USE_REGEX
- regex_init(&my_charset_latin1);
+ my_regex_init(&my_charset_latin1);
#endif
if (!(default_charset_info= get_charset_by_csname(default_character_set_name,
MY_CS_PRIMARY,
@@ -3593,7 +3597,7 @@ static void bootstrap(FILE *file)
thd->client_capabilities=0;
my_net_init(&thd->net,(st_vio*) 0);
thd->max_client_packet_length= thd->net.max_packet;
- thd->master_access= ~(ulong)0;
+ thd->security_ctx->master_access= ~(ulong)0;
thd->thread_id=thread_id++;
thread_count++;
@@ -3933,7 +3937,7 @@ extern "C" pthread_handler_decl(handle_connections_sockets,
continue;
}
if (sock == unix_sock)
- thd->host=(char*) my_localhost;
+ thd->security_ctx->host=(char*) my_localhost;
#ifdef __WIN__
/* Set default wait_timeout */
ulong wait_timeout= global_system_variables.net_wait_timeout * 1000;
@@ -4024,8 +4028,8 @@ extern "C" pthread_handler_decl(handle_connections_namedpipes,arg)
delete thd;
continue;
}
- /* host name is unknown */
- thd->host = my_strdup(my_localhost,MYF(0)); /* Host is unknown */
+ /* Host is unknown */
+ thd->security_ctx->host= my_strdup(my_localhost, MYF(0));
create_new_thread(thd);
}
@@ -4216,7 +4220,7 @@ pthread_handler_decl(handle_connections_shared_memory,arg)
errmsg= 0;
goto errorconn;
}
- thd->host= my_strdup(my_localhost,MYF(0)); /* Host is unknown */
+ thd->security_ctx->host= my_strdup(my_localhost, MYF(0)); /* Host is unknown */
create_new_thread(thd);
connect_number++;
continue;
@@ -4372,6 +4376,7 @@ enum options_mysqld
OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
+ OPT_MYISAM_STATS_METHOD,
OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
OPT_OPEN_FILES_LIMIT,
@@ -5555,6 +5560,11 @@ The minimum value for this variable is 4096.",
(gptr*) &global_system_variables.myisam_sort_buff_size,
(gptr*) &max_system_variables.myisam_sort_buff_size, 0,
GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0},
+ {"myisam_stats_method", OPT_MYISAM_STATS_METHOD,
+ "Specifies how MyISAM index statistics collection code should threat NULLs. "
+ "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), and \"nulls_equal\" (emulate 4.0 behavior).",
+ (gptr*) &myisam_stats_method_str, (gptr*) &myisam_stats_method_str, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"net_buffer_length", OPT_NET_BUFFER_LENGTH,
"Buffer length for TCP/IP and socket communication.",
(gptr*) &global_system_variables.net_buffer_length,
@@ -5863,6 +5873,7 @@ struct show_var_st status_vars[]= {
{"Com_show_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
{"Com_show_logs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_LOGS]), SHOW_LONG_STATUS},
{"Com_show_master_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
+ {"Com_show_ndb_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NDBCLUSTER_STATUS]), SHOW_LONG_STATUS},
{"Com_show_new_master", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NEW_MASTER]), SHOW_LONG_STATUS},
{"Com_show_open_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
{"Com_show_privileges", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PRIVILEGES]), SHOW_LONG_STATUS},
@@ -6138,6 +6149,7 @@ static void mysql_init_variables(void)
query_id= thread_id= 1L;
strmov(server_version, MYSQL_SERVER_VERSION);
myisam_recover_options_str= sql_mode_str= "OFF";
+ myisam_stats_method_str= "nulls_unequal";
my_bind_addr = htonl(INADDR_ANY);
threads.empty();
thread_cache.empty();
@@ -6180,6 +6192,12 @@ static void mysql_init_variables(void)
max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
global_system_variables.old_passwords= 0;
global_system_variables.old_alter_table= 0;
+
+ /*
+ Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
+ when collecting index statistics for MyISAM tables.
+ */
+ global_system_variables.myisam_stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
/* Variables that depends on compile options */
#ifndef DBUG_OFF
@@ -6249,7 +6267,7 @@ static void mysql_init_variables(void)
#else
have_openssl=SHOW_OPTION_NO;
#endif
-#ifdef HAVE_BROKEN_REALPATH
+#if !defined(HAVE_REALPATH) || defined(HAVE_BROKEN_REALPATH)
have_symlink=SHOW_OPTION_NO;
#else
have_symlink=SHOW_OPTION_YES;
@@ -6795,6 +6813,17 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
fprintf(stderr, "Unknown option to tc-heuristic-recover: %s\n",argument);
exit(1);
}
+ }
+ case OPT_MYISAM_STATS_METHOD:
+ {
+ myisam_stats_method_str= argument;
+ int method;
+ if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0)
+ {
+ fprintf(stderr, "Invalid value of myisam_stats_method: %s.\n", argument);
+ exit(1);
+ }
+ global_system_variables.myisam_stats_method= method-1;
break;
}
case OPT_SQL_MODE:
@@ -6930,7 +6959,7 @@ static void get_options(int argc,char **argv)
usage();
exit(0);
}
-#if defined(HAVE_BROKEN_REALPATH)
+#if !defined(HAVE_REALPATH) || defined(HAVE_BROKEN_REALPATH)
my_use_symdir=0;
my_disable_symlinks=1;
have_symlink=SHOW_OPTION_NO;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index b69822d201b..2f4cf1c4752 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -750,10 +750,9 @@ int QUICK_RANGE_SELECT::init()
{
DBUG_ENTER("QUICK_RANGE_SELECT::init");
- if (file->inited == handler::NONE)
- DBUG_RETURN(error= file->ha_index_init(index, 1));
- error= 0;
- DBUG_RETURN(0);
+ if (file->inited != handler::NONE)
+ file->ha_index_or_rnd_end();
+ DBUG_RETURN(error= file->ha_index_init(index, 1));
}
@@ -3539,17 +3538,17 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
switch (cond_func->functype()) {
case Item_func::BETWEEN:
- if (cond_func->arguments()[0]->type() != Item::FIELD_ITEM)
+ if (cond_func->arguments()[0]->real_item()->type() != Item::FIELD_ITEM)
DBUG_RETURN(0);
- field_item= (Item_field*) (cond_func->arguments()[0]);
+ field_item= (Item_field*) (cond_func->arguments()[0]->real_item());
value= NULL;
break;
case Item_func::IN_FUNC:
{
Item_func_in *func=(Item_func_in*) cond_func;
- if (func->key_item()->type() != Item::FIELD_ITEM)
+ if (func->key_item()->real_item()->type() != Item::FIELD_ITEM)
DBUG_RETURN(0);
- field_item= (Item_field*) (func->key_item());
+ field_item= (Item_field*) (func->key_item()->real_item());
value= NULL;
break;
}
@@ -5123,6 +5122,8 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree)
if (cpk_scan)
param->is_ror_scan= TRUE;
}
+ if (param->table->file->index_flags(key, 0, TRUE) & HA_KEY_SCAN_NOT_ROR)
+ param->is_ror_scan= FALSE;
DBUG_PRINT("exit", ("Records: %lu", (ulong) records));
DBUG_RETURN(records);
}
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 9802bbddde6..2e87f9cf0db 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -80,6 +80,8 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
List_iterator_fast<Item> it(all_fields);
int const_result= 1;
bool recalc_const_item= 0;
+ longlong count= 1;
+ bool is_exact_count= TRUE;
table_map removed_tables= 0, outer_tables= 0, used_tables= 0;
table_map where_tables= 0;
Item *item;
@@ -88,9 +90,13 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
if (conds)
where_tables= conds->used_tables();
- /* Don't replace expression on a table that is part of an outer join */
+ /*
+ Analyze outer join dependencies, and, if possible, compute the number
+ of returned rows.
+ */
for (TABLE_LIST *tl= tables; tl; tl= tl->next_leaf)
{
+ /* Don't replace expression on a table that is part of an outer join */
if (tl->on_expr)
{
outer_tables|= tl->table->map;
@@ -106,11 +112,27 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
}
else
used_tables|= tl->table->map;
+
+ /*
+ If the storage manager of 'tl' gives exact row count, compute the total
+ number of rows. If there are no outer table dependencies, this count
+ may be used as the real count.
+ */
+ if (tl->table->file->table_flags() & HA_NOT_EXACT_COUNT)
+ {
+ is_exact_count= FALSE;
+ count= 1; // ensure count != 0
+ }
+ else
+ {
+ tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
+ count*= tl->table->file->records;
+ }
}
/*
- Iterate through item is select part and replace COUNT(), MIN() and MAX()
- with constants (if possible)
+ Iterate through all items in the SELECT clause and replace
+ COUNT(), MIN() and MAX() with constants (if possible).
*/
while ((item= it++))
@@ -122,9 +144,11 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
case Item_sum::COUNT_FUNC:
/*
If the expr in count(expr) can never be null we can change this
- to the number of rows in the tables
+ to the number of rows in the tables if this number is exact and
+ there are no outer joins.
*/
- if (!conds && !((Item_sum_count*) item)->args[0]->maybe_null)
+ if (!conds && !((Item_sum_count*) item)->args[0]->maybe_null &&
+ !outer_tables && is_exact_count)
{
longlong count= 1;
TABLE_LIST *table;
@@ -210,12 +234,27 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
}
removed_tables|= table->map;
}
- else if (!expr->const_item()) // This is VERY seldom false
+ else if (!expr->const_item() || !is_exact_count)
{
+ /*
+ The optimization is not applicable in both cases:
+ (a) 'expr' is a non-constant expression. Then we can't
+ replace 'expr' by a constant.
+ (b) 'expr' is a costant. According to ANSI, MIN/MAX must return
+ NULL if the query does not return any rows. Thus, if we are not
+ able to determine if the query returns any rows, we can't apply
+ the optimization and replace MIN/MAX with a constant.
+ */
const_result= 0;
break;
}
- ((Item_sum_min*) item_sum)->reset();
+ if (!count)
+ {
+ /* If count == 0, then we know that is_exact_count == TRUE. */
+ ((Item_sum_min*) item_sum)->clear(); /* Set to NULL. */
+ }
+ else
+ ((Item_sum_min*) item_sum)->reset(); /* Set to the constant value. */
((Item_sum_min*) item_sum)->make_const();
recalc_const_item= 1;
break;
@@ -282,13 +321,28 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
}
removed_tables|= table->map;
}
- else if (!expr->const_item()) // This is VERY seldom false
+ else if (!expr->const_item() || !is_exact_count)
{
+ /*
+ The optimization is not applicable in both cases:
+ (a) 'expr' is a non-constant expression. Then we can't
+ replace 'expr' by a constant.
+ (b) 'expr' is a costant. According to ANSI, MIN/MAX must return
+ NULL if the query does not return any rows. Thus, if we are not
+ able to determine if the query returns any rows, we can't apply
+ the optimization and replace MIN/MAX with a constant.
+ */
const_result= 0;
break;
}
- ((Item_sum_min*) item_sum)->reset();
- ((Item_sum_min*) item_sum)->make_const();
+ if (!count)
+ {
+ /* If count != 1, then we know that is_exact_count == TRUE. */
+ ((Item_sum_max*) item_sum)->clear(); /* Set to NULL. */
+ }
+ else
+ ((Item_sum_max*) item_sum)->reset(); /* Set to the constant value. */
+ ((Item_sum_max*) item_sum)->make_const();
recalc_const_item= 1;
break;
}
diff --git a/sql/parse_file.cc b/sql/parse_file.cc
index 82ce2f2d7b5..5c7053e6e2a 100644
--- a/sql/parse_file.cc
+++ b/sql/parse_file.cc
@@ -333,6 +333,59 @@ err_w_file:
DBUG_RETURN(TRUE);
}
+/*
+ Renames a frm file (including backups) in same schema
+
+ SYNOPSIS
+ rename_in_schema_file
+ schema name of given schema
+ old_name original file name
+ new_name new file name
+ revision revision number
+ num_view_backups number of backups
+
+ RETURN
+ 0 - OK
+ 1 - Error (only if renaming of frm failed)
+
+*/
+my_bool rename_in_schema_file(const char *schema, const char *old_name,
+ const char *new_name, ulonglong revision,
+ uint num_view_backups)
+{
+ char old_path[FN_REFLEN], new_path[FN_REFLEN], arc_path[FN_REFLEN];
+
+ strxnmov(old_path, FN_REFLEN, mysql_data_home, "/", schema, "/",
+ old_name, reg_ext, NullS);
+ (void) unpack_filename(old_path, old_path);
+
+ strxnmov(new_path, FN_REFLEN, mysql_data_home, "/", schema, "/",
+ new_name, reg_ext, NullS);
+ (void) unpack_filename(new_path, new_path);
+
+ if (my_rename(old_path, new_path, MYF(MY_WME)))
+ return 1;
+
+ /* check if arc_dir exists */
+ strxnmov(arc_path, FN_REFLEN, mysql_data_home, "/", schema, "/arc", NullS);
+ (void) unpack_filename(arc_path, arc_path);
+
+ if (revision > 0 && !access(arc_path, F_OK))
+ {
+ ulonglong limit= (revision > num_view_backups) ? revision - num_view_backups : 0;
+ while (revision > limit) {
+ my_snprintf(old_path, FN_REFLEN, "%s/%s%s-%04lu",
+ arc_path, old_name, reg_ext, (ulong)revision);
+ (void) unpack_filename(old_path, old_path);
+ my_snprintf(new_path, FN_REFLEN, "%s/%s%s-%04lu",
+ arc_path, new_name, reg_ext, (ulong)revision);
+ (void) unpack_filename(new_path, new_path);
+ my_rename(old_path, new_path, MYF(0));
+ revision--;
+ }
+ }
+ return 0;
+}
/*
Prepare frm to parse (read to memory)
diff --git a/sql/parse_file.h b/sql/parse_file.h
index cc0aa6556f6..b4199e4fbf1 100644
--- a/sql/parse_file.h
+++ b/sql/parse_file.h
@@ -48,6 +48,9 @@ my_bool
sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
const LEX_STRING *type,
gptr base, File_option *parameters, uint versions);
+my_bool rename_in_schema_file(const char *schema, const char *old_name,
+ const char *new_name, ulonglong revision,
+ uint num_view_backups);
class File_parser: public Sql_alloc
{
diff --git a/sql/password.c b/sql/password.c
index 60cc0ac0c97..aa05be8c740 100644
--- a/sql/password.c
+++ b/sql/password.c
@@ -318,8 +318,8 @@ void create_random_string(char *to, uint length, struct rand_struct *rand_st)
str, len IN the beginning and the length of the input string
*/
-static void
-octet2hex(char *to, const uint8 *str, uint len)
+void
+octet2hex(char *to, const unsigned char *str, uint len)
{
const uint8 *str_end= str + len;
for (; str != str_end; ++str)
diff --git a/sql/protocol.h b/sql/protocol.h
index 2717d2258fa..c00bbba4cc9 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -150,30 +150,6 @@ public:
virtual bool store(Field *field);
};
-class Protocol_cursor :public Protocol_simple
-{
-public:
- MEM_ROOT *alloc;
- MYSQL_FIELD *fields;
- MYSQL_ROWS *data;
- MYSQL_ROWS **prev_record;
- ulong row_count;
-
- Protocol_cursor() :data(NULL) {}
- Protocol_cursor(THD *thd_arg, MEM_ROOT *ini_alloc) :Protocol_simple(thd_arg), alloc(ini_alloc), data(NULL) {}
- bool prepare_for_send(List<Item> *item_list)
- {
- row_count= 0;
- fields= NULL;
- data= NULL;
- prev_record= &data;
- return Protocol_simple::prepare_for_send(item_list);
- }
- bool send_fields(List<Item> *list, uint flags);
- bool write();
- uint get_field_count() { return field_count; }
-};
-
void send_warning(THD *thd, uint sql_errno, const char *err=0);
void net_printf_error(THD *thd, uint sql_errno, ...);
void net_send_error(THD *thd, uint sql_errno=0, const char *err=0);
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index a30776057b1..93aafbdc0e0 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -67,13 +67,11 @@ static int init_failsafe_rpl_thread(THD* thd)
this thread has no other error reporting method).
*/
thd->system_thread = thd->bootstrap = 1;
- thd->host_or_ip= "";
+ thd->security_ctx->skip_grants();
thd->client_capabilities = 0;
my_net_init(&thd->net, 0);
thd->net.read_timeout = slave_net_timeout;
thd->max_client_packet_length=thd->net.max_packet;
- thd->master_access= ~(ulong)0;
- thd->priv_user = 0;
pthread_mutex_lock(&LOCK_thread_count);
thd->thread_id = thread_id++;
pthread_mutex_unlock(&LOCK_thread_count);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index e7adc7387c0..e1dc23f6032 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -270,6 +270,12 @@ sys_var_long_ptr sys_myisam_data_pointer_size("myisam_data_pointer_size",
sys_var_thd_ulonglong sys_myisam_max_sort_file_size("myisam_max_sort_file_size", &SV::myisam_max_sort_file_size, fix_myisam_max_sort_file_size, 1);
sys_var_thd_ulong sys_myisam_repair_threads("myisam_repair_threads", &SV::myisam_repair_threads);
sys_var_thd_ulong sys_myisam_sort_buffer_size("myisam_sort_buffer_size", &SV::myisam_sort_buff_size);
+
+sys_var_thd_enum sys_myisam_stats_method("myisam_stats_method",
+ &SV::myisam_stats_method,
+ &myisam_stats_method_typelib,
+ NULL);
+
sys_var_thd_ulong sys_net_buffer_length("net_buffer_length",
&SV::net_buffer_length);
sys_var_thd_ulong sys_net_read_timeout("net_read_timeout",
@@ -641,6 +647,7 @@ sys_var *sys_variables[]=
&sys_myisam_max_sort_file_size,
&sys_myisam_repair_threads,
&sys_myisam_sort_buffer_size,
+ &sys_myisam_stats_method,
&sys_net_buffer_length,
&sys_net_read_timeout,
&sys_net_retry_count,
@@ -912,6 +919,9 @@ struct show_var_st init_vars[]= {
{sys_myisam_repair_threads.name, (char*) &sys_myisam_repair_threads,
SHOW_SYS},
{sys_myisam_sort_buffer_size.name, (char*) &sys_myisam_sort_buffer_size, SHOW_SYS},
+
+ {sys_myisam_stats_method.name, (char*) &sys_myisam_stats_method, SHOW_SYS},
+
#ifdef __NT__
{"named_pipe", (char*) &opt_enable_named_pipe, SHOW_MY_BOOL},
#endif
@@ -1112,9 +1122,10 @@ static void sys_default_init_slave(THD* thd, enum_var_type type)
static int sys_check_ftb_syntax(THD *thd, set_var *var)
{
- if (thd->master_access & SUPER_ACL)
- return ft_boolean_check_syntax_string((byte*) var->value->str_value.c_ptr()) ?
- -1 : 0;
+ if (thd->security_ctx->master_access & SUPER_ACL)
+ return (ft_boolean_check_syntax_string((byte*)
+ var->value->str_value.c_ptr()) ?
+ -1 : 0);
else
{
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
@@ -2709,7 +2720,7 @@ static bool set_option_autocommit(THD *thd, set_var *var)
static int check_log_update(THD *thd, set_var *var)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (!(thd->master_access & SUPER_ACL))
+ if (!(thd->security_ctx->master_access & SUPER_ACL))
{
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
return 1;
@@ -2755,7 +2766,7 @@ static int check_pseudo_thread_id(THD *thd, set_var *var)
{
var->save_result.ulonglong_value= var->value->val_int();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (thd->master_access & SUPER_ACL)
+ if (thd->security_ctx->master_access & SUPER_ACL)
return 0;
else
{
@@ -3120,10 +3131,10 @@ int set_var_password::check(THD *thd)
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!user->host.str)
{
- if (thd->priv_host != 0)
+ if (*thd->security_ctx->priv_host != 0)
{
- user->host.str= (char *) thd->priv_host;
- user->host.length= strlen(thd->priv_host);
+ user->host.str= (char *) thd->security_ctx->priv_host;
+ user->host.length= strlen(thd->security_ctx->priv_host);
}
else
{
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 61d89545d61..3aabc4e5b1f 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5311,7 +5311,8 @@ ER_XAER_NOTA XAE04
ER_XAER_INVAL XAE05
eng "XAER_INVAL: Invalid arguments (or unsupported command)"
ER_XAER_RMFAIL XAE07
- eng "XAER_RMFAIL: The command cannot be executed in the %.64s state"
+ eng "XAER_RMFAIL: The command cannot be executed when global transaction is in the %.64s state"
+ rus "XAER_RMFAIL: ÜÔÕ ËÏÍÁÎÄÕ ÎÅÌØÚÑ ×ÙÐÏÌÎÑÔØ ËÏÇÄÁ ÇÌÏÂÁÌØÎÁÑ ÔÒÁÎÚÁËÃÉÑ ÎÁÈÏÄÉÔÓÑ × ÓÏÓÔÏÑÎÉÉ '%.64s'"
ER_XAER_OUTSIDE XAE09
eng "XAER_OUTSIDE: Some work is done outside global transaction"
ER_XAER_RMERR XAE03
@@ -5366,12 +5367,12 @@ ER_TOO_BIG_SCALE 42000 S1009
eng "Too big scale %d specified for column '%-.64s'. Maximum is %d."
ER_TOO_BIG_PRECISION 42000 S1009
eng "Too big precision %d specified for column '%-.64s'. Maximum is %d."
-ER_SCALE_BIGGER_THAN_PRECISION 42000 S1009
- eng "Scale may not be larger than the precision (column '%-.64s')."
+ER_M_BIGGER_THAN_D 42000 S1009
+ eng "For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '%-.64s')."
ER_WRONG_LOCK_OF_SYSTEM_TABLE
eng "You can't combine write-locking of system '%-.64s.%-.64s' table with other tables"
ER_CONNECT_TO_FOREIGN_DATA_SOURCE
- eng "Unable to connect to foreign data source - database '%s'!"
+ eng "Unable to connect to foreign data source - database '%.64s'!"
ER_QUERY_ON_FOREIGN_DATA_SOURCE
eng "There was a problem processing the query on the foreign data source. Data source error: '%-.64s'"
ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST
@@ -5400,11 +5401,11 @@ ER_DATETIME_FUNCTION_OVERFLOW 22008
ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
eng "Can't update table '%-.64s' in stored function/trigger because it is already used by statement which invoked this stored function/trigger."
ER_VIEW_PREVENT_UPDATE
- eng "The definition of table '%-.64s' prevents operation %s on table '%-.64s'."
+ eng "The definition of table '%-.64s' prevents operation %.64s on table '%-.64s'."
ER_PS_NO_RECURSION
eng "The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner"
ER_SP_CANT_SET_AUTOCOMMIT
- eng "Not allowed to set autocommit from a stored function or trigger"
+ eng "Not allowed to set autocommit from a stored function or trigger"
ER_NO_VIEW_USER
eng "View definer is not fully qualified"
ER_VIEW_FRM_NO_USER
@@ -5413,6 +5414,12 @@ ER_VIEW_OTHER_USER
eng "You need the SUPER privilege for creation view with %-.64s@%-.64s definer"
ER_NO_SUCH_USER
eng "There is not %-.64s@%-.64s registered"
+ER_FORBID_SCHEMA_CHANGE
+ eng "Changing schema from '%-.64s' to '%-.64s' is not allowed."
+ER_ROW_IS_REFERENCED_2 23000
+ eng "Cannot delete or update a parent row: a foreign key constraint fails (%.192s)"
+ER_NO_REFERENCED_ROW_2 23000
+ eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)"
ER_PARTITION_REQUIRES_VALUES_ERROR
eng "%s PARTITIONING requires definition of VALUES %s for each partition"
swe "%s PARTITIONering kräver definition av VALUES %s för varje partition"
diff --git a/sql/slave.cc b/sql/slave.cc
index 757d8bc212d..fb7b9275d0d 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -37,7 +37,7 @@ typedef bool (*CHECK_KILLED_FUNC)(THD*,void*);
volatile bool slave_sql_running = 0, slave_io_running = 0;
char* slave_load_tmpdir = 0;
MASTER_INFO *active_mi;
-bool replicate_same_server_id;
+my_bool replicate_same_server_id;
ulonglong relay_log_space_limit = 0;
/*
@@ -2426,17 +2426,10 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
DBUG_ENTER("init_slave_thread");
thd->system_thread = (thd_type == SLAVE_THD_SQL) ?
SYSTEM_THREAD_SLAVE_SQL : SYSTEM_THREAD_SLAVE_IO;
- /*
- The two next lines are needed for replication of SP (CREATE PROCEDURE
- needs a valid user to store in mysql.proc).
- */
- thd->priv_user= (char *) "";
- thd->priv_host[0]= '\0';
- thd->host_or_ip= "";
+ thd->security_ctx->skip_grants();
thd->client_capabilities = 0;
my_net_init(&thd->net, 0);
thd->net.read_timeout = slave_net_timeout;
- thd->master_access= ~(ulong)0;
thd->slave_thread = 1;
set_slave_thread_options(thd);
/*
diff --git a/sql/slave.h b/sql/slave.h
index ead1aa87ce6..486bb3055f5 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -552,7 +552,7 @@ extern "C" pthread_handler_decl(handle_slave_sql,arg);
extern bool volatile abort_loop;
extern MASTER_INFO main_mi, *active_mi; /* active_mi for multi-master */
extern LIST master_list;
-extern bool replicate_same_server_id;
+extern my_bool replicate_same_server_id;
extern int disconnect_slave_event_count, abort_slave_event_count ;
diff --git a/sql/sp.cc b/sql/sp.cc
index e979921492f..18d94a85884 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -494,7 +494,8 @@ db_create_routine(THD *thd, int type, sp_head *sp)
else
{
restore_record(table, s->default_values); // Get default values for fields
- strxmov(definer, thd->priv_user, "@", thd->priv_host, NullS);
+ strxmov(definer, thd->security_ctx->priv_user, "@",
+ thd->security_ctx->priv_host, NullS);
if (table->s->fields != MYSQL_PROC_FIELD_COUNT)
{
@@ -569,7 +570,7 @@ db_create_routine(THD *thd, int type, sp_head *sp)
goto done;
}
}
- if (!(thd->master_access & SUPER_ACL))
+ if (!(thd->security_ctx->master_access & SUPER_ACL))
{
my_message(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER,
ER(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER), MYF(0));
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 1a7599d7bbc..671acbc2a0c 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -199,11 +199,18 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type,
Item *it= sp_prepare_func_item(thd, it_addr);
uint rsize;
Query_arena backup_arena;
+ Item *old_item_next, *old_free_list, **p_free_list;
DBUG_PRINT("info", ("type: %d", type));
if (!it)
- {
DBUG_RETURN(NULL);
+
+ if (reuse)
+ {
+ old_item_next= reuse->next;
+ p_free_list= use_callers_arena ? &thd->spcont->callers_arena->free_list :
+ &thd->free_list;
+ old_free_list= *p_free_list;
}
switch (sp_map_result_type(type)) {
@@ -312,15 +319,23 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type,
default:
DBUG_ASSERT(0);
}
- it->rsize= rsize;
-
- DBUG_RETURN(it);
+ goto end;
return_null_item:
CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize) Item_null(),
use_callers_arena, &backup_arena);
+end:
it->rsize= rsize;
+ if (reuse && it == reuse)
+ {
+ /*
+ The Item constructor registered itself in the arena free list,
+ while the item slot is reused, so we have to restore the list.
+ */
+ it->next= old_item_next;
+ *p_free_list= old_free_list;
+ }
DBUG_RETURN(it);
}
@@ -1000,7 +1015,7 @@ int sp_head::execute(THD *thd)
ip= hip;
ret= 0;
ctx->clear_handler();
- ctx->in_handler= TRUE;
+ ctx->enter_handler(hip);
thd->clear_error();
thd->killed= THD::NOT_KILLED;
continue;
@@ -1358,14 +1373,6 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args)
uint offset= static_cast<Item_splocal *>(it)->get_offset();
Item *val= nctx->get_item(i);
Item *orig= octx->get_item(offset);
- Item *o_item_next;
- /* we'll use callers_arena in sp_eval_func_item */
- Item *o_free_list= thd->spcont->callers_arena->free_list;
-
- LINT_INIT(o_item_next);
-
- if (orig)
- o_item_next= orig->next;
/*
We might need to allocate new item if we weren't able to
@@ -1380,15 +1387,6 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args)
}
if (copy != orig)
octx->set_item(offset, copy);
- if (orig && copy == orig)
- {
- /*
- A reused item slot, where the constructor put it in the
- free_list, so we have to restore the list.
- */
- thd->spcont->callers_arena->free_list= o_free_list;
- copy->next= o_item_next;
- }
}
else
{
@@ -1636,8 +1634,10 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
tables.db= (char*) "mysql";
tables.table_name= tables.alias= (char*) "proc";
*full_access= (!check_table_access(thd, SELECT_ACL, &tables, 1) ||
- (!strcmp(sp->m_definer_user.str, thd->priv_user) &&
- !strcmp(sp->m_definer_host.str, thd->priv_host)));
+ (!strcmp(sp->m_definer_user.str,
+ thd->security_ctx->priv_user) &&
+ !strcmp(sp->m_definer_host.str,
+ thd->security_ctx->priv_host)));
if (!*full_access)
return check_some_routine_access(thd, sp->m_db.str, sp->m_name.str,
sp->m_type == TYPE_ENUM_PROCEDURE);
@@ -2378,7 +2378,7 @@ sp_instr_hreturn::execute(THD *thd, uint *nextp)
thd->spcont->restore_variables(m_frame);
*nextp= thd->spcont->pop_hstack();
}
- thd->spcont->in_handler= FALSE;
+ thd->spcont->exit_handler();
DBUG_RETURN(0);
}
@@ -2476,6 +2476,10 @@ sp_instr_cpop::backpatch(uint dest, sp_pcontext *dst_ctx)
int
sp_instr_copen::execute(THD *thd, uint *nextp)
{
+ /*
+ We don't store a pointer to the cursor in the instruction to be
+ able to reuse the same instruction among different threads in future.
+ */
sp_cursor *c= thd->spcont->get_cursor(m_cursor);
int res;
DBUG_ENTER("sp_instr_copen::execute");
@@ -2484,41 +2488,33 @@ sp_instr_copen::execute(THD *thd, uint *nextp)
res= -1;
else
{
- sp_lex_keeper *lex_keeper= c->pre_open(thd);
- if (!lex_keeper) // cursor already open or OOM
- {
- res= -1;
- *nextp= m_ip+1;
- }
- else
- {
- Query_arena *old_arena= thd->stmt_arena;
+ sp_lex_keeper *lex_keeper= c->get_lex_keeper();
+ Query_arena *old_arena= thd->stmt_arena;
- /*
- Get the Query_arena from the cpush instruction, which contains
- the free_list of the query, so new items (if any) are stored in
- the right free_list, and we can cleanup after each open.
- */
- thd->stmt_arena= c->get_instr();
- res= lex_keeper->reset_lex_and_exec_core(thd, nextp, FALSE, this);
- /* Cleanup the query's items */
- if (thd->stmt_arena->free_list)
- cleanup_items(thd->stmt_arena->free_list);
- thd->stmt_arena= old_arena;
- /*
- Work around the fact that errors in selects are not returned properly
- (but instead converted into a warning), so if a condition handler
- caught, we have lost the result code.
- */
- if (!res)
- {
- uint dummy1, dummy2;
+ /*
+ Get the Query_arena from the cpush instruction, which contains
+ the free_list of the query, so new items (if any) are stored in
+ the right free_list, and we can cleanup after each open.
+ */
+ thd->stmt_arena= c->get_instr();
+ res= lex_keeper->reset_lex_and_exec_core(thd, nextp, FALSE, this);
+ /* Cleanup the query's items */
+ if (thd->stmt_arena->free_list)
+ cleanup_items(thd->stmt_arena->free_list);
+ thd->stmt_arena= old_arena;
+ /*
+ Work around the fact that errors in selects are not returned properly
+ (but instead converted into a warning), so if a condition handler
+ caught, we have lost the result code.
+ */
+ if (!res)
+ {
+ uint dummy1, dummy2;
- if (thd->spcont->found_handler(&dummy1, &dummy2))
- res= -1;
- }
- c->post_open(thd, res ? FALSE : TRUE);
+ if (thd->spcont->found_handler(&dummy1, &dummy2))
+ res= -1;
}
+ /* TODO: Assert here that we either have an error or a cursor */
}
DBUG_RETURN(res);
}
@@ -2527,7 +2523,8 @@ sp_instr_copen::execute(THD *thd, uint *nextp)
int
sp_instr_copen::exec_core(THD *thd, uint *nextp)
{
- int res= mysql_execute_command(thd);
+ sp_cursor *c= thd->spcont->get_cursor(m_cursor);
+ int res= c->open(thd);
*nextp= m_ip+1;
return res;
}
@@ -2582,14 +2579,7 @@ sp_instr_cfetch::execute(THD *thd, uint *nextp)
Query_arena backup_arena;
DBUG_ENTER("sp_instr_cfetch::execute");
- if (! c)
- res= -1;
- else
- {
- thd->set_n_backup_active_arena(thd->spcont->callers_arena, &backup_arena);
- res= c->fetch(thd, &m_varlist);
- thd->restore_active_arena(thd->spcont->callers_arena, &backup_arena);
- }
+ res= c ? c->fetch(thd, &m_varlist) : -1;
*nextp= m_ip+1;
DBUG_RETURN(res);
@@ -2645,54 +2635,36 @@ sp_instr_error::print(String *str)
*/
#ifndef NO_EMBEDDED_ACCESS_CHECKS
-void
-sp_change_security_context(THD *thd, sp_head *sp, st_sp_security_context *ctxp)
-{
- ctxp->changed= (sp->m_chistics->suid != SP_IS_NOT_SUID &&
- (strcmp(sp->m_definer_user.str, thd->priv_user) ||
- strcmp(sp->m_definer_host.str, thd->priv_host)));
-
- if (ctxp->changed)
+bool
+sp_change_security_context(THD *thd, sp_head *sp, Security_context **backup)
+{
+ *backup= 0;
+ if (sp->m_chistics->suid != SP_IS_NOT_SUID &&
+ (strcmp(sp->m_definer_user.str,
+ thd->security_ctx->priv_user) ||
+ my_strcasecmp(system_charset_info, sp->m_definer_host.str,
+ thd->security_ctx->priv_host)))
{
- ctxp->master_access= thd->master_access;
- ctxp->db_access= thd->db_access;
- ctxp->priv_user= thd->priv_user;
- strncpy(ctxp->priv_host, thd->priv_host, sizeof(ctxp->priv_host));
- ctxp->user= thd->user;
- ctxp->host= thd->host;
- ctxp->ip= thd->ip;
-
- /* Change thise just to do the acl_getroot_no_password */
- thd->user= sp->m_definer_user.str;
- thd->host= thd->ip = sp->m_definer_host.str;
-
- if (acl_getroot_no_password(thd))
- { // Failed, run as invoker for now
- ctxp->changed= FALSE;
- thd->master_access= ctxp->master_access;
- thd->db_access= ctxp->db_access;
- thd->priv_user= ctxp->priv_user;
- strncpy(thd->priv_host, ctxp->priv_host, sizeof(thd->priv_host));
+ if (acl_getroot_no_password(&sp->m_security_ctx, sp->m_definer_user.str,
+ sp->m_definer_host.str,
+ sp->m_definer_host.str,
+ sp->m_db.str))
+ {
+ my_error(ER_NO_SUCH_USER, MYF(0), sp->m_definer_user.str,
+ sp->m_definer_host.str);
+ return TRUE;
}
-
- /* Restore these immiediately */
- thd->user= ctxp->user;
- thd->host= ctxp->host;
- thd->ip= ctxp->ip;
+ *backup= thd->security_ctx;
+ thd->security_ctx= &sp->m_security_ctx;
}
+ return FALSE;
}
void
-sp_restore_security_context(THD *thd, sp_head *sp, st_sp_security_context *ctxp)
+sp_restore_security_context(THD *thd, Security_context *backup)
{
- if (ctxp->changed)
- {
- ctxp->changed= FALSE;
- thd->master_access= ctxp->master_access;
- thd->db_access= ctxp->db_access;
- thd->priv_user= ctxp->priv_user;
- strncpy(thd->priv_host, ctxp->priv_host, sizeof(thd->priv_host));
- }
+ if (backup)
+ thd->security_ctx= backup;
}
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 9888fe74149..ed0f3987e01 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -151,6 +151,12 @@ public:
// Pointers set during parsing
uchar *m_param_begin, *m_param_end, *m_body_begin;
+ /*
+ Security context for stored routine which should be run under
+ definer privileges.
+ */
+ Security_context m_security_ctx;
+
static void *
operator new(size_t size);
@@ -860,6 +866,12 @@ public:
virtual void print(String *str);
+ /*
+ This call is used to cleanup the instruction when a sensitive
+ cursor is closed. For now stored procedures always use materialized
+ cursors and the call is not used.
+ */
+ virtual void cleanup_stmt() { /* no op */ }
private:
sp_lex_keeper m_lex_keeper;
@@ -1017,23 +1029,12 @@ private:
}; // class sp_instr_error : public sp_instr
-struct st_sp_security_context
-{
- bool changed;
- uint master_access;
- uint db_access;
- char *priv_user;
- char priv_host[MAX_HOSTNAME];
- char *user;
- char *host;
- char *ip;
-};
-
#ifndef NO_EMBEDDED_ACCESS_CHECKS
+bool
+sp_change_security_context(THD *thd, sp_head *sp,
+ Security_context **backup);
void
-sp_change_security_context(THD *thd, sp_head *sp, st_sp_security_context *ctxp);
-void
-sp_restore_security_context(THD *thd, sp_head *sp,st_sp_security_context *ctxp);
+sp_restore_security_context(THD *thd, Security_context *backup);
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
TABLE_LIST *
@@ -1041,4 +1042,7 @@ sp_add_to_query_tables(THD *thd, LEX *lex,
const char *db, const char *name,
thr_lock_type locktype);
+Item *sp_eval_func_item(THD *thd, Item **it, enum_field_types type,
+ Item *reuse, bool use_callers_arena);
+
#endif /* _SP_HEAD_H_ */
diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc
index 748c09f56c7..252bd7e5cab 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -25,17 +25,18 @@
#include "mysql.h"
#include "sp_head.h"
+#include "sql_cursor.h"
#include "sp_rcontext.h"
#include "sp_pcontext.h"
sp_rcontext::sp_rcontext(uint fsize, uint hmax, uint cmax)
: m_count(0), m_fsize(fsize), m_result(NULL), m_hcount(0), m_hsp(0),
- m_hfound(-1), m_ccount(0)
+ m_ihsp(0), m_hfound(-1), m_ccount(0)
{
- in_handler= FALSE;
m_frame= (Item **)sql_alloc(fsize * sizeof(Item*));
m_handler= (sp_handler_t *)sql_alloc(hmax * sizeof(sp_handler_t));
m_hstack= (uint *)sql_alloc(hmax * sizeof(uint));
+ m_in_handler= (uint *)sql_alloc(hmax * sizeof(uint));
m_cstack= (sp_cursor **)sql_alloc(cmax * sizeof(sp_cursor *));
m_saved.empty();
}
@@ -45,31 +46,18 @@ int
sp_rcontext::set_item_eval(THD *thd, uint idx, Item **item_addr,
enum_field_types type)
{
- extern Item *sp_eval_func_item(THD *thd, Item **it, enum_field_types type,
- Item *reuse, bool use_callers_arena);
Item *it;
Item *reuse_it;
- Item *old_item_next;
/* sp_eval_func_item will use callers_arena */
- Item *old_free_list= thd->spcont->callers_arena->free_list;
int res;
- LINT_INIT(old_item_next);
- if ((reuse_it= get_item(idx)))
- old_item_next= reuse_it->next;
+ reuse_it= get_item(idx);
it= sp_eval_func_item(thd, item_addr, type, reuse_it, TRUE);
if (! it)
res= -1;
else
{
res= 0;
- if (reuse_it && it == reuse_it)
- {
- // A reused item slot, where the constructor put it in the free_list,
- // so we have to restore the list.
- thd->spcont->callers_arena->free_list= old_free_list;
- it->next= old_item_next;
- }
set_item(idx, it);
}
@@ -80,8 +68,6 @@ bool
sp_rcontext::find_handler(uint sql_errno,
MYSQL_ERROR::enum_warning_level level)
{
- if (in_handler)
- return 0; // Already executing a handler
if (m_hfound >= 0)
return 1; // Already got one
@@ -91,6 +77,13 @@ sp_rcontext::find_handler(uint sql_errno,
while (i--)
{
sp_cond_type_t *cond= m_handler[i].cond;
+ int j= m_ihsp;
+
+ while (j--)
+ if (m_in_handler[j] == m_handler[i].handler)
+ break;
+ if (j >= 0)
+ continue; // Already executing this handler
switch (cond->type)
{
@@ -170,7 +163,8 @@ sp_rcontext::pop_cursors(uint count)
*/
sp_cursor::sp_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i)
- :m_lex_keeper(lex_keeper), m_prot(NULL), m_isopen(0), m_current_row(NULL),
+ :m_lex_keeper(lex_keeper),
+ server_side_cursor(NULL),
m_i(i)
{
/*
@@ -182,59 +176,37 @@ sp_cursor::sp_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i)
/*
- pre_open cursor
+ Open an SP cursor
SYNOPSIS
- pre_open()
- THD Thread handler
+ open()
+ THD Thread handler
- NOTES
- We have to open cursor in two steps to make it easy for sp_instr_copen
- to reuse the sp_instr::exec_stmt() code.
- If this function returns 0, post_open should not be called
RETURN
- 0 ERROR
+ 0 in case of success, -1 otherwise
*/
-sp_lex_keeper*
-sp_cursor::pre_open(THD *thd)
+int
+sp_cursor::open(THD *thd)
{
- if (m_isopen)
+ if (server_side_cursor)
{
my_message(ER_SP_CURSOR_ALREADY_OPEN, ER(ER_SP_CURSOR_ALREADY_OPEN),
MYF(0));
- return NULL;
+ return -1;
}
- init_alloc_root(&m_mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
- if ((m_prot= new Protocol_cursor(thd, &m_mem_root)) == NULL)
- return NULL;
-
- /* Save for execution. Will be restored in post_open */
- m_oprot= thd->protocol;
- m_nseof= thd->net.no_send_eof;
-
- /* Change protocol for execution */
- thd->protocol= m_prot;
- thd->net.no_send_eof= TRUE;
- return m_lex_keeper;
-}
-
-
-void
-sp_cursor::post_open(THD *thd, my_bool was_opened)
-{
- thd->net.no_send_eof= m_nseof; // Restore the originals
- thd->protocol= m_oprot;
- if ((m_isopen= was_opened))
- m_current_row= m_prot->data;
+ if (mysql_open_cursor(thd, (uint) ALWAYS_MATERIALIZED_CURSOR, &result,
+ &server_side_cursor))
+ return -1;
+ return 0;
}
int
sp_cursor::close(THD *thd)
{
- if (! m_isopen)
+ if (! server_side_cursor)
{
my_message(ER_SP_CURSOR_NOT_OPEN, ER(ER_SP_CURSOR_NOT_OPEN), MYF(0));
return -1;
@@ -247,106 +219,82 @@ sp_cursor::close(THD *thd)
void
sp_cursor::destroy()
{
- if (m_prot)
- {
- delete m_prot;
- m_prot= NULL;
- free_root(&m_mem_root, MYF(0));
- }
- m_isopen= FALSE;
+ delete server_side_cursor;
+ server_side_cursor= 0;
}
+
int
sp_cursor::fetch(THD *thd, List<struct sp_pvar> *vars)
{
- List_iterator_fast<struct sp_pvar> li(*vars);
- sp_pvar_t *pv;
- MYSQL_ROW row;
- uint fldcount;
-
- if (! m_isopen)
+ if (! server_side_cursor)
{
my_message(ER_SP_CURSOR_NOT_OPEN, ER(ER_SP_CURSOR_NOT_OPEN), MYF(0));
return -1;
}
- if (m_current_row == NULL)
+ if (vars->elements != result.get_field_count())
{
- my_message(ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA), MYF(0));
+ my_message(ER_SP_WRONG_NO_OF_FETCH_ARGS,
+ ER(ER_SP_WRONG_NO_OF_FETCH_ARGS), MYF(0));
return -1;
}
- row= m_current_row->data;
- for (fldcount= 0 ; (pv= li++) ; fldcount++)
- {
- Item *it;
- Item *reuse;
- uint rsize;
- Item *old_item_next;
- Item *old_free_list= thd->free_list;
- const char *s;
- LINT_INIT(old_item_next);
-
- if (fldcount >= m_prot->get_field_count())
- {
- my_message(ER_SP_WRONG_NO_OF_FETCH_ARGS,
- ER(ER_SP_WRONG_NO_OF_FETCH_ARGS), MYF(0));
- return -1;
- }
+ result.set_spvar_list(vars);
- if ((reuse= thd->spcont->get_item(pv->offset)))
- old_item_next= reuse->next;
+ /* Attempt to fetch one row */
+ if (server_side_cursor->is_open())
+ server_side_cursor->fetch(1);
- s= row[fldcount];
- if (!s)
- it= new(reuse, &rsize) Item_null();
- else
- {
- /*
- Length of data can be calculated as:
- pointer_to_next_not_null_object - s -1
- where the last -1 is to remove the end \0
- */
- uint len;
- MYSQL_ROW next= row+fldcount+1;
- while (!*next) // Skip nulls
- next++;
- len= (*next -s)-1;
- switch (sp_map_result_type(pv->type)) {
- case INT_RESULT:
- it= new(reuse, &rsize) Item_int(s);
- break;
- case REAL_RESULT:
- it= new(reuse, &rsize) Item_float(s, len);
- break;
- case DECIMAL_RESULT:
- it= new(reuse, &rsize) Item_decimal(s, len, thd->db_charset);
- break;
- case STRING_RESULT:
- /* TODO: Document why we do an extra copy of the string 's' here */
- it= new(reuse, &rsize) Item_string(thd->strmake(s, len), len,
- thd->db_charset);
- break;
- case ROW_RESULT:
- default:
- DBUG_ASSERT(0);
- }
- }
- it->rsize= rsize;
- if (reuse && it == reuse)
- {
- // A reused item slot, where the constructor put it in the free_list,
- // so we have to restore the list.
- thd->free_list= old_free_list;
- it->next= old_item_next;
- }
- thd->spcont->set_item(pv->offset, it);
- }
- if (fldcount < m_prot->get_field_count())
+ /*
+ If the cursor was pointing after the last row, the fetch will
+ close it instead of sending any rows.
+ */
+ if (! server_side_cursor->is_open())
{
- my_message(ER_SP_WRONG_NO_OF_FETCH_ARGS,
- ER(ER_SP_WRONG_NO_OF_FETCH_ARGS), MYF(0));
+ my_message(ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA), MYF(0));
return -1;
}
- m_current_row= m_current_row->next;
+
return 0;
}
+
+
+/***************************************************************************
+ Select_fetch_into_spvars
+****************************************************************************/
+
+int Select_fetch_into_spvars::prepare(List<Item> &fields, SELECT_LEX_UNIT *u)
+{
+ /*
+ Cache the number of columns in the result set in order to easily
+ return an error if column count does not match value count.
+ */
+ field_count= fields.elements;
+ return select_result_interceptor::prepare(fields, u);
+}
+
+
+bool Select_fetch_into_spvars::send_data(List<Item> &items)
+{
+ List_iterator_fast<struct sp_pvar> pv_iter(*spvar_list);
+ List_iterator_fast<Item> item_iter(items);
+ sp_pvar_t *pv;
+ Item *item;
+
+ /* Must be ensured by the caller */
+ DBUG_ASSERT(spvar_list->elements == items.elements);
+
+ /*
+ Assign the row fetched from a server side cursor to stored
+ procedure variables.
+ */
+ for (; pv= pv_iter++, item= item_iter++; )
+ {
+ Item *reuse= thd->spcont->get_item(pv->offset);
+ /* Evaluate a new item on the arena of the calling instruction */
+ Item *it= sp_eval_func_item(thd, &item, pv->type, reuse, TRUE);
+
+ thd->spcont->set_item(pv->offset, it);
+ }
+ return FALSE;
+}
diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h
index 36380952e5d..22fa4f6e865 100644
--- a/sql/sp_rcontext.h
+++ b/sql/sp_rcontext.h
@@ -58,7 +58,6 @@ class sp_rcontext : public Sql_alloc
public:
- bool in_handler;
/*
Arena used to (re) allocate items on . E.g. reallocate INOUT/OUT
SP parameters when they don't fit into prealloced items. This
@@ -169,6 +168,18 @@ class sp_rcontext : public Sql_alloc
return m_hstack[--m_hsp];
}
+ inline void
+ enter_handler(int hid)
+ {
+ m_in_handler[m_ihsp++]= hid;
+ }
+
+ inline void
+ exit_handler()
+ {
+ m_ihsp-= 1;
+ }
+
// Save variables starting at fp and up
void
save_variables(uint fp);
@@ -203,12 +214,14 @@ private:
Item *m_result; // For FUNCTIONs
- sp_handler_t *m_handler;
- uint m_hcount;
- uint *m_hstack;
- uint m_hsp;
- int m_hfound; // Set by find_handler; -1 if not found
- List<Item> m_saved; // Saved variables
+ sp_handler_t *m_handler; // Visible handlers
+ uint m_hcount; // Stack pointer for m_handler
+ uint *m_hstack; // Return stack for continue handlers
+ uint m_hsp; // Stack pointer for m_hstack
+ uint *m_in_handler; // Active handler, for recursion check
+ uint m_ihsp; // Stack pointer for m_in_handler
+ int m_hfound; // Set by find_handler; -1 if not found
+ List<Item> m_saved; // Saved variables during handler exec.
sp_cursor **m_cstack;
uint m_ccount;
@@ -216,6 +229,27 @@ private:
}; // class sp_rcontext : public Sql_alloc
+/*
+ An interceptor of cursor result set used to implement
+ FETCH <cname> INTO <varlist>.
+*/
+
+class Select_fetch_into_spvars: public select_result_interceptor
+{
+ List<struct sp_pvar> *spvar_list;
+ uint field_count;
+public:
+ uint get_field_count() { return field_count; }
+ void set_spvar_list(List<struct sp_pvar> *vars) { spvar_list= vars; }
+
+ virtual bool send_eof() { return FALSE; }
+ virtual bool send_data(List<Item> &items);
+ virtual int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
+};
+
+
+/* A mediator between stored procedures and server side cursors */
+
class sp_cursor : public Sql_alloc
{
public:
@@ -227,12 +261,11 @@ public:
destroy();
}
- // We have split this in two to make it easy for sp_instr_copen
- // to reuse the sp_instr::exec_stmt() code.
sp_lex_keeper *
- pre_open(THD *thd);
- void
- post_open(THD *thd, my_bool was_opened);
+ get_lex_keeper() { return m_lex_keeper; }
+
+ int
+ open(THD *thd);
int
close(THD *thd);
@@ -240,7 +273,7 @@ public:
inline my_bool
is_open()
{
- return m_isopen;
+ return test(server_side_cursor);
}
int
@@ -251,18 +284,13 @@ public:
{
return m_i;
}
-
+
private:
- MEM_ROOT m_mem_root; // My own mem_root
+ Select_fetch_into_spvars result;
sp_lex_keeper *m_lex_keeper;
- Protocol_cursor *m_prot;
- my_bool m_isopen;
- my_bool m_nseof; // Original no_send_eof
- Protocol *m_oprot; // Original protcol
- MYSQL_ROWS *m_current_row;
+ Server_side_cursor *server_side_cursor;
sp_instr_cpush *m_i; // My push instruction
-
void
destroy();
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index c7a6387aab1..7a87f01258a 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -692,8 +692,8 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
SYNOPSIS
acl_getroot()
thd thread handle. If all checks are OK,
- thd->priv_user, thd->master_access are updated.
- thd->host, thd->ip, thd->user are used for checks.
+ thd->security_ctx->priv_user/master_access are updated.
+ thd->security_ctx->host/ip/user are used for checks.
mqh user resources; on success mqh is reset, else
unchanged
passwd scrambled & crypted password, received from client
@@ -718,6 +718,7 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
ulong user_access= NO_ACCESS;
int res= 1;
ACL_USER *acl_user= 0;
+ Security_context *sctx= thd->security_ctx;
DBUG_ENTER("acl_getroot");
if (!initialized)
@@ -725,9 +726,7 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
/*
here if mysqld's been started with --skip-grant-tables option.
*/
- thd->priv_user= (char *) ""; // privileges for
- *thd->priv_host= '\0'; // the user are unknown
- thd->master_access= ~NO_ACCESS; // everything is allowed
+ sctx->skip_grants();
bzero((char*) mqh, sizeof(*mqh));
DBUG_RETURN(0);
}
@@ -743,9 +742,9 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
for (uint i=0 ; i < acl_users.elements ; i++)
{
ACL_USER *acl_user_tmp= dynamic_element(&acl_users,i,ACL_USER*);
- if (!acl_user_tmp->user || !strcmp(thd->user, acl_user_tmp->user))
+ if (!acl_user_tmp->user || !strcmp(sctx->user, acl_user_tmp->user))
{
- if (compare_hostname(&acl_user_tmp->host, thd->host, thd->ip))
+ if (compare_hostname(&acl_user_tmp->host, sctx->host, sctx->ip))
{
/* check password: it should be empty or valid */
if (passwd_len == acl_user_tmp->salt_len)
@@ -892,14 +891,14 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
break;
#endif /* HAVE_OPENSSL */
}
- thd->master_access= user_access;
- thd->priv_user= acl_user->user ? thd->user : (char *) "";
+ sctx->master_access= user_access;
+ sctx->priv_user= acl_user->user ? sctx->user : (char *) "";
*mqh= acl_user->user_resource;
if (acl_user->host.hostname)
- strmake(thd->priv_host, acl_user->host.hostname, MAX_HOSTNAME);
+ strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME);
else
- *thd->priv_host= 0;
+ *sctx->priv_host= 0;
}
VOID(pthread_mutex_unlock(&acl_cache->lock));
DBUG_RETURN(res);
@@ -907,47 +906,62 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
/*
- * This is like acl_getroot() above, but it doesn't check password,
- * and we don't care about the user resources.
- * Used to get access rights for SQL SECURITY DEFINER invocation of
- * stored procedures.
- */
-int acl_getroot_no_password(THD *thd)
+ This is like acl_getroot() above, but it doesn't check password,
+ and we don't care about the user resources.
+
+ SYNOPSIS
+ acl_getroot_no_password()
+ sctx Context which should be initialized
+ user user name
+ host host name
+ ip IP
+ db current data base name
+
+ RETURN
+ FALSE OK
+ TRUE Error
+*/
+
+bool acl_getroot_no_password(Security_context *sctx, char *user, char *host,
+ char *ip, char *db)
{
int res= 1;
uint i;
ACL_USER *acl_user= 0;
DBUG_ENTER("acl_getroot_no_password");
+ sctx->user= user;
+ sctx->host= host;
+ sctx->ip= ip;
+ sctx->host_or_ip= host ? host : (ip ? ip : "");
+
if (!initialized)
{
- /*
+ /*
here if mysqld's been started with --skip-grant-tables option.
*/
- thd->priv_user= (char *) ""; // privileges for
- *thd->priv_host= '\0'; // the user are unknown
- thd->master_access= ~NO_ACCESS; // everything is allowed
- DBUG_RETURN(0);
+ sctx->skip_grants();
+ DBUG_RETURN(FALSE);
}
VOID(pthread_mutex_lock(&acl_cache->lock));
- thd->master_access= 0;
- thd->db_access= 0;
+ sctx->master_access= 0;
+ sctx->db_access= 0;
/*
Find acl entry in user database.
This is specially tailored to suit the check we do for CALL of
- a stored procedure; thd->user is set to what is actually a
+ a stored procedure; user is set to what is actually a
priv_user, which can be ''.
*/
for (i=0 ; i < acl_users.elements ; i++)
{
acl_user= dynamic_element(&acl_users,i,ACL_USER*);
- if ((!acl_user->user && (!thd->user || !thd->user[0])) ||
- (acl_user->user && strcmp(thd->user, acl_user->user) == 0))
+ if ((!acl_user->user && (!user || !user[0])) ||
+ (acl_user->user && strcmp(user, acl_user->user) == 0))
{
- if (compare_hostname(&acl_user->host, thd->host, thd->ip))
+ if (compare_hostname(&acl_user->host, host, ip))
{
res= 0;
break;
@@ -961,25 +975,25 @@ int acl_getroot_no_password(THD *thd)
{
ACL_DB *acl_db= dynamic_element(&acl_dbs, i, ACL_DB*);
if (!acl_db->user ||
- (thd->user && thd->user[0] && !strcmp(thd->user, acl_db->user)))
+ (user && user[0] && !strcmp(user, acl_db->user)))
{
- if (compare_hostname(&acl_db->host, thd->host, thd->ip))
+ if (compare_hostname(&acl_db->host, host, ip))
{
- if (!acl_db->db || (thd->db && !strcmp(acl_db->db, thd->db)))
+ if (!acl_db->db || (db && !strcmp(acl_db->db, db)))
{
- thd->db_access= acl_db->access;
+ sctx->db_access= acl_db->access;
break;
}
}
}
}
- thd->master_access= acl_user->access;
- thd->priv_user= acl_user->user ? thd->user : (char *) "";
+ sctx->master_access= acl_user->access;
+ sctx->priv_user= acl_user->user ? user : (char *) "";
if (acl_user->host.hostname)
- strmake(thd->priv_host, acl_user->host.hostname, MAX_HOSTNAME);
+ strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME);
else
- *thd->priv_host= 0;
+ *sctx->priv_host= 0;
}
VOID(pthread_mutex_unlock(&acl_cache->lock));
DBUG_RETURN(res);
@@ -1333,13 +1347,14 @@ bool check_change_password(THD *thd, const char *host, const char *user,
return(1);
}
if (!thd->slave_thread &&
- (strcmp(thd->user,user) ||
- my_strcasecmp(system_charset_info, host, thd->priv_host)))
+ (strcmp(thd->security_ctx->user, user) ||
+ my_strcasecmp(system_charset_info, host,
+ thd->security_ctx->priv_host)))
{
if (check_access(thd, UPDATE_ACL, "mysql",0,1,0,0))
return(1);
}
- if (!thd->slave_thread && !thd->user[0])
+ if (!thd->slave_thread && !thd->security_ctx->user[0])
{
my_message(ER_PASSWORD_ANONYMOUS_USER, ER(ER_PASSWORD_ANONYMOUS_USER),
MYF(0));
@@ -1472,7 +1487,7 @@ bool is_acl_user(const char *host, const char *user)
{
bool res;
VOID(pthread_mutex_lock(&acl_cache->lock));
- res= find_acl_user(host, user, TRUE);
+ res= find_acl_user(host, user, TRUE) != NULL;
VOID(pthread_mutex_unlock(&acl_cache->lock));
return res;
}
@@ -1645,9 +1660,10 @@ static bool update_user_table(THD *thd, TABLE *table,
static bool test_if_create_new_users(THD *thd)
{
- bool create_new_users= test(thd->master_access & INSERT_ACL) ||
+ Security_context *sctx= thd->security_ctx;
+ bool create_new_users= test(sctx->master_access & INSERT_ACL) ||
(!opt_safe_user_create &&
- test(thd->master_access & CREATE_USER_ACL));
+ test(sctx->master_access & CREATE_USER_ACL));
if (!create_new_users)
{
TABLE_LIST tl;
@@ -1657,8 +1673,8 @@ static bool test_if_create_new_users(THD *thd)
tl.table_name= (char*) "user";
create_new_users= 1;
- db_access=acl_get(thd->host, thd->ip,
- thd->priv_user, tl.db, 0);
+ db_access=acl_get(sctx->host, sctx->ip,
+ sctx->priv_user, tl.db, 0);
if (!(db_access & INSERT_ACL))
{
if (check_grant(thd, INSERT_ACL, &tl, 0, UINT_MAX, 1))
@@ -1737,7 +1753,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
else if (!can_create_user)
{
my_error(ER_CANT_CREATE_USER_WITH_GRANT, MYF(0),
- thd->user, thd->host_or_ip);
+ thd->security_ctx->user, thd->security_ctx->host_or_ip);
goto end;
}
old_row_exists = 0;
@@ -2449,7 +2465,8 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
byte user_key[MAX_KEY_LENGTH];
DBUG_ENTER("replace_table_table");
- strxmov(grantor, thd->user, "@", thd->host_or_ip, NullS);
+ strxmov(grantor, thd->security_ctx->user, "@",
+ thd->security_ctx->host_or_ip, NullS);
/*
The following should always succeed as new users are created before
@@ -2571,7 +2588,8 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name,
DBUG_RETURN(-1);
}
- strxmov(grantor, thd->user, "@", thd->host_or_ip, NullS);
+ strxmov(grantor, thd->security_ctx->user, "@",
+ thd->security_ctx->host_or_ip, NullS);
/*
The following should always succeed as new users are created before
@@ -2762,7 +2780,8 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
get_privilege_desc(command, sizeof(command),
table_list->grant.want_privilege);
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
- command, thd->priv_user, thd->host_or_ip, table_list->alias);
+ command, thd->security_ctx->priv_user,
+ thd->security_ctx->host_or_ip, table_list->alias);
DBUG_RETURN(-1);
}
}
@@ -3486,11 +3505,11 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
uint show_table, uint number, bool no_errors)
{
TABLE_LIST *table;
- char *user = thd->priv_user;
+ Security_context *sctx= thd->security_ctx;
DBUG_ENTER("check_grant");
DBUG_ASSERT(number > 0);
- want_access&= ~thd->master_access;
+ want_access&= ~sctx->master_access;
if (!want_access)
DBUG_RETURN(0); // ok
@@ -3508,8 +3527,9 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
table->grant.want_privilege= 0;
continue; // Already checked
}
- if (!(grant_table= table_hash_search(thd->host,thd->ip,
- table->db,user, table->table_name,0)))
+ if (!(grant_table= table_hash_search(sctx->host, sctx->ip,
+ table->db, sctx->priv_user,
+ table->table_name,0)))
{
want_access &= ~table->grant.privilege;
goto err; // No grants
@@ -3543,8 +3563,8 @@ err:
get_privilege_desc(command, sizeof(command), want_access);
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
command,
- thd->priv_user,
- thd->host_or_ip,
+ sctx->priv_user,
+ sctx->host_or_ip,
table ? table->table_name : "unknown");
}
DBUG_RETURN(1);
@@ -3555,6 +3575,7 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
const char *db_name, const char *table_name,
const char *name, uint length, uint show_tables)
{
+ Security_context *sctx= thd->security_ctx;
GRANT_TABLE *grant_table;
GRANT_COLUMN *grant_column;
ulong want_access= grant->want_privilege & ~grant->privilege;
@@ -3571,8 +3592,8 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
if (grant->version != grant_version)
{
grant->grant_table=
- table_hash_search(thd->host, thd->ip, db_name,
- thd->priv_user,
+ table_hash_search(sctx->host, sctx->ip, db_name,
+ sctx->priv_user,
table_name, 0); /* purecov: inspected */
grant->version= grant_version; /* purecov: inspected */
}
@@ -3601,8 +3622,8 @@ err:
get_privilege_desc(command, sizeof(command), want_access);
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
command,
- thd->priv_user,
- thd->host_or_ip,
+ sctx->priv_user,
+ sctx->host_or_ip,
name,
table_name);
}
@@ -3614,6 +3635,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant,
const char* db_name, const char *table_name,
Field_iterator *fields)
{
+ Security_context *sctx= thd->security_ctx;
GRANT_TABLE *grant_table;
GRANT_COLUMN *grant_column;
@@ -3630,8 +3652,8 @@ bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant,
if (grant->version != grant_version)
{
grant->grant_table=
- table_hash_search(thd->host, thd->ip, db_name,
- thd->priv_user,
+ table_hash_search(sctx->host, sctx->ip, db_name,
+ sctx->priv_user,
table_name, 0); /* purecov: inspected */
grant->version= grant_version; /* purecov: inspected */
}
@@ -3657,8 +3679,8 @@ err2:
get_privilege_desc(command, sizeof(command), want_access);
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
command,
- thd->priv_user,
- thd->host_or_ip,
+ sctx->priv_user,
+ sctx->host_or_ip,
fields->name(),
table_name);
return 1;
@@ -3673,11 +3695,12 @@ err2:
bool check_grant_db(THD *thd,const char *db)
{
+ Security_context *sctx= thd->security_ctx;
char helping [NAME_LEN+USERNAME_LENGTH+2];
uint len;
bool error= 1;
- len= (uint) (strmov(strmov(helping,thd->priv_user)+1,db)-helping)+ 1;
+ len= (uint) (strmov(strmov(helping, sctx->priv_user) + 1, db) - helping) + 1;
rw_rdlock(&LOCK_grant);
for (uint idx=0 ; idx < column_priv_hash.records ; idx++)
@@ -3686,7 +3709,7 @@ bool check_grant_db(THD *thd,const char *db)
idx);
if (len < grant_table->key_length &&
!memcmp(grant_table->hash_key,helping,len) &&
- compare_hostname(&grant_table->host, thd->host, thd->ip))
+ compare_hostname(&grant_table->host, sctx->host, sctx->ip))
{
error=0; // Found match
break;
@@ -3714,15 +3737,16 @@ bool check_grant_db(THD *thd,const char *db)
1 Error: User did not have the requested privielges
****************************************************************************/
-bool check_grant_routine(THD *thd, ulong want_access,
+bool check_grant_routine(THD *thd, ulong want_access,
TABLE_LIST *procs, bool is_proc, bool no_errors)
{
TABLE_LIST *table;
- char *user= thd->priv_user;
- char *host= thd->priv_host;
+ Security_context *sctx= thd->security_ctx;
+ char *user= sctx->priv_user;
+ char *host= sctx->priv_host;
DBUG_ENTER("check_grant_routine");
- want_access&= ~thd->master_access;
+ want_access&= ~sctx->master_access;
if (!want_access)
DBUG_RETURN(0); // ok
@@ -3730,7 +3754,7 @@ bool check_grant_routine(THD *thd, ulong want_access,
for (table= procs; table; table= table->next_global)
{
GRANT_NAME *grant_proc;
- if ((grant_proc= routine_hash_search(host,thd->ip, table->db, user,
+ if ((grant_proc= routine_hash_search(host, sctx->ip, table->db, user,
table->table_name, is_proc, 0)))
table->grant.privilege|= grant_proc->privs;
@@ -3785,9 +3809,12 @@ bool check_routine_level_acl(THD *thd, const char *db, const char *name,
if (grant_option)
{
GRANT_NAME *grant_proc;
+ Security_context *sctx= thd->security_ctx;
rw_rdlock(&LOCK_grant);
- if ((grant_proc= routine_hash_search(thd->priv_host, thd->ip, db,
- thd->priv_user, name, is_proc, 0)))
+ if ((grant_proc= routine_hash_search(sctx->priv_host,
+ sctx->ip, db,
+ sctx->priv_user,
+ name, is_proc, 0)))
no_routine_acl= !(grant_proc->privs & SHOW_PROC_ACLS);
rw_unlock(&LOCK_grant);
}
@@ -3802,7 +3829,7 @@ bool check_routine_level_acl(THD *thd, const char *db, const char *name,
ulong get_table_grant(THD *thd, TABLE_LIST *table)
{
ulong privilege;
- char *user = thd->priv_user;
+ Security_context *sctx= thd->security_ctx;
const char *db = table->db ? table->db : thd->db;
GRANT_TABLE *grant_table;
@@ -3810,7 +3837,7 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table)
#ifdef EMBEDDED_LIBRARY
grant_table= NULL;
#else
- grant_table= table_hash_search(thd->host, thd->ip, db, user,
+ grant_table= table_hash_search(sctx->host, sctx->ip, db, sctx->priv_user,
table->table_name, 0);
#endif
table->grant.grant_table=grant_table; // Remember for column test
@@ -3853,9 +3880,10 @@ ulong get_column_grant(THD *thd, GRANT_INFO *grant,
/* reload table if someone has modified any grants */
if (grant->version != grant_version)
{
+ Security_context *sctx= thd->security_ctx;
grant->grant_table=
- table_hash_search(thd->host, thd->ip, db_name,
- thd->priv_user,
+ table_hash_search(sctx->host, sctx->ip,
+ db_name, sctx->priv_user,
table_name, 0); /* purecov: inspected */
grant->version= grant_version; /* purecov: inspected */
}
@@ -5425,22 +5453,24 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool is_proc)
{
+ Security_context *sctx= thd->security_ctx;
LEX_USER *combo;
TABLE_LIST tables[1];
List<LEX_USER> user_list;
bool result;
- DBUG_ENTER("sp_grant_privileges");
+ DBUG_ENTER("sp_grant_privileges");
if (!(combo=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
DBUG_RETURN(TRUE);
- combo->user.str= thd->user;
+ combo->user.str= sctx->user;
- if (!find_acl_user(combo->host.str=(char*)thd->host_or_ip, combo->user.str,
+ if (!find_acl_user(combo->host.str=(char*)sctx->host_or_ip, combo->user.str,
+ FALSE) &&
+ !find_acl_user(combo->host.str=(char*)sctx->host, combo->user.str,
FALSE) &&
- !find_acl_user(combo->host.str=(char*)thd->host, combo->user.str,
+ !find_acl_user(combo->host.str=(char*)sctx->ip, combo->user.str,
FALSE) &&
- !find_acl_user(combo->host.str=(char*)thd->ip, combo->user.str, FALSE) &&
!find_acl_user(combo->host.str=(char*)"%", combo->user.str, FALSE))
DBUG_RETURN(TRUE);
@@ -5557,7 +5587,7 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
char buff[100];
TABLE *table= tables->table;
bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1,0);
- char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%";
+ char *curr_host= thd->security_ctx->priv_host_name();
DBUG_ENTER("fill_schema_user_privileges");
for (counter=0 ; counter < acl_users.elements ; counter++)
@@ -5570,7 +5600,7 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
host= "";
if (no_global_access &&
- (strcmp(thd->priv_user, user) ||
+ (strcmp(thd->security_ctx->priv_user, user) ||
my_strcasecmp(system_charset_info, curr_host, host)))
continue;
@@ -5610,7 +5640,7 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
char buff[100];
TABLE *table= tables->table;
bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1,0);
- char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%";
+ char *curr_host= thd->security_ctx->priv_host_name();
DBUG_ENTER("fill_schema_schema_privileges");
for (counter=0 ; counter < acl_dbs.elements ; counter++)
@@ -5624,7 +5654,7 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
host= "";
if (no_global_access &&
- (strcmp(thd->priv_user, user) ||
+ (strcmp(thd->security_ctx->priv_user, user) ||
my_strcasecmp(system_charset_info, curr_host, host)))
continue;
@@ -5665,7 +5695,7 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
char buff[100];
TABLE *table= tables->table;
bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1,0);
- char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%";
+ char *curr_host= thd->security_ctx->priv_host_name();
DBUG_ENTER("fill_schema_table_privileges");
for (index=0 ; index < column_priv_hash.records ; index++)
@@ -5677,7 +5707,7 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
user= "";
if (no_global_access &&
- (strcmp(thd->priv_user, user) ||
+ (strcmp(thd->security_ctx->priv_user, user) ||
my_strcasecmp(system_charset_info, curr_host,
grant_table->host.hostname)))
continue;
@@ -5727,7 +5757,7 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
char buff[100];
TABLE *table= tables->table;
bool no_global_access= check_access(thd, SELECT_ACL, "mysql",0,1,1,0);
- char *curr_host= thd->priv_host ? thd->priv_host : (char *) "%";
+ char *curr_host= thd->security_ctx->priv_host_name();
DBUG_ENTER("fill_schema_table_privileges");
for (index=0 ; index < column_priv_hash.records ; index++)
@@ -5739,7 +5769,7 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
user= "";
if (no_global_access &&
- (strcmp(thd->priv_user, user) ||
+ (strcmp(thd->security_ctx->priv_user, user) ||
my_strcasecmp(system_charset_info, curr_host,
grant_table->host.hostname)))
continue;
@@ -5803,6 +5833,7 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
const char *db, const char *table)
{
+ Security_context *sctx= thd->security_ctx;
/* --skip-grants */
if (!initialized)
{
@@ -5811,13 +5842,13 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
}
/* global privileges */
- grant->privilege= thd->master_access;
+ grant->privilege= sctx->master_access;
- if (!thd->priv_user)
+ if (!sctx->priv_user)
return; // it is slave
/* db privileges */
- grant->privilege|= acl_get(thd->host, thd->ip, thd->priv_user, db, 0);
+ grant->privilege|= acl_get(sctx->host, sctx->ip, sctx->priv_user, db, 0);
if (!grant_option)
return;
@@ -5827,8 +5858,8 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
{
rw_rdlock(&LOCK_grant);
grant->grant_table=
- table_hash_search(thd->host, thd->ip, db,
- thd->priv_user,
+ table_hash_search(sctx->host, sctx->ip, db,
+ sctx->priv_user,
table, 0); /* purecov: inspected */
grant->version= grant_version; /* purecov: inspected */
rw_unlock(&LOCK_grant);
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index 0d739e860e9..0a9c6ba785f 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -182,7 +182,8 @@ ulong acl_get(const char *host, const char *ip,
const char *user, const char *db, my_bool db_is_pattern);
int acl_getroot(THD *thd, USER_RESOURCES *mqh, const char *passwd,
uint passwd_len);
-int acl_getroot_no_password(THD *thd);
+bool acl_getroot_no_password(Security_context *sctx, char *user, char *host,
+ char *ip, char *db);
bool acl_check_host(const char *host, const char *ip);
bool check_change_password(THD *thd, const char *host, const char *user,
char *password, uint password_len);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 38a9d259d24..1de9411cad0 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1327,6 +1327,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
table->keys_in_use_for_query= table->s->keys_in_use;
table->insert_values= 0;
table->used_keys= table->s->keys_for_keyread;
+ table->fulltext_searched= 0;
+ table->file->ft_handler= 0;
if (table->timestamp_field)
table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
table_list->updatable= 1; // It is not derived table nor non-updatable VIEW
@@ -2146,7 +2148,7 @@ static bool check_lock_and_start_stmt(THD *thd, TABLE *table,
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),table->alias);
DBUG_RETURN(1);
}
- if ((error=table->file->start_stmt(thd)))
+ if ((error=table->file->start_stmt(thd, lock_type)))
{
table->file->print_error(error,MYF(0));
DBUG_RETURN(1);
@@ -2953,6 +2955,18 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
belongs - differs from 'table_list' only for
NATURAL_USING joins.
+ DESCRIPTION
+ Find a field in a table reference depending on the type of table
+ reference. There are three types of table references with respect
+ to the representation of their result columns:
+ - an array of Field_translator objects for MERGE views and some
+ information_schema tables,
+ - an array of Field objects (and possibly a name hash) for stored
+ tables,
+ - a list of Natural_join_column objects for NATURAL/USING joins.
+ This procedure detects the type of the table reference 'table_list'
+ and calls the corresponding search routine.
+
RETURN
0 field is not found
view_ref_found found value in VIEW (real result is in *ref)
@@ -2976,16 +2990,29 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
/*
Check that the table and database that qualify the current field name
- are the same as the table we are going to search for the field.
- This is done differently for NATURAL/USING joins or nested joins that
- are operands of NATURAL/USING joins because there we can't simply
- compare the qualifying table and database names with the ones of
- 'table_list' because each field in such a join may originate from a
- different table.
+ are the same as the table reference we are going to search for the field.
+
+ Exclude from the test below nested joins because the columns in a
+ nested join generally originate from different tables. Nested joins
+ also have no table name, except when a nested join is a merge view
+ or an information schema table.
+
+ We include explicitly table references with a 'field_translation' table,
+ because if there are views over natural joins we don't want to search
+ inside the view, but we want to search directly in the view columns
+ which are represented as a 'field_translation'.
+
TODO: Ensure that table_name, db_name and tables->db always points to
something !
*/
- if (!(table_list->nested_join && table_list->join_columns) &&
+ if (/* Exclude nested joins. */
+ (!table_list->nested_join ||
+ /* Include merge views and information schema tables. */
+ table_list->field_translation) &&
+ /*
+ Test if the field qualifiers match the table reference we plan
+ to search.
+ */
table_name && table_name[0] &&
(my_strcasecmp(table_alias_charset, table_list->alias, table_name) ||
(db_name && db_name[0] && table_list->db && table_list->db[0] &&
@@ -2993,25 +3020,45 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(0);
*actual_table= NULL;
+
if (table_list->field_translation)
{
+ /* 'table_list' is a view or an information schema table. */
if ((fld= find_field_in_view(thd, table_list, name, item_name, length,
ref, check_grants_view,
register_tree_change)))
*actual_table= table_list;
}
- else if (table_list->nested_join && table_list->join_columns)
+ else if (!table_list->nested_join)
+ {
+ /* 'table_list' is a stored table. */
+ DBUG_ASSERT(table_list->table);
+ if ((fld= find_field_in_table(thd, table_list->table, name, length,
+ check_grants_table, allow_rowid,
+ cached_field_index_ptr)))
+ *actual_table= table_list;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ /* check for views with temporary table algorithm */
+ if (check_grants_view && table_list->view &&
+ fld && fld != WRONG_GRANT &&
+ check_grant_column(thd, &table_list->grant,
+ table_list->view_db.str,
+ table_list->view_name.str,
+ name, length))
+ fld= WRONG_GRANT;
+#endif
+ }
+ else
{
/*
- If this is a NATURAL/USING join, or an operand of such join which is a
- join itself, and the field name is qualified, then search for the field
- in the operands of the join.
+ 'table_list' is a NATURAL/USING join, or an operand of such join that
+ is a nested join itself.
+
+ If the field name we search for is qualified, then search for the field
+ in the table references used by NATURAL/USING the join.
*/
if (table_name && table_name[0])
{
- /*
- Qualified field; Search for it in the tables used by the natural join.
- */
List_iterator<TABLE_LIST> it(table_list->nested_join->join_list);
TABLE_LIST *table;
while ((table= it++))
@@ -3037,23 +3084,6 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
check_grants_table || check_grants_view,
register_tree_change, actual_table);
}
- else
- {
- if ((fld= find_field_in_table(thd, table_list->table, name, length,
- check_grants_table, allow_rowid,
- cached_field_index_ptr)))
- *actual_table= table_list;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- /* check for views with temporary table algorithm */
- if (check_grants_view && table_list->view &&
- fld && fld != WRONG_GRANT &&
- check_grant_column(thd, &table_list->grant,
- table_list->view_db.str,
- table_list->view_name.str,
- name, length))
- fld= WRONG_GRANT;
-#endif
- }
DBUG_RETURN(fld);
}
@@ -3364,9 +3394,9 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
for (uint i= 0; (item=li++); i++)
{
- if (field_name && item->type() == Item::FIELD_ITEM)
+ if (field_name && item->real_item()->type() == Item::FIELD_ITEM)
{
- Item_field *item_field= (Item_field*) item;
+ Item_ident *item_field= (Item_ident*) item;
/*
In case of group_concat() with ORDER BY condition in the QUERY
@@ -3466,7 +3496,7 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
}
}
}
- else if (!table_name && (item->eq(find,0) ||
+ else if (!table_name && (find->eq(item,0) ||
find->name && item->name &&
!my_strcasecmp(system_charset_info,
item->name,find->name)))
@@ -4617,7 +4647,8 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
VIEW_ANY_ACL)))
{
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), "ANY",
- thd->priv_user, thd->host_or_ip,
+ thd->security_ctx->priv_user,
+ thd->security_ctx->host_or_ip,
fld->field_name, field_table_name);
DBUG_RETURN(TRUE);
}
@@ -4805,9 +4836,6 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
}
DBUG_RETURN(test(thd->net.report_error));
-err:
- if (arena)
- thd->restore_active_arena(arena, &backup);
err_no_arena:
DBUG_RETURN(1);
}
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 1ca9db44cc7..f17825e6d2c 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1299,7 +1299,8 @@ void Query_cache::invalidate_locked_for_write(TABLE_LIST *tables_used)
DUMP(this);
for (; tables_used; tables_used= tables_used->next_local)
{
- if (tables_used->lock_type & (TL_WRITE_LOW_PRIORITY | TL_WRITE))
+ if (tables_used->lock_type & (TL_WRITE_LOW_PRIORITY | TL_WRITE) &&
+ tables_used->table)
invalidate_table(tables_used->table);
}
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 2699a4fa628..fc7ea6a2794 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -181,9 +181,10 @@ THD::THD()
spcont(NULL)
{
stmt_arena= this;
- host= user= priv_user= db= ip= 0;
+ db= 0;
catalog= (char*)"std"; // the only catalog we have for now
- host_or_ip= "connecting host";
+ main_security_ctx.init();
+ security_ctx= &main_security_ctx;
locked=some_tables_deleted=no_errors=password= 0;
query_start_used= 0;
count_cuted_fields= CHECK_FIELD_IGNORE;
@@ -236,9 +237,6 @@ THD::THD()
server_id = ::server_id;
slave_net = 0;
command=COM_CONNECT;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- db_access=NO_ACCESS;
-#endif
*scramble= '\0';
init();
@@ -426,12 +424,8 @@ THD::~THD()
ha_close_connection(this);
- DBUG_PRINT("info", ("freeing host"));
- if (host != my_localhost) // If not pointer to constant
- safeFree(host);
- if (user != delayed_user)
- safeFree(user);
- safeFree(ip);
+ DBUG_PRINT("info", ("freeing security context"));
+ main_security_ctx.destroy();
safeFree(db);
free_root(&warn_root,MYF(0));
#ifdef USING_TRANSACTIONS
@@ -1544,6 +1538,19 @@ void Query_arena::free_items()
}
+void Query_arena::set_query_arena(Query_arena *set)
+{
+ mem_root= set->mem_root;
+ free_list= set->free_list;
+ state= set->state;
+}
+
+
+void Query_arena::cleanup_stmt()
+{
+ DBUG_ASSERT("Query_arena::cleanup_stmt()" == "not implemented");
+}
+
/*
Statement functions
*/
@@ -1601,12 +1608,6 @@ void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
}
-void Statement::close_cursor()
-{
- DBUG_ASSERT("Statement::close_cursor()" == "not implemented");
-}
-
-
void THD::end_statement()
{
/* Cleanup SQL processing state to resuse this statement in next query. */
@@ -1648,13 +1649,6 @@ void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
DBUG_VOID_RETURN;
}
-void Query_arena::set_query_arena(Query_arena *set)
-{
- mem_root= set->mem_root;
- free_list= set->free_list;
- state= set->state;
-}
-
Statement::~Statement()
{
/*
@@ -1723,9 +1717,11 @@ int Statement_map::insert(Statement *statement)
void Statement_map::close_transient_cursors()
{
+#ifdef TO_BE_IMPLEMENTED
Statement *stmt;
while ((stmt= transient_cursor_list.head()))
stmt->close_cursor(); /* deletes itself from the list */
+#endif
}
@@ -1827,6 +1823,38 @@ void THD::set_status_var_init()
bzero((char*) &status_var, sizeof(status_var));
}
+
+void Security_context::init()
+{
+ host= user= priv_user= ip= 0;
+ host_or_ip= "connecting host";
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ db_access= NO_ACCESS;
+#endif
+}
+
+
+void Security_context::destroy()
+{
+ // If not pointer to constant
+ if (host != my_localhost)
+ safeFree(host);
+ if (user != delayed_user)
+ safeFree(user);
+ safeFree(ip);
+}
+
+
+void Security_context::skip_grants()
+{
+ /* privileges for the user are unknown everything is allowed */
+ host_or_ip= (char *)"";
+ master_access= ~NO_ACCESS;
+ priv_user= (char *)"";
+ *priv_host= '\0';
+}
+
+
/****************************************************************************
Handling of open and locked tables states.
@@ -1954,8 +1982,8 @@ HASH xid_cache;
static byte *xid_get_hash_key(const byte *ptr,uint *length,
my_bool not_used __attribute__((unused)))
{
- *length=((XID_STATE*)ptr)->xid.length();
- return (byte *)&((XID_STATE*)ptr)->xid;
+ *length=((XID_STATE*)ptr)->xid.key_length();
+ return ((XID_STATE*)ptr)->xid.key();
}
static void xid_free_hash (void *ptr)
@@ -1983,7 +2011,7 @@ void xid_cache_free()
XID_STATE *xid_cache_search(XID *xid)
{
pthread_mutex_lock(&LOCK_xid_cache);
- XID_STATE *res=(XID_STATE *)hash_search(&xid_cache, (byte *)xid, xid->length());
+ XID_STATE *res=(XID_STATE *)hash_search(&xid_cache, xid->key(), xid->key_length());
pthread_mutex_unlock(&LOCK_xid_cache);
return res;
}
@@ -1994,7 +2022,7 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state)
XID_STATE *xs;
my_bool res;
pthread_mutex_lock(&LOCK_xid_cache);
- if (hash_search(&xid_cache, (byte *)xid, xid->length()))
+ if (hash_search(&xid_cache, xid->key(), xid->key_length()))
res=0;
else if (!(xs=(XID_STATE *)my_malloc(sizeof(*xs), MYF(MY_WME))))
res=1;
@@ -2013,8 +2041,8 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state)
bool xid_cache_insert(XID_STATE *xid_state)
{
pthread_mutex_lock(&LOCK_xid_cache);
- DBUG_ASSERT(hash_search(&xid_cache, (byte *)&xid_state->xid,
- xid_state->xid.length())==0);
+ DBUG_ASSERT(hash_search(&xid_cache, xid_state->xid.key(),
+ xid_state->xid.key_length())==0);
my_bool res=my_hash_insert(&xid_cache, (byte*)xid_state);
pthread_mutex_unlock(&LOCK_xid_cache);
return res;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 59b51a702aa..727ed282836 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -510,6 +510,7 @@ struct system_variables
ulong multi_range_count;
ulong myisam_repair_threads;
ulong myisam_sort_buff_size;
+ ulong myisam_stats_method;
ulong net_buffer_length;
ulong net_interactive_timeout;
ulong net_read_timeout;
@@ -742,10 +743,12 @@ public:
void set_query_arena(Query_arena *set);
void free_items();
+ /* Close the active state associated with execution of this statement */
+ virtual void cleanup_stmt();
};
-class Cursor;
+class Server_side_cursor;
/*
State of a single command executed against this connection.
@@ -828,7 +831,7 @@ public:
*/
char *query;
uint32 query_length; // current query length
- Cursor *cursor;
+ Server_side_cursor *cursor;
public:
@@ -845,8 +848,6 @@ public:
void restore_backup_statement(Statement *stmt, Statement *backup);
/* return class type */
virtual Type type() const;
- /* Close the cursor open for this statement, if there is one */
- virtual void close_cursor();
};
@@ -898,9 +899,6 @@ public:
}
hash_delete(&st_hash, (byte *) statement);
}
- void add_transient_cursor(Statement *stmt)
- { transient_cursor_list.append(stmt); }
- void erase_transient_cursor(Statement *stmt) { stmt->unlink(); }
/*
Close all cursors of this connection that use tables of a storage
engine that has transaction-specific state and therefore can not
@@ -953,6 +951,34 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state);
bool xid_cache_insert(XID_STATE *xid_state);
void xid_cache_delete(XID_STATE *xid_state);
+
+class Security_context {
+public:
+ /*
+ host - host of the client
+ user - user of the client, set to NULL until the user has been read from
+ the connection
+ priv_user - The user privilege we are using. May be "" for anonymous user.
+ ip - client IP
+ */
+ char *host, *user, *priv_user, *ip;
+ /* The host privilege we are using */
+ char priv_host[MAX_HOSTNAME];
+ /* points to host if host is available, otherwise points to ip */
+ const char *host_or_ip;
+ ulong master_access; /* Global privileges from mysql.user */
+ ulong db_access; /* Privileges for current db */
+
+ void init();
+ void destroy();
+ void skip_grants();
+ inline char *priv_host_name()
+ {
+ return (*priv_host ? priv_host : (char *)"%");
+ }
+};
+
+
/*
A registry for item tree transformations performed during
query optimization. We register only those changes which require
@@ -1125,13 +1151,8 @@ public:
char *thread_stack;
/*
- host - host of the client
- user - user of the client, set to NULL until the user has been read from
- the connection
- priv_user - The user privilege we are using. May be '' for anonymous user.
db - currently selected database
catalog - currently selected catalog
- ip - client IP
WARNING: some members of THD (currently 'db', 'catalog' and 'query') are
set and alloced by the slave SQL thread (for the THD of that thread); that
thread is (and must remain, for now) the only responsible for freeing these
@@ -1140,8 +1161,10 @@ public:
properly. For details see the 'err:' label of the pthread_handler_decl of
the slave SQL thread, in sql/slave.cc.
*/
- char *host,*user,*priv_user,*db,*catalog,*ip;
- char priv_host[MAX_HOSTNAME];
+ char *db, *catalog;
+ Security_context main_security_ctx;
+ Security_context *security_ctx;
+
/* remote (peer) port */
uint16 peer_port;
/*
@@ -1150,13 +1173,9 @@ public:
a time-consuming piece that MySQL can get stuck in for a long time.
*/
const char *proc_info;
- /* points to host if host is available, otherwise points to ip */
- const char *host_or_ip;
ulong client_capabilities; /* What the client supports */
ulong max_client_packet_length;
- ulong master_access; /* Global privileges from mysql.user */
- ulong db_access; /* Privileges for current db */
HASH handler_tables_hash;
/*
@@ -1824,18 +1843,21 @@ public:
}
};
-class select_union :public select_result_interceptor {
- public:
- TABLE *table;
+class select_union :public select_result_interceptor
+{
TMP_TABLE_PARAM tmp_table_param;
+public:
+ TABLE *table;
- select_union(TABLE *table_par);
- ~select_union();
+ select_union() :table(0) {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
bool send_data(List<Item> &items);
bool send_eof();
bool flush();
- void set_table(TABLE *tbl) { table= tbl; }
+
+ bool create_result_table(THD *thd, List<Item> *column_types,
+ bool is_distinct, ulonglong options,
+ const char *alias);
};
/* Base subselect interface class */
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
new file mode 100644
index 00000000000..e8da691ea18
--- /dev/null
+++ b/sql/sql_cursor.cc
@@ -0,0 +1,660 @@
+/* Copyright (C) 2005 MySQL AB & MySQL Finland AB & TCX DataKonsult 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 */
+#ifdef USE_PRAGMA_IMPLEMENTATION
+#pragma implementation /* gcc class implementation */
+#endif
+
+#include "mysql_priv.h"
+#include "sql_cursor.h"
+#include "sql_select.h"
+
+/****************************************************************************
+ Declarations.
+****************************************************************************/
+
+/*
+ Sensitive_cursor -- a sensitive non-materialized server side
+ cursor An instance of this class cursor has its own runtime
+ state -- list of used items and memory root for runtime memory,
+ open and locked tables, change list for the changes of the
+ parsed tree. This state is freed when the cursor is closed.
+*/
+
+class Sensitive_cursor: public Server_side_cursor
+{
+ MEM_ROOT main_mem_root;
+ Query_arena *stmt_arena;
+ JOIN *join;
+ TABLE *open_tables;
+ MYSQL_LOCK *lock;
+ TABLE *derived_tables;
+ /* List of items created during execution */
+ query_id_t query_id;
+ struct Engine_info
+ {
+ const handlerton *ht;
+ void *read_view;
+ };
+ Engine_info ht_info[MAX_HA];
+ Item_change_list change_list;
+ my_bool close_at_commit;
+ THR_LOCK_OWNER lock_id;
+private:
+ /* bzero cursor state in THD */
+ void reset_thd(THD *thd);
+public:
+ Sensitive_cursor(THD *thd, select_result *result_arg);
+
+ THR_LOCK_OWNER *get_lock_id() { return &lock_id; }
+ /* Save THD state into cursor */
+ void post_open(THD *thd);
+
+ virtual bool is_open() const { return join != 0; }
+ virtual int open(JOIN *join);
+ virtual void fetch(ulong num_rows);
+ virtual void close();
+ virtual ~Sensitive_cursor();
+};
+
+
+/*
+ Materialized_cursor -- an insensitive materialized server-side
+ cursor. The result set of this cursor is saved in a temporary
+ table at open. The cursor itself is simply an interface for the
+ handler of the temporary table.
+*/
+
+class Materialized_cursor: public Server_side_cursor
+{
+ MEM_ROOT main_mem_root;
+ /* A fake unit to supply to select_send when fetching */
+ SELECT_LEX_UNIT fake_unit;
+ TABLE *table;
+ List<Item> item_list;
+ ulong fetch_limit;
+ ulong fetch_count;
+public:
+ Materialized_cursor(select_result *result, TABLE *table);
+
+ virtual bool is_open() const { return table != 0; }
+ virtual int open(JOIN *join __attribute__((unused)));
+ virtual void fetch(ulong num_rows);
+ virtual void close();
+ virtual ~Materialized_cursor();
+};
+
+
+/*
+ Select_materialize -- a mediator between a cursor query and the
+ protocol. In case we were not able to open a non-materialzed
+ cursor, it creates an internal temporary HEAP table, and insert
+ all rows into it. When the table reaches max_heap_table_size,
+ it's converted to a MyISAM table. Later this table is used to
+ create a Materialized_cursor.
+*/
+
+class Select_materialize: public select_union
+{
+ select_result *result; /* the result object of the caller (PS or SP) */
+public:
+ Select_materialize(select_result *result_arg) :result(result_arg) {}
+ virtual bool send_fields(List<Item> &list, uint flags);
+};
+
+
+/**************************************************************************/
+
+/*
+ Attempt to open a materialized or non-materialized cursor.
+
+ SYNOPSIS
+ mysql_open_cursor()
+ thd thread handle
+ flags [in] create a materialized cursor or not
+ result [in] result class of the caller used as a destination
+ for the rows fetched from the cursor
+ pcursor [out] a pointer to store a pointer to cursor in
+
+ RETURN VALUE
+ 0 the query has been successfully executed; in this
+ case pcursor may or may not contain
+ a pointer to an open cursor.
+ non-zero an error, 'pcursor' has been left intact.
+*/
+
+int mysql_open_cursor(THD *thd, uint flags, select_result *result,
+ Server_side_cursor **pcursor)
+{
+ Sensitive_cursor *sensitive_cursor;
+ select_result *save_result;
+ Select_materialize *result_materialize;
+ LEX *lex= thd->lex;
+ int rc;
+
+ /*
+ The lifetime of the sensitive cursor is the same or less as the
+ lifetime of the runtime memory of the statement it's opened for.
+ */
+ if (! (result_materialize= new (thd->mem_root) Select_materialize(result)))
+ return 1;
+
+ if (! (sensitive_cursor= new (thd->mem_root) Sensitive_cursor(thd, result)))
+ {
+ delete result;
+ return 1;
+ }
+
+ save_result= lex->result;
+
+ lex->result= result_materialize;
+ if (! (flags & (uint) ALWAYS_MATERIALIZED_CURSOR))
+ {
+ thd->lock_id= sensitive_cursor->get_lock_id();
+ thd->cursor= sensitive_cursor;
+ }
+
+ rc= mysql_execute_command(thd);
+
+ lex->result= save_result;
+ thd->lock_id= &thd->main_lock_id;
+ thd->cursor= 0;
+
+ /*
+ Possible options here:
+ - a sensitive cursor is open. In this case rc is 0 and
+ result_materialize->table is NULL, or
+ - a materialized cursor is open. In this case rc is 0 and
+ result_materialize->table is not NULL
+ - an error occured during materializaton.
+ result_materialize->table is not NULL, but rc != 0
+ - successful completion of mysql_execute_command without
+ a cursor: rc is 0, result_materialize->table is NULL,
+ sensitive_cursor is not open.
+ This is possible if some command writes directly to the
+ network, bypassing select_result mechanism. An example of
+ such command is SHOW VARIABLES or SHOW STATUS.
+ */
+ if (rc)
+ goto err_open;
+
+ if (sensitive_cursor->is_open())
+ {
+ DBUG_ASSERT(!result_materialize->table);
+ /*
+ It's safer if we grab THD state after mysql_execute_command
+ is finished and not in Sensitive_cursor::open(), because
+ currently the call to Sensitive_cursor::open is buried deep
+ in JOIN::exec of the top level join.
+ */
+ sensitive_cursor->post_open(thd);
+ *pcursor= sensitive_cursor;
+ goto end;
+ }
+ else if (result_materialize->table)
+ {
+ Materialized_cursor *materialized_cursor;
+ TABLE *table= result_materialize->table;
+ MEM_ROOT *mem_root= &table->mem_root;
+
+ if (!(materialized_cursor= new (mem_root)
+ Materialized_cursor(result, table)))
+ {
+ rc= 1;
+ goto err_open;
+ }
+
+ if ((rc= materialized_cursor->open(0)))
+ {
+ delete materialized_cursor;
+ goto err_open;
+ }
+
+ *pcursor= materialized_cursor;
+ thd->stmt_arena->cleanup_stmt();
+ goto end;
+ }
+
+err_open:
+ DBUG_ASSERT(! (sensitive_cursor && sensitive_cursor->is_open()));
+ delete sensitive_cursor;
+ if (result_materialize->table)
+ free_tmp_table(thd, result_materialize->table);
+end:
+ delete result_materialize;
+ return rc;
+}
+
+/****************************************************************************
+ Server_side_cursor
+****************************************************************************/
+
+Server_side_cursor::~Server_side_cursor()
+{
+}
+
+
+void Server_side_cursor::operator delete(void *ptr, size_t size)
+{
+ Server_side_cursor *cursor= (Server_side_cursor*) ptr;
+ MEM_ROOT own_root= *cursor->mem_root;
+
+ DBUG_ENTER("Server_side_cursor::operator delete");
+ TRASH(ptr, size);
+ /*
+ If this cursor has never been opened mem_root is empty. Otherwise
+ mem_root points to the memory the cursor object was allocated in.
+ In this case it's important to call free_root last, and free a copy
+ instead of *mem_root to avoid writing into freed memory.
+ */
+ free_root(&own_root, MYF(0));
+ DBUG_VOID_RETURN;
+}
+
+/****************************************************************************
+ Sensitive_cursor
+****************************************************************************/
+
+Sensitive_cursor::Sensitive_cursor(THD *thd, select_result *result_arg)
+ :Server_side_cursor(&main_mem_root, result_arg),
+ stmt_arena(0),
+ join(0),
+ close_at_commit(FALSE)
+{
+ /* We will overwrite it at open anyway. */
+ init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
+ thr_lock_owner_init(&lock_id, &thd->lock_info);
+ bzero((void*) ht_info, sizeof(ht_info));
+}
+
+
+void
+Sensitive_cursor::post_open(THD *thd)
+{
+ Engine_info *info;
+ /*
+ We need to save and reset thd->mem_root, otherwise it'll be
+ freed later in mysql_parse.
+
+ We can't just change thd->mem_root here as we want to keep the
+ things that are already allocated in thd->mem_root for
+ Sensitive_cursor::fetch()
+ */
+ *mem_root= *thd->mem_root;
+ stmt_arena= thd->stmt_arena;
+ state= stmt_arena->state;
+ /* Allocate a new memory root for thd */
+ init_sql_alloc(thd->mem_root,
+ thd->variables.query_alloc_block_size,
+ thd->variables.query_prealloc_size);
+
+ /*
+ Save tables and zero THD pointers to prevent table close in
+ close_thread_tables.
+ */
+ derived_tables= thd->derived_tables;
+ open_tables= thd->open_tables;
+ lock= thd->lock;
+ query_id= thd->query_id;
+ free_list= thd->free_list;
+ change_list= thd->change_list;
+ reset_thd(thd);
+ /* Now we have an active cursor and can cause a deadlock */
+ thd->lock_info.n_cursors++;
+
+ close_at_commit= FALSE; /* reset in case we're reusing the cursor */
+ info= &ht_info[0];
+ for (handlerton **pht= thd->transaction.stmt.ht; *pht; pht++)
+ {
+ const handlerton *ht= *pht;
+ close_at_commit|= test(ht->flags & HTON_CLOSE_CURSORS_AT_COMMIT);
+ if (ht->create_cursor_read_view)
+ {
+ info->ht= ht;
+ info->read_view= (ht->create_cursor_read_view)();
+ ++info;
+ }
+ }
+ /*
+ XXX: thd->locked_tables is not changed.
+ What problems can we have with it if cursor is open?
+ TODO: must be fixed because of the prelocked mode.
+ */
+}
+
+
+void
+Sensitive_cursor::reset_thd(THD *thd)
+{
+ thd->derived_tables= 0;
+ thd->open_tables= 0;
+ thd->lock= 0;
+ thd->free_list= 0;
+ thd->change_list.empty();
+}
+
+
+int
+Sensitive_cursor::open(JOIN *join_arg)
+{
+ join= join_arg;
+ THD *thd= join->thd;
+ /* First non-constant table */
+ JOIN_TAB *join_tab= join->join_tab + join->const_tables;
+ DBUG_ENTER("Sensitive_cursor::open");
+
+ join->change_result(result);
+ /*
+ Send fields description to the client; server_status is sent
+ in 'EOF' packet, which follows send_fields().
+ We don't simply use SEND_EOF flag of send_fields because we also
+ want to flush the network buffer, which is done only in a standalone
+ send_eof().
+ */
+ result->send_fields(*join->fields, Protocol::SEND_NUM_ROWS);
+ thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
+ result->send_eof();
+ thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
+
+ /* Prepare JOIN for reading rows. */
+ join->tmp_table= 0;
+ join->join_tab[join->tables-1].next_select= setup_end_select_func(join);
+ join->send_records= 0;
+ join->fetch_limit= join->unit->offset_limit_cnt;
+
+ /* Disable JOIN CACHE as it is not working with cursors yet */
+ for (JOIN_TAB *tab= join_tab;
+ tab != join->join_tab + join->tables - 1;
+ tab++)
+ {
+ if (tab->next_select == sub_select_cache)
+ tab->next_select= sub_select;
+ }
+
+ DBUG_ASSERT(join_tab->table->reginfo.not_exists_optimize == 0);
+ DBUG_ASSERT(join_tab->not_used_in_distinct == 0);
+ /*
+ null_row is set only if row not found and it's outer join: should never
+ happen for the first table in join_tab list
+ */
+ DBUG_ASSERT(join_tab->table->null_row == 0);
+ DBUG_RETURN(0);
+}
+
+
+/*
+ SYNOPSIS
+ Sensitive_cursor::fetch()
+ num_rows fetch up to this number of rows (maybe less)
+
+ DESCRIPTION
+ Fetch next num_rows rows from the cursor and send them to the client
+
+ Precondition:
+ Sensitive_cursor is open
+
+ RETURN VALUES:
+ none, this function will send OK to the clinet or set an error
+ message in THD
+*/
+
+void
+Sensitive_cursor::fetch(ulong num_rows)
+{
+ THD *thd= join->thd;
+ JOIN_TAB *join_tab= join->join_tab + join->const_tables;
+ enum_nested_loop_state error= NESTED_LOOP_OK;
+ Query_arena backup_arena;
+ Engine_info *info;
+ DBUG_ENTER("Sensitive_cursor::fetch");
+ DBUG_PRINT("enter",("rows: %lu", num_rows));
+
+ DBUG_ASSERT(thd->derived_tables == 0 && thd->open_tables == 0 &&
+ thd->lock == 0);
+
+ thd->derived_tables= derived_tables;
+ thd->open_tables= open_tables;
+ thd->lock= lock;
+ thd->query_id= query_id;
+ thd->change_list= change_list;
+ /* save references to memory allocated during fetch */
+ thd->set_n_backup_active_arena(this, &backup_arena);
+
+ for (info= ht_info; info->read_view ; info++)
+ (info->ht->set_cursor_read_view)(info->read_view);
+
+ join->fetch_limit+= num_rows;
+
+ error= sub_select(join, join_tab, 0);
+ if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS)
+ error= sub_select(join,join_tab,1);
+ if (error == NESTED_LOOP_QUERY_LIMIT)
+ error= NESTED_LOOP_OK; /* select_limit used */
+ if (error == NESTED_LOOP_CURSOR_LIMIT)
+ join->resume_nested_loop= TRUE;
+
+#ifdef USING_TRANSACTIONS
+ ha_release_temporary_latches(thd);
+#endif
+ /* Grab free_list here to correctly free it in close */
+ thd->restore_active_arena(this, &backup_arena);
+
+ change_list= thd->change_list;
+ reset_thd(thd);
+
+ for (info= ht_info; info->read_view; info++)
+ (info->ht->set_cursor_read_view)(0);
+
+ if (error == NESTED_LOOP_CURSOR_LIMIT)
+ {
+ /* Fetch limit worked, possibly more rows are there */
+ thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
+ result->send_eof();
+ thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
+ }
+ else
+ {
+ close();
+ if (error == NESTED_LOOP_OK)
+ {
+ thd->server_status|= SERVER_STATUS_LAST_ROW_SENT;
+ result->send_eof();
+ thd->server_status&= ~SERVER_STATUS_LAST_ROW_SENT;
+ }
+ else if (error != NESTED_LOOP_KILLED)
+ my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+void
+Sensitive_cursor::close()
+{
+ THD *thd= join->thd;
+ DBUG_ENTER("Sensitive_cursor::close");
+
+ for (Engine_info *info= ht_info; info->read_view; info++)
+ {
+ (info->ht->close_cursor_read_view)(info->read_view);
+ info->read_view= 0;
+ info->ht= 0;
+ }
+
+ thd->change_list= change_list;
+ {
+ /*
+ XXX: Another hack: we need to set THD state as if in a fetch to be
+ able to call stmt close.
+ */
+ DBUG_ASSERT(lock || open_tables || derived_tables);
+
+ TABLE *tmp_derived_tables= thd->derived_tables;
+ MYSQL_LOCK *tmp_lock= thd->lock;
+
+ thd->open_tables= open_tables;
+ thd->derived_tables= derived_tables;
+ thd->lock= lock;
+
+ /* Is expected to at least close tables and empty thd->change_list */
+ stmt_arena->cleanup_stmt();
+
+ thd->open_tables= tmp_derived_tables;
+ thd->derived_tables= tmp_derived_tables;
+ thd->lock= tmp_lock;
+ }
+ thd->lock_info.n_cursors--; /* Decrease the number of active cursors */
+ join= 0;
+ stmt_arena= 0;
+ free_items();
+ change_list.empty();
+ DBUG_VOID_RETURN;
+}
+
+
+Sensitive_cursor::~Sensitive_cursor()
+{
+ if (is_open())
+ close();
+}
+
+/***************************************************************************
+ Materialized_cursor
+****************************************************************************/
+
+Materialized_cursor::Materialized_cursor(select_result *result_arg,
+ TABLE *table_arg)
+ :Server_side_cursor(&table_arg->mem_root, result_arg),
+ table(table_arg),
+ fetch_limit(0),
+ fetch_count(0)
+{
+ fake_unit.init_query();
+ fake_unit.thd= table->in_use;
+}
+
+
+int Materialized_cursor::open(JOIN *join __attribute__((unused)))
+{
+ THD *thd= fake_unit.thd;
+ int rc;
+ Query_arena backup_arena;
+
+ thd->set_n_backup_active_arena(this, &backup_arena);
+ /* Create a list of fields and start sequential scan */
+ rc= (table->fill_item_list(&item_list) ||
+ result->prepare(item_list, &fake_unit) ||
+ table->file->ha_rnd_init(TRUE));
+ thd->restore_active_arena(this, &backup_arena);
+ return rc;
+}
+
+
+/*
+ Fetch up to the given number of rows from a materialized cursor.
+
+ DESCRIPTION
+ Precondition: the cursor is open.
+
+ If the cursor points after the last row, the fetch will automatically
+ close the cursor and not send any data (except the 'EOF' packet
+ with SERVER_STATUS_LAST_ROW_SENT). This is an extra round trip
+ and probably should be improved to return
+ SERVER_STATUS_LAST_ROW_SENT along with the last row.
+
+ RETURN VALUE
+ none, in case of success the row is sent to the client, otherwise
+ an error message is set in THD
+*/
+
+void Materialized_cursor::fetch(ulong num_rows)
+{
+ THD *thd= table->in_use;
+
+ int res= 0;
+ for (fetch_limit+= num_rows; fetch_count < fetch_limit; fetch_count++)
+ {
+ if ((res= table->file->rnd_next(table->record[0])))
+ break;
+ /* Send data only if the read was successful. */
+ result->send_data(item_list);
+ }
+
+ switch (res) {
+ case 0:
+ thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
+ result->send_eof();
+ thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
+ break;
+ case HA_ERR_END_OF_FILE:
+ thd->server_status|= SERVER_STATUS_LAST_ROW_SENT;
+ result->send_eof();
+ thd->server_status&= ~SERVER_STATUS_LAST_ROW_SENT;
+ close();
+ break;
+ default:
+ table->file->print_error(res, MYF(0));
+ close();
+ break;
+ }
+}
+
+
+void Materialized_cursor::close()
+{
+ /* Free item_list items */
+ free_items();
+ (void) table->file->ha_rnd_end();
+ /*
+ We need to grab table->mem_root to prevent free_tmp_table from freeing:
+ the cursor object was allocated in this memory.
+ */
+ main_mem_root= table->mem_root;
+ mem_root= &main_mem_root;
+ clear_alloc_root(&table->mem_root);
+ free_tmp_table(table->in_use, table);
+ table= 0;
+}
+
+
+Materialized_cursor::~Materialized_cursor()
+{
+ if (is_open())
+ close();
+}
+
+
+/***************************************************************************
+ Select_materialize
+****************************************************************************/
+
+bool Select_materialize::send_fields(List<Item> &list, uint flags)
+{
+ bool rc;
+ DBUG_ASSERT(table == 0);
+ if (create_result_table(unit->thd, unit->get_unit_column_types(),
+ FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, ""))
+ return TRUE;
+ /*
+ We can't simply supply SEND_EOF flag to send_fields, because send_fields
+ doesn't flush the network buffer.
+ */
+ rc= result->send_fields(list, Protocol::SEND_NUM_ROWS);
+ thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
+ result->send_eof();
+ thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
+ return rc;
+}
+
diff --git a/sql/sql_cursor.h b/sql/sql_cursor.h
new file mode 100644
index 00000000000..d1156dfba8d
--- /dev/null
+++ b/sql/sql_cursor.h
@@ -0,0 +1,65 @@
+#ifndef _sql_cursor_h_
+#define _sql_cursor_h_
+/* Copyright (C) 2005 MySQL AB & MySQL Finland AB & TCX DataKonsult 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 */
+
+#ifdef USE_PRAGMA_INTERFACE
+#pragma interface /* gcc class interface */
+#endif
+
+/*
+ Declarations for implementation of server side cursors. Only
+ read-only non-scrollable cursors are currently implemented.
+*/
+
+/*
+ Server_side_cursor -- an interface for materialized and
+ sensitive (non-materialized) implementation of cursors. All
+ cursors are self-contained (created in their own memory root).
+ For that reason they must be deleted only using a pointer to
+ Server_side_cursor, not to its base class.
+*/
+
+class Server_side_cursor: protected Query_arena, public Sql_alloc
+{
+protected:
+ /* Row destination used for fetch */
+ select_result *result;
+public:
+ Server_side_cursor(MEM_ROOT *mem_root_arg, select_result *result_arg)
+ :Query_arena(mem_root_arg, INITIALIZED), result(result_arg)
+ {}
+
+ virtual bool is_open() const= 0;
+
+ virtual int open(JOIN *top_level_join)= 0;
+ virtual void fetch(ulong num_rows)= 0;
+ virtual void close()= 0;
+ virtual ~Server_side_cursor();
+
+ static void operator delete(void *ptr, size_t size);
+};
+
+
+int mysql_open_cursor(THD *thd, uint flags,
+ select_result *result,
+ Server_side_cursor **res);
+
+/* Possible values for flags */
+
+enum { ANY_CURSOR= 1, ALWAYS_MATERIALIZED_CURSOR= 2 };
+
+#endif /* _sql_cusor_h_ */
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index e8fb8d9ce16..a5dabc8140c 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -1094,6 +1094,7 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
bool system_db= 0;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong db_access;
+ Security_context *sctx= thd->security_ctx;
#endif
DBUG_ENTER("mysql_change_db");
DBUG_PRINT("enter",("name: '%s'",name));
@@ -1131,22 +1132,20 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!no_access_check)
{
- if (test_all_bits(thd->master_access,DB_ACLS))
+ if (test_all_bits(sctx->master_access, DB_ACLS))
db_access=DB_ACLS;
else
- db_access= (acl_get(thd->host,thd->ip, thd->priv_user,dbname,0) |
- thd->master_access);
+ db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname, 0) |
+ sctx->master_access);
if (!(db_access & DB_ACLS) && (!grant_option ||
check_grant_db(thd,dbname)))
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
- thd->priv_user,
- thd->priv_host,
+ sctx->priv_user,
+ sctx->priv_host,
dbname);
- mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
- thd->priv_user,
- thd->priv_host,
- dbname);
+ mysql_log.write(thd, COM_INIT_DB, ER(ER_DBACCESS_DENIED_ERROR),
+ sctx->priv_user, sctx->priv_host, dbname);
my_free(dbname,MYF(0));
DBUG_RETURN(1);
}
@@ -1168,7 +1167,7 @@ end:
thd->db_length=db_length;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!no_access_check)
- thd->db_access=db_access;
+ sctx->db_access= db_access;
#endif
if (system_db)
{
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 00d82bcdfda..584601fe202 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -266,19 +266,12 @@ cleanup:
delete select;
transactional_table= table->file->has_transactions();
- /*
- We write to the binary log even if we deleted no row, because maybe the
- user is using this command to ensure that a table is clean on master *and
- on slave*. Think of the case of a user having played separately with the
- master's table and slave's table and wanting to take a fresh identical
- start now.
- error < 0 means "really no error". error <= 0 means "maybe some error".
- */
- if ((deleted || (error < 0)) && (error <= 0 || !transactional_table))
+ /* See similar binlogging code in sql_update.cc, for comments */
+ if ((error < 0) || (deleted && !transactional_table))
{
if (mysql_bin_log.is_open())
{
- if (error <= 0)
+ if (error < 0)
thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_table, FALSE);
@@ -328,6 +321,7 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
SELECT_LEX *select_lex= &thd->lex->select_lex;
DBUG_ENTER("mysql_prepare_delete");
+ thd->allow_sum_func= 0;
if (setup_tables(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list,
table_list, conds, &select_lex->leaf_tables,
@@ -736,6 +730,9 @@ bool multi_delete::send_eof()
/* Does deletes for the last n - 1 tables, returns 0 if ok */
int local_error= do_deletes(); // returns 0 if success
+ /* compute a total error to know if something failed */
+ local_error= local_error || error;
+
/* reset used flags */
thd->proc_info="end";
@@ -748,19 +745,11 @@ bool multi_delete::send_eof()
query_cache_invalidate3(thd, delete_tables, 1);
}
- /*
- Write the SQL statement to the binlog if we deleted
- rows and we succeeded, or also in an error case when there
- was a non-transaction-safe table involved, since
- modifications in it cannot be rolled back.
- Note that if we deleted nothing we don't write to the binlog (TODO:
- fix this).
- */
- if (deleted && ((error <= 0 && !local_error) || normal_tables))
+ if ((local_error == 0) || (deleted && normal_tables))
{
if (mysql_bin_log.is_open())
{
- if (error <= 0 && !local_error)
+ if (local_error == 0)
thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_tables, FALSE);
@@ -816,7 +805,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
TABLE *table= *table_ptr;
table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
db_type table_type= table->s->db_type;
- if (!ha_supports_generate(table_type))
+ if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
goto trunc_by_del;
strmov(path, table->s->path);
*table_ptr= table->next; // Unlink table from list
@@ -847,7 +836,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
table_list->db, table_list->table_name);
DBUG_RETURN(TRUE);
}
- if (!ha_supports_generate(table_type) || thd->lex->sphead)
+ if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE)
+ || thd->lex->sphead)
goto trunc_by_del;
if (lock_and_wait_for_table_name(thd, table_list))
DBUG_RETURN(TRUE);
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 7b9191cd841..74b239e1637 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -27,7 +27,7 @@
/*
- call given derived table processor (preparing or filling tables)
+ Call given derived table processor (preparing or filling tables)
SYNOPSIS
mysql_handle_derived()
@@ -36,7 +36,6 @@
RETURN
0 ok
- -1 Error
1 Error and error message given
*/
@@ -97,14 +96,14 @@ out:
RETURN
0 ok
- 1 Error
- -1 Error and error message given
- */
+ 1 Error and an error message was given
+*/
int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
{
SELECT_LEX_UNIT *unit= orig_table_list->derived;
int res= 0;
+ ulonglong create_options;
DBUG_ENTER("mysql_derived_prepare");
if (unit)
{
@@ -118,21 +117,18 @@ int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
for (SELECT_LEX *sl= first_select; sl; sl= sl->next_select())
sl->context.outer_context= 0;
- if (!(derived_result= new select_union(0)))
+ if (!(derived_result= new select_union))
DBUG_RETURN(1); // out of memory
// st_select_lex_unit::prepare correctly work for single select
- if ((res= unit->prepare(thd, derived_result, 0, orig_table_list->alias)))
+ if ((res= unit->prepare(thd, derived_result, 0)))
goto exit;
- if (check_duplicate_names(unit->types, 0))
- {
- res= -1;
+ if ((res= check_duplicate_names(unit->types, 0)))
goto exit;
- }
- derived_result->tmp_table_param.init();
- derived_result->tmp_table_param.field_count= unit->types.elements;
+ create_options= (first_select->options | thd->options |
+ TMP_TABLE_ALL_COLUMNS);
/*
Temp table is created so that it hounours if UNION without ALL is to be
processed
@@ -143,18 +139,12 @@ int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
!unit->union_distinct->next_select() (i.e. it is union and last distinct
SELECT is last SELECT of UNION).
*/
- if (!(table= create_tmp_table(thd, &derived_result->tmp_table_param,
- unit->types, (ORDER*) 0,
- FALSE, 1,
- (first_select->options | thd->options |
- TMP_TABLE_ALL_COLUMNS),
- HA_POS_ERROR,
- orig_table_list->alias)))
- {
- res= -1;
+ if ((res= derived_result->create_result_table(thd, &unit->types, FALSE,
+ create_options,
+ orig_table_list->alias)))
goto exit;
- }
- derived_result->set_table(table);
+
+ table= derived_result->table;
exit:
/* Hide "Unknown column" or "Unknown function" error */
@@ -231,9 +221,8 @@ exit:
RETURN
0 ok
- 1 Error
- -1 Error and error message given
- */
+ 1 Error and an error message was given
+*/
int mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
{
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 3d7ca8059b9..d1122cf2ac4 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -285,7 +285,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
By default, both logs are enabled (this won't cause problems if the server
runs without --log-update or --log-bin).
*/
- bool log_on= (thd->options & OPTION_BIN_LOG) || (!(thd->master_access & SUPER_ACL));
+ bool log_on= (thd->options & OPTION_BIN_LOG) ||
+ (!(thd->security_ctx->master_access & SUPER_ACL));
bool transactional_table;
uint value_count;
ulong counter = 1;
@@ -1277,8 +1278,8 @@ public:
table(0),tables_in_use(0),stacked_inserts(0), status(0), dead(0),
group_count(0)
{
- thd.user=thd.priv_user=(char*) delayed_user;
- thd.host=(char*) my_localhost;
+ thd.security_ctx->user=thd.security_ctx->priv_user=(char*) delayed_user;
+ thd.security_ctx->host=(char*) my_localhost;
thd.current_tablenr=0;
thd.version=refresh_version;
thd.command=COM_DELAYED_INSERT;
@@ -1288,7 +1289,7 @@ public:
bzero((char*) &thd.net, sizeof(thd.net)); // Safety
bzero((char*) &table_list, sizeof(table_list)); // Safety
thd.system_thread= SYSTEM_THREAD_DELAYED_INSERT;
- thd.host_or_ip= "";
+ thd.security_ctx->host_or_ip= "";
bzero((char*) &info,sizeof(info));
pthread_mutex_init(&mutex,MY_MUTEX_INIT_FAST);
pthread_cond_init(&cond,NULL);
@@ -1311,7 +1312,7 @@ public:
pthread_cond_destroy(&cond_client);
thd.unlink(); // Must be unlinked under lock
x_free(thd.query);
- thd.user=thd.host=0;
+ thd.security_ctx->user= thd.security_ctx->host=0;
thread_count--;
delayed_insert_threads--;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 381d6573a09..7640b6eb569 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -54,7 +54,7 @@ enum enum_sql_command {
SQLCOM_SHOW_DATABASES, SQLCOM_SHOW_TABLES, SQLCOM_SHOW_FIELDS,
SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_LOGS, SQLCOM_SHOW_STATUS,
- SQLCOM_SHOW_INNODB_STATUS, SQLCOM_SHOW_MUTEX_STATUS,
+ SQLCOM_SHOW_INNODB_STATUS, SQLCOM_SHOW_NDBCLUSTER_STATUS, SQLCOM_SHOW_MUTEX_STATUS,
SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT,
SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS,
SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_CREATE_DB, SQLCOM_SHOW_TABLE_STATUS,
@@ -433,10 +433,6 @@ public:
{
return my_reinterpret_cast(st_select_lex*)(slave);
}
- st_select_lex* first_select_in_union()
- {
- return my_reinterpret_cast(st_select_lex*)(slave);
- }
st_select_lex_unit* next_unit()
{
return my_reinterpret_cast(st_select_lex_unit*)(next);
@@ -446,8 +442,7 @@ public:
void exclude_tree();
/* UNION methods */
- bool prepare(THD *thd, select_result *result, ulong additional_options,
- const char *tmp_table_alias);
+ bool prepare(THD *thd, select_result *result, ulong additional_options);
bool exec();
bool cleanup();
inline void unclean() { cleaned= 0; }
@@ -463,7 +458,10 @@ public:
friend void lex_start(THD *thd, uchar *buf, uint length);
friend int subselect_union_engine::exec();
+
+ List<Item> *get_unit_column_types();
};
+
typedef class st_select_lex_unit SELECT_LEX_UNIT;
/*
diff --git a/sql/sql_list.h b/sql/sql_list.h
index e4a34cc0aa1..285f1d6e501 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -32,6 +32,8 @@ public:
{
return (void*) sql_alloc((uint) size);
}
+ static void *operator new[](size_t size, MEM_ROOT *mem_root)
+ { return (void*) alloc_root(mem_root, (uint) size); }
static void *operator new(size_t size, MEM_ROOT *mem_root)
{ return (void*) alloc_root(mem_root, (uint) size); }
static void operator delete(void *ptr, size_t size) { TRASH(ptr, size); }
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 8eec970b4df..895065241f4 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -147,6 +147,10 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
MYF(0));
DBUG_RETURN(TRUE);
}
+ /*
+ This needs to be done before external_lock
+ */
+ ha_enable_transaction(thd, FALSE);
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
if (setup_tables(thd, &thd->lex->select_lex.context,
@@ -363,7 +367,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (ignore ||
handle_duplicates == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
- ha_enable_transaction(thd, FALSE);
table->file->start_bulk_insert((ha_rows) 0);
table->copy_blobs=1;
@@ -383,10 +386,10 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
*enclosed, skip_lines, ignore);
if (table->file->end_bulk_insert())
error=1; /* purecov: inspected */
- ha_enable_transaction(thd, TRUE);
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->next_number_field=0;
}
+ ha_enable_transaction(thd, TRUE);
if (file >= 0)
my_close(file,MYF(0));
free_blobs(table); /* if pack_blob was used */
@@ -552,6 +555,8 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
while ((sql_field= (Item_field*) it++))
{
Field *field= sql_field->field;
+ if (field == table->next_number_field)
+ table->auto_increment_field_not_null= TRUE;
/*
No fields specified in fields_vars list can be null in this format.
Mark field as not null, we should do this for each row because of
@@ -570,6 +575,8 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
{
uint length;
byte save_chr;
+ if (field == table->next_number_field)
+ table->auto_increment_field_not_null= TRUE;
if ((length=(uint) (read_info.row_end-pos)) >
field->field_length)
length=field->field_length;
@@ -692,6 +699,8 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
Field *field= ((Item_field *)item)->field;
field->reset();
field->set_null();
+ if (field == table->next_number_field)
+ table->auto_increment_field_not_null= TRUE;
if (!field->maybe_null())
{
if (field->type() == FIELD_TYPE_TIMESTAMP)
@@ -709,9 +718,12 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
if (item->type() == Item::FIELD_ITEM)
{
+
Field *field= ((Item_field *)item)->field;
field->set_notnull();
read_info.row_end[0]=0; // Safe to change end marker
+ if (field == table->next_number_field)
+ table->auto_increment_field_not_null= TRUE;
field->store((char*) pos, length, read_info.read_charset);
}
else
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d9f5c178370..48dc8f68707 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -26,6 +26,10 @@
#include "ha_innodb.h"
#endif
+#ifdef HAVE_NDBCLUSTER_DB
+#include "ha_ndbcluster.h"
+#endif
+
#include "sp_head.h"
#include "sp.h"
#include "sp_cache.h"
@@ -131,6 +135,12 @@ static bool end_active_trans(THD *thd)
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
DBUG_RETURN(1);
}
+ if (thd->transaction.xid_state.xa_state != XA_NOTR)
+ {
+ my_error(ER_XAER_RMFAIL, MYF(0),
+ xa_state_names[thd->transaction.xid_state.xa_state]);
+ DBUG_RETURN(1);
+ }
if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
OPTION_TABLE_LOCK))
{
@@ -180,13 +190,8 @@ static bool begin_trans(THD *thd)
*/
inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
{
- return (rpl_filter->is_on() && tables &&
- !(thd->spcont || rpl_filter->tables_ok(thd->db, tables)) &&
- ((thd->lex->sql_command != SQLCOM_DELETE_MULTI) ||
- !(thd->spcont ||
- rpl_filter->tables_ok(thd->db,
- (TABLE_LIST *)
- thd->lex->auxilliary_table_list.first))));
+ return rpl_filter->is_on() && tables &&
+ !rpl_filter->tables_ok(thd->db, tables);
}
#endif
@@ -249,7 +254,7 @@ end:
SYNOPSIS
check_user()
- thd thread handle, thd->{host,user,ip} are used
+ thd thread handle, thd->security_ctx->{host,user,ip} are used
command originator of the check: now check_user is called
during connect and change user procedures; used for
logging.
@@ -264,8 +269,8 @@ end:
are 'IN'.
RETURN VALUE
- 0 OK; thd->user, thd->master_access, thd->priv_user, thd->db and
- thd->db_access are updated; OK is sent to client;
+ 0 OK; thd->security_ctx->user/master_access/priv_user/db_access and
+ thd->db are updated; OK is sent to client;
-1 access denied or handshake error; error is sent to client;
>0 error, not sent to client
*/
@@ -277,7 +282,7 @@ int check_user(THD *thd, enum enum_server_command command,
DBUG_ENTER("check_user");
#ifdef NO_EMBEDDED_ACCESS_CHECKS
- thd->master_access= GLOBAL_ACLS; // Full rights
+ thd->main_security_ctx.master_access= GLOBAL_ACLS; // Full rights
/* Change database if necessary */
if (db && db[0])
{
@@ -344,15 +349,17 @@ int check_user(THD *thd, enum enum_server_command command,
if (opt_secure_auth_local)
{
net_printf_error(thd, ER_SERVER_IS_IN_SECURE_AUTH_MODE,
- thd->user, thd->host_or_ip);
+ thd->main_security_ctx.user,
+ thd->main_security_ctx.host_or_ip);
mysql_log.write(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
- thd->user, thd->host_or_ip);
+ thd->main_security_ctx.user,
+ thd->main_security_ctx.host_or_ip);
DBUG_RETURN(-1);
}
/* We have to read very specific packet size */
if (send_old_password_request(thd) ||
my_net_read(net) != SCRAMBLE_LENGTH_323 + 1)
- {
+ {
inc_host_errors(&thd->remote.sin_addr);
DBUG_RETURN(ER_HANDSHAKE_ERROR);
}
@@ -364,22 +371,27 @@ int check_user(THD *thd, enum enum_server_command command,
/* here res is always >= 0 */
if (res == 0)
{
- if (!(thd->master_access & NO_ACCESS)) // authentication is OK
+ if (!(thd->main_security_ctx.master_access &
+ NO_ACCESS)) // authentication is OK
{
DBUG_PRINT("info",
("Capabilities: %d packet_length: %ld Host: '%s' "
"Login user: '%s' Priv_user: '%s' Using password: %s "
"Access: %u db: '%s'",
- thd->client_capabilities, thd->max_client_packet_length,
- thd->host_or_ip, thd->user, thd->priv_user,
+ thd->client_capabilities,
+ thd->max_client_packet_length,
+ thd->main_security_ctx.host_or_ip,
+ thd->main_security_ctx.user,
+ thd->main_security_ctx.priv_user,
passwd_len ? "yes": "no",
- thd->master_access, thd->db ? thd->db : "*none*"));
+ thd->main_security_ctx.master_access,
+ (thd->db ? thd->db : "*none*")));
if (check_count)
{
VOID(pthread_mutex_lock(&LOCK_thread_count));
bool count_ok= thread_count <= max_connections + delayed_insert_threads
- || (thd->master_access & SUPER_ACL);
+ || (thd->main_security_ctx.master_access & SUPER_ACL);
VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (!count_ok)
{ // too many connections
@@ -389,11 +401,13 @@ int check_user(THD *thd, enum enum_server_command command,
}
/* Why logging is performed before all checks've passed? */
- mysql_log.write(thd,command,
- (thd->priv_user == thd->user ?
+ mysql_log.write(thd, command,
+ (thd->main_security_ctx.priv_user ==
+ thd->main_security_ctx.user ?
(char*) "%s@%s on %s" :
(char*) "%s@%s as anonymous on %s"),
- thd->user, thd->host_or_ip,
+ thd->main_security_ctx.user,
+ thd->main_security_ctx.host_or_ip,
db ? db : (char*) "");
/*
@@ -401,14 +415,16 @@ int check_user(THD *thd, enum enum_server_command command,
set to 0 here because we don't have an active database yet (and we
may not have an active database to set.
*/
- thd->db_access=0;
+ thd->main_security_ctx.db_access=0;
/* Don't allow user to connect if he has done too many queries */
if ((ur.questions || ur.updates || ur.conn_per_hour || ur.user_conn ||
max_user_connections) &&
get_or_create_user_conn(thd,
- opt_old_style_user_limits ? thd->user : thd->priv_user,
- opt_old_style_user_limits ? thd->host_or_ip : thd->priv_host,
+ (opt_old_style_user_limits ? thd->main_security_ctx.user :
+ thd->main_security_ctx.priv_user),
+ (opt_old_style_user_limits ? thd->main_security_ctx.host_or_ip :
+ thd->main_security_ctx.priv_host),
&ur))
DBUG_RETURN(-1);
if (thd->user_connect &&
@@ -443,12 +459,12 @@ int check_user(THD *thd, enum enum_server_command command,
DBUG_RETURN(-1);
}
net_printf_error(thd, ER_ACCESS_DENIED_ERROR,
- thd->user,
- thd->host_or_ip,
+ thd->main_security_ctx.user,
+ thd->main_security_ctx.host_or_ip,
passwd_len ? ER(ER_YES) : ER(ER_NO));
mysql_log.write(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
- thd->user,
- thd->host_or_ip,
+ thd->main_security_ctx.user,
+ thd->main_security_ctx.host_or_ip,
passwd_len ? ER(ER_YES) : ER(ER_NO));
DBUG_RETURN(-1);
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
@@ -772,41 +788,45 @@ static int check_connection(THD *thd)
DBUG_PRINT("info",
("New connection received on %s", vio_description(net->vio)));
- if (!thd->host) // If TCP/IP connection
+ if (!thd->main_security_ctx.host) // If TCP/IP connection
{
char ip[30];
if (vio_peer_addr(net->vio, ip, &thd->peer_port))
return (ER_BAD_HOST_ERROR);
- if (!(thd->ip= my_strdup(ip,MYF(0))))
+ if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(0))))
return (ER_OUT_OF_RESOURCES);
- thd->host_or_ip= thd->ip;
+ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip;
vio_in_addr(net->vio,&thd->remote.sin_addr);
if (!(specialflag & SPECIAL_NO_RESOLVE))
{
vio_in_addr(net->vio,&thd->remote.sin_addr);
- thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors);
+ thd->main_security_ctx.host=
+ ip_to_hostname(&thd->remote.sin_addr, &connect_errors);
/* Cut very long hostnames to avoid possible overflows */
- if (thd->host)
+ if (thd->main_security_ctx.host)
{
- if (thd->host != my_localhost)
- thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0;
- thd->host_or_ip= thd->host;
+ if (thd->main_security_ctx.host != my_localhost)
+ thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
+ HOSTNAME_LENGTH)]= 0;
+ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
}
if (connect_errors > max_connect_errors)
return(ER_HOST_IS_BLOCKED);
}
DBUG_PRINT("info",("Host: %s ip: %s",
- thd->host ? thd->host : "unknown host",
- thd->ip ? thd->ip : "unknown ip"));
- if (acl_check_host(thd->host,thd->ip))
+ (thd->main_security_ctx.host ?
+ thd->main_security_ctx.host : "unknown host"),
+ (thd->main_security_ctx.ip ?
+ thd->main_security_ctx.ip : "unknown ip")));
+ if (acl_check_host(thd->main_security_ctx.host, thd->main_security_ctx.ip))
return(ER_HOST_NOT_PRIVILEGED);
}
else /* Hostname given means that the connection was on a socket */
{
- DBUG_PRINT("info",("Host: %s",thd->host));
- thd->host_or_ip= thd->host;
- thd->ip= 0;
+ DBUG_PRINT("info",("Host: %s", thd->main_security_ctx.host));
+ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
+ thd->main_security_ctx.ip= 0;
/* Reset sin_addr */
bzero((char*) &thd->remote, sizeof(thd->remote));
}
@@ -989,9 +1009,9 @@ static int check_connection(THD *thd)
thd->charset(), &dummy_errors)]= '\0';
user= user_buff;
- if (thd->user)
- x_free(thd->user);
- if (!(thd->user= my_strdup(user, MYF(0))))
+ if (thd->main_security_ctx.user)
+ x_free(thd->main_security_ctx.user);
+ if (!(thd->main_security_ctx.user= my_strdup(user, MYF(0))))
return (ER_OUT_OF_RESOURCES);
return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);
}
@@ -1079,13 +1099,14 @@ pthread_handler_decl(handle_one_connection,arg)
{
int error;
NET *net= &thd->net;
+ Security_context *sctx= thd->security_ctx;
thd->thread_stack= (char*) &thd;
net->no_send_error= 0;
if ((error=check_connection(thd)))
{ // Wrong permissions
if (error > 0)
- net_printf_error(thd, error, thd->host_or_ip);
+ net_printf_error(thd, error, sctx->host_or_ip);
#ifdef __NT__
if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
my_sleep(1000); /* must wait after eof() */
@@ -1094,7 +1115,7 @@ pthread_handler_decl(handle_one_connection,arg)
goto end_thread;
}
#ifdef __NETWARE__
- netware_reg_user(thd->ip, thd->user, "MySQL");
+ netware_reg_user(sctx->ip, sctx->user, "MySQL");
#endif
if (thd->variables.max_join_size == HA_POS_ERROR)
thd->options |= OPTION_BIG_SELECTS;
@@ -1107,7 +1128,7 @@ pthread_handler_decl(handle_one_connection,arg)
thd->set_time();
thd->init_for_queries();
- if (sys_init_connect.value_length && !(thd->master_access & SUPER_ACL))
+ if (sys_init_connect.value_length && !(sctx->master_access & SUPER_ACL))
{
execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
if (thd->query_error)
@@ -1131,8 +1152,8 @@ pthread_handler_decl(handle_one_connection,arg)
if (!thd->killed && thd->variables.log_warnings > 1)
sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
thd->thread_id,(thd->db ? thd->db : "unconnected"),
- thd->user ? thd->user : "unauthenticated",
- thd->host_or_ip,
+ sctx->user ? sctx->user : "unauthenticated",
+ sctx->host_or_ip,
(net->last_errno ? ER(net->last_errno) :
ER(ER_UNKNOWN_ERROR)));
net_send_error(thd, net->last_errno, NullS);
@@ -1195,7 +1216,8 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg)
thd->proc_info=0;
thd->version=refresh_version;
- thd->priv_user=thd->user=(char*) my_strdup("boot", MYF(MY_WME));
+ thd->security_ctx->priv_user=
+ thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
buff= (char*) thd->net.buff;
thd->init_for_queries();
@@ -1354,6 +1376,12 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
DBUG_RETURN(1);
}
+ if (thd->transaction.xid_state.xa_state != XA_NOTR)
+ {
+ my_error(ER_XAER_RMFAIL, MYF(0),
+ xa_state_names[thd->transaction.xid_state.xa_state]);
+ DBUG_RETURN(1);
+ }
switch (completion) {
case COMMIT:
/*
@@ -1590,17 +1618,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
db= db_buff;
/* Save user and privileges */
- uint save_master_access= thd->master_access;
- uint save_db_access= thd->db_access;
uint save_db_length= thd->db_length;
- char *save_user= thd->user;
- char *save_priv_user= thd->priv_user;
char *save_db= thd->db;
+ Security_context save_security_ctx= *thd->security_ctx;
USER_CONN *save_user_connect= thd->user_connect;
-
- if (!(thd->user= my_strdup(user, MYF(0))))
+
+ if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
{
- thd->user= save_user;
+ thd->security_ctx->user= save_security_ctx.user;
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
break;
}
@@ -1614,12 +1639,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* authentication failure, we shall restore old user */
if (res > 0)
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
- x_free(thd->user);
- thd->user= save_user;
- thd->priv_user= save_priv_user;
+ x_free(thd->security_ctx->user);
+ *thd->security_ctx= save_security_ctx;
thd->user_connect= save_user_connect;
- thd->master_access= save_master_access;
- thd->db_access= save_db_access;
thd->db= save_db;
thd->db_length= save_db_length;
}
@@ -1629,7 +1651,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (save_user_connect)
decrease_user_connections(save_user_connect);
x_free((gptr) save_db);
- x_free((gptr) save_user);
+ x_free((gptr) save_security_ctx.user);
}
break;
}
@@ -1971,12 +1993,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
case COM_PROCESS_INFO:
statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST],
&LOCK_status);
- if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
+ if (!thd->security_ctx->priv_user[0] &&
+ check_global_access(thd, PROCESS_ACL))
break;
mysql_log.write(thd,command,NullS);
mysqld_list_processes(thd,
- thd->master_access & PROCESS_ACL ?
- NullS : thd->priv_user, 0);
+ thd->security_ctx->master_access & PROCESS_ACL ?
+ NullS : thd->security_ctx->priv_user, 0);
break;
case COM_PROCESS_KILL:
{
@@ -2144,7 +2167,8 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
if (!thd->col_access && check_grant_db(thd,db))
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
- thd->priv_user, thd->priv_host, db);
+ thd->security_ctx->priv_user, thd->security_ctx->priv_host,
+ db);
DBUG_RETURN(1);
}
/*
@@ -2402,7 +2426,8 @@ mysql_execute_command(THD *thd)
Except for the replication thread and the 'super' users.
*/
if (opt_readonly &&
- !(thd->slave_thread || (thd->master_access & SUPER_ACL)) &&
+ !(thd->slave_thread ||
+ (thd->security_ctx->master_access & SUPER_ACL)) &&
uc_update_queries[lex->sql_command])
{
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
@@ -2673,6 +2698,13 @@ mysql_execute_command(THD *thd)
res = load_master_data(thd);
break;
#endif /* HAVE_REPLICATION */
+#ifdef HAVE_NDBCLUSTER_DB
+ case SQLCOM_SHOW_NDBCLUSTER_STATUS:
+ {
+ res = ndbcluster_show_status(thd);
+ break;
+ }
+#endif
#ifdef HAVE_INNOBASE_DB
case SQLCOM_SHOW_INNODB_STATUS:
{
@@ -3381,11 +3413,14 @@ end_with_restore_list:
res = mysql_drop_index(thd, first_table, &lex->alter_info);
break;
case SQLCOM_SHOW_PROCESSLIST:
- if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
+ if (!thd->security_ctx->priv_user[0] &&
+ check_global_access(thd,PROCESS_ACL))
break;
mysqld_list_processes(thd,
- thd->master_access & PROCESS_ACL ? NullS :
- thd->priv_user,lex->verbose);
+ (thd->security_ctx->master_access & PROCESS_ACL ?
+ NullS :
+ thd->security_ctx->priv_user),
+ lex->verbose);
break;
case SQLCOM_SHOW_STORAGE_ENGINES:
res= mysqld_show_storage_engines(thd);
@@ -3723,7 +3758,7 @@ end_with_restore_list:
select_lex->db ? is_schema_db(select_lex->db) : 0))
goto error;
- if (thd->user) // If not replication
+ if (thd->security_ctx->user) // If not replication
{
LEX_USER *user;
uint counter;
@@ -3739,9 +3774,9 @@ end_with_restore_list:
user->host.str);
// Are we trying to change a password of another user
DBUG_ASSERT(user->host.str != 0);
- if (strcmp(thd->user, user->user.str) ||
+ if (strcmp(thd->security_ctx->user, user->user.str) ||
my_strcasecmp(system_charset_info,
- user->host.str, thd->host_or_ip))
+ user->host.str, thd->security_ctx->host_or_ip))
{
// TODO: use check_change_password()
if (check_acl_user(user, &counter) && user->password.str &&
@@ -3868,8 +3903,8 @@ end_with_restore_list:
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
case SQLCOM_SHOW_GRANTS:
- if ((thd->priv_user &&
- !strcmp(thd->priv_user,lex->grant_user->user.str)) ||
+ if ((thd->security_ctx->priv_user &&
+ !strcmp(thd->security_ctx->priv_user, lex->grant_user->user.str)) ||
!check_access(thd, SELECT_ACL, "mysql",0,1,0,0))
{
res = mysql_show_grants(thd,lex->grant_user);
@@ -3905,6 +3940,12 @@ end_with_restore_list:
break;
case SQLCOM_BEGIN:
+ if (thd->transaction.xid_state.xa_state != XA_NOTR)
+ {
+ my_error(ER_XAER_RMFAIL, MYF(0),
+ xa_state_names[thd->transaction.xid_state.xa_state]);
+ break;
+ }
if (begin_trans(thd))
goto error;
send_ok(thd);
@@ -4143,7 +4184,7 @@ end_with_restore_list:
else
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- st_sp_security_context save_ctx;
+ Security_context *save_ctx;
#endif
ha_rows select_limit;
/* bits that should be cleared in thd->server_status */
@@ -4189,23 +4230,23 @@ end_with_restore_list:
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (check_routine_access(thd, EXECUTE_ACL,
- sp->m_db.str, sp->m_name.str, TRUE, 0))
+ if (check_routine_access(thd, EXECUTE_ACL,
+ sp->m_db.str, sp->m_name.str, TRUE, 0) ||
+ sp_change_security_context(thd, sp, &save_ctx))
{
#ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok;
#endif
goto error;
}
- sp_change_security_context(thd, sp, &save_ctx);
- if (save_ctx.changed &&
- check_routine_access(thd, EXECUTE_ACL,
- sp->m_db.str, sp->m_name.str, TRUE, 0))
+ if (save_ctx &&
+ check_routine_access(thd, EXECUTE_ACL,
+ sp->m_db.str, sp->m_name.str, TRUE, 0))
{
#ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok;
#endif
- sp_restore_security_context(thd, sp, &save_ctx);
+ sp_restore_security_context(thd, save_ctx);
goto error;
}
@@ -4245,7 +4286,7 @@ end_with_restore_list:
thd->variables.select_limit= select_limit;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- sp_restore_security_context(thd, sp, &save_ctx);
+ sp_restore_security_context(thd, save_ctx);
#endif
#ifndef EMBEDDED_LIBRARY
@@ -4477,10 +4518,10 @@ end_with_restore_list:
mysql_bin_log.is_open())
{
String buff;
- LEX_STRING command[3]=
- {{STRING_WITH_LEN("CREATE ")},
- {STRING_WITH_LEN("ALTER ")},
- {STRING_WITH_LEN("CREATE OR REPLACE ")}};
+ const LEX_STRING command[3]=
+ {{(char *)STRING_WITH_LEN("CREATE ")},
+ {(char *)STRING_WITH_LEN("ALTER ")},
+ {(char *)STRING_WITH_LEN("CREATE OR REPLACE ")}};
thd->clear_error();
buff.append(command[thd->lex->create_view_mode].str,
@@ -4807,6 +4848,7 @@ bool
check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
bool dont_check_global_grants, bool no_errors, bool schema_db)
{
+ Security_context *sctx= thd->security_ctx;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong db_access;
bool db_is_pattern= test(want_access & GRANT_ACL);
@@ -4815,7 +4857,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
const char *db_name;
DBUG_ENTER("check_access");
DBUG_PRINT("enter",("db: %s want_access: %lu master_access: %lu",
- db ? db : "", want_access, thd->master_access));
+ db ? db : "", want_access, sctx->master_access));
if (save_priv)
*save_priv=0;
else
@@ -4837,7 +4879,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
{
if (!no_errors)
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
- thd->priv_user, thd->priv_host, db_name);
+ sctx->priv_user,
+ sctx->priv_host, db_name);
DBUG_RETURN(TRUE);
}
else
@@ -4850,28 +4893,29 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
#ifdef NO_EMBEDDED_ACCESS_CHECKS
DBUG_RETURN(0);
#else
- if ((thd->master_access & want_access) == want_access)
+ if ((sctx->master_access & want_access) == want_access)
{
/*
If we don't have a global SELECT privilege, we have to get the database
specific access rights to be able to handle queries of type
UPDATE t1 SET a=1 WHERE b > 0
*/
- db_access= thd->db_access;
- if (!(thd->master_access & SELECT_ACL) &&
+ db_access= sctx->db_access;
+ if (!(sctx->master_access & SELECT_ACL) &&
(db && (!thd->db || db_is_pattern || strcmp(db,thd->db))))
- db_access=acl_get(thd->host, thd->ip, thd->priv_user, db, db_is_pattern);
- *save_priv=thd->master_access | db_access;
+ db_access=acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
+ db_is_pattern);
+ *save_priv=sctx->master_access | db_access;
DBUG_RETURN(FALSE);
}
- if (((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
+ if (((want_access & ~sctx->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
! db && dont_check_global_grants)
{ // We can never grant this
DBUG_PRINT("error",("No possible access"));
if (!no_errors)
my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
- thd->priv_user,
- thd->priv_host,
+ sctx->priv_user,
+ sctx->priv_host,
(thd->password ?
ER(ER_YES) :
ER(ER_NO))); /* purecov: tested */
@@ -4882,15 +4926,16 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
DBUG_RETURN(FALSE); // Allow select on anything
if (db && (!thd->db || db_is_pattern || strcmp(db,thd->db)))
- db_access=acl_get(thd->host, thd->ip, thd->priv_user, db, db_is_pattern);
+ db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
+ db_is_pattern);
else
- db_access=thd->db_access;
+ db_access= sctx->db_access;
DBUG_PRINT("info",("db_access: %lu", db_access));
/* Remove SHOW attribute and access rights we already have */
- want_access &= ~(thd->master_access | EXTRA_ACL);
+ want_access &= ~(sctx->master_access | EXTRA_ACL);
DBUG_PRINT("info",("db_access: %lu want_access: %lu",
db_access, want_access));
- db_access= ((*save_priv=(db_access | thd->master_access)) & want_access);
+ db_access= ((*save_priv=(db_access | sctx->master_access)) & want_access);
/* grant_option is set if there exists a single table or column grant */
if (db_access == want_access ||
@@ -4901,8 +4946,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
DBUG_PRINT("error",("Access denied"));
if (!no_errors)
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
- thd->priv_user,
- thd->priv_host,
+ sctx->priv_user, sctx->priv_host,
(db ? db : (thd->db ?
thd->db :
"unknown"))); /* purecov: tested */
@@ -4936,7 +4980,7 @@ bool check_global_access(THD *thd, ulong want_access)
return 0;
#else
char command[128];
- if ((thd->master_access & want_access))
+ if ((thd->security_ctx->master_access & want_access))
return 0;
get_privilege_desc(command, sizeof(command), want_access);
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
@@ -4964,7 +5008,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
{
if (!no_errors)
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
- thd->priv_user, thd->priv_host,
+ thd->security_ctx->priv_user, thd->security_ctx->priv_host,
information_schema_name.str);
return TRUE;
}
@@ -4973,7 +5017,8 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
my_tz_check_n_skip_implicit_tables(&tables,
thd->lex->time_zone_tables_used))
continue;
- if ((thd->master_access & want_access) == (want_access & ~EXTRA_ACL) &&
+ if ((thd->security_ctx->master_access & want_access) ==
+ (want_access & ~EXTRA_ACL) &&
thd->db)
tables->grant.privilege= want_access;
else if (tables->db && tables->db == thd->db)
@@ -5010,7 +5055,8 @@ check_routine_access(THD *thd, ulong want_access,char *db, char *name,
tables->db= db;
tables->table_name= tables->alias= name;
- if ((thd->master_access & want_access) == want_access && !thd->db)
+ if ((thd->security_ctx->master_access & want_access) == want_access &&
+ !thd->db)
tables->grant.privilege= want_access;
else if (check_access(thd,want_access,db,&tables->grant.privilege,
0, no_errors, test(tables->schema_table)))
@@ -5043,7 +5089,7 @@ bool check_some_routine_access(THD *thd, const char *db, const char *name,
bool is_proc)
{
ulong save_priv;
- if (thd->master_access & SHOW_PROC_ACLS)
+ if (thd->security_ctx->master_access & SHOW_PROC_ACLS)
return FALSE;
/*
There are no routines in information_schema db. So we can safely
@@ -5240,6 +5286,7 @@ void mysql_reset_thd_for_next_command(THD *thd)
thd->server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
SERVER_QUERY_NO_INDEX_USED |
SERVER_QUERY_NO_GOOD_INDEX_USED);
+ DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
thd->tmp_table_used= 0;
if (!thd->in_sub_stmt)
{
@@ -5617,8 +5664,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
and so on, the display width is ignored.
*/
char buf[32];
- my_snprintf(buf, sizeof(buf),
- "TIMESTAMP(%s)", length, system_charset_info);
+ my_snprintf(buf, sizeof(buf), "TIMESTAMP(%s)", length);
push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DEPRECATED_SYNTAX,
ER(ER_WARN_DEPRECATED_SYNTAX),
@@ -5724,7 +5770,7 @@ new_create_field(THD *thd, char *field_name, enum_field_types type,
}
if (new_field->length < new_field->decimals)
{
- my_error(ER_SCALE_BIGGER_THAN_PRECISION, MYF(0), field_name);
+ my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
DBUG_RETURN(NULL);
}
new_field->length=
@@ -5787,19 +5833,31 @@ new_create_field(THD *thd, char *field_name, enum_field_types type,
new_field->decimals= NOT_FIXED_DEC;
break;
}
- if (!length)
+ if (!length && !decimals)
{
new_field->length = FLT_DIG+6;
new_field->decimals= NOT_FIXED_DEC;
}
+ if (new_field->length < new_field->decimals &&
+ new_field->decimals != NOT_FIXED_DEC)
+ {
+ my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
+ DBUG_RETURN(NULL);
+ }
break;
case FIELD_TYPE_DOUBLE:
allowed_type_modifier= AUTO_INCREMENT_FLAG;
- if (!length)
+ if (!length && !decimals)
{
new_field->length = DBL_DIG+7;
new_field->decimals=NOT_FIXED_DEC;
}
+ if (new_field->length < new_field->decimals &&
+ new_field->decimals != NOT_FIXED_DEC)
+ {
+ my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
+ DBUG_RETURN(NULL);
+ }
break;
case FIELD_TYPE_TIMESTAMP:
if (!length)
@@ -6764,8 +6822,8 @@ void kill_one_thread(THD *thd, ulong id, bool only_kill_query)
VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (tmp)
{
- if ((thd->master_access & SUPER_ACL) ||
- !strcmp(thd->user,tmp->user))
+ if ((thd->security_ctx->master_access & SUPER_ACL) ||
+ !strcmp(thd->security_ctx->user, tmp->security_ctx->user))
{
tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
error=0;
@@ -7182,6 +7240,12 @@ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
target_tbl->table_name, "MULTI DELETE");
DBUG_RETURN(TRUE);
}
+ if (!walk->derived)
+ {
+ target_tbl->table_name= walk->table_name;
+ target_tbl->table_name_length= walk->table_name_length;
+ }
+ walk->updating= target_tbl->updating;
walk->lock_type= target_tbl->lock_type;
target_tbl->correspondent_table= walk; // Remember corresponding table
}
@@ -7390,7 +7454,7 @@ Item *negate_expression(THD *thd, Item *expr)
SYNOPSIS
default_definer()
- thd thread handler
+ Secytity_context current decurity context
definer structure where it should be assigned
RETURN
@@ -7398,14 +7462,14 @@ Item *negate_expression(THD *thd, Item *expr)
TRUE Error
*/
-bool default_view_definer(THD *thd, st_lex_user *definer)
+bool default_view_definer(Security_context *sctx, st_lex_user *definer)
{
- definer->user.str= thd->priv_user;
- definer->user.length= strlen(thd->priv_user);
- if (*thd->priv_host != 0)
+ definer->user.str= sctx->priv_user;
+ definer->user.length= strlen(sctx->priv_user);
+ if (*sctx->priv_host != 0)
{
- definer->host.str= thd->priv_host;
- definer->host.length= strlen(thd->priv_host);
+ definer->host.str= sctx->priv_host;
+ definer->host.length= strlen(sctx->priv_host);
}
else
{
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 4cda4ed108a..16433e42e3c 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -71,6 +71,7 @@ When one supplies long data for a placeholder:
#include "mysql_priv.h"
#include "sql_select.h" // for JOIN
+#include "sql_cursor.h"
#include "sp_head.h"
#include "sp.h"
#include "sp_cache.h"
@@ -81,6 +82,18 @@ When one supplies long data for a placeholder:
#include <mysql_com.h>
#endif
+/* A result class used to send cursor rows using the binary protocol. */
+
+class Select_fetch_protocol_prep: public select_send
+{
+ Protocol_prep protocol;
+public:
+ Select_fetch_protocol_prep(THD *thd);
+ virtual bool send_fields(List<Item> &list, uint flags);
+ virtual bool send_data(List<Item> &items);
+ virtual bool send_eof();
+};
+
/******************************************************************************
Prepared_statement: a statement that can contain placeholders
******************************************************************************/
@@ -89,6 +102,7 @@ class Prepared_statement: public Statement
{
public:
THD *thd;
+ Select_fetch_protocol_prep result;
Protocol *protocol;
Item_param **param_array;
uint param_count;
@@ -109,8 +123,9 @@ public:
virtual ~Prepared_statement();
void setup_set_params();
virtual Query_arena::Type type() const;
- virtual void close_cursor();
+ virtual void cleanup_stmt();
bool set_name(LEX_STRING *name);
+ inline void close_cursor() { delete cursor; cursor= 0; }
bool prepare(const char *packet, uint packet_length);
bool execute(String *expanded_query, bool open_cursor);
@@ -140,8 +155,6 @@ inline bool is_param_null(const uchar *pos, ulong param_no)
return pos[param_no/8] & (1 << (param_no & 7));
}
-enum { STMT_QUERY_LOG_LENGTH= 8192 };
-
/*
Find a prepared statement in the statement map by id.
@@ -1264,7 +1277,7 @@ static int mysql_test_select(Prepared_statement *stmt,
It is not SELECT COMMAND for sure, so setup_tables will be called as
usual, and we pass 0 as setup_tables_done_option
*/
- if (unit->prepare(thd, 0, 0, ""))
+ if (unit->prepare(thd, 0, 0))
goto error;
if (!lex->describe && !text_protocol)
{
@@ -1395,7 +1408,7 @@ static bool select_like_stmt_test(Prepared_statement *stmt,
thd->used_tables= 0; // Updated by setup_fields
/* Calls JOIN::prepare */
- DBUG_RETURN(lex->unit.prepare(thd, 0, setup_tables_done_option, ""));
+ DBUG_RETURN(lex->unit.prepare(thd, 0, setup_tables_done_option));
}
/*
@@ -1785,19 +1798,6 @@ static bool init_param_array(Prepared_statement *stmt)
}
-/* Cleanup PS after execute/prepare and restore THD state */
-
-static void cleanup_stmt_and_thd_after_use(Statement *stmt, THD *thd)
-{
- DBUG_ENTER("cleanup_stmt_and_thd_after_use");
- stmt->lex->unit.cleanup();
- cleanup_items(stmt->free_list);
- thd->rollback_item_tree_changes();
- thd->cleanup_after_query();
- DBUG_VOID_RETURN;
-}
-
-
/*
COM_STMT_PREPARE handler.
@@ -2129,8 +2129,8 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
lex->result->cleanup();
lex->result->set_thd(thd);
}
-
- DBUG_VOID_RETURN;
+ thd->allow_sum_func= 0;
+ DBUG_VOID_RETURN;
}
@@ -2221,16 +2221,14 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
test(flags & (ulong) CURSOR_TYPE_READ_ONLY));
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
- if (rc)
- goto err;
- mysql_log.write(thd, COM_STMT_EXECUTE, "[%lu] %s", stmt->id, thd->query);
+ if (rc == 0)
+ mysql_log.write(thd, COM_STMT_EXECUTE, "[%lu] %s", stmt->id, thd->query);
DBUG_VOID_RETURN;
set_params_data_err:
my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_execute");
-err:
reset_stmt_params(stmt);
DBUG_VOID_RETURN;
}
@@ -2285,14 +2283,16 @@ void mysql_sql_stmt_execute(THD *thd)
if (stmt->set_params_from_vars(stmt, lex->prepared_stmt_params,
&expanded_query))
- {
- my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE");
- DBUG_VOID_RETURN;
- }
+ goto set_params_data_err;
(void) stmt->execute(&expanded_query, FALSE);
DBUG_VOID_RETURN;
+
+set_params_data_err:
+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE");
+ reset_stmt_params(stmt);
+ DBUG_VOID_RETURN;
}
@@ -2313,7 +2313,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
ulong num_rows= uint4korr(packet+4);
Prepared_statement *stmt;
Statement stmt_backup;
- Cursor *cursor;
+ Server_side_cursor *cursor;
DBUG_ENTER("mysql_stmt_fetch");
statistic_increment(thd->status_var.com_stmt_fetch, &LOCK_status);
@@ -2321,7 +2321,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
DBUG_VOID_RETURN;
cursor= stmt->cursor;
- if (!cursor || !cursor->is_open())
+ if (!cursor)
{
my_error(ER_STMT_HAS_NO_OPEN_CURSOR, MYF(0), stmt_id);
DBUG_VOID_RETURN;
@@ -2333,25 +2333,16 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), QUERY_PRIOR);
- thd->protocol= stmt->protocol; // Switch to binary protocol
cursor->fetch(num_rows);
- thd->protocol= &thd->protocol_simple; // Use normal protocol
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
if (!cursor->is_open())
{
- /* We're done with the fetch: reset PS for next execution */
- cleanup_stmt_and_thd_after_use(stmt, thd);
+ stmt->close_cursor();
+ thd->cursor= 0;
reset_stmt_params(stmt);
- /*
- Must be the last, as some memory is still needed for
- the previous calls.
- */
- free_root(cursor->mem_root, MYF(0));
- if (cursor->close_at_commit)
- thd->stmt_map.erase_transient_cursor(stmt);
}
thd->restore_backup_statement(stmt, &stmt_backup);
@@ -2384,14 +2375,19 @@ void mysql_stmt_reset(THD *thd, char *packet)
/* There is always space for 4 bytes in buffer */
ulong stmt_id= uint4korr(packet);
Prepared_statement *stmt;
- Cursor *cursor;
DBUG_ENTER("mysql_stmt_reset");
statistic_increment(thd->status_var.com_stmt_reset, &LOCK_status);
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset")))
DBUG_VOID_RETURN;
- stmt->close_cursor(); /* will reset statement params */
+ stmt->close_cursor();
+
+ /*
+ Clear parameters from data which could be set by
+ mysql_stmt_send_long_data() call.
+ */
+ reset_stmt_params(stmt);
stmt->state= Query_arena::PREPARED;
@@ -2533,11 +2529,65 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
}
+/***************************************************************************
+ Select_fetch_protocol_prep
+****************************************************************************/
+
+Select_fetch_protocol_prep::Select_fetch_protocol_prep(THD *thd)
+ :protocol(thd)
+{}
+
+bool Select_fetch_protocol_prep::send_fields(List<Item> &list, uint flags)
+{
+ bool rc;
+ Protocol *save_protocol= thd->protocol;
+
+ /*
+ Protocol::send_fields caches the information about column types:
+ this information is later used to send data. Therefore, the same
+ dedicated Protocol object must be used for all operations with
+ a cursor.
+ */
+ thd->protocol= &protocol;
+ rc= select_send::send_fields(list, flags);
+ thd->protocol= save_protocol;
+
+ return rc;
+}
+
+bool Select_fetch_protocol_prep::send_eof()
+{
+ Protocol *save_protocol= thd->protocol;
+
+ thd->protocol= &protocol;
+ ::send_eof(thd);
+ thd->protocol= save_protocol;
+ return FALSE;
+}
+
+
+bool
+Select_fetch_protocol_prep::send_data(List<Item> &fields)
+{
+ Protocol *save_protocol= thd->protocol;
+ bool rc;
+
+ thd->protocol= &protocol;
+ rc= select_send::send_data(fields);
+ thd->protocol= save_protocol;
+ return rc;
+}
+
+/***************************************************************************
+ Prepared_statement
+****************************************************************************/
+
Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg)
:Statement(INITIALIZED, ++thd_arg->statement_id_counter,
thd_arg->variables.query_alloc_block_size,
thd_arg->variables.query_prealloc_size),
thd(thd_arg),
+ result(thd_arg),
protocol(protocol_arg),
param_array(0),
param_count(0),
@@ -2585,17 +2635,7 @@ Prepared_statement::~Prepared_statement()
{
DBUG_ENTER("Prepared_statement::~Prepared_statement");
DBUG_PRINT("enter",("stmt: %p cursor: %p", this, cursor));
- if (cursor)
- {
- if (cursor->is_open())
- {
- cursor->close(FALSE);
- cleanup_items(free_list);
- thd->rollback_item_tree_changes();
- free_root(cursor->mem_root, MYF(0));
- }
- cursor->Cursor::~Cursor();
- }
+ delete cursor;
/*
We have to call free on the items even if cleanup is called as some items,
like Item_param, don't free everything until free_items()
@@ -2612,25 +2652,18 @@ Query_arena::Type Prepared_statement::type() const
}
-void Prepared_statement::close_cursor()
+void Prepared_statement::cleanup_stmt()
{
- DBUG_ENTER("Prepared_statement::close_cursor");
+ DBUG_ENTER("Prepared_statement::cleanup_stmt");
DBUG_PRINT("enter",("stmt: %p", this));
- if (cursor && cursor->is_open())
- {
- thd->change_list= cursor->change_list;
- cursor->close(FALSE);
- cleanup_stmt_and_thd_after_use(this, thd);
- free_root(cursor->mem_root, MYF(0));
- if (cursor->close_at_commit)
- thd->stmt_map.erase_transient_cursor(this);
- }
- /*
- Clear parameters from data which could be set by
- mysql_stmt_send_long_data() call.
- */
- reset_stmt_params(this);
+ /* The order is important */
+ lex->unit.cleanup();
+ cleanup_items(free_list);
+ thd->cleanup_after_query();
+ close_thread_tables(thd);
+ thd->rollback_item_tree_changes();
+
DBUG_VOID_RETURN;
}
@@ -2734,14 +2767,13 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
if (rc == 0)
rc= check_prepared_statement(this, name.str != 0);
- if (rc && thd->lex->sphead)
+ if (rc && lex->sphead)
{
- delete thd->lex->sphead;
- thd->lex->sphead= NULL;
+ delete lex->sphead;
+ lex->sphead= NULL;
}
lex_end(lex);
- close_thread_tables(thd);
- cleanup_stmt_and_thd_after_use(this, thd);
+ cleanup_stmt();
thd->restore_backup_statement(this, &stmt_backup);
thd->stmt_arena= old_stmt_arena;
@@ -2781,7 +2813,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
Statement stmt_backup;
Query_arena *old_stmt_arena;
Item *old_free_list;
- bool rc= 1;
+ bool rc= TRUE;
statistic_increment(thd->status_var.com_stmt_execute, &LOCK_status);
@@ -2789,18 +2821,35 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
if (state == Query_arena::ERROR)
{
my_message(last_errno, last_error, MYF(0));
- return 1;
+ return TRUE;
}
if (flags & IS_IN_USE)
{
my_error(ER_PS_NO_RECURSION, MYF(0));
- return 1;
+ return TRUE;
}
+
+ /*
+ For SHOW VARIABLES lex->result is NULL, as it's a non-SELECT
+ command. For such queries we don't return an error and don't
+ open a cursor -- the client library will recognize this case and
+ materialize the result set.
+ For SELECT statements lex->result is created in
+ check_prepared_statement. lex->result->simple_select() is FALSE
+ in INSERT ... SELECT and similar commands.
+ */
+
+ if (open_cursor && lex->result && !lex->result->simple_select())
+ {
+ DBUG_PRINT("info",("Cursor asked for not SELECT stmt"));
+ my_error(ER_SP_BAD_CURSOR_QUERY, MYF(0));
+ return TRUE;
+ }
+
/* In case the command has a call to SP which re-uses this statement name */
flags|= IS_IN_USE;
- if (cursor && cursor->is_open())
- close_cursor();
+ close_cursor();
/*
If the free_list is not empty, we'll wrongly free some externally
@@ -2808,32 +2857,6 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
*/
DBUG_ASSERT(thd->change_list.is_empty());
DBUG_ASSERT(thd->free_list == NULL);
- if (open_cursor)
- {
- if (!lex->result || !lex->result->simple_select())
- {
- DBUG_PRINT("info",("Cursor asked for not SELECT stmt"));
- /*
- If lex->result is set in the parser, this is not a SELECT
- statement: we can't open a cursor for it.
- */
- my_error(ER_SP_BAD_CURSOR_QUERY, MYF(0));
- goto error;
- }
-
- DBUG_PRINT("info",("Using READ_ONLY cursor"));
- if (!cursor && !(cursor= new (mem_root) Cursor(thd)))
- goto error;
- /* If lex->result is set, mysql_execute_command will use it */
- lex->result= &cursor->result;
- protocol= &cursor->protocol;
- thd->lock_id= &cursor->lock_id;
- /*
- Currently cursors can be used only from C API, so
- we don't have to create an own memory root for them:
- the one in THD is clean and can be used.
- */
- }
thd->set_n_backup_statement(this, &stmt_backup);
if (expanded_query->length() &&
alloc_query(thd, (char*) expanded_query->ptr(),
@@ -2862,38 +2885,27 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
reinit_stmt_before_use(thd, lex);
thd->protocol= protocol; /* activate stmt protocol */
- mysql_execute_command(thd);
+ rc= open_cursor ? mysql_open_cursor(thd, (uint) ALWAYS_MATERIALIZED_CURSOR,
+ &result, &cursor) :
+ mysql_execute_command(thd);
thd->protocol= &thd->protocol_simple; /* use normal protocol */
- if (cursor && cursor->is_open())
- {
- /*
- It's safer if we grab THD state after mysql_execute_command is
- finished and not in Cursor::open(), because currently the call to
- Cursor::open is buried deep in JOIN::exec of the top level join.
- */
- cursor->init_from_thd(thd);
+ /* Assert that if an error, no cursor is open */
+ DBUG_ASSERT(! (rc && cursor));
- if (cursor->close_at_commit)
- thd->stmt_map.add_transient_cursor(this);
- }
- else
+ if (! cursor)
{
- close_thread_tables(thd);
- cleanup_stmt_and_thd_after_use(this, thd);
+ cleanup_stmt();
reset_stmt_params(this);
}
thd->set_statement(&stmt_backup);
- thd->lock_id= &thd->main_lock_id;
thd->stmt_arena= old_stmt_arena;
if (state == Query_arena::PREPARED)
state= Query_arena::EXECUTED;
- rc= 0;
error:
- thd->lock_id= &thd->main_lock_id;
flags&= ~IS_IN_USE;
return rc;
}
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 3880aa428b9..154e828b47e 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -133,11 +133,12 @@ static TABLE_LIST *
rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
{
TABLE_LIST *ren_table,*new_table;
+ frm_type_enum frm_type;
DBUG_ENTER("rename_tables");
for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
{
- db_type table_type;
+ int rc= 1;
char name[FN_REFLEN];
const char *new_alias, *old_alias;
@@ -164,19 +165,36 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
ren_table->db, old_alias,
reg_ext);
unpack_filename(name, name);
- if ((table_type=get_table_type(thd, name)) == DB_TYPE_UNKNOWN)
- {
- my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
- if (!skip_error)
- DBUG_RETURN(ren_table);
- }
- else if (mysql_rename_table(table_type,
- ren_table->db, old_alias,
- new_table->db, new_alias))
+
+ frm_type= mysql_frm_type(name);
+ switch (frm_type)
{
- if (!skip_error)
- DBUG_RETURN(ren_table);
+ case FRMTYPE_TABLE:
+ {
+ db_type table_type;
+ if ((table_type= get_table_type(thd, name)) == DB_TYPE_UNKNOWN)
+ my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
+ else
+ rc= mysql_rename_table(table_type, ren_table->db, old_alias,
+ new_table->db, new_alias);
+ break;
+ }
+ case FRMTYPE_VIEW:
+ /* change of schema is not allowed */
+ if (strcmp(ren_table->db, new_table->db))
+ my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db,
+ new_table->db);
+ else
+ rc= mysql_rename_view(thd, new_alias, ren_table);
+ break;
+ default:
+ DBUG_ASSERT(0); // should never happen
+ case FRMTYPE_ERROR:
+ my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
+ break;
}
+ if (rc && !skip_error)
+ DBUG_RETURN(ren_table);
}
DBUG_RETURN(0);
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index b8f9d30faab..a02a61b7a86 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -23,6 +23,7 @@
#include "mysql_priv.h"
#include "sql_select.h"
+#include "sql_cursor.h"
#include <m_ctype.h>
#include <hash.h>
@@ -107,20 +108,15 @@ static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
static bool open_tmp_table(TABLE *table);
static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
ulong options);
-static Next_select_func setup_end_select_func(JOIN *join);
static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
Procedure *proc);
static enum_nested_loop_state
-sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
-static enum_nested_loop_state
evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
int error, my_bool *report_error);
static enum_nested_loop_state
evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab);
static enum_nested_loop_state
-sub_select(JOIN *join,JOIN_TAB *join_tab, bool end_of_records);
-static enum_nested_loop_state
flush_cached_records(JOIN *join, JOIN_TAB *join_tab, bool skip_last);
static enum_nested_loop_state
end_send(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
@@ -1728,262 +1724,6 @@ JOIN::destroy()
DBUG_RETURN(error);
}
-
-/************************* Cursor ******************************************/
-
-Cursor::Cursor(THD *thd)
- :Query_arena(&main_mem_root, INITIALIZED),
- join(0), unit(0),
- protocol(thd),
- close_at_commit(FALSE)
-{
- /* We will overwrite it at open anyway. */
- init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
- thr_lock_owner_init(&lock_id, &thd->lock_info);
- bzero((void*) ht_info, sizeof(ht_info));
-}
-
-
-void
-Cursor::init_from_thd(THD *thd)
-{
- Engine_info *info;
- /*
- We need to save and reset thd->mem_root, otherwise it'll be freed
- later in mysql_parse.
-
- We can't just change the thd->mem_root here as we want to keep the
- things that are already allocated in thd->mem_root for Cursor::fetch()
- */
- main_mem_root= *thd->mem_root;
- state= thd->stmt_arena->state;
- /* Allocate new memory root for thd */
- init_sql_alloc(thd->mem_root,
- thd->variables.query_alloc_block_size,
- thd->variables.query_prealloc_size);
-
- /*
- The same is true for open tables and lock: save tables and zero THD
- pointers to prevent table close in close_thread_tables (This is a part
- of the temporary solution to make cursors work with minimal changes to
- the current source base).
- */
- derived_tables= thd->derived_tables;
- open_tables= thd->open_tables;
- lock= thd->lock;
- query_id= thd->query_id;
- free_list= thd->free_list;
- change_list= thd->change_list;
- reset_thd(thd);
- /* Now we have an active cursor and can cause a deadlock */
- thd->lock_info.n_cursors++;
-
- close_at_commit= FALSE; /* reset in case we're reusing the cursor */
- info= &ht_info[0];
- for (handlerton **pht= thd->transaction.stmt.ht; *pht; pht++)
- {
- const handlerton *ht= *pht;
- close_at_commit|= test(ht->flags & HTON_CLOSE_CURSORS_AT_COMMIT);
- if (ht->create_cursor_read_view)
- {
- info->ht= ht;
- info->read_view= (ht->create_cursor_read_view)();
- ++info;
- }
- }
- /*
- XXX: thd->locked_tables is not changed.
- What problems can we have with it if cursor is open?
- TODO: must be fixed because of the prelocked mode.
- */
-}
-
-
-void
-Cursor::reset_thd(THD *thd)
-{
- thd->derived_tables= 0;
- thd->open_tables= 0;
- thd->lock= 0;
- thd->free_list= 0;
- thd->change_list.empty();
-}
-
-
-int
-Cursor::open(JOIN *join_arg)
-{
- join= join_arg;
- THD *thd= join->thd;
- /* First non-constant table */
- JOIN_TAB *join_tab= join->join_tab + join->const_tables;
- DBUG_ENTER("Cursor::open");
-
- /*
- Send fields description to the client; server_status is sent
- in 'EOF' packet, which ends send_fields().
- */
- thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
- join->result->send_fields(*join->fields, Protocol::SEND_NUM_ROWS);
- ::send_eof(thd);
- thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
-
- /* Prepare JOIN for reading rows. */
- join->tmp_table= 0;
- join->join_tab[join->tables-1].next_select= setup_end_select_func(join);
- join->send_records= 0;
- join->fetch_limit= join->unit->offset_limit_cnt;
-
- /* Disable JOIN CACHE as it is not working with cursors yet */
- for (JOIN_TAB *tab= join_tab;
- tab != join->join_tab + join->tables - 1;
- tab++)
- {
- if (tab->next_select == sub_select_cache)
- tab->next_select= sub_select;
- }
-
- DBUG_ASSERT(join_tab->table->reginfo.not_exists_optimize == 0);
- DBUG_ASSERT(join_tab->not_used_in_distinct == 0);
- /*
- null_row is set only if row not found and it's outer join: should never
- happen for the first table in join_tab list
- */
- DBUG_ASSERT(join_tab->table->null_row == 0);
- DBUG_RETURN(0);
-}
-
-
-/*
- DESCRIPTION
- Fetch next num_rows rows from the cursor and sent them to the client
- PRECONDITION:
- Cursor is open
- RETURN VALUES:
- none, this function will send error or OK to network if necessary.
-*/
-
-void
-Cursor::fetch(ulong num_rows)
-{
- THD *thd= join->thd;
- JOIN_TAB *join_tab= join->join_tab + join->const_tables;
- enum_nested_loop_state error= NESTED_LOOP_OK;
- Query_arena backup_arena;
- Engine_info *info;
- DBUG_ENTER("Cursor::fetch");
- DBUG_PRINT("enter",("rows: %lu", num_rows));
-
- DBUG_ASSERT(thd->derived_tables == 0 && thd->open_tables == 0 &&
- thd->lock == 0);
-
- thd->derived_tables= derived_tables;
- thd->open_tables= open_tables;
- thd->lock= lock;
- thd->query_id= query_id;
- thd->change_list= change_list;
- /* save references to memory, allocated during fetch */
- thd->set_n_backup_active_arena(this, &backup_arena);
-
- for (info= ht_info; info->read_view ; info++)
- (info->ht->set_cursor_read_view)(info->read_view);
-
- join->fetch_limit+= num_rows;
-
- error= sub_select(join, join_tab, 0);
- if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS)
- error= sub_select(join,join_tab,1);
- if (error == NESTED_LOOP_QUERY_LIMIT)
- error= NESTED_LOOP_OK; /* select_limit used */
- if (error == NESTED_LOOP_CURSOR_LIMIT)
- join->resume_nested_loop= TRUE;
-
-#ifdef USING_TRANSACTIONS
- ha_release_temporary_latches(thd);
-#endif
- /* Grab free_list here to correctly free it in close */
- thd->restore_active_arena(this, &backup_arena);
-
- for (info= ht_info; info->read_view; info++)
- (info->ht->set_cursor_read_view)(0);
-
- if (error == NESTED_LOOP_CURSOR_LIMIT)
- {
- /* Fetch limit worked, possibly more rows are there */
- thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
- ::send_eof(thd);
- thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
- change_list= thd->change_list;
- reset_thd(thd);
- }
- else
- {
- close(TRUE);
- if (error == NESTED_LOOP_OK)
- {
- thd->server_status|= SERVER_STATUS_LAST_ROW_SENT;
- ::send_eof(thd);
- thd->server_status&= ~SERVER_STATUS_LAST_ROW_SENT;
- }
- else if (error != NESTED_LOOP_KILLED)
- my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
- }
- DBUG_VOID_RETURN;
-}
-
-
-void
-Cursor::close(bool is_active)
-{
- THD *thd= join->thd;
- DBUG_ENTER("Cursor::close");
-
- /*
- In case of UNIONs JOIN is freed inside of unit->cleanup(),
- otherwise in select_lex->cleanup().
- */
- if (unit)
- (void) unit->cleanup();
- else
- (void) join->select_lex->cleanup();
-
- for (Engine_info *info= ht_info; info->read_view; info++)
- {
- (info->ht->close_cursor_read_view)(info->read_view);
- info->read_view= 0;
- info->ht= 0;
- }
-
- if (is_active)
- close_thread_tables(thd);
- else
- {
- /* XXX: Another hack: closing tables used in the cursor */
- DBUG_ASSERT(lock || open_tables || derived_tables);
-
- TABLE *tmp_derived_tables= thd->derived_tables;
- MYSQL_LOCK *tmp_lock= thd->lock;
-
- thd->open_tables= open_tables;
- thd->derived_tables= derived_tables;
- thd->lock= lock;
- close_thread_tables(thd);
-
- thd->open_tables= tmp_derived_tables;
- thd->derived_tables= tmp_derived_tables;
- thd->lock= tmp_lock;
- }
- thd->lock_info.n_cursors--; /* Decrease the number of active cursors */
- join= 0;
- unit= 0;
- free_items();
- change_list.empty();
- DBUG_VOID_RETURN;
-}
-
-
-/*********************************************************************/
-
/*
An entry point to single-unit select (a select without UNION).
@@ -2063,9 +1803,9 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
}
else
{
- if (join->prepare(rref_pointer_array, tables, wild_num,
- conds, og_num, order, group, having, proc_param,
- select_lex, unit))
+ if (err= join->prepare(rref_pointer_array, tables, wild_num,
+ conds, og_num, order, group, having, proc_param,
+ select_lex, unit))
{
goto err;
}
@@ -2080,9 +1820,9 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
DBUG_RETURN(TRUE);
thd->proc_info="init";
thd->used_tables=0; // Updated by setup_fields
- if (join->prepare(rref_pointer_array, tables, wild_num,
- conds, og_num, order, group, having, proc_param,
- select_lex, unit))
+ if (err= join->prepare(rref_pointer_array, tables, wild_num,
+ conds, og_num, order, group, having, proc_param,
+ select_lex, unit))
{
goto err;
}
@@ -2124,7 +1864,7 @@ err:
if (free_join)
{
thd->proc_info="end";
- err= select_lex->cleanup();
+ err|= select_lex->cleanup();
DBUG_RETURN(err || thd->net.report_error);
}
DBUG_RETURN(join->error);
@@ -2658,7 +2398,6 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
field Field used in comparision
eq_func True if we used =, <=> or IS NULL
value Value used for comparison with field
- Is NULL for BETWEEN and IN
usable_tables Tables which can be used for key optimization
NOTES
@@ -2682,6 +2421,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
!field->table->maybe_null || field->null_ptr)
return; // Not a key. Skip it
exists_optimize= KEY_OPTIMIZE_EXISTS;
+ DBUG_ASSERT(num_values == 1);
}
else
{
@@ -2733,7 +2473,26 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
eq_func is NEVER true when num_values > 1
*/
if (!eq_func)
- return;
+ {
+ /*
+ Additional optimization: if we're processing
+ "t.key BETWEEN c1 AND c1" then proceed as if we were processing
+ "t.key = c1".
+ TODO: This is a very limited fix. A more generic fix is possible.
+ There are 2 options:
+ A) Make equality propagation code be able to handle BETWEEN
+ (including cases like t1.key BETWEEN t2.key AND t3.key)
+ B) Make range optimizer to infer additional "t.key = c" equalities
+ and use them in equality propagation process (see details in
+ OptimizerKBAndTodo)
+ */
+ if ((cond->functype() == Item_func::BETWEEN) &&
+ value[0]->eq(value[1], field->binary()))
+ eq_func= TRUE;
+ else
+ return;
+ }
+
if (field->result_type() == STRING_RESULT)
{
if ((*value)->result_type() != STRING_RESULT)
@@ -2760,7 +2519,6 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
}
}
}
- DBUG_ASSERT(num_values == 1);
/*
For the moment eq_func is always true. This slot is reserved for future
extensions where we want to remembers other things than just eq comparisons
@@ -5991,7 +5749,7 @@ void JOIN::join_free(bool full)
cleanup(full);
for (unit= select_lex->first_inner_unit(); unit; unit= unit->next_unit())
- for (sl= unit->first_select_in_union(); sl; sl= sl->next_select())
+ for (sl= unit->first_select(); sl; sl= sl->next_select())
{
JOIN *join= sl->join;
if (join)
@@ -8092,18 +7850,24 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
if (field->maybe_null && !field->field->maybe_null())
{
result= create_tmp_field_from_item(thd, item, table, NULL,
- modify_item, convert_blob_length);
+ modify_item, convert_blob_length);
*from_field= field->field;
if (result && modify_item)
- ((Item_field*)item)->result_field= result;
+ field->result_field= result;
}
- else if (table_cant_handle_bit_fields && field->field->type() == FIELD_TYPE_BIT)
+ else if (table_cant_handle_bit_fields && field->field->type() ==
+ FIELD_TYPE_BIT)
+ {
+ *from_field= field->field;
result= create_tmp_field_from_item(thd, item, table, copy_func,
modify_item, convert_blob_length);
+ if (result && modify_item)
+ field->result_field= result;
+ }
else
result= create_tmp_field_from_field(thd, (*from_field= field->field),
item->name, table,
- modify_item ? (Item_field*) item :
+ modify_item ? field :
NULL,
convert_blob_length);
if (orig_type == Item::REF_ITEM && orig_modify)
@@ -8137,9 +7901,31 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
/*
Create a temp table according to a field list.
- Set distinct if duplicates could be removed
- Given fields field pointers are changed to point at tmp_table
- for send_fields
+
+ SYNOPSIS
+ create_tmp_table()
+ thd thread handle
+ param a description used as input to create the table
+ fields list of items that will be used to define
+ column types of the table (also see NOTES)
+ group TODO document
+ distinct should table rows be distinct
+ save_sum_fields see NOTES
+ select_options
+ rows_limit
+ table_alias possible name of the temporary table that can be used
+ for name resolving; can be "".
+
+ DESCRIPTION
+ Given field pointers are changed to point at tmp_table for
+ send_fields. The table object is self contained: it's
+ allocated in its own memory root, as well as Field objects
+ created for table columns.
+ This function will replace Item_sum items in 'fields' list with
+ corresponding Item_field items, pointing at the fields in the
+ temporary table, unless this was prohibited by TRUE
+ value of argument save_sum_fields. The Item_field objects
+ are created in THD memory root.
*/
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
@@ -8153,6 +7939,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ulonglong select_options, ha_rows rows_limit,
char *table_alias)
{
+ MEM_ROOT *mem_root_save, own_root;
TABLE *table;
uint i,field_count,null_count,null_pack_length;
uint hidden_null_count, hidden_null_pack_length, hidden_field_count;
@@ -8217,29 +8004,33 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
field_count=param->field_count+param->func_count+param->sum_func_count;
hidden_field_count=param->hidden_field_count;
- if (!my_multi_malloc(MYF(MY_WME),
- &table,sizeof(*table),
- &reg_field, sizeof(Field*)*(field_count+1),
- &blob_field, sizeof(uint)*(field_count+1),
- &from_field, sizeof(Field*)*field_count,
- &copy_func,sizeof(*copy_func)*(param->func_count+1),
- &param->keyinfo,sizeof(*param->keyinfo),
- &key_part_info,
- sizeof(*key_part_info)*(param->group_parts+1),
- &param->start_recinfo,
- sizeof(*param->recinfo)*(field_count*2+4),
- &tmpname,(uint) strlen(path)+1,
- &group_buff,group && ! using_unique_constraint ?
- param->group_length : 0,
- NullS))
+
+ init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
+
+ if (!multi_alloc_root(&own_root,
+ &table, sizeof(*table),
+ &reg_field, sizeof(Field*) * (field_count+1),
+ &blob_field, sizeof(uint)*(field_count+1),
+ &from_field, sizeof(Field*)*field_count,
+ &copy_func, sizeof(*copy_func)*(param->func_count+1),
+ &param->keyinfo, sizeof(*param->keyinfo),
+ &key_part_info,
+ sizeof(*key_part_info)*(param->group_parts+1),
+ &param->start_recinfo,
+ sizeof(*param->recinfo)*(field_count*2+4),
+ &tmpname, (uint) strlen(path)+1,
+ &group_buff, group && ! using_unique_constraint ?
+ param->group_length : 0,
+ NullS))
{
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
DBUG_RETURN(NULL); /* purecov: inspected */
}
- if (!(param->copy_field=copy=new Copy_field[field_count]))
+ /* Copy_field belongs to TMP_TABLE_PARAM, allocate it in THD mem_root */
+ if (!(param->copy_field= copy= new (thd->mem_root) Copy_field[field_count]))
{
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
- my_free((gptr) table,MYF(0)); /* purecov: inspected */
+ free_root(&own_root, MYF(0)); /* purecov: inspected */
DBUG_RETURN(NULL); /* purecov: inspected */
}
param->items_to_copy= copy_func;
@@ -8249,6 +8040,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
bzero((char*) table,sizeof(*table));
bzero((char*) reg_field,sizeof(Field*)*(field_count+1));
bzero((char*) from_field,sizeof(Field*)*field_count);
+
+ table->mem_root= own_root;
+ mem_root_save= thd->mem_root;
+ thd->mem_root= &table->mem_root;
+
table->field=reg_field;
table->alias= table_alias;
table->reginfo.lock_type=TL_WRITE; /* Will be updated */
@@ -8315,7 +8111,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
Field *new_field=
create_tmp_field(thd, table, arg, arg->type(), &copy_func,
tmp_from_field, group != 0,not_all_columns,
- group || distinct,
+ distinct,
param->convert_blob_length);
if (!new_field)
goto err; // Should be OOM
@@ -8326,6 +8122,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
*blob_field++= (uint) (reg_field - table->field);
blob_count++;
}
+ if (new_field->type() == FIELD_TYPE_BIT)
+ total_uneven_bit_length+= new_field->field_length & 7;
new_field->field_index= (uint) (reg_field - table->field);
*(reg_field++)= new_field;
if (new_field->real_type() == MYSQL_TYPE_STRING ||
@@ -8334,7 +8132,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
string_count++;
string_total_length+= new_field->pack_length();
}
+ thd->mem_root= mem_root_save;
thd->change_item_tree(argp, new Item_field(new_field));
+ thd->mem_root= &table->mem_root;
if (!(new_field->flags & NOT_NULL_FLAG))
{
null_count++;
@@ -8360,12 +8160,16 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
write rows to the temporary table.
We here distinguish between UNION and multi-table-updates by the fact
that in the later case group is set to the row pointer.
+
+ The test for item->marker == 4 is ensure we don't create a group-by
+ key over a bit field as heap tables can't handle that.
*/
Field *new_field= (param->schema_table) ?
create_tmp_field_for_schema(thd, item, table) :
create_tmp_field(thd, table, item, type, &copy_func,
tmp_from_field, group != 0,
- not_all_columns || group != 0, 0,
+ not_all_columns || group != 0,
+ item->marker == 4,
param->convert_blob_length);
if (!new_field)
@@ -8398,7 +8202,14 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
*(reg_field++) =new_field;
}
if (!--hidden_field_count)
+ {
+ /*
+ This was the last hidden field; Remember how many hidden fields could
+ have null
+ */
hidden_null_count=null_count;
+ null_count= 0;
+ }
}
DBUG_ASSERT(field_count >= (uint) (reg_field - table->field));
field_count= (uint) (reg_field - table->field);
@@ -8438,8 +8249,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
null_count++;
}
hidden_null_pack_length=(hidden_null_count+7)/8;
- null_pack_length= hidden_null_count +
- (null_count + total_uneven_bit_length + 7) / 8;
+ null_pack_length= (hidden_null_pack_length +
+ (null_count + total_uneven_bit_length + 7) / 8);
reclength+=null_pack_length;
if (!reclength)
reclength=1; // Dummy select
@@ -8454,7 +8265,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
{
uint alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
table->s->rec_buff_length= alloc_length;
- if (!(table->record[0]= (byte *) my_malloc(alloc_length*3, MYF(MY_WME))))
+ if (!(table->record[0]= (byte*)
+ alloc_root(&table->mem_root, alloc_length*3)))
goto err;
table->record[1]= table->record[0]+alloc_length;
table->s->default_values= table->record[1]+alloc_length;
@@ -8640,8 +8452,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->s->uniques= 1;
}
if (!(key_part_info= (KEY_PART_INFO*)
- sql_calloc((keyinfo->key_parts)*sizeof(KEY_PART_INFO))))
+ alloc_root(&table->mem_root,
+ keyinfo->key_parts * sizeof(KEY_PART_INFO))))
goto err;
+ bzero((void*) key_part_info, keyinfo->key_parts * sizeof(KEY_PART_INFO));
table->key_info=keyinfo;
keyinfo->key_part=key_part_info;
keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
@@ -8689,10 +8503,15 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (create_myisam_tmp_table(table,param,select_options))
goto err;
}
- if (!open_tmp_table(table))
- DBUG_RETURN(table);
+ if (open_tmp_table(table))
+ goto err;
- err:
+ thd->mem_root= mem_root_save;
+
+ DBUG_RETURN(table);
+
+err:
+ thd->mem_root= mem_root_save;
free_tmp_table(thd,table); /* purecov: inspected */
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
DBUG_RETURN(NULL); /* purecov: inspected */
@@ -8837,11 +8656,12 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
if (table->s->keys)
{ // Get keys for ni_create
bool using_unique_constraint=0;
- HA_KEYSEG *seg= (HA_KEYSEG*) sql_calloc(sizeof(*seg) *
- keyinfo->key_parts);
+ HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root,
+ sizeof(*seg) * keyinfo->key_parts);
if (!seg)
goto err;
+ bzero(seg, sizeof(*seg) * keyinfo->key_parts);
if (keyinfo->key_length >= table->file->max_key_length() ||
keyinfo->key_parts > table->file->max_key_parts() ||
table->s->uniques)
@@ -8938,13 +8758,14 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
void
free_tmp_table(THD *thd, TABLE *entry)
{
+ MEM_ROOT own_root= entry->mem_root;
const char *save_proc_info;
DBUG_ENTER("free_tmp_table");
DBUG_PRINT("enter",("table: %s",entry->alias));
save_proc_info=thd->proc_info;
thd->proc_info="removing tmp table";
- free_blobs(entry);
+
if (entry->file)
{
if (entry->db_stat)
@@ -8965,12 +8786,11 @@ free_tmp_table(THD *thd, TABLE *entry)
/* free blobs */
for (Field **ptr=entry->field ; *ptr ; ptr++)
(*ptr)->free();
- my_free((gptr) entry->record[0],MYF(0));
free_io_cache(entry);
bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
- my_free((gptr) entry,MYF(0));
+ free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
thd->proc_info=save_proc_info;
DBUG_VOID_RETURN;
@@ -9090,7 +8910,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
end_select function to use. This function can't fail.
*/
-static Next_select_func setup_end_select_func(JOIN *join)
+Next_select_func setup_end_select_func(JOIN *join)
{
TABLE *table= join->tmp_table;
Next_select_func end_select;
@@ -9245,7 +9065,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
}
-static enum_nested_loop_state
+enum_nested_loop_state
sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
{
enum_nested_loop_state rc;
@@ -9386,7 +9206,7 @@ sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
return one of enum_nested_loop_state, except NESTED_LOOP_NO_MORE_ROWS.
*/
-static enum_nested_loop_state
+enum_nested_loop_state
sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
{
join_tab->table->null_row=0;
@@ -12409,6 +12229,11 @@ calc_group_buffer(JOIN *join,ORDER *group)
key_length+=MAX_BLOB_WIDTH; // Can't be used as a key
else if (field->type() == MYSQL_TYPE_VARCHAR)
key_length+= field->field_length + HA_KEY_BLOB_LENGTH;
+ else if (field->type() == FIELD_TYPE_BIT)
+ {
+ /* Bit is usually stored as a longlong key for group fields */
+ key_length+= 8; // Big enough
+ }
else
key_length+= field->pack_length();
}
@@ -13813,8 +13638,7 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
unit->fake_select_lex->type= "UNION RESULT";
unit->fake_select_lex->options|= SELECT_DESCRIBE;
- if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE,
- "")))
+ if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
res= unit->exec();
res|= unit->cleanup();
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index ce40f657a8e..be51851e760 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -101,7 +101,7 @@ enum enum_nested_loop_state
typedef enum_nested_loop_state
(*Next_select_func)(JOIN *, struct st_join_table *, bool);
typedef int (*Read_record_func)(struct st_join_table *tab);
-
+Next_select_func setup_end_select_func(JOIN *join);
typedef struct st_join_table {
TABLE *table;
@@ -141,6 +141,11 @@ typedef struct st_join_table {
void cleanup();
} JOIN_TAB;
+enum_nested_loop_state sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool
+ end_of_records);
+enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab, bool
+ end_of_records);
+
typedef struct st_position /* Used in find_best */
{
@@ -373,58 +378,6 @@ class JOIN :public Sql_alloc
};
-/*
- Server-side cursor (now stands only for basic read-only cursor)
- See class implementation in sql_select.cc
- A cursor has its own runtime state - list of used items and memory root of
- used memory - which is different from Prepared statement runtime: it must
- be different at least for the purpose of reusing the same prepared
- statement for many cursors.
-*/
-
-class Cursor: public Sql_alloc, public Query_arena
-{
- MEM_ROOT main_mem_root;
- JOIN *join;
- SELECT_LEX_UNIT *unit;
-
- TABLE *open_tables;
- MYSQL_LOCK *lock;
- TABLE *derived_tables;
- /* List of items created during execution */
- query_id_t query_id;
- struct Engine_info
- {
- const handlerton *ht;
- void *read_view;
- };
- Engine_info ht_info[MAX_HA];
-public:
- Protocol_prep protocol;
- Item_change_list change_list;
- select_send result;
- THR_LOCK_OWNER lock_id;
- my_bool close_at_commit;
-
- /* Temporary implementation as now we replace THD state by value */
- /* Save THD state into cursor */
- void init_from_thd(THD *thd);
- /* bzero cursor state in THD */
- void reset_thd(THD *thd);
-
- int open(JOIN *join);
- void fetch(ulong num_rows);
- void reset() { join= 0; }
- bool is_open() const { return join != 0; }
-
- void close(bool is_active);
-
- void set_unit(SELECT_LEX_UNIT *unit_arg) { unit= unit_arg; }
- Cursor(THD *thd);
- ~Cursor() {}
-};
-
-
typedef struct st_select_check {
uint const_ref,reg_ref;
} SELECT_CHECK;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index c0bb29e035b..24acb1fb6d1 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -67,18 +67,18 @@ bool mysqld_show_storage_engines(THD *thd)
const char *default_type_name=
ha_get_storage_engine((enum db_type)thd->variables.table_type);
- show_table_type_st *types;
- for (types= sys_table_types; types->type; types++)
+ handlerton **types;
+ for (types= sys_table_types; *types; types++)
{
protocol->prepare_for_resend();
- protocol->store(types->type, system_charset_info);
- const char *option_name= show_comp_option_name[(int) *types->value];
+ protocol->store((*types)->name, system_charset_info);
+ const char *option_name= show_comp_option_name[(int) (*types)->state];
- if (*types->value == SHOW_OPTION_YES &&
- !my_strcasecmp(system_charset_info, default_type_name, types->type))
+ if ((*types)->state == SHOW_OPTION_YES &&
+ !my_strcasecmp(system_charset_info, default_type_name, (*types)->name))
option_name= "DEFAULT";
protocol->store(option_name, system_charset_info);
- protocol->store(types->comment, system_charset_info);
+ protocol->store((*types)->comment, system_charset_info);
if (protocol->write())
DBUG_RETURN(TRUE);
}
@@ -415,8 +415,9 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
bool mysqld_show_create_db(THD *thd, char *dbname,
HA_CREATE_INFO *create_info)
{
+ Security_context *sctx= thd->security_ctx;
int length;
- char path[FN_REFLEN];
+ char path[FN_REFLEN];
char buff[2048];
String buffer(buff, sizeof(buff), system_charset_info);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -435,17 +436,17 @@ bool mysqld_show_create_db(THD *thd, char *dbname,
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (test_all_bits(thd->master_access,DB_ACLS))
+ if (test_all_bits(sctx->master_access, DB_ACLS))
db_access=DB_ACLS;
else
- db_access= (acl_get(thd->host,thd->ip, thd->priv_user,dbname,0) |
- thd->master_access);
+ db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname, 0) |
+ sctx->master_access);
if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname)))
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
- thd->priv_user, thd->host_or_ip, dbname);
+ sctx->priv_user, sctx->host_or_ip, dbname);
mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
- thd->priv_user, thd->host_or_ip, dbname);
+ sctx->priv_user, sctx->host_or_ip, dbname);
DBUG_RETURN(TRUE);
}
#endif
@@ -793,7 +794,8 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
field->sql_type(type);
packet->append(type.ptr(), type.length(), system_charset_info);
- if (field->has_charset() && !limited_mysql_mode && !foreign_db_mode)
+ if (field->has_charset() &&
+ !(thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)))
{
if (field->charset() != share->table_charset)
{
@@ -832,7 +834,7 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
has_default= (field->type() != FIELD_TYPE_BLOB &&
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
field->unireg_check != Field::NEXT_NUMBER &&
- !((foreign_db_mode || limited_mysql_mode) &&
+ !((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) &&
has_now_default));
if (has_default)
@@ -862,12 +864,13 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
packet->append(tmp);
}
- if (!foreign_db_mode && !limited_mysql_mode &&
+ if (!(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS) &&
table->timestamp_field == field &&
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
packet->append(" on update CURRENT_TIMESTAMP",28);
- if (field->unireg_check == Field::NEXT_NUMBER && !foreign_db_mode)
+ if (field->unireg_check == Field::NEXT_NUMBER &&
+ !(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS))
packet->append(" auto_increment", 15 );
if (field->comment.length)
@@ -1210,24 +1213,26 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
THD *tmp;
while ((tmp=it++))
{
+ Security_context *tmp_sctx= tmp->security_ctx;
struct st_my_thread_var *mysys_var;
if ((tmp->vio_ok() || tmp->system_thread) &&
- (!user || (tmp->user && !strcmp(tmp->user,user))))
+ (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
{
- thread_info *thd_info=new thread_info;
+ thread_info *thd_info= new thread_info;
thd_info->thread_id=tmp->thread_id;
- thd_info->user=thd->strdup(tmp->user ? tmp->user :
- (tmp->system_thread ?
- "system user" : "unauthenticated user"));
- if (tmp->peer_port && (tmp->host || tmp->ip) && thd->host_or_ip[0])
+ thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
+ (tmp->system_thread ?
+ "system user" : "unauthenticated user"));
+ if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
+ thd->security_ctx->host_or_ip[0])
{
if ((thd_info->host= thd->alloc(LIST_PROCESS_HOST_LEN+1)))
my_snprintf((char *) thd_info->host, LIST_PROCESS_HOST_LEN,
- "%s:%u", tmp->host_or_ip, tmp->peer_port);
+ "%s:%u", tmp_sctx->host_or_ip, tmp->peer_port);
}
else
- thd_info->host= thd->strdup(tmp->host_or_ip);
+ thd_info->host= thd->strdup(tmp_sctx->host_or_ip);
if ((thd_info->db=tmp->db)) // Safe test
thd_info->db=thd->strdup(thd_info->db);
thd_info->command=(int) tmp->command;
@@ -1278,6 +1283,9 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thread_info *thd_info;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ Security_context *sctx;
+#endif
time_t now= time(0);
while ((thd_info=thread_infos.get()))
{
@@ -2014,7 +2022,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
enum enum_schema_tables schema_table_idx;
List<char> bases;
List_iterator_fast<char> it(bases);
- COND *partial_cond;
+ COND *partial_cond;
+ Security_context *sctx= thd->security_ctx;
uint derived_tables= lex->derived_tables;
int error= 1;
Open_tables_state open_tables_state_backup;
@@ -2086,8 +2095,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!check_access(thd,SELECT_ACL, base_name,
&thd->col_access, 0, 1, with_i_schema) ||
- thd->master_access & (DB_ACLS | SHOW_DB_ACL) ||
- acl_get(thd->host, thd->ip, thd->priv_user, base_name,0) ||
+ sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
+ acl_get(sctx->host, sctx->ip, sctx->priv_user, base_name,0) ||
(grant_option && !check_grant_db(thd, base_name)))
#endif
{
@@ -2219,6 +2228,7 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond)
bool with_i_schema;
HA_CREATE_INFO create;
TABLE *table= tables->table;
+ Security_context *sctx= thd->security_ctx;
DBUG_ENTER("fill_schema_shemata");
if (make_db_list(thd, &files, &idx_field_vals,
@@ -2237,8 +2247,8 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond)
continue;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) ||
- acl_get(thd->host, thd->ip, thd->priv_user, file_name,0) ||
+ if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
+ acl_get(sctx->host, sctx->ip, sctx->priv_user, file_name,0) ||
(grant_option && !check_grant_db(thd, file_name)))
#endif
{
@@ -2839,7 +2849,8 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond)
Open_tables_state open_tables_state_backup;
DBUG_ENTER("fill_schema_proc");
- strxmov(definer, thd->priv_user, "@", thd->priv_host, NullS);
+ strxmov(definer, thd->security_ctx->priv_user, "@",
+ thd->security_ctx->priv_host, NullS);
/* We use this TABLE_LIST instance only for checking of privileges. */
bzero((char*) &proc_tables,sizeof(proc_tables));
proc_tables.db= (char*) "mysql";
@@ -2977,7 +2988,7 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables,
CHARSET_INFO *cs= system_charset_info;
DBUG_ENTER("get_schema_views_record");
char definer[HOSTNAME_LENGTH + USERNAME_LENGTH + 2];
- uint defiler_len;
+ uint definer_len;
if (!res)
{
if (tables->view)
@@ -3002,9 +3013,9 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables,
table->field[5]->store(STRING_WITH_LEN("YES"), cs);
else
table->field[5]->store(STRING_WITH_LEN("NO"), cs);
- defiler_len= (strxmov(definer, tables->definer.user.str, "@",
- tables->definer.host.str, NullS) - definer) - 1;
- table->field[6]->store(definer, defiler_len, cs);
+ definer_len= (strxmov(definer, tables->definer.user.str, "@",
+ tables->definer.host.str, NullS) - definer);
+ table->field[6]->store(definer, definer_len, cs);
if (tables->view_suid)
table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs);
else
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 59e23f8b972..a1f2be7e11c 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3867,6 +3867,16 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (create_info->row_type == ROW_TYPE_NOT_USED)
create_info->row_type= table->s->row_type;
+ DBUG_PRINT("info", ("old type: %d new type: %d", old_db_type, new_db_type));
+ if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED)
+ || ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
+ {
+ DBUG_PRINT("info", ("doesn't support alter"));
+ my_error(ER_ILLEGAL_HA, MYF(0), table_name);
+ DBUG_RETURN(TRUE);
+ }
+ DBUG_PRINT("info", ("supports alter"));
+
thd->proc_info="setup";
if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
!table->s->tmp_table) // no need to touch frm
@@ -4880,7 +4890,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
strxmov(table_name, table->db ,".", table->table_name, NullS);
- t= table->table= open_ltable(thd, table, TL_READ_NO_INSERT);
+ t= table->table= open_ltable(thd, table, TL_READ);
thd->clear_error(); // these errors shouldn't get client
protocol->prepare_for_resend();
@@ -4906,6 +4916,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
{
/* calculating table's checksum */
ha_checksum crc= 0;
+ uchar null_mask=256 - (1 << t->s->last_null_bit_pos);
/*
Set all bits in read set and inform InnoDB that we are reading all
@@ -4927,9 +4938,15 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
continue;
break;
}
- if (t->record[0] != (byte*) t->field[0]->ptr)
- row_crc= my_checksum(row_crc, t->record[0],
- ((byte*) t->field[0]->ptr) - t->record[0]);
+ if (t->s->null_bytes)
+ {
+ /* fix undefined null bits */
+ t->record[0][t->s->null_bytes-1] |= null_mask;
+ if (!(t->s->db_create_options & HA_OPTION_PACK_RECORD))
+ t->record[0][0] |= 1;
+
+ row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
+ }
for (uint i= 0; i < t->s->fields; i++ )
{
@@ -4973,9 +4990,9 @@ static bool check_engine(THD *thd, const char *table_name,
enum db_type *new_engine)
{
enum db_type req_engine= *new_engine;
- bool no_substitution=
+ bool no_substitution=
test(thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION);
- if ((*new_engine=
+ if ((*new_engine=
ha_checktype(thd, req_engine, no_substitution, 1)) == DB_TYPE_UNKNOWN)
return TRUE;
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 7342c146045..df8de59508d 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -172,7 +172,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
stronger test will be removed, the test below will hold.
*/
if (!trust_routine_creators && mysql_bin_log.is_open() &&
- !(thd->master_access & SUPER_ACL))
+ !(thd->security_ctx->master_access & SUPER_ACL))
{
my_message(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER,
ER(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER), MYF(0));
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 556493f4fc8..951248e8cd8 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -23,6 +23,7 @@
#include "mysql_priv.h"
#include "sql_select.h"
+#include "sql_cursor.h"
bool mysql_union(THD *thd, LEX *lex, select_result *result,
SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
@@ -30,13 +31,9 @@ bool mysql_union(THD *thd, LEX *lex, select_result *result,
DBUG_ENTER("mysql_union");
bool res;
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
- setup_tables_done_option, "")))
+ setup_tables_done_option)))
res= unit->exec();
- if (!res && thd->cursor && thd->cursor->is_open())
- {
- thd->cursor->set_unit(unit);
- }
- else
+ if (res || !thd->cursor || !thd->cursor->is_open())
res|= unit->cleanup();
DBUG_RETURN(res);
}
@@ -46,16 +43,6 @@ bool mysql_union(THD *thd, LEX *lex, select_result *result,
** store records in temporary table for UNION
***************************************************************************/
-select_union::select_union(TABLE *table_par)
- :table(table_par)
-{
-}
-
-select_union::~select_union()
-{
-}
-
-
int select_union::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
{
unit= u;
@@ -103,6 +90,45 @@ bool select_union::flush()
return 0;
}
+/*
+ Create a temporary table to store the result of select_union.
+
+ SYNOPSIS
+ select_union::create_result_table()
+ thd thread handle
+ column_types a list of items used to define columns of the
+ temporary table
+ is_union_distinct if set, the temporary table will eliminate
+ duplicates on insert
+ options create options
+
+ DESCRIPTION
+ Create a temporary table that is used to store the result of a UNION,
+ derived table, or a materialized cursor.
+
+ RETURN VALUE
+ 0 The table has been created successfully.
+ 1 create_tmp_table failed.
+*/
+
+bool
+select_union::create_result_table(THD *thd, List<Item> *column_types,
+ bool is_union_distinct, ulonglong options,
+ const char *alias)
+{
+ DBUG_ASSERT(table == 0);
+ tmp_table_param.init();
+ tmp_table_param.field_count= column_types->elements;
+
+ if (! (table= create_tmp_table(thd, &tmp_table_param, *column_types,
+ (ORDER*) 0, is_union_distinct, 1,
+ options, HA_POS_ERROR, (char*) alias)))
+ return TRUE;
+ table->file->extra(HA_EXTRA_WRITE_CACHE);
+ table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+ return FALSE;
+}
+
/*
initialization procedures before fake_select_lex preparation()
@@ -133,11 +159,10 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd)
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
- ulong additional_options,
- const char *tmp_table_alias)
+ ulong additional_options)
{
SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
- SELECT_LEX *sl, *first_select;
+ SELECT_LEX *sl, *first_sl= first_select();
select_result *tmp_result;
bool is_union;
TABLE *empty_table= 0;
@@ -156,7 +181,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
if (describe)
{
/* fast reinit for EXPLAIN */
- for (sl= first_select_in_union(); sl; sl= sl->next_select())
+ for (sl= first_sl; sl; sl= sl->next_select())
{
sl->join->result= result;
select_limit_cnt= HA_POS_ERROR;
@@ -175,17 +200,16 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
prepared= 1;
res= FALSE;
- thd_arg->lex->current_select= sl= first_select= first_select_in_union();
- found_rows_for_union= first_select->options & OPTION_FOUND_ROWS;
- is_union= test(first_select->next_select());
+ thd_arg->lex->current_select= sl= first_sl;
+ found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
+ is_union= test(first_sl->next_select());
/* Global option */
if (is_union)
{
- if (!(tmp_result= union_result= new select_union(0)))
+ if (!(tmp_result= union_result= new select_union))
goto err;
- union_result->tmp_table_param.init();
if (describe)
tmp_result= sel_result;
}
@@ -238,8 +262,8 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
information about fields lengths and exact types
*/
if (!is_union)
- types= first_select_in_union()->item_list;
- else if (sl == first_select)
+ types= first_sl->item_list;
+ else if (sl == first_sl)
{
/*
We need to create an empty table object. It is used
@@ -287,7 +311,6 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
all collations together for UNION.
*/
List_iterator_fast<Item> tp(types);
- Query_arena *arena= thd->stmt_arena;
Item *type;
ulonglong create_options;
@@ -301,7 +324,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
}
}
- create_options= (first_select_in_union()->options | thd_arg->options |
+ create_options= (first_sl->options | thd_arg->options |
TMP_TABLE_ALL_COLUMNS);
/*
Force the temporary table to be a MyISAM table if we're going to use
@@ -312,47 +335,35 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
if (global_parameters->ftfunc_list->elements)
create_options= create_options | TMP_TABLE_FORCE_MYISAM;
- union_result->tmp_table_param.field_count= types.elements;
- if (!(table= create_tmp_table(thd_arg,
- &union_result->tmp_table_param, types,
- (ORDER*) 0, (bool) union_distinct, 1,
- create_options, HA_POS_ERROR,
- (char *) tmp_table_alias)))
+ if (union_result->create_result_table(thd, &types, test(union_distinct),
+ create_options, ""))
goto err;
- table->file->extra(HA_EXTRA_WRITE_CACHE);
- table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
bzero((char*) &result_table_list, sizeof(result_table_list));
result_table_list.db= (char*) "";
result_table_list.table_name= result_table_list.alias= (char*) "union";
- result_table_list.table= table;
- union_result->set_table(table);
+ result_table_list.table= table= union_result->table;
thd_arg->lex->current_select= lex_select_save;
if (!item_list.elements)
{
- Field **field;
- Query_arena *tmp_arena,backup;
- tmp_arena= thd->activate_stmt_arena_if_needed(&backup);
+ Query_arena *arena, backup_arena;
- for (field= table->field; *field; field++)
- {
- Item_field *item= new Item_field(*field);
- if (!item || item_list.push_back(item))
- {
- if (tmp_arena)
- thd->restore_active_arena(tmp_arena, &backup);
- DBUG_RETURN(TRUE);
- }
- }
- if (tmp_arena)
- thd->restore_active_arena(tmp_arena, &backup);
- if (arena->is_stmt_prepare_or_first_sp_execute())
+ arena= thd->activate_stmt_arena_if_needed(&backup_arena);
+
+ res= table->fill_item_list(&item_list);
+
+ if (arena)
+ thd->restore_active_arena(arena, &backup_arena);
+
+ if (res)
+ goto err;
+
+ if (thd->stmt_arena->is_stmt_prepare())
{
- /* prepare fake select to initialize it correctly */
+ /* Validate the global parameters of this union */
+
init_prepare_fake_select_lex(thd);
- /*
- Should be done only once (the only item_list per statement).
- */
+ /* Should be done only once (the only item_list per statement) */
DBUG_ASSERT(fake_select_lex->join == 0);
if (!(fake_select_lex->join= new JOIN(thd, item_list, thd->options,
result)))
@@ -375,19 +386,14 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
fake_select_lex->table_list.empty();
}
}
- else if (!arena->is_conventional())
+ else
{
+ DBUG_ASSERT(!thd->stmt_arena->is_conventional());
/*
We're in execution of a prepared statement or stored procedure:
reset field items to point at fields from the created temporary table.
*/
- List_iterator_fast<Item> it(item_list);
- for (Field **field= table->field; *field; field++)
- {
- Item_field *item_field= (Item_field*) it++;
- DBUG_ASSERT(item_field != 0);
- item_field->reset_field(*field);
- }
+ table->reset_item_list(&item_list);
}
}
@@ -404,7 +410,7 @@ err:
bool st_select_lex_unit::exec()
{
SELECT_LEX *lex_select_save= thd->lex->current_select;
- SELECT_LEX *select_cursor=first_select_in_union();
+ SELECT_LEX *select_cursor=first_select();
ulonglong add_rows=0;
ha_rows examined_rows= 0;
DBUG_ENTER("st_select_lex_unit::exec");
@@ -595,7 +601,7 @@ bool st_select_lex_unit::cleanup()
table= 0; // Safety
}
- for (SELECT_LEX *sl= first_select_in_union(); sl; sl= sl->next_select())
+ for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
error|= sl->cleanup();
if (fake_select_lex)
@@ -652,7 +658,7 @@ bool st_select_lex_unit::change_result(select_subselect *result,
select_subselect *old_result)
{
bool res= FALSE;
- for (SELECT_LEX *sl= first_select_in_union(); sl; sl= sl->next_select())
+ for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
{
if (sl->join && sl->join->result == old_result)
if (sl->join->change_result(result))
@@ -663,6 +669,36 @@ bool st_select_lex_unit::change_result(select_subselect *result,
return (res);
}
+/*
+ Get column type information for this unit.
+
+ SYNOPSIS
+ st_select_lex_unit::get_unit_column_types()
+
+ DESCRIPTION
+ For a single-select the column types are taken
+ from the list of selected items. For a union this function
+ assumes that st_select_lex_unit::prepare has been called
+ and returns the type holders that were created for unioned
+ column types of all selects.
+
+ NOTES
+ The implementation of this function should be in sync with
+ st_select_lex_unit::prepare()
+*/
+
+List<Item> *st_select_lex_unit::get_unit_column_types()
+{
+ bool is_union= test(first_select()->next_select());
+
+ if (is_union)
+ {
+ DBUG_ASSERT(prepared);
+ /* Types are generated during prepare */
+ return &types;
+ }
+ return &first_select()->item_list;
+}
bool st_select_lex::cleanup()
{
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 7e20817c7c7..72a8eef9a55 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -580,11 +580,20 @@ int mysql_update(THD *thd,
query_cache_invalidate3(thd, table_list, 1);
}
- if ((updated || (error < 0)) && (error <= 0 || !transactional_table))
+ /*
+ error < 0 means really no error at all: we processed all rows until the
+ last one without error. error > 0 means an error (e.g. unique key
+ violation and no IGNORE or REPLACE). error == 0 is also an error (if
+ preparing the record or invoking before triggers fails). See
+ ha_autocommit_or_rollback(error>=0) and DBUG_RETURN(error>=0) below.
+ Sometimes we want to binlog even if we updated no rows, in case user used
+ it to be sure master and slave are in same state.
+ */
+ if ((error < 0) || (updated && !transactional_table))
{
if (mysql_bin_log.is_open())
{
- if (error <= 0)
+ if (error < 0)
thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_table, FALSE);
@@ -667,6 +676,7 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
bzero((char*) &tables,sizeof(tables)); // For ORDER BY
tables.table= table;
tables.alias= table_list->alias;
+ thd->allow_sum_func= 0;
if (setup_tables(thd, &select_lex->context, &select_lex->top_join_list,
table_list, conds, &select_lex->leaf_tables,
@@ -1544,16 +1554,14 @@ bool multi_update::send_eof()
/*
Write the SQL statement to the binlog if we updated
rows and we succeeded or if we updated some non
- transacational tables.
- Note that if we updated nothing we don't write to the binlog (TODO:
- fix this).
+ transactional tables.
*/
- if (updated && (local_error <= 0 || !trans_safe))
+ if ((local_error == 0) || (updated && !trans_safe))
{
if (mysql_bin_log.is_open())
{
- if (local_error <= 0)
+ if (local_error == 0)
thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_tables, FALSE);
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index c26f9cc4d71..f956d9d4928 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -214,12 +214,13 @@ bool mysql_create_view(THD *thd,
- same as current user
- current user has SUPER_ACL
*/
- if (strcmp(lex->create_view_definer->user.str, thd->priv_user) != 0 ||
+ if (strcmp(lex->create_view_definer->user.str,
+ thd->security_ctx->priv_user) != 0 ||
my_strcasecmp(system_charset_info,
lex->create_view_definer->host.str,
- thd->priv_host) != 0)
+ thd->security_ctx->priv_host) != 0)
{
- if (!(thd->master_access & SUPER_ACL))
+ if (!(thd->security_ctx->master_access & SUPER_ACL))
{
my_error(ER_VIEW_OTHER_USER, MYF(0), lex->create_view_definer->user.str,
lex->create_view_definer->host.str);
@@ -275,7 +276,8 @@ bool mysql_create_view(THD *thd,
if (check_some_access(thd, VIEW_ANY_ACL, tbl))
{
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
- "ANY", thd->priv_user, thd->host_or_ip, tbl->table_name);
+ "ANY", thd->security_ctx->priv_user,
+ thd->security_ctx->priv_host, tbl->table_name);
res= TRUE;
goto err;
}
@@ -378,7 +380,7 @@ bool mysql_create_view(THD *thd,
/* prepare select to resolve all fields */
lex->view_prepare_mode= 1;
- if (unit->prepare(thd, 0, 0, view->view_name.str))
+ if (unit->prepare(thd, 0, 0))
{
/*
some errors from prepare are reported to user, if is not then
@@ -441,7 +443,8 @@ bool mysql_create_view(THD *thd,
{
/* VIEW column has more privileges */
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
- "create view", thd->priv_user, thd->host_or_ip, item->name,
+ "create view", thd->security_ctx->priv_user,
+ thd->security_ctx->priv_host, item->name,
view->table_name);
res= TRUE;
goto err;
@@ -481,6 +484,8 @@ err:
static const int revision_number_position= 8;
/* index of last required parameter for making view */
static const int required_view_parameters= 10;
+/* number of backups */
+static const int num_view_backups= 3;
/*
table of VIEW .frm field descriptors
@@ -708,7 +713,7 @@ loop_out:
}
if (sql_create_definition_file(&dir, &file, view_file_type,
- (gptr)view, view_parameters, 3))
+ (gptr)view, view_parameters, num_view_backups))
{
DBUG_RETURN(thd->net.report_error? -1 : 1);
}
@@ -786,7 +791,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_VIEW_FRM_NO_USER, ER(ER_VIEW_FRM_NO_USER),
table->db, table->table_name);
- if (default_view_definer(thd, &table->definer))
+ if (default_view_definer(thd->security_ctx, &table->definer))
goto err;
}
@@ -1165,7 +1170,7 @@ frm_type_enum mysql_frm_type(char *path)
int length;
DBUG_ENTER("mysql_frm_type");
- if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(MY_WME))) < 0)
+ if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
{
DBUG_RETURN(FRMTYPE_ERROR);
}
@@ -1369,3 +1374,94 @@ int view_checksum(THD *thd, TABLE_LIST *view)
HA_ADMIN_WRONG_CHECKSUM :
HA_ADMIN_OK);
}
+
+/*
+ rename view
+
+ Synopsis:
+ renames a view
+
+ Parameters:
+ thd thread handler
+ new_name new name of view
+ view view
+
+ Return values:
+ FALSE Ok
+ TRUE Error
+*/
+bool
+mysql_rename_view(THD *thd,
+ const char *new_name,
+ TABLE_LIST *view)
+{
+ LEX_STRING pathstr, file;
+ File_parser *parser;
+ char view_path[FN_REFLEN];
+ bool error= TRUE;
+
+ DBUG_ENTER("mysql_rename_view");
+
+ strxnmov(view_path, FN_REFLEN, mysql_data_home, "/", view->db, "/",
+ view->table_name, reg_ext, NullS);
+ (void) unpack_filename(view_path, view_path);
+
+ pathstr.str= (char *)view_path;
+ pathstr.length= strlen(view_path);
+
+ if ((parser= sql_parse_prepare(&pathstr, thd->mem_root, 1)) &&
+ is_equal(&view_type, parser->type()))
+ {
+ TABLE_LIST view_def;
+ char dir_buff[FN_REFLEN], file_buff[FN_REFLEN];
+
+ /*
+ To be PS-friendly we should either to restore state of
+ TABLE_LIST object pointed by 'view' after using it for
+ view definition parsing or use temporary 'view_def'
+ object for it.
+ */
+ bzero(&view_def, sizeof(view_def));
+ view_def.timestamp.str= view_def.timestamp_buffer;
+ view_def.view_suid= TRUE;
+
+ /* get view definition and source */
+ if (parser->parse((gptr)&view_def, thd->mem_root, view_parameters,
+ sizeof(view_parameters)/sizeof(view_parameters[0])-1))
+ goto err;
+
+ /* rename view and it's backups */
+ if (rename_in_schema_file(view->db, view->table_name, new_name,
+ view_def.revision - 1, num_view_backups))
+ goto err;
+
+ strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", view->db, "/", NullS);
+ (void) unpack_filename(dir_buff, dir_buff);
+
+ pathstr.str= (char*)dir_buff;
+ pathstr.length= strlen(dir_buff);
+
+ file.str= file_buff;
+ file.length= (strxnmov(file_buff, FN_REFLEN, new_name, reg_ext, NullS)
+ - file_buff);
+
+ if (sql_create_definition_file(&pathstr, &file, view_file_type,
+ (gptr)&view_def, view_parameters,
+ num_view_backups))
+ {
+ /* restore renamed view in case of error */
+ rename_in_schema_file(view->db, new_name, view->table_name,
+ view_def.revision - 1, num_view_backups);
+ goto err;
+ }
+ } else
+ DBUG_RETURN(1);
+
+ /* remove cache entries */
+ query_cache_invalidate3(thd, view, 0);
+ sp_cache_invalidate();
+ error= FALSE;
+
+err:
+ DBUG_RETURN(error);
+}
diff --git a/sql/sql_view.h b/sql/sql_view.h
index 9d961feb143..4cc9eb454fb 100644
--- a/sql/sql_view.h
+++ b/sql/sql_view.h
@@ -34,6 +34,7 @@ int view_checksum(THD *thd, TABLE_LIST *view);
extern TYPELIB updatable_views_with_limit_typelib;
bool check_duplicate_names(List<Item>& item_list, bool gen_unique_view_names);
+bool mysql_rename_view(THD *thd, const char *new_name, TABLE_LIST *view);
#define VIEW_ANY_ACL (SELECT_ACL | UPDATE_ACL | INSERT_ACL | DELETE_ACL)
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 49c385dd1be..77c1a37e16e 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -5370,27 +5370,48 @@ simple_expr:
$$= new Item_func_sp(Lex->current_context(), name);
lex->safe_to_cache_query=0;
}
- | IDENT_sys '(' udf_expr_list ')'
+ | IDENT_sys '('
{
#ifdef HAVE_DLOPEN
- udf_func *udf;
+ 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())
+ {
+ yyerror(ER(ER_SYNTAX_ERROR));
+ YYABORT;
+ }
+ }
+ $<udf>$= udf;
+#endif
+ }
+ udf_expr_list ')'
+ {
+#ifdef HAVE_DLOPEN
+ udf_func *udf= $<udf>3;
SELECT_LEX *sel= Select;
- if (using_udf_functions && (udf=find_udf($1.str, $1.length)))
+ if (udf)
{
+ if (udf->type == UDFTYPE_AGGREGATE)
+ Select->in_sum_expr--;
+
switch (udf->returns) {
case STRING_RESULT:
if (udf->type == UDFTYPE_FUNCTION)
{
- if ($3 != NULL)
- $$ = new Item_func_udf_str(udf, *$3);
+ if ($4 != NULL)
+ $$ = new Item_func_udf_str(udf, *$4);
else
$$ = new Item_func_udf_str(udf);
}
else
{
- if ($3 != NULL)
- $$ = new Item_sum_udf_str(udf, *$3);
+ if ($4 != NULL)
+ $$ = new Item_sum_udf_str(udf, *$4);
else
$$ = new Item_sum_udf_str(udf);
}
@@ -5398,15 +5419,15 @@ simple_expr:
case REAL_RESULT:
if (udf->type == UDFTYPE_FUNCTION)
{
- if ($3 != NULL)
- $$ = new Item_func_udf_float(udf, *$3);
+ if ($4 != NULL)
+ $$ = new Item_func_udf_float(udf, *$4);
else
$$ = new Item_func_udf_float(udf);
}
else
{
- if ($3 != NULL)
- $$ = new Item_sum_udf_float(udf, *$3);
+ if ($4 != NULL)
+ $$ = new Item_sum_udf_float(udf, *$4);
else
$$ = new Item_sum_udf_float(udf);
}
@@ -5414,15 +5435,15 @@ simple_expr:
case INT_RESULT:
if (udf->type == UDFTYPE_FUNCTION)
{
- if ($3 != NULL)
- $$ = new Item_func_udf_int(udf, *$3);
+ if ($4 != NULL)
+ $$ = new Item_func_udf_int(udf, *$4);
else
$$ = new Item_func_udf_int(udf);
}
else
{
- if ($3 != NULL)
- $$ = new Item_sum_udf_int(udf, *$3);
+ if ($4 != NULL)
+ $$ = new Item_sum_udf_int(udf, *$4);
else
$$ = new Item_sum_udf_int(udf);
}
@@ -5430,15 +5451,15 @@ simple_expr:
case DECIMAL_RESULT:
if (udf->type == UDFTYPE_FUNCTION)
{
- if ($3 != NULL)
- $$ = new Item_func_udf_decimal(udf, *$3);
+ if ($4 != NULL)
+ $$ = new Item_func_udf_decimal(udf, *$4);
else
$$ = new Item_func_udf_decimal(udf);
}
else
{
- if ($3 != NULL)
- $$ = new Item_sum_udf_decimal(udf, *$3);
+ if ($4 != NULL)
+ $$ = new Item_sum_udf_decimal(udf, *$4);
else
$$ = new Item_sum_udf_decimal(udf);
}
@@ -5454,8 +5475,8 @@ simple_expr:
sp_name *name= sp_name_current_db_new(YYTHD, $1);
sp_add_used_routine(lex, YYTHD, name, TYPE_ENUM_FUNCTION);
- if ($3)
- $$= new Item_func_sp(Lex->current_context(), name, *$3);
+ 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;
@@ -7145,15 +7166,16 @@ show_param:
LEX *lex=Lex;
lex->sql_command= SQLCOM_SHOW_GRANTS;
THD *thd= lex->thd;
+ Security_context *sctx= thd->security_ctx;
LEX_USER *curr_user;
if (!(curr_user= (LEX_USER*) thd->alloc(sizeof(st_lex_user))))
YYABORT;
- curr_user->user.str= thd->priv_user;
- curr_user->user.length= strlen(thd->priv_user);
- if (*thd->priv_host != 0)
+ curr_user->user.str= sctx->priv_user;
+ curr_user->user.length= strlen(sctx->priv_user);
+ if (*sctx->priv_host != 0)
{
- curr_user->host.str= thd->priv_host;
- curr_user->host.length= strlen(thd->priv_host);
+ curr_user->host.str= sctx->priv_host;
+ curr_user->host.length= strlen(sctx->priv_host);
}
else
{
@@ -7239,6 +7261,9 @@ show_engine_param:
STATUS_SYM
{
switch (Lex->create_info.db_type) {
+ case DB_TYPE_NDBCLUSTER:
+ Lex->sql_command = SQLCOM_SHOW_NDBCLUSTER_STATUS;
+ break;
case DB_TYPE_INNODB:
Lex->sql_command = SQLCOM_SHOW_INNODB_STATUS;
break;
@@ -8054,14 +8079,15 @@ user:
| CURRENT_USER optional_braces
{
THD *thd= YYTHD;
+ Security_context *sctx= thd->security_ctx;
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
YYABORT;
- $$->user.str= thd->priv_user;
- $$->user.length= strlen(thd->priv_user);
- if (*thd->priv_host != 0)
+ $$->user.str= sctx->priv_user;
+ $$->user.length= strlen(sctx->priv_user);
+ if (*sctx->priv_host != 0)
{
- $$->host.str= thd->priv_host;
- $$->host.length= strlen(thd->priv_host);
+ $$->host.str= sctx->priv_host;
+ $$->host.length= strlen(sctx->priv_host);
}
else
{
@@ -8588,7 +8614,7 @@ option_value:
if (!(user=(LEX_USER*) thd->alloc(sizeof(LEX_USER))))
YYABORT;
user->host=null_lex_str;
- user->user.str=thd->priv_user;
+ user->user.str=thd->security_ctx->priv_user;
thd->lex->var_list.push_back(new set_var_password(user, $3));
}
| PASSWORD FOR_SYM user equal text_or_password
@@ -9521,7 +9547,8 @@ view_user:
if (!(thd->lex->create_view_definer=
(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
YYABORT;
- if (default_view_definer(thd, thd->lex->create_view_definer))
+ if (default_view_definer(thd->security_ctx,
+ thd->lex->create_view_definer))
YYABORT;
}
| CURRENT_USER optional_braces
@@ -9530,7 +9557,8 @@ view_user:
if (!(thd->lex->create_view_definer=
(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
YYABORT;
- if (default_view_definer(thd, thd->lex->create_view_definer))
+ if (default_view_definer(thd->security_ctx,
+ thd->lex->create_view_definer))
YYABORT;
}
| DEFINER_SYM EQ ident_or_text '@' ident_or_text
diff --git a/sql/table.cc b/sql/table.cc
index 9d91cb51ee1..d3f7d2b3b9f 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -290,8 +290,6 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
keynames=(char*) key_part;
strpos+= (strmov(keynames, (char *) strpos) - keynames)+1;
- share->null_bytes= null_pos - (uchar*) outparam->null_flags + (null_bit_pos + 7) / 8;
-
share->reclength = uint2korr((head+16));
if (*(head+26) == 1)
share->system= 1; /* one-record-database */
@@ -351,7 +349,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
char *buff;
if (!(buff= alloc_root(&outparam->mem_root, n_length)))
goto err;
- if (my_pread(file, buff, n_length, record_offset + share->reclength,
+ if (my_pread(file, (byte*)buff, n_length, record_offset + share->reclength,
MYF(MY_NABP)))
goto err;
share->connect_string.length= uint2korr(buff);
@@ -473,6 +471,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
{
outparam->null_flags=null_pos=(uchar*) record+1;
null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
+ /* null_bytes below is only correct under the condition that
+ there are no bit fields. Correct values is set below after the
+ table struct is initialized */
share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
}
else
@@ -885,6 +886,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
(*save++)= i;
}
}
+
if (outparam->file->ha_allocate_read_write_set(share->fields))
goto err;
@@ -895,6 +897,10 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
#endif
goto err;
+ /* the correct null_bytes can now be set, since bitfields have been taken into account */
+ share->null_bytes= null_pos - (uchar*) outparam->null_flags + (null_bit_pos + 7) / 8;
+ share->last_null_bit_pos= null_bit_pos;
+
/* The table struct is now initialized; Open the table */
error=2;
if (db_stat)
@@ -1725,6 +1731,63 @@ db_type get_table_type(THD *thd, const char *name)
DBUG_RETURN(ha_checktype(thd,(enum db_type) (uint) *(head+3),0,0));
}
+/*
+ Create Item_field for each column in the table.
+
+ SYNPOSIS
+ st_table::fill_item_list()
+ item_list a pointer to an empty list used to store items
+
+ DESCRIPTION
+ Create Item_field object for each column in the table and
+ initialize it with the corresponding Field. New items are
+ created in the current THD memory root.
+
+ RETURN VALUE
+ 0 success
+ 1 out of memory
+*/
+
+bool st_table::fill_item_list(List<Item> *item_list) const
+{
+ /*
+ All Item_field's created using a direct pointer to a field
+ are fixed in Item_field constructor.
+ */
+ for (Field **ptr= field; *ptr; ptr++)
+ {
+ Item_field *item= new Item_field(*ptr);
+ if (!item || item_list->push_back(item))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ Reset an existing list of Item_field items to point to the
+ Fields of this table.
+
+ SYNPOSIS
+ st_table::fill_item_list()
+ item_list a non-empty list with Item_fields
+
+ DESCRIPTION
+ This is a counterpart of fill_item_list used to redirect
+ Item_fields to the fields of a newly created table.
+ The caller must ensure that number of items in the item_list
+ is the same as the number of columns in the table.
+*/
+
+void st_table::reset_item_list(List<Item> *item_list) const
+{
+ List_iterator_fast<Item> it(*item_list);
+ for (Field **ptr= field; *ptr; ptr++)
+ {
+ Item_field *item_field= (Item_field*) it++;
+ DBUG_ASSERT(item_field != 0);
+ item_field->reset_field(*ptr);
+ }
+}
/*
calculate md5 of query
@@ -2268,8 +2331,10 @@ TABLE_LIST *st_table_list::first_leaf_for_name_resolution()
List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list);
cur_table_ref= it++;
/*
- If 'this' is a RIGHT JOIN, the operands in 'join_list' are in reverse
- order, thus the first operand is already at the front of the list.
+ If the current nested join is a RIGHT JOIN, the operands in
+ 'join_list' are in reverse order, thus the first operand is
+ already at the front of the list. Otherwise the first operand
+ is in the end of the list of join operands.
*/
if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
{
@@ -2320,9 +2385,11 @@ TABLE_LIST *st_table_list::last_leaf_for_name_resolution()
cur_nested_join;
cur_nested_join= cur_table_ref->nested_join)
{
+ cur_table_ref= cur_nested_join->join_list.head();
/*
- If 'this' is a RIGHT JOIN, the operands in 'join_list' are in reverse
- order, thus the last operand is in the end of the list.
+ If the current nested is a RIGHT JOIN, the operands in
+ 'join_list' are in reverse order, thus the last operand is in the
+ end of the list.
*/
if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
{
@@ -2332,8 +2399,6 @@ TABLE_LIST *st_table_list::last_leaf_for_name_resolution()
while ((next= it++))
cur_table_ref= next;
}
- else
- cur_table_ref= cur_nested_join->join_list.head();
if (cur_table_ref->is_leaf_for_name_resolution())
break;
}
@@ -2401,22 +2466,6 @@ Field *Natural_join_column::field()
const char *Natural_join_column::table_name()
{
return table_ref->alias;
- /*
- TODO:
- I think that it is sufficient to return just
- table->alias, which is correctly set to either
- the view name, the table name, or the alias to
- the table reference (view or stored table).
- */
-#ifdef NOT_YET
- if (view_field)
- return table_ref->view_name.str;
-
- DBUG_ASSERT(!strcmp(table_ref->table_name,
- table_ref->table->s->table_name));
- return table_ref->table_name;
-}
-#endif
}
@@ -2552,7 +2601,7 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
DBUG_RETURN(field);
}
Item *item= new Item_direct_view_ref(&view->view->select_lex.context,
- field_ref, view->view_name.str,
+ field_ref, view->alias,
name);
DBUG_RETURN(item);
}
diff --git a/sql/table.h b/sql/table.h
index f3f1444a797..c1de61ef273 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -145,7 +145,7 @@ typedef struct st_table_share
enum tmp_table_type tmp_table;
uint blob_ptr_size; /* 4 or 8 */
- uint null_bytes;
+ uint null_bytes, last_null_bit_pos;
uint key_length; /* Length of table_cache_key */
uint fields; /* Number of fields */
uint rec_buff_length; /* Size of table->record[] buffer */
@@ -274,6 +274,9 @@ struct st_table {
GRANT_INFO grant;
FILESORT_INFO sort;
TABLE_SHARE share_not_to_be_used; /* To be deleted when true shares */
+
+ bool fill_item_list(List<Item> *item_list) const;
+ void reset_item_list(List<Item> *item_list) const;
};
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 0279f224940..592093350f1 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -167,8 +167,8 @@ bool mysql_create_frm(THD *thd, my_string file_name,
{
char buff[2];
int2store(buff,create_info->connect_string.length);
- if (my_write(file, buff, sizeof(buff), MYF(MY_NABP)) ||
- my_write(file, create_info->connect_string.str,
+ if (my_write(file, (const byte*)buff, sizeof(buff), MYF(MY_NABP)) ||
+ my_write(file, (const byte*)create_info->connect_string.str,
create_info->connect_string.length, MYF(MY_NABP)))
goto err;
}
diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
index aa3aef7f97c..3a3b64dd51b 100644
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
@@ -321,7 +321,9 @@ buf_page_is_corrupted(
fprintf(stderr,
" InnoDB: Error: page %lu log sequence number %lu %lu\n"
"InnoDB: is in the future! Current system log sequence number %lu %lu.\n"
-"InnoDB: Your database may be corrupt.\n",
+"InnoDB: Your database may be corrupt or you may have copied the InnoDB\n"
+"InnoDB: tablespace but not the InnoDB log files. See\n"
+"http://dev.mysql.com/doc/mysql/en/backing-up.html for more information.\n",
(ulong) mach_read_from_4(read_buf + FIL_PAGE_OFFSET),
(ulong) ut_dulint_get_high(
mach_read_from_8(read_buf + FIL_PAGE_LSN)),
diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
index ffb16790b2d..e39d1ae0a71 100644
--- a/storage/innobase/buf/buf0flu.c
+++ b/storage/innobase/buf/buf0flu.c
@@ -230,7 +230,7 @@ buf_flush_buffered_writes(void)
ulint len2;
ulint i;
- if (trx_doublewrite == NULL) {
+ if (!srv_use_doublewrite_buf || trx_doublewrite == NULL) {
os_aio_simulated_wake_handler_threads();
return;
@@ -503,7 +503,7 @@ buf_flush_write_block_low(
#endif
buf_flush_init_for_writing(block->frame, block->newest_modification,
block->space, block->offset);
- if (!trx_doublewrite) {
+ if (!srv_use_doublewrite_buf || !trx_doublewrite) {
fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER,
FALSE, block->space, block->offset, 0, UNIV_PAGE_SIZE,
(void*)block->frame, (void*)block);
diff --git a/storage/innobase/data/data0data.c b/storage/innobase/data/data0data.c
index 194213a04e1..19304a7a8e1 100644
--- a/storage/innobase/data/data0data.c
+++ b/storage/innobase/data/data0data.c
@@ -561,12 +561,12 @@ dtuple_convert_big_rec(
}
/* We do not store externally fields which are smaller than
- DICT_MAX_COL_PREFIX_LEN */
+ DICT_MAX_INDEX_COL_LEN */
- ut_a(DICT_MAX_COL_PREFIX_LEN > REC_1BYTE_OFFS_LIMIT);
+ ut_a(DICT_MAX_INDEX_COL_LEN > REC_1BYTE_OFFS_LIMIT);
if (longest < BTR_EXTERN_FIELD_REF_SIZE + 10
- + DICT_MAX_COL_PREFIX_LEN) {
+ + DICT_MAX_INDEX_COL_LEN) {
/* Cannot shorten more */
mem_heap_free(heap);
@@ -588,10 +588,10 @@ dtuple_convert_big_rec(
dfield = dtuple_get_nth_field(entry, longest_i);
vector->fields[n_fields].field_no = longest_i;
- ut_a(dfield->len > DICT_MAX_COL_PREFIX_LEN);
+ ut_a(dfield->len > DICT_MAX_INDEX_COL_LEN);
vector->fields[n_fields].len = dfield->len
- - DICT_MAX_COL_PREFIX_LEN;
+ - DICT_MAX_INDEX_COL_LEN;
vector->fields[n_fields].data = mem_heap_alloc(heap,
vector->fields[n_fields].len);
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index 5eee57c250b..fb95ffbd80c 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -1625,7 +1625,7 @@ dict_index_add_col(
variable-length fields, so that the extern flag can be embedded in
the length word. */
- if (field->fixed_len > DICT_MAX_COL_PREFIX_LEN) {
+ if (field->fixed_len > DICT_MAX_INDEX_COL_LEN) {
field->fixed_len = 0;
}
@@ -2189,7 +2189,7 @@ dict_foreign_error_report(
dict_foreign_error_report_low(file, fk->foreign_table_name);
fputs(msg, file);
fputs(" Constraint:\n", file);
- dict_print_info_on_foreign_key_in_create_format(file, NULL, fk);
+ dict_print_info_on_foreign_key_in_create_format(file, NULL, fk, TRUE);
if (fk->foreign_index) {
fputs("\nThe index in the foreign key in table is ", file);
ut_print_name(file, NULL, fk->foreign_index->name);
@@ -4330,9 +4330,10 @@ CREATE TABLE. */
void
dict_print_info_on_foreign_key_in_create_format(
/*============================================*/
- FILE* file, /* in: file where to print */
- trx_t* trx, /* in: transaction */
- dict_foreign_t* foreign)/* in: foreign key constraint */
+ FILE* file, /* in: file where to print */
+ trx_t* trx, /* in: transaction */
+ dict_foreign_t* foreign, /* in: foreign key constraint */
+ ibool add_newline) /* in: whether to add a newline */
{
const char* stripped_id;
ulint i;
@@ -4345,7 +4346,16 @@ dict_print_info_on_foreign_key_in_create_format(
stripped_id = foreign->id;
}
- fputs(",\n CONSTRAINT ", file);
+ putc(',', file);
+
+ if (add_newline) {
+ /* SHOW CREATE TABLE wants constraints each printed nicely
+ on its own line, while error messages want no newlines
+ inserted. */
+ fputs("\n ", file);
+ }
+
+ fputs(" CONSTRAINT ", file);
ut_print_name(file, trx, stripped_id);
fputs(" FOREIGN KEY (", file);
@@ -4447,7 +4457,7 @@ dict_print_info_on_foreign_keys(
while (foreign != NULL) {
if (create_table_format) {
dict_print_info_on_foreign_key_in_create_format(
- file, trx, foreign);
+ file, trx, foreign, TRUE);
} else {
ulint i;
fputs("; (", file);
diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h
index 1f3a32fa70c..d28b0b129a1 100644
--- a/storage/innobase/include/btr0btr.h
+++ b/storage/innobase/include/btr0btr.h
@@ -23,16 +23,6 @@ special big record storage structure */
#define BTR_PAGE_MAX_REC_SIZE (UNIV_PAGE_SIZE / 2 - 200)
-/* Maximum key size in a B-tree: the records on non-leaf levels must be
-shorter than this */
-
-#define BTR_PAGE_MAX_KEY_SIZE 1024
-
-/* If data in page drops below this limit, we try to compress it.
-NOTE! The value has to be > 2 * BTR_MAX_KEY_SIZE */
-
-#define BTR_COMPRESS_LIMIT (UNIV_PAGE_SIZE / 4 + 1);
-
/* Latching modes for the search function (in btr0cur.*) */
#define BTR_SEARCH_LEAF RW_S_LATCH
#define BTR_MODIFY_LEAF RW_X_LATCH
diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic
index 06d45dd5501..d4a7b3c64b8 100644
--- a/storage/innobase/include/data0type.ic
+++ b/storage/innobase/include/data0type.ic
@@ -420,7 +420,7 @@ dtype_get_fixed_size(
}
/***************************************************************************
-Returns the size of a fixed size data type, 0 if not a fixed size type. */
+Returns the minimum size of a data type. */
UNIV_INLINE
ulint
dtype_get_min_size(
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index a1232acdca7..5215d51cabe 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -375,9 +375,10 @@ CREATE TABLE. */
void
dict_print_info_on_foreign_key_in_create_format(
/*============================================*/
- FILE* file, /* in: file where to print */
- trx_t* trx, /* in: transaction */
- dict_foreign_t* foreign);/* in: foreign key constraint */
+ FILE* file, /* in: file where to print */
+ trx_t* trx, /* in: transaction */
+ dict_foreign_t* foreign, /* in: foreign key constraint */
+ ibool add_newline); /* in: whether to add a newline */
/************************************************************************
Displays the names of the index and the table. */
void
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index ff6c4ec9b28..7eec86d0bcb 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -152,12 +152,12 @@ struct dict_col_struct{
in some of the functions below */
};
-/* DICT_MAX_COL_PREFIX_LEN is measured in bytes. Starting from 4.1.6, we
-set max col prefix len to < 3 * 256, so that one can create a column prefix
-index on 255 characters of a TEXT field also in the UTF-8 charset. In that
-charset, a character may take at most 3 bytes. */
+/* DICT_MAX_INDEX_COL_LEN is measured in bytes and is the max index column
+length + 1. Starting from 4.1.6, we set it to < 3 * 256, so that one can
+create a column prefix index on 255 characters of a TEXT field also in the
+UTF-8 charset. In that charset, a character may take at most 3 bytes. */
-#define DICT_MAX_COL_PREFIX_LEN 768
+#define DICT_MAX_INDEX_COL_LEN 768
/* Data structure for a field in an index */
struct dict_field_struct{
@@ -169,12 +169,12 @@ struct dict_field_struct{
prefix in bytes in a MySQL index of
type, e.g., INDEX (textcol(25));
must be smaller than
- DICT_MAX_COL_PREFIX_LEN; NOTE that
+ DICT_MAX_INDEX_COL_LEN; NOTE that
in the UTF-8 charset, MySQL sets this
to 3 * the prefix len in UTF-8 chars */
ulint fixed_len; /* 0 or the fixed length of the
column if smaller than
- DICT_MAX_COL_PREFIX_LEN */
+ DICT_MAX_INDEX_COL_LEN */
ulint fixed_offs; /* offset to the field, or
ULINT_UNDEFINED if it is not fixed
within the record (due to preceding
diff --git a/storage/innobase/include/mem0mem.h b/storage/innobase/include/mem0mem.h
index 87afdb8f91c..3768e93c03e 100644
--- a/storage/innobase/include/mem0mem.h
+++ b/storage/innobase/include/mem0mem.h
@@ -99,8 +99,7 @@ heap freeing. */
/*********************************************************************
NOTE: Use the corresponding macros instead of this function. Creates a
memory heap which allocates memory from dynamic space. For debugging
-purposes, takes also the file name and line as argument in the debug
-version. */
+purposes, takes also the file name and line as argument. */
UNIV_INLINE
mem_heap_t*
mem_heap_create_func(
diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic
index 8c87c884d78..28562f7c9f8 100644
--- a/storage/innobase/include/mem0mem.ic
+++ b/storage/innobase/include/mem0mem.ic
@@ -371,8 +371,7 @@ mem_heap_free_top(
/*********************************************************************
NOTE: Use the corresponding macros instead of this function. Creates a
memory heap which allocates memory from dynamic space. For debugging
-purposes, takes also the file name and line as argument in the debug
-version. */
+purposes, takes also the file name and line as argument. */
UNIV_INLINE
mem_heap_t*
mem_heap_create_func(
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
index adbc4afafd2..224fd59a76b 100644
--- a/storage/innobase/include/os0file.h
+++ b/storage/innobase/include/os0file.h
@@ -432,6 +432,17 @@ os_file_read(
offset */
ulint n); /* in: number of bytes to read */
/***********************************************************************
+Rewind file to its start, read at most size - 1 bytes from it to str, and
+NUL-terminate str. All errors are silently ignored. This function is
+mostly meant to be used with temporary files. */
+
+void
+os_file_read_string(
+/*================*/
+ FILE* file, /* in: file to read from */
+ char* str, /* in: buffer where to read */
+ ulint size); /* in: size of buffer */
+/***********************************************************************
Requests a synchronous positioned read operation. This function does not do
any error handling. In case of error it returns FALSE. */
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index a61705b90be..b5da4634d98 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -335,8 +335,14 @@ int
row_create_index_for_mysql(
/*=======================*/
/* out: error number or DB_SUCCESS */
- dict_index_t* index, /* in: index defintion */
- trx_t* trx); /* in: transaction handle */
+ dict_index_t* index, /* in: index definition */
+ trx_t* trx, /* in: transaction handle */
+ const ulint* field_lengths); /* in: if not NULL, must contain
+ dict_index_get_n_fields(index)
+ actual field lengths for the
+ index columns, which are
+ then checked for not being too
+ large. */
/*************************************************************************
Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 5dbf003594f..0dc82893ad1 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -56,6 +56,22 @@ void
trx_search_latch_release_if_reserved(
/*=================================*/
trx_t* trx); /* in: transaction */
+/**********************************************************************
+Set detailed error message for the transaction. */
+void
+trx_set_detailed_error(
+/*===================*/
+ trx_t* trx, /* in: transaction struct */
+ const char* msg); /* in: detailed error message */
+/*****************************************************************
+Set detailed error message for the transaction from a file. Note that the
+file is rewinded before reading from it. */
+
+void
+trx_set_detailed_error_from_file(
+/*=============================*/
+ trx_t* trx, /* in: transaction struct */
+ FILE* file); /* in: file to read message from */
/********************************************************************
Retrieves the error_info field from a trx. */
@@ -205,7 +221,7 @@ trx_recover_for_mysql(
XID* xid_list, /* in/out: prepared transactions */
ulint len); /* in: number of slots in xid_list */
/***********************************************************************
-This function is used to commit one X/Open XA distributed transaction
+This function is used to find one X/Open XA distributed transaction
which is in the prepared state */
trx_t *
trx_get_trx_by_xid(
@@ -649,6 +665,9 @@ struct trx_struct{
trx_undo_arr_t* undo_no_arr; /* array of undo numbers of undo log
records which are currently processed
by a rollback operation */
+ /*------------------------------*/
+ char detailed_error[256]; /* detailed error message for last
+ error, or empty. */
};
#define TRX_MAX_N_THREADS 32 /* maximum number of concurrent
diff --git a/storage/innobase/include/ut0mem.h b/storage/innobase/include/ut0mem.h
index 74357f6bf13..b9bbe0b5c92 100644
--- a/storage/innobase/include/ut0mem.h
+++ b/storage/innobase/include/ut0mem.h
@@ -119,6 +119,31 @@ int
ut_strcmp(const void* str1, const void* str2);
/**************************************************************************
+Copies up to size - 1 characters from the NUL-terminated string src to
+dst, NUL-terminating the result. Returns strlen(src), so truncation
+occurred if the return value >= size. */
+
+ulint
+ut_strlcpy(
+/*=======*/
+ /* out: strlen(src) */
+ char* dst, /* in: destination buffer */
+ const char* src, /* in: source buffer */
+ ulint size); /* in: size of destination buffer */
+
+/**************************************************************************
+Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last
+(size - 1) bytes of src, not the first. */
+
+ulint
+ut_strlcpy_rev(
+/*===========*/
+ /* out: strlen(src) */
+ char* dst, /* in: destination buffer */
+ const char* src, /* in: source buffer */
+ ulint size); /* in: size of destination buffer */
+
+/**************************************************************************
Compute strlen(ut_strcpyq(str, q)). */
UNIV_INLINE
ulint
diff --git a/storage/innobase/mem/mem0mem.c b/storage/innobase/mem/mem0mem.c
index 85f0119d02a..daf78008d45 100644
--- a/storage/innobase/mem/mem0mem.c
+++ b/storage/innobase/mem/mem0mem.c
@@ -187,9 +187,7 @@ mem_heap_create_block(
}
block->magic_n = MEM_BLOCK_MAGIC_N;
- ut_memcpy(&(block->file_name), file_name + ut_strlen(file_name) - 7,
- 7);
- block->file_name[7]='\0';
+ ut_strlcpy_rev(block->file_name, file_name, sizeof(block->file_name));
block->line = line;
#ifdef MEM_PERIODIC_CHECK
diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
index 9c87b59f018..20a3303d12d 100644
--- a/storage/innobase/os/os0file.c
+++ b/storage/innobase/os/os0file.c
@@ -2249,6 +2249,29 @@ error_handling:
}
/***********************************************************************
+Rewind file to its start, read at most size - 1 bytes from it to str, and
+NUL-terminate str. All errors are silently ignored. This function is
+mostly meant to be used with temporary files. */
+
+void
+os_file_read_string(
+/*================*/
+ FILE* file, /* in: file to read from */
+ char* str, /* in: buffer where to read */
+ ulint size) /* in: size of buffer */
+{
+ size_t flen;
+
+ if (size == 0) {
+ return;
+ }
+
+ rewind(file);
+ flen = fread(str, 1, size - 1, file);
+ str[flen] = '\0';
+}
+
+/***********************************************************************
Requests a synchronous write operation. */
ibool
diff --git a/storage/innobase/os/os0proc.c b/storage/innobase/os/os0proc.c
index 167aed93de7..24bb007e504 100644
--- a/storage/innobase/os/os0proc.c
+++ b/storage/innobase/os/os0proc.c
@@ -292,6 +292,9 @@ os_awe_allocate_physical_mem(
return(TRUE);
#else
+ UT_NOT_USED(n_megabytes);
+ UT_NOT_USED(page_info);
+
return(FALSE);
#endif
}
@@ -349,6 +352,8 @@ os_awe_allocate_virtual_mem_window(
return(ptr);
#else
+ UT_NOT_USED(size);
+
return(NULL);
#endif
}
@@ -476,6 +481,10 @@ os_awe_map_physical_mem_to_window(
return(TRUE);
#else
+ UT_NOT_USED(ptr);
+ UT_NOT_USED(n_mem_pages);
+ UT_NOT_USED(page_info);
+
return(FALSE);
#endif
}
diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c
index fbc33aea669..9480c978755 100644
--- a/storage/innobase/rem/rem0rec.c
+++ b/storage/innobase/rem/rem0rec.c
@@ -621,7 +621,7 @@ rec_set_nth_field_extern_bit_new(
if (field->fixed_len) {
/* fixed-length fields cannot be external
(Fixed-length fields longer than
- DICT_MAX_COL_PREFIX_LEN will be treated as
+ DICT_MAX_INDEX_COL_LEN will be treated as
variable-length ones in dict_index_add_col().) */
ut_ad(i != ith);
continue;
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index 75d8117a73e..5e833372299 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -579,6 +579,32 @@ row_ins_cascade_calc_update_vec(
}
/*************************************************************************
+Set detailed error message associated with foreign key errors for
+the given transaction. */
+static
+void
+row_ins_set_detailed(
+/*=================*/
+ trx_t* trx, /* in: transaction */
+ dict_foreign_t* foreign) /* in: foreign key constraint */
+{
+
+ FILE* tf = os_file_create_tmpfile();
+
+ if (tf) {
+ ut_print_name(tf, trx, foreign->foreign_table_name);
+ dict_print_info_on_foreign_key_in_create_format(tf, trx,
+ foreign, FALSE);
+
+ trx_set_detailed_error_from_file(trx, tf);
+
+ fclose(tf);
+ } else {
+ trx_set_detailed_error(trx, "temp file creation failed");
+ }
+}
+
+/*************************************************************************
Reports a foreign key error associated with an update or a delete of a
parent table index entry. */
static
@@ -598,6 +624,8 @@ row_ins_foreign_report_err(
FILE* ef = dict_foreign_err_file;
trx_t* trx = thr_get_trx(thr);
+ row_ins_set_detailed(trx, foreign);
+
mutex_enter(&dict_foreign_err_mutex);
rewind(ef);
ut_print_timestamp(ef);
@@ -607,7 +635,8 @@ row_ins_foreign_report_err(
fputs("Foreign key constraint fails for table ", ef);
ut_print_name(ef, trx, foreign->foreign_table_name);
fputs(":\n", ef);
- dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign);
+ dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
+ TRUE);
putc('\n', ef);
fputs(errstr, ef);
fputs(" in parent table, in index ", ef);
@@ -648,7 +677,9 @@ row_ins_foreign_report_add_err(
child table */
{
FILE* ef = dict_foreign_err_file;
-
+
+ row_ins_set_detailed(trx, foreign);
+
mutex_enter(&dict_foreign_err_mutex);
rewind(ef);
ut_print_timestamp(ef);
@@ -657,7 +688,8 @@ row_ins_foreign_report_add_err(
fputs("Foreign key constraint fails for table ", ef);
ut_print_name(ef, trx, foreign->foreign_table_name);
fputs(":\n", ef);
- dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign);
+ dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
+ TRUE);
fputs("\nTrying to add in child table, in index ", ef);
ut_print_name(ef, trx, foreign->foreign_index->name);
if (entry) {
@@ -1224,6 +1256,9 @@ run_again:
if (check_table == NULL || check_table->ibd_file_missing) {
if (check_ref) {
FILE* ef = dict_foreign_err_file;
+
+ row_ins_set_detailed(trx, foreign);
+
mutex_enter(&dict_foreign_err_mutex);
rewind(ef);
ut_print_timestamp(ef);
@@ -1233,7 +1268,7 @@ run_again:
ut_print_name(ef, trx, foreign->foreign_table_name);
fputs(":\n", ef);
dict_print_info_on_foreign_key_in_create_format(ef,
- trx, foreign);
+ trx, foreign, TRUE);
fputs("\nTrying to add to index ", ef);
ut_print_name(ef, trx, foreign->foreign_index->name);
fputs(" tuple:\n", ef);
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 26aae117d1d..82f7daf2ed8 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -1973,13 +1973,20 @@ row_create_index_for_mysql(
/*=======================*/
/* out: error number or DB_SUCCESS */
dict_index_t* index, /* in: index definition */
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx, /* in: transaction handle */
+ const ulint* field_lengths) /* in: if not NULL, must contain
+ dict_index_get_n_fields(index)
+ actual field lengths for the
+ index columns, which are
+ then checked for not being too
+ large. */
{
ind_node_t* node;
mem_heap_t* heap;
que_thr_t* thr;
ulint err;
ulint i, j;
+ ulint len;
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
@@ -2018,10 +2025,16 @@ row_create_index_for_mysql(
}
}
- /* Check also that prefix_len < DICT_MAX_COL_PREFIX_LEN */
+ /* Check also that prefix_len and actual length
+ < DICT_MAX_INDEX_COL_LEN */
+
+ len = dict_index_get_nth_field(index, i)->prefix_len;
- if (dict_index_get_nth_field(index, i)->prefix_len
- >= DICT_MAX_COL_PREFIX_LEN) {
+ if (field_lengths) {
+ len = ut_max(len, field_lengths[i]);
+ }
+
+ if (len >= DICT_MAX_INDEX_COL_LEN) {
err = DB_TOO_BIG_RECORD;
goto error_handling;
diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
index 325b0a109cf..e5151ebf631 100644
--- a/storage/innobase/srv/srv0start.c
+++ b/storage/innobase/srv/srv0start.c
@@ -1540,7 +1540,7 @@ NetWare. */
#endif
sync_order_checks_on = TRUE;
- if (srv_use_doublewrite_buf && trx_doublewrite == NULL) {
+ if (trx_doublewrite == NULL) {
/* Create the doublewrite buffer to a new tablespace */
trx_sys_create_doublewrite_buf();
diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c
index bf48c30e942..23f1dc40d00 100644
--- a/storage/innobase/trx/trx0sys.c
+++ b/storage/innobase/trx/trx0sys.c
@@ -126,22 +126,6 @@ trx_doublewrite_init(
}
/********************************************************************
-Frees the doublewrite buffer. */
-static
-void
-trx_doublewrite_free(void)
-/*======================*/
-{
- mutex_free(&(trx_doublewrite->mutex));
-
- mem_free(trx_doublewrite->buf_block_arr);
- ut_free(trx_doublewrite->write_buf_unaligned);
-
- mem_free(trx_doublewrite);
- trx_doublewrite = NULL;
-}
-
-/********************************************************************
Marks the trx sys header when we have successfully upgraded to the >= 4.1.x
multiple tablespace format. */
@@ -529,9 +513,6 @@ trx_sys_doublewrite_init_or_restore_pages(
fil_flush_file_spaces(FIL_TABLESPACE);
- if (!srv_use_doublewrite_buf)
- trx_doublewrite_free();
-
leave_func:
ut_free(unaligned_read_buf);
}
diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
index 078befb81d2..090057f5d46 100644
--- a/storage/innobase/trx/trx0trx.c
+++ b/storage/innobase/trx/trx0trx.c
@@ -52,6 +52,32 @@ trx_start_if_not_started_noninline(
trx_start_if_not_started(trx);
}
+/*****************************************************************
+Set detailed error message for the transaction. */
+
+void
+trx_set_detailed_error(
+/*===================*/
+ trx_t* trx, /* in: transaction struct */
+ const char* msg) /* in: detailed error message */
+{
+ ut_strlcpy(trx->detailed_error, msg, sizeof(trx->detailed_error));
+}
+
+/*****************************************************************
+Set detailed error message for the transaction from a file. Note that the
+file is rewinded before reading from it. */
+
+void
+trx_set_detailed_error_from_file(
+/*=============================*/
+ trx_t* trx, /* in: transaction struct */
+ FILE* file) /* in: file to read message from */
+{
+ os_file_read_string(file, trx->detailed_error,
+ sizeof(trx->detailed_error));
+}
+
/********************************************************************
Retrieves the error_info field from a trx. */
@@ -130,6 +156,7 @@ trx_create(
trx->undo_no_arr = NULL;
trx->error_state = DB_SUCCESS;
+ trx->detailed_error[0] = '\0';
trx->sess = sess;
trx->que_state = TRX_QUE_RUNNING;
diff --git a/storage/innobase/ut/ut0mem.c b/storage/innobase/ut/ut0mem.c
index 3e8fd79a739..47b1e24e5e1 100644
--- a/storage/innobase/ut/ut0mem.c
+++ b/storage/innobase/ut/ut0mem.c
@@ -343,6 +343,54 @@ ut_free_all_mem(void)
}
/**************************************************************************
+Copies up to size - 1 characters from the NUL-terminated string src to
+dst, NUL-terminating the result. Returns strlen(src), so truncation
+occurred if the return value >= size. */
+
+ulint
+ut_strlcpy(
+/*=======*/
+ /* out: strlen(src) */
+ char* dst, /* in: destination buffer */
+ const char* src, /* in: source buffer */
+ ulint size) /* in: size of destination buffer */
+{
+ ulint src_size = strlen(src);
+
+ if (size != 0) {
+ ulint n = ut_min(src_size, size - 1);
+
+ memcpy(dst, src, n);
+ dst[n] = '\0';
+ }
+
+ return(src_size);
+}
+
+/**************************************************************************
+Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last
+(size - 1) bytes of src, not the first. */
+
+ulint
+ut_strlcpy_rev(
+/*===========*/
+ /* out: strlen(src) */
+ char* dst, /* in: destination buffer */
+ const char* src, /* in: source buffer */
+ ulint size) /* in: size of destination buffer */
+{
+ ulint src_size = strlen(src);
+
+ if (size != 0) {
+ ulint n = ut_min(src_size, size - 1);
+
+ memcpy(dst, src + src_size - n, n + 1);
+ }
+
+ return(src_size);
+}
+
+/**************************************************************************
Make a quoted copy of a NUL-terminated string. Leading and trailing
quotes will not be included; only embedded quotes will be escaped.
See also ut_strlenq() and ut_memcpyq(). */
diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c
index 078853bad19..563abf9f0cf 100644
--- a/storage/myisam/ft_boolean_search.c
+++ b/storage/myisam/ft_boolean_search.c
@@ -510,7 +510,8 @@ static int _ftb_check_phrase(const byte *s0, const byte *e0,
for (;;)
{
n_word= (FT_WORD *)phrase_element->data;
- if (my_strnncoll(cs, h_word.pos, h_word.len, n_word->pos, n_word->len))
+ if (my_strnncoll(cs, (const uchar *) h_word.pos, h_word.len,
+ (const uchar *) n_word->pos, n_word->len))
break;
if (! (phrase_element= phrase_element->next))
DBUG_RETURN(1);
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index ee64f9b9979..074a1b23686 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -80,6 +80,7 @@ void myisamchk_init(MI_CHECK *param)
param->start_check_pos=0;
param->max_record_length= LONGLONG_MAX;
param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
+ param->stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
}
/* Check the status flags for the table */
@@ -559,10 +560,11 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
ha_checksum *key_checksum, uint level)
{
int flag;
- uint used_length,comp_flag,nod_flag,key_length=0,not_used;
+ uint used_length,comp_flag,nod_flag,key_length=0;
uchar key[MI_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos;
my_off_t next_page,record;
char llbuff[22];
+ uint diff_pos;
DBUG_ENTER("chk_index");
DBUG_DUMP("buff",(byte*) buff,mi_getint(buff));
@@ -620,7 +622,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
}
if ((*keys)++ &&
(flag=ha_key_cmp(keyinfo->seg,info->lastkey,key,key_length,
- comp_flag, &not_used)) >=0)
+ comp_flag, &diff_pos)) >=0)
{
DBUG_DUMP("old",(byte*) info->lastkey, info->lastkey_length);
DBUG_DUMP("new",(byte*) key, key_length);
@@ -636,11 +638,11 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
{
if (*keys != 1L) /* not first_key */
{
- uint diff;
- ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,
- SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
- &diff);
- param->unique_count[diff-1]++;
+ if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
+ ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,
+ SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
+ &diff_pos);
+ param->unique_count[diff_pos-1]++;
}
}
(*key_checksum)+= mi_byte_checksum((byte*) key,
@@ -1090,7 +1092,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
"Keypointers and record positions doesn't match");
error=1;
}
- else if (param->glob_crc != info->s->state.checksum &&
+ else if (param->glob_crc != info->state->checksum &&
(info->s->options &
(HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)))
{
@@ -1386,7 +1388,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
info->state->data_file_length=sort_param.max_pos;
}
if (param->testflag & T_CALC_CHECKSUM)
- share->state.checksum=param->glob_crc;
+ info->state->checksum=param->glob_crc;
if (!(param->testflag & T_SILENT))
{
@@ -2014,7 +2016,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
sort_param.sort_info=&sort_info;
sort_param.fix_datafile= (my_bool) (! rep_quick);
sort_param.master =1;
-
+
del=info->state->del;
param->glob_crc=0;
if (param->testflag & T_CALC_CHECKSUM)
@@ -2154,7 +2156,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
my_errno);
}
if (param->testflag & T_CALC_CHECKSUM)
- share->state.checksum=param->glob_crc;
+ info->state->checksum=param->glob_crc;
if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0)))
mi_check_print_warning(param,
@@ -2575,7 +2577,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
my_errno);
}
if (param->testflag & T_CALC_CHECKSUM)
- share->state.checksum=param->glob_crc;
+ info->state->checksum=param->glob_crc;
if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0)))
mi_check_print_warning(param,
@@ -3250,9 +3252,10 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
(uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
&diff_pos);
- ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
- (uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
- &diff_pos);
+ if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
+ ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
+ (uchar*) a, USE_WHOLE_KEY,
+ SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, &diff_pos);
sort_param->unique[diff_pos-1]++;
}
else
@@ -3805,7 +3808,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
(*org_info)->s->state.create_time=share.state.create_time;
(*org_info)->s->state.unique=(*org_info)->this_unique=
share.state.unique;
- (*org_info)->s->state.checksum=share.state.checksum;
+ (*org_info)->state->checksum=info.state->checksum;
(*org_info)->state->del=info.state->del;
(*org_info)->s->state.dellink=share.state.dellink;
(*org_info)->state->empty=info.state->empty;
@@ -3989,9 +3992,10 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
unique[0]= (#different values of {keypart1}) - 1
unique[1]= (#different values of {keypart2,keypart1} tuple) - unique[0] - 1
...
- Here we assume that NULL != NULL (see SEARCH_NULL_ARE_NOT_EQUAL). The
- 'unique' array is collected in one sequential scan through the entire
+ The 'unique' array is collected in one sequential scan through the entire
index. This is done in two places: in chk_index() and in sort_key_write().
+ Statistics collection may consider NULLs as either equal or unequal (see
+ SEARCH_NULL_ARE_NOT_EQUAL, MI_STATS_METHOD_*).
Output is an array:
rec_per_key_part[k] =
diff --git a/storage/myisam/mi_dbug.c b/storage/myisam/mi_dbug.c
index e782d21afe7..ddc8a403a33 100644
--- a/storage/myisam/mi_dbug.c
+++ b/storage/myisam/mi_dbug.c
@@ -40,12 +40,12 @@ void _mi_print_key(FILE *stream, register HA_KEYSEG *keyseg,
end= key+ keyseg->length;
if (keyseg->flag & HA_NULL_PART)
{
- if (!*key)
+ /* A NULL value is encoded by a 1-byte flag. Zero means NULL. */
+ if (! *(key++))
{
fprintf(stream,"NULL");
continue;
}
- key++;
}
switch (keyseg->type) {
diff --git a/storage/myisam/mi_delete.c b/storage/myisam/mi_delete.c
index 60a07254e82..62ca7f8ff61 100644
--- a/storage/myisam/mi_delete.c
+++ b/storage/myisam/mi_delete.c
@@ -93,7 +93,7 @@ int mi_delete(MI_INFO *info,const byte *record)
if ((*share->delete_record)(info))
goto err; /* Remove record from database */
- info->s->state.checksum-=info->checksum;
+ info->state->checksum-=info->checksum;
info->update= HA_STATE_CHANGED+HA_STATE_DELETED+HA_STATE_ROW_CHANGED;
info->state->records--;
diff --git a/storage/myisam/mi_delete_all.c b/storage/myisam/mi_delete_all.c
index 3033249886f..a30abb95070 100644
--- a/storage/myisam/mi_delete_all.c
+++ b/storage/myisam/mi_delete_all.c
@@ -41,7 +41,7 @@ int mi_delete_all_rows(MI_INFO *info)
info->state->key_file_length=share->base.keystart;
info->state->data_file_length=0;
info->state->empty=info->state->key_empty=0;
- state->checksum=0;
+ info->state->checksum=0;
for (i=share->base.max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; )
state->key_del[i]= HA_OFFSET_ERROR;
diff --git a/storage/myisam/mi_key.c b/storage/myisam/mi_key.c
index ae50900a190..4cabfc91197 100644
--- a/storage/myisam/mi_key.c
+++ b/storage/myisam/mi_key.c
@@ -358,7 +358,7 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
byte *blob_ptr;
DBUG_ENTER("_mi_put_key_in_record");
- blob_ptr= info->lastkey2; /* Place to put blob parts */
+ blob_ptr= (byte*) info->lastkey2; /* Place to put blob parts */
key=(byte*) info->lastkey; /* KEy that was read */
key_end=key+info->lastkey_length;
for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index 82663e0c318..955d55cf765 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -199,7 +199,8 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
DBUG_PRINT("warning",("saved_base_info_length: %d base_info_length: %d",
len,MI_BASE_INFO_SIZE))
}
- disk_pos=my_n_base_info_read((uchar*) disk_cache + base_pos, &share->base);
+ disk_pos= (char*)
+ my_n_base_info_read((uchar*) disk_cache + base_pos, &share->base);
share->state.state_length=base_pos;
if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
@@ -822,7 +823,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
mi_sizestore(ptr,state->state.empty); ptr +=8;
mi_sizestore(ptr,state->state.key_empty); ptr +=8;
mi_int8store(ptr,state->auto_increment); ptr +=8;
- mi_int8store(ptr,(ulonglong) state->checksum);ptr +=8;
+ mi_int8store(ptr,(ulonglong) state->state.checksum);ptr +=8;
mi_int4store(ptr,state->process); ptr +=4;
mi_int4store(ptr,state->unique); ptr +=4;
mi_int4store(ptr,state->status); ptr +=4;
@@ -863,7 +864,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
}
-char *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
+uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
{
uint i,keys,key_parts,key_blocks;
memcpy_fixed(&state->header,ptr, sizeof(state->header));
@@ -884,7 +885,7 @@ char *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
state->state.empty = mi_sizekorr(ptr); ptr +=8;
state->state.key_empty= mi_sizekorr(ptr); ptr +=8;
state->auto_increment=mi_uint8korr(ptr); ptr +=8;
- state->checksum=(ha_checksum) mi_uint8korr(ptr); ptr +=8;
+ state->state.checksum=(ha_checksum) mi_uint8korr(ptr); ptr +=8;
state->process= mi_uint4korr(ptr); ptr +=4;
state->unique = mi_uint4korr(ptr); ptr +=4;
state->status = mi_uint4korr(ptr); ptr +=4;
@@ -974,7 +975,7 @@ uint mi_base_info_write(File file, MI_BASE_INFO *base)
}
-char *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
+uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
{
base->keystart = mi_sizekorr(ptr); ptr +=8;
base->max_data_file_length = mi_sizekorr(ptr); ptr +=8;
diff --git a/storage/myisam/mi_rkey.c b/storage/myisam/mi_rkey.c
index 635a7eb2c48..575a5e34488 100644
--- a/storage/myisam/mi_rkey.c
+++ b/storage/myisam/mi_rkey.c
@@ -31,8 +31,8 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
HA_KEYSEG *last_used_keyseg;
uint pack_key_length, use_key_length, nextflag;
DBUG_ENTER("mi_rkey");
- DBUG_PRINT("enter",("base: %lx inx: %d search_flag: %d",
- info,inx,search_flag));
+ DBUG_PRINT("enter", ("base: %p buf: %p inx: %d search_flag: %d",
+ info, buf, inx, search_flag));
if ((inx = _mi_check_index(info,inx)) < 0)
DBUG_RETURN(my_errno);
@@ -56,9 +56,12 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
{
if (key_len == 0)
key_len=USE_WHOLE_KEY;
+ /* Save the packed key for later use in the second buffer of lastkey. */
key_buff=info->lastkey+info->s->base.max_key_length;
pack_key_length=_mi_pack_key(info,(uint) inx, key_buff, (uchar*) key,
key_len, &last_used_keyseg);
+ /* Save packed_key_length for use by the MERGE engine. */
+ info->pack_key_length= pack_key_length;
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE, keyinfo->seg,
key_buff, pack_key_length););
}
diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c
index b7360dba7f3..185f196a814 100644
--- a/storage/myisam/mi_search.c
+++ b/storage/myisam/mi_search.c
@@ -915,11 +915,21 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
reg1 HA_KEYSEG *keyseg;
uchar *start_key,*page,*page_end,*from,*from_end;
uint length,tmp;
+ DBUG_ENTER("_mi_get_binary_pack_key");
page= *page_pos;
page_end=page+MI_MAX_KEY_BUFF+1;
start_key=key;
+ /*
+ Keys are compressed the following way:
+
+ prefix length Packed length of prefix for the prev key. (1 or 3 bytes)
+ for each key segment:
+ [is null] Null indicator if can be null (1 byte, zero means null)
+ [length] Packed length if varlength (1 or 3 bytes)
+ pointer Reference to the data file (last_keyseg->length).
+ */
get_key_length(length,page);
if (length)
{
@@ -930,7 +940,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
DBUG_DUMP("key",(char*) *page_pos,16);
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
- return 0; /* Wrong key */
+ DBUG_RETURN(0); /* Wrong key */
}
from=key; from_end=key+length;
}
@@ -992,12 +1002,12 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
DBUG_PRINT("error",("Error when unpacking key"));
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
- return 0; /* Error */
+ DBUG_RETURN(0); /* Error */
}
memcpy((byte*) key,(byte*) from,(size_t) length);
*page_pos= from+length;
}
- return((uint) (key-start_key)+keyseg->length);
+ DBUG_RETURN((uint) (key-start_key)+keyseg->length);
}
diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c
index 5727c699469..60225ccc7f3 100644
--- a/storage/myisam/mi_test1.c
+++ b/storage/myisam/mi_test1.c
@@ -237,7 +237,7 @@ static int run_test(const char *filename)
pos=HA_OFFSET_ERROR;
}
if (found != row_count)
- printf("Found %ld of %ld rows\n", found,row_count);
+ printf("Found %ld of %ld rows\n", (ulong) found, (ulong) row_count);
}
if (!silent)
@@ -303,7 +303,8 @@ static int run_test(const char *filename)
if ((error=mi_rrnd(file,read_record,i == 1 ? 0L : HA_OFFSET_ERROR)) == -1)
{
if (found != row_count-deleted)
- printf("Found only %ld of %ld rows\n",found,row_count-deleted);
+ printf("Found only %ld of %ld rows\n", (ulong) found,
+ (ulong) (row_count - deleted));
break;
}
if (!error)
diff --git a/storage/myisam/mi_update.c b/storage/myisam/mi_update.c
index ab23f2e6da9..86652996afe 100644
--- a/storage/myisam/mi_update.c
+++ b/storage/myisam/mi_update.c
@@ -162,7 +162,7 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
if (auto_key_changed)
update_auto_increment(info,newrec);
if (share->calc_checksum)
- share->state.checksum+=(info->checksum - old_checksum);
+ info->state->checksum+=(info->checksum - old_checksum);
info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV |
key_changed);
diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c
index c8f9aa84a41..8785adae9a2 100644
--- a/storage/myisam/mi_write.c
+++ b/storage/myisam/mi_write.c
@@ -142,7 +142,7 @@ int mi_write(MI_INFO *info, byte *record)
{
if ((*share->write_record)(info,record))
goto err;
- share->state.checksum+=info->checksum;
+ info->state->checksum+=info->checksum;
}
if (share->base.auto_key)
update_auto_increment(info,record);
diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c
index 78ae756bf7c..a90495e5fcb 100644
--- a/storage/myisam/myisamchk.c
+++ b/storage/myisam/myisamchk.c
@@ -67,6 +67,7 @@ static const char *field_pack[]=
"no zeros", "blob", "constant", "table-lockup",
"always zero","varchar","unique-hash","?","?"};
+static const char *myisam_stats_method_str="nulls_unequal";
static void get_options(int *argc,char * * *argv);
static void print_version(void);
@@ -155,7 +156,7 @@ enum options_mc {
OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
OPT_FT_MAX_WORD_LEN, OPT_FT_STOPWORD_FILE,
- OPT_MAX_RECORD_LENGTH, OPT_AUTO_CLOSE
+ OPT_MAX_RECORD_LENGTH, OPT_AUTO_CLOSE, OPT_STATS_METHOD
};
static struct my_option my_long_options[] =
@@ -336,6 +337,11 @@ static struct my_option my_long_options[] =
"Use stopwords from this file instead of built-in list.",
(gptr*) &ft_stopword_file, (gptr*) &ft_stopword_file, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"stats_method", OPT_STATS_METHOD,
+ "Specifies how index statistics collection code should threat NULLs. "
+ "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), and \"nulls_equal\" (emulate 4.0 behavior).",
+ (gptr*) &myisam_stats_method_str, (gptr*) &myisam_stats_method_str, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -465,6 +471,12 @@ static void usage(void)
#include <help_end.h>
+const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
+ NullS};
+TYPELIB myisam_stats_method_typelib= {
+ array_elements(myisam_stats_method_names) - 1, "",
+ myisam_stats_method_names, NULL};
+
/* Read options */
static my_bool
@@ -684,6 +696,18 @@ get_one_option(int optid,
else
check_param.testflag|= T_CALC_CHECKSUM;
break;
+ case OPT_STATS_METHOD:
+ {
+ int method;
+ myisam_stats_method_str= argument;
+ if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0)
+ {
+ fprintf(stderr, "Invalid value of stats_method: %s.\n", argument);
+ exit(1);
+ }
+ check_param.stats_method= (enum_mi_stats_method) (method-1);
+ break;
+ }
#ifdef DEBUG /* Only useful if debugging */
case OPT_START_CHECK_POS:
check_param.start_check_pos= strtoull(argument, NULL, 0);
@@ -1237,7 +1261,7 @@ static void descript(MI_CHECK *param, register MI_INFO *info, my_string name)
share->base.raid_chunksize);
}
if (share->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
- printf("Checksum: %23s\n",llstr(info->s->state.checksum,llbuff));
+ printf("Checksum: %23s\n",llstr(info->state->checksum,llbuff));
;
if (share->options & HA_OPTION_DELAY_KEY_WRITE)
printf("Keys are only flushed at close\n");
@@ -1552,7 +1576,7 @@ static int mi_sort_records(MI_CHECK *param,
old_record_count=info->state->records;
info->state->records=0;
if (sort_info.new_data_file_type != COMPRESSED_RECORD)
- share->state.checksum=0;
+ info->state->checksum=0;
if (sort_record_index(&sort_param,info,keyinfo,share->state.key_root[sort_key],
temp_buff, sort_key,new_file,update_index) ||
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index 82f7fd7360e..87a1b757d88 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -38,6 +38,7 @@ typedef struct st_mi_status_info
my_off_t key_empty; /* lost space in indexfile */
my_off_t key_file_length;
my_off_t data_file_length;
+ ha_checksum checksum;
} MI_STATUS_INFO;
typedef struct st_mi_state_info
@@ -75,7 +76,6 @@ typedef struct st_mi_state_info
ulong sec_index_changed; /* Updated when new sec_index */
ulong sec_index_used; /* which extra index are in use */
ulonglong key_map; /* Which keys are in use */
- ha_checksum checksum;
ulong version; /* timestamp of create */
time_t create_time; /* Time when created database */
time_t recover_time; /* Time for last recover */
@@ -261,6 +261,7 @@ struct st_myisam_info {
uint last_rkey_length; /* Last length in mi_rkey() */
enum ha_rkey_function last_key_func; /* CONTAIN, OVERLAP, etc */
uint save_lastkey_length;
+ uint pack_key_length; /* For MYISAMMRG */
int errkey; /* Got last error on this key */
int lock_type; /* How database was locked */
int tmp_lock_type; /* When locked by readinfo */
@@ -679,10 +680,10 @@ extern uint read_pack_length(uint version, const uchar *buf, ulong *length);
extern uint calc_pack_length(uint version, ulong length);
uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite);
-char *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state);
+uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state);
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead);
uint mi_base_info_write(File file, MI_BASE_INFO *base);
-char *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base);
+uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base);
int mi_keyseg_write(File file, const HA_KEYSEG *keyseg);
char *mi_keyseg_read(char *ptr, HA_KEYSEG *keyseg);
uint mi_keydef_write(File file, MI_KEYDEF *keydef);
diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c
index 3b091cd6ea2..114e80d8f1a 100644
--- a/storage/myisam/myisampack.c
+++ b/storage/myisam/myisampack.c
@@ -2008,7 +2008,7 @@ static char *hexdigits(ulonglong value)
static int write_header(PACK_MRG_INFO *mrg,uint head_length,uint trees,
my_off_t tot_elements,my_off_t filelength)
{
- byte *buff=file_buffer.pos;
+ byte *buff= (byte*) file_buffer.pos;
bzero(buff,HEAD_LENGTH);
memcpy_fixed(buff,myisam_pack_file_magic,4);
@@ -2024,7 +2024,7 @@ static int write_header(PACK_MRG_INFO *mrg,uint head_length,uint trees,
if (test_only)
return 0;
VOID(my_seek(file_buffer.file,0L,MY_SEEK_SET,MYF(0)));
- return my_write(file_buffer.file,file_buffer.pos,HEAD_LENGTH,
+ return my_write(file_buffer.file,(const byte *) file_buffer.pos,HEAD_LENGTH,
MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL)) != 0;
}
@@ -2472,7 +2472,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
{
if (flush_buffer((ulong) max_calc_length + (ulong) max_pack_length))
break;
- record_pos=file_buffer.pos;
+ record_pos= (byte*) file_buffer.pos;
file_buffer.pos+=max_pack_length;
for (start_pos=record, count= huff_counts; count < end_count ; count++)
{
@@ -2795,7 +2795,8 @@ static char *make_old_name(char *new_name, char *old_name)
static void init_file_buffer(File file, pbool read_buffer)
{
file_buffer.file=file;
- file_buffer.buffer=my_malloc(ALIGN_SIZE(RECORD_CACHE_SIZE),MYF(MY_WME));
+ file_buffer.buffer= (uchar*) my_malloc(ALIGN_SIZE(RECORD_CACHE_SIZE),
+ MYF(MY_WME));
file_buffer.end=file_buffer.buffer+ALIGN_SIZE(RECORD_CACHE_SIZE)-8;
file_buffer.pos_in_file=0;
error_on_write=0;
@@ -2837,7 +2838,8 @@ static int flush_buffer(ulong neaded_length)
file_buffer.pos_in_file+=length;
if (test_only)
return 0;
- if (error_on_write|| my_write(file_buffer.file,file_buffer.buffer,
+ if (error_on_write|| my_write(file_buffer.file,
+ (const byte*) file_buffer.buffer,
length,
MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL)))
{
@@ -2850,13 +2852,13 @@ static int flush_buffer(ulong neaded_length)
{
char *tmp;
neaded_length+=256; /* some margin */
- tmp=my_realloc(file_buffer.buffer, neaded_length,MYF(MY_WME));
+ tmp= my_realloc((char*) file_buffer.buffer, neaded_length,MYF(MY_WME));
if (!tmp)
return 1;
file_buffer.pos= ((uchar*) tmp +
(ulong) (file_buffer.pos - file_buffer.buffer));
- file_buffer.buffer=tmp;
- file_buffer.end=tmp+neaded_length-8;
+ file_buffer.buffer= (uchar*) tmp;
+ file_buffer.end= (uchar*) (tmp+neaded_length-8);
}
return 0;
}
@@ -2965,7 +2967,7 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length,
share->state.key_root[key]= HA_OFFSET_ERROR;
for (key=0 ; key < share->state.header.max_block_size ; key++)
share->state.key_del[key]= HA_OFFSET_ERROR;
- share->state.checksum=crc; /* Save crc here */
+ isam_file->state->checksum=crc; /* Save crc here */
share->changed=1; /* Force write of header */
share->state.open_count=0;
share->global_changed=0;
@@ -3001,7 +3003,7 @@ static int save_state_mrg(File file,PACK_MRG_INFO *mrg,my_off_t new_length,
state.dellink= HA_OFFSET_ERROR;
state.version=(ulong) time((time_t*) 0);
mi_clear_all_keys_active(state.key_map);
- state.checksum=crc;
+ state.state.checksum=crc;
if (isam_file->s->base.keys)
isamchk_neaded=1;
state.changed=STATE_CHANGED | STATE_NOT_ANALYZED; /* Force check of table */
diff --git a/storage/myisam/sp_key.c b/storage/myisam/sp_key.c
index 1d43f89cba9..77cecdc0931 100644
--- a/storage/myisam/sp_key.c
+++ b/storage/myisam/sp_key.c
@@ -142,7 +142,7 @@ static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims,
{
if ((*wkb) > end - 8)
return -1;
- get_double(&ord, *wkb);
+ get_double(&ord, (const byte*) *wkb);
(*wkb)+= 8;
if (ord < *mbr)
float8store((char*) mbr, ord);
diff --git a/storage/myisammrg/myrg_rkey.c b/storage/myisammrg/myrg_rkey.c
index a85ef6a3b5e..f87b264081e 100644
--- a/storage/myisammrg/myrg_rkey.c
+++ b/storage/myisammrg/myrg_rkey.c
@@ -44,11 +44,12 @@ int myrg_rkey(MYRG_INFO *info,byte *buf,int inx, const byte *key,
MYRG_TABLE *table;
MI_INFO *mi;
int err;
+ DBUG_ENTER("myrg_rkey");
LINT_INIT(key_buff);
LINT_INIT(pack_key_length);
if (_myrg_init_queue(info,inx,search_flag))
- return my_errno;
+ DBUG_RETURN(my_errno);
for (table=info->open_tables ; table != info->end_table ; table++)
{
@@ -57,8 +58,9 @@ int myrg_rkey(MYRG_INFO *info,byte *buf,int inx, const byte *key,
if (table == info->open_tables)
{
err=mi_rkey(mi,0,inx,key,key_len,search_flag);
+ /* Get the saved packed key and packed key length. */
key_buff=(byte*) mi->lastkey+mi->s->base.max_key_length;
- pack_key_length=mi->last_rkey_length;
+ pack_key_length=mi->pack_key_length;
}
else
{
@@ -71,17 +73,22 @@ int myrg_rkey(MYRG_INFO *info,byte *buf,int inx, const byte *key,
{
if (err == HA_ERR_KEY_NOT_FOUND)
continue;
- return err;
+ DBUG_PRINT("exit", ("err: %d", err));
+ DBUG_RETURN(err);
}
/* adding to queue */
queue_insert(&(info->by_key),(byte *)table);
}
+ DBUG_PRINT("info", ("tables with matches: %u", info->by_key.elements));
if (!info->by_key.elements)
- return HA_ERR_KEY_NOT_FOUND;
+ DBUG_RETURN(HA_ERR_KEY_NOT_FOUND);
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
mi->once_flags|= RRND_PRESERVE_LASTINX;
- return _myrg_mi_read_record(mi,buf);
+ DBUG_PRINT("info", ("using table no: %d",
+ info->current_table - info->open_tables + 1));
+ DBUG_DUMP("result key", (byte*) mi->lastkey, mi->lastkey_length);
+ DBUG_RETURN(_myrg_mi_read_record(mi,buf));
}
diff --git a/storage/ndb/include/kernel/GlobalSignalNumbers.h b/storage/ndb/include/kernel/GlobalSignalNumbers.h
index 141e7392250..2cecd109ac1 100644
--- a/storage/ndb/include/kernel/GlobalSignalNumbers.h
+++ b/storage/ndb/include/kernel/GlobalSignalNumbers.h
@@ -554,7 +554,6 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
#define GSN_STATISTICS_CONF 454
#define GSN_START_ORD 455
-/* 456 unused */
/* 457 unused */
#define GSN_EVENT_SUBSCRIBE_REQ 458
@@ -830,14 +829,6 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
#define GSN_656
-/**
- * Management server
- */
-#define GSN_MGM_LOCK_CONFIG_REQ 657
-#define GSN_MGM_LOCK_CONFIG_REP 658
-#define GSN_MGM_UNLOCK_CONFIG_REQ 659
-#define GSN_MGM_UNLOCK_CONFIG_REP 660
-
#define GSN_UTIL_CREATE_LOCK_REQ 132
#define GSN_UTIL_CREATE_LOCK_REF 133
#define GSN_UTIL_CREATE_LOCK_CONF 188
@@ -894,6 +885,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
#define GSN_RESUME_REQ 682
#define GSN_STOP_REQ 443
#define GSN_STOP_REF 444
+#define GSN_STOP_CONF 456
#define GSN_API_VERSION_REQ 697
#define GSN_API_VERSION_CONF 698
diff --git a/storage/ndb/include/kernel/signaldata/ApiVersion.hpp b/storage/ndb/include/kernel/signaldata/ApiVersion.hpp
index 28281e7d186..a3774c9fba6 100644
--- a/storage/ndb/include/kernel/signaldata/ApiVersion.hpp
+++ b/storage/ndb/include/kernel/signaldata/ApiVersion.hpp
@@ -49,12 +49,11 @@ class ApiVersionConf {
*/
friend class MgmtSrv;
public:
- STATIC_CONST( SignalLength = 3 );
+ STATIC_CONST( SignalLength = 4 );
Uint32 senderRef;
Uint32 nodeId; //api node id
Uint32 version; // Version of API node
-
-
+ Uint32 inet_addr;
};
#endif
diff --git a/storage/ndb/include/kernel/signaldata/StopReq.hpp b/storage/ndb/include/kernel/signaldata/StopReq.hpp
index ea453ae115d..8e6a0b90a91 100644
--- a/storage/ndb/include/kernel/signaldata/StopReq.hpp
+++ b/storage/ndb/include/kernel/signaldata/StopReq.hpp
@@ -67,6 +67,13 @@ public:
static bool getStopAbort(const Uint32 & requestInfo);
};
+struct StopConf
+{
+ STATIC_CONST( SignalLength = 2 );
+ Uint32 senderData;
+ Uint32 nodeState;
+};
+
class StopRef
{
/**
@@ -86,7 +93,8 @@ public:
OK = 0,
NodeShutdownInProgress = 1,
SystemShutdownInProgress = 2,
- NodeShutdownWouldCauseSystemCrash = 3
+ NodeShutdownWouldCauseSystemCrash = 3,
+ TransactionAbortFailed = 4
};
public:
diff --git a/storage/ndb/include/mgmapi/ndb_logevent.h b/storage/ndb/include/mgmapi/ndb_logevent.h
index f3f9d04e6d0..b0c14f91c4c 100644
--- a/storage/ndb/include/mgmapi/ndb_logevent.h
+++ b/storage/ndb/include/mgmapi/ndb_logevent.h
@@ -148,9 +148,9 @@ extern "C" {
/** NDB_MGM_EVENT_CATEGORY_INFO */
NDB_LE_InfoEvent = 49,
- /* GREP */
- NDB_LE_GrepSubscriptionInfo = 52,
- NDB_LE_GrepSubscriptionAlert = 53,
+ /* SINGLE USER */
+ NDB_LE_SingleUser = 52,
+ /* NDB_LE_ UNUSED = 53, */
/** NDB_MGM_EVENT_CATEGORY_BACKUP */
NDB_LE_BackupStarted = 54,
@@ -607,6 +607,11 @@ extern "C" {
unsigned backup_id;
unsigned error;
} BackupAborted;
+ /** Log event data @ref NDB_LE_SingleUser */
+ struct {
+ unsigned type;
+ unsigned node_id;
+ } SingleUser;
#ifndef DOXYGEN_FIX
};
#else
diff --git a/storage/ndb/include/ndbapi/Ndb.hpp b/storage/ndb/include/ndbapi/Ndb.hpp
index cae2c4653e6..f8337d4b281 100644
--- a/storage/ndb/include/ndbapi/Ndb.hpp
+++ b/storage/ndb/include/ndbapi/Ndb.hpp
@@ -986,10 +986,10 @@ class NdbBlob;
class NdbReceiver;
class TransporterFacade;
class PollGuard;
+template <class T> struct Ndb_free_list_t;
typedef void (* NdbEventCallback)(NdbEventOperation*, Ndb*, void*);
-
#if defined NDB_OSE
/**
* Default time to wait for response after request has been sent to
@@ -1473,8 +1473,20 @@ public:
*/
NdbTransaction* hupp( NdbTransaction* );
Uint32 getReference() const { return theMyRef;}
+
+ struct Free_list_usage
+ {
+ const char * m_name;
+ Uint32 m_created;
+ Uint32 m_free;
+ Uint32 m_sizeof;
+ };
+
+ Free_list_usage * get_free_list_usage(Free_list_usage*);
#endif
+
+
/*****************************************************************************
* These are service routines used by the other classes in the NDBAPI.
****************************************************************************/
@@ -1650,22 +1662,8 @@ private:
class NdbDictionaryImpl* theDictionary;
class NdbEventBuffer* theEventBuffer;
- NdbTransaction* theConIdleList; // First connection in idle list.
-
- NdbOperation* theOpIdleList; // First operation in the idle list.
-
- NdbIndexScanOperation* theScanOpIdleList; // First scan operation in the idle list.
- NdbIndexOperation* theIndexOpIdleList; // First index operation in the idle list.
NdbTransaction* theTransactionList;
NdbTransaction** theConnectionArray;
- NdbRecAttr* theRecAttrIdleList;
- NdbApiSignal* theSignalIdleList; // First signal in idlelist.
- NdbLabel* theLabelList; // First label descriptor in list
- NdbBranch* theBranchList; // First branch descriptor in list
- NdbSubroutine* theSubroutineList; // First subroutine descriptor in
- NdbCall* theCallList; // First call descriptor in list
- NdbReceiver* theScanList;
- NdbBlob* theNdbBlobIdleList;
Uint32 theMyRef; // My block reference
Uint32 theNode; // The node number of our node
diff --git a/storage/ndb/include/ndbapi/NdbBlob.hpp b/storage/ndb/include/ndbapi/NdbBlob.hpp
index 271287b765c..cb0caafe34f 100644
--- a/storage/ndb/include/ndbapi/NdbBlob.hpp
+++ b/storage/ndb/include/ndbapi/NdbBlob.hpp
@@ -277,7 +277,7 @@ private:
// for keeping in lists
NdbBlob* theNext;
// initialization
- NdbBlob();
+ NdbBlob(Ndb*);
void init();
void release();
// classify operations
@@ -329,6 +329,10 @@ private:
int getOperationType() const;
friend class NdbOut& operator<<(NdbOut&, const NdbBlob&);
#endif
+
+ void next(NdbBlob* obj) { theNext= obj;}
+ NdbBlob* next() { return theNext;}
+ friend struct Ndb_free_list_t<NdbBlob>;
};
#endif
diff --git a/storage/ndb/include/ndbapi/NdbIndexOperation.hpp b/storage/ndb/include/ndbapi/NdbIndexOperation.hpp
index 3de6835238e..a8a15978568 100644
--- a/storage/ndb/include/ndbapi/NdbIndexOperation.hpp
+++ b/storage/ndb/include/ndbapi/NdbIndexOperation.hpp
@@ -181,6 +181,7 @@ private:
// Private attributes
const NdbIndexImpl* m_theIndex;
+ friend struct Ndb_free_list_t<NdbIndexOperation>;
};
#endif
diff --git a/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp b/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp
index fd7e9f2d05c..dea0a079d4a 100644
--- a/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp
+++ b/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp
@@ -168,9 +168,10 @@ private:
int compare(Uint32 key, Uint32 cols, const NdbReceiver*, const NdbReceiver*);
Uint32 m_sort_columns;
-
Uint32 m_this_bound_start;
Uint32 * m_first_bound_word;
+
+ friend struct Ndb_free_list_t<NdbIndexScanOperation>;
};
#endif
diff --git a/storage/ndb/include/ndbapi/NdbOperation.hpp b/storage/ndb/include/ndbapi/NdbOperation.hpp
index fca610772cc..1035c642c97 100644
--- a/storage/ndb/include/ndbapi/NdbOperation.hpp
+++ b/storage/ndb/include/ndbapi/NdbOperation.hpp
@@ -22,6 +22,7 @@
#include "NdbError.hpp"
#include "NdbReceiver.hpp"
#include "NdbDictionary.hpp"
+#include "Ndb.hpp"
class Ndb;
class NdbApiSignal;
@@ -756,8 +757,6 @@ protected:
/******************************************************************************
* These are the methods used to create and delete the NdbOperation objects.
*****************************************************************************/
- NdbOperation(Ndb* aNdb);
- virtual ~NdbOperation();
bool needReply();
/******************************************************************************
@@ -769,6 +768,8 @@ protected:
int init(const class NdbTableImpl*, NdbTransaction* aCon);
void initInterpreter();
+ NdbOperation(Ndb* aNdb);
+ virtual ~NdbOperation();
void next(NdbOperation*); // Set next pointer
NdbOperation* next(); // Get next pointer
public:
@@ -965,6 +966,8 @@ protected:
* IgnoreError on connection level.
*/
Int8 m_abortOption;
+
+ friend struct Ndb_free_list_t<NdbOperation>;
};
#ifdef NDB_NO_DROPPED_SIGNAL
diff --git a/storage/ndb/include/ndbapi/NdbRecAttr.hpp b/storage/ndb/include/ndbapi/NdbRecAttr.hpp
index 50de4f3277e..3607a64f3b3 100644
--- a/storage/ndb/include/ndbapi/NdbRecAttr.hpp
+++ b/storage/ndb/include/ndbapi/NdbRecAttr.hpp
@@ -17,7 +17,8 @@
#ifndef NdbRecAttr_H
#define NdbRecAttr_H
-#include <NdbDictionary.hpp>
+#include "NdbDictionary.hpp"
+#include "Ndb.hpp"
class NdbOperation;
@@ -248,7 +249,6 @@ public:
const NdbRecAttr* next() const;
#endif
private:
- NdbRecAttr();
Uint32 attrId() const; /* Get attribute id */
bool setNULL(); /* Set NULL indicator */
@@ -258,6 +258,7 @@ private:
void release(); /* Release memory if allocated */
void init(); /* Initialise object when allocated */
+ NdbRecAttr(Ndb*);
void next(NdbRecAttr* aRecAttr);
NdbRecAttr* next();
@@ -280,6 +281,8 @@ private:
Uint32 theAttrSize;
Uint32 theArraySize;
const NdbDictionary::Column* m_column;
+
+ friend struct Ndb_free_list_t<NdbRecAttr>;
};
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
diff --git a/storage/ndb/include/ndbapi/NdbTransaction.hpp b/storage/ndb/include/ndbapi/NdbTransaction.hpp
index 2e102b104d8..a6ba6a11c4d 100644
--- a/storage/ndb/include/ndbapi/NdbTransaction.hpp
+++ b/storage/ndb/include/ndbapi/NdbTransaction.hpp
@@ -18,8 +18,9 @@
#define NdbTransaction_H
#include <ndb_types.h>
-#include <NdbError.hpp>
-#include <NdbDictionary.hpp>
+#include "NdbError.hpp"
+#include "NdbDictionary.hpp"
+#include "Ndb.hpp"
class NdbTransaction;
class NdbOperation;
@@ -581,9 +582,7 @@ private:
/**************************************************************************
* These are the create and delete methods of this class. *
**************************************************************************/
-
NdbTransaction(Ndb* aNdb);
-
~NdbTransaction();
void init(); // Initialize connection object for new transaction
@@ -807,6 +806,7 @@ private:
void define_scan_op(NdbIndexScanOperation*);
friend class HugoOperations;
+ friend struct Ndb_free_list_t<NdbTransaction>;
};
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
diff --git a/storage/ndb/src/common/debugger/EventLogger.cpp b/storage/ndb/src/common/debugger/EventLogger.cpp
index 06345695107..36796e700b4 100644
--- a/storage/ndb/src/common/debugger/EventLogger.cpp
+++ b/storage/ndb/src/common/debugger/EventLogger.cpp
@@ -669,6 +669,27 @@ void getTextBackupAborted(QQQQ) {
theData[3]);
}
+void getTextSingleUser(QQQQ) {
+ switch (theData[1])
+ {
+ case 0:
+ BaseString::snprintf(m_text, m_text_len, "Entering single user mode");
+ break;
+ case 1:
+ BaseString::snprintf(m_text, m_text_len,
+ "Entered single user mode "
+ "Node %d has exclusive access", theData[2]);
+ break;
+ case 2:
+ BaseString::snprintf(m_text, m_text_len,"Exiting single user mode");
+ break;
+ default:
+ BaseString::snprintf(m_text, m_text_len,
+ "Unknown single user report %d", theData[1]);
+ break;
+ }
+}
+
#if 0
BaseString::snprintf(m_text,
m_text_len,
@@ -753,6 +774,9 @@ const EventLoggerBase::EventRepLogLevelMatrix EventLoggerBase::matrix[] = {
ROW(InfoEvent, LogLevel::llInfo, 2, Logger::LL_INFO ),
ROW(EventBufferStatus, LogLevel::llInfo, 7, Logger::LL_INFO ),
+ //Single User
+ ROW(SingleUser, LogLevel::llInfo, 7, Logger::LL_INFO ),
+
// Backup
ROW(BackupStarted, LogLevel::llBackup, 7, Logger::LL_INFO ),
ROW(BackupCompleted, LogLevel::llBackup, 7, Logger::LL_INFO ),
diff --git a/storage/ndb/src/common/util/SimpleProperties.cpp b/storage/ndb/src/common/util/SimpleProperties.cpp
index c25aaea491a..c9251c6a854 100644
--- a/storage/ndb/src/common/util/SimpleProperties.cpp
+++ b/storage/ndb/src/common/util/SimpleProperties.cpp
@@ -51,11 +51,12 @@ SimpleProperties::Writer::add(const char * value, int len){
union {
Uint32 lastWord;
char lastBytes[4];
- };
- memcpy(lastBytes,
+ } tmp;
+ tmp.lastWord =0 ;
+ memcpy(tmp.lastBytes,
value + putLen*4,
len - putLen*4);
- return putWord(lastWord);
+ return putWord(tmp.lastWord);
}
bool
diff --git a/storage/ndb/src/kernel/blocks/backup/Backup.cpp b/storage/ndb/src/kernel/blocks/backup/Backup.cpp
index 063e36a775f..cbffd6bcb6b 100644
--- a/storage/ndb/src/kernel/blocks/backup/Backup.cpp
+++ b/storage/ndb/src/kernel/blocks/backup/Backup.cpp
@@ -3262,6 +3262,7 @@ Backup::execBACKUP_FRAGMENT_REQ(Signal* signal)
req->requestInfo = 0;
req->savePointId = 0;
req->tableId = table.tableId;
+ ScanFragReq::setReadCommittedFlag(req->requestInfo, 1);
ScanFragReq::setLockMode(req->requestInfo, 0);
ScanFragReq::setHoldLockFlag(req->requestInfo, 0);
ScanFragReq::setKeyinfoFlag(req->requestInfo, 0);
diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
index a09ee0472a4..7ec3bde41e8 100644
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
@@ -3255,8 +3255,8 @@ Dbdict::alterTable_backup_mutex_locked(Signal* signal,
lreq->gci = tablePtr.p->gciTableCreated;
lreq->requestType = AlterTabReq::AlterTablePrepare;
- sendSignal(rg, GSN_ALTER_TAB_REQ, signal,
- AlterTabReq::SignalLength, JBB);
+ sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal,
+ AlterTabReq::SignalLength, JBB);
}
void Dbdict::alterTableRef(Signal * signal,
@@ -3740,8 +3740,8 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){
lreq->gci = gci;
lreq->requestType = AlterTabReq::AlterTableCommit;
- sendSignal(rg, GSN_ALTER_TAB_REQ, signal,
- AlterTabReq::SignalLength, JBB);
+ sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal,
+ AlterTabReq::SignalLength, JBB);
}
}
else {
diff --git a/storage/ndb/src/kernel/blocks/dbdict/Makefile.am b/storage/ndb/src/kernel/blocks/dbdict/Makefile.am
index 0c22e06b855..367e3cf203b 100644
--- a/storage/ndb/src/kernel/blocks/dbdict/Makefile.am
+++ b/storage/ndb/src/kernel/blocks/dbdict/Makefile.am
@@ -1,12 +1,20 @@
-#SUBDIRS = printSchemafile
-
noinst_LIBRARIES = libdbdict.a
+EXTRA_PROGRAMS = printSchemaFile
libdbdict_a_SOURCES = Dbdict.cpp
+printSchemaFile_SOURCES = printSchemaFile.cpp
+
include $(top_srcdir)/storage/ndb/config/common.mk.am
include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
+LDADD += \
+ $(top_builddir)/storage/ndb/src/common/util/libgeneral.la \
+ $(top_builddir)/storage/ndb/src/common/portlib/libportlib.la \
+ $(top_builddir)/dbug/libdbug.a \
+ $(top_builddir)/mysys/libmysys.a \
+ $(top_builddir)/strings/libmystrings.a
+
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp b/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp
index 9858744a61d..f73654fd9d5 100644
--- a/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp
+++ b/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp
@@ -1,14 +1,3 @@
-#if 0
-make -f Makefile -f - printSchemaFile <<'_eof_'
-printSchemaFile: printSchemaFile.cpp SchemaFile.hpp
- $(CXXCOMPILE) -o $@ $@.cpp -L../../../common/util/.libs -lgeneral
-ifneq ($(MYSQL_HOME),)
- ln -sf `pwd`/$@ $(MYSQL_HOME)/bin/$@
-endif
-_eof_
-exit $?
-#endif
-
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -36,14 +25,19 @@ exit $?
static const char* progname = 0;
static bool allflag = false;
static bool checkonly = false;
-static int xitcode = 0;
+static bool equalcontents = false;
+static bool okquiet = false;
static void
usage()
{
- ndbout << "Usage " << progname
- << " [-ac]"
- << " P0.SchemaLog" << endl;
+ ndbout
+ << "Usage: " << progname << " [-aceq]" << " file ..." << endl
+ << "-a print also unused slots" << endl
+ << "-c check only (return status 1 on error)" << endl
+ << "-e check also that the files have identical contents" << endl
+ << "-q no output if file is ok" << endl
+ << "Example: " << progname << " -ceq ndb_*_fs/D[12]/DBDICT/P0.SchemaLog" << endl;
}
static void
@@ -57,53 +51,78 @@ fill(const char * buf, int mod)
}
}
-static void
+static const char*
+version(Uint32 v)
+{
+ static char buf[40];
+ sprintf(buf, "%d.%d.%d", v >> 16, (v >> 8) & 0xFF, v & 0xFF);
+ return buf;
+}
+
+static int
print_head(const char * filename, const SchemaFile * sf)
{
+ int retcode = 0;
+
if (! checkonly) {
ndbout << "----- Schemafile: " << filename << " -----" << endl;
- ndbout_c("Magic: %.*s ByteOrder: %.8x NdbVersion: %d.%d.%d FileSize: %d",
+ ndbout_c("Magic: %.*s ByteOrder: %.8x NdbVersion: %s FileSize: %d",
sizeof(sf->Magic),
sf->Magic,
sf->ByteOrder,
- sf->NdbVersion >> 16,
- (sf->NdbVersion >> 8) & 0xFF,
- sf->NdbVersion & 0xFF,
+ version(sf->NdbVersion),
sf->FileSize);
}
+
+ if (memcmp(sf->Magic, "NDBSCHMA", sizeof(sf->Magic) != 0)) {
+ ndbout << filename << ": invalid header magic" << endl;
+ retcode = 1;
+ }
+
+ if ((sf->NdbVersion >> 16) < 4 || (sf->NdbVersion >> 16) > 9) {
+ ndbout << filename << ": impossible version " << hex << sf->NdbVersion << endl;
+ retcode = 1;
+ }
+
+ return retcode;
}
-static void
-print_old(const char * filename, const SchemaFile * sf)
+static int
+print_old(const char * filename, const SchemaFile * sf, Uint32 sz)
{
- print_head(filename, sf);
+ int retcode = 0;
+
+ if (print_head(filename, sf) != 0)
+ retcode = 1;
for (Uint32 i = 0; i < sf->NoOfTableEntries; i++) {
SchemaFile::TableEntry_old te = sf->TableEntries_old[i];
if (allflag ||
(te.m_tableState != SchemaFile::INIT &&
te.m_tableState != SchemaFile::DROP_TABLE_COMMITTED)) {
- ndbout << "Table " << i << ":"
- << " State = " << te.m_tableState
- << " version = " << table_version_major(te.m_tableVersion) <<
- << "(" << table_version_minor(te.m_tableVersion) << ")"
- << " type = " << te.m_tableType
- << " noOfPages = " << te.m_noOfPages
- << " gcp: " << te.m_gcp << endl;
+ if (! checkonly)
+ ndbout << "Table " << i << ":"
+ << " State = " << te.m_tableState
+ << " version = " << te.m_tableVersion
+ << " type = " << te.m_tableType
+ << " noOfPages = " << te.m_noOfPages
+ << " gcp: " << te.m_gcp << endl;
}
}
+ return retcode;
}
-static void
+static int
print(const char * filename, const SchemaFile * xsf, Uint32 sz)
{
int retcode = 0;
- print_head(filename, xsf);
+ if (print_head(filename, xsf) != 0)
+ retcode = 1;
assert(sizeof(SchemaFile) == NDB_SF_PAGE_SIZE);
if (xsf->FileSize != sz || xsf->FileSize % NDB_SF_PAGE_SIZE != 0) {
- ndbout << "***** invalid FileSize " << xsf->FileSize << endl;
+ ndbout << filename << ": invalid FileSize " << xsf->FileSize << endl;
retcode = 1;
}
Uint32 noOfPages = xsf->FileSize / NDB_SF_PAGE_SIZE;
@@ -112,19 +131,23 @@ print(const char * filename, const SchemaFile * xsf, Uint32 sz)
ndbout << "----- Page: " << n << " (" << noOfPages << ") -----" << endl;
}
const SchemaFile * sf = &xsf[n];
+ if (memcmp(sf->Magic, xsf->Magic, sizeof(sf->Magic)) != 0) {
+ ndbout << filename << ": page " << n << " invalid magic" << endl;
+ retcode = 1;
+ }
if (sf->FileSize != xsf->FileSize) {
- ndbout << "***** page " << n << " FileSize changed to " << sf->FileSize << "!=" << xsf->FileSize << endl;
+ ndbout << filename << ": page " << n << " FileSize changed to " << sf->FileSize << "!=" << xsf->FileSize << endl;
retcode = 1;
}
Uint32 cs = 0;
for (Uint32 j = 0; j < NDB_SF_PAGE_SIZE_IN_WORDS; j++)
cs ^= ((const Uint32*)sf)[j];
if (cs != 0) {
- ndbout << "***** page " << n << " invalid CheckSum" << endl;
+ ndbout << filename << ": page " << n << " invalid CheckSum" << endl;
retcode = 1;
}
if (sf->NoOfTableEntries != NDB_SF_PAGE_ENTRIES) {
- ndbout << "***** page " << n << " invalid NoOfTableEntries " << sf->NoOfTableEntries << endl;
+ ndbout << filename << ": page " << n << " invalid NoOfTableEntries " << sf->NoOfTableEntries << endl;
retcode = 1;
}
for (Uint32 i = 0; i < NDB_SF_PAGE_ENTRIES; i++) {
@@ -142,31 +165,41 @@ print(const char * filename, const SchemaFile * xsf, Uint32 sz)
<< " gcp: " << te.m_gcp << endl;
}
if (te.m_unused[0] != 0 || te.m_unused[1] != 0 || te.m_unused[2] != 0) {
- ndbout << "***** entry " << j << " garbage in m_unused[3]" << endl;
+ ndbout << filename << ": entry " << j << " garbage in m_unused[3]" << endl;
retcode = 1;
}
}
}
- if (retcode != 0)
- xitcode = 1;
- else if (checkonly)
- ndbout << "ok: " << filename << endl;
+ return retcode;
}
NDB_COMMAND(printSchemafile,
"printSchemafile", "printSchemafile", "Prints a schemafile", 16384)
{
progname = argv[0];
+ int exitcode = 0;
- while (argv[1][0] == '-') {
+ while (argc > 1 && argv[1][0] == '-') {
if (strchr(argv[1], 'a') != 0)
allflag = true;
if (strchr(argv[1], 'c') != 0)
checkonly = true;
+ if (strchr(argv[1], 'e') != 0)
+ equalcontents = true;
+ if (strchr(argv[1], 'q') != 0)
+ okquiet = true;
+ if (strchr(argv[1], 'h') != 0 || strchr(argv[1], '?') != 0) {
+ usage();
+ return 0;
+ }
argc--, argv++;
}
+ const char * prevfilename = 0;
+ Uint32 * prevbuf = 0;
+ Uint32 prevbytes = 0;
+
while (argc > 1) {
const char * filename = argv[1];
argc--, argv++;
@@ -174,8 +207,9 @@ NDB_COMMAND(printSchemafile,
struct stat sbuf;
const int res = stat(filename, &sbuf);
if (res != 0) {
- ndbout << "Could not find file: \"" << filename << "\"" << endl;
- return 1;
+ ndbout << filename << ": not found errno=" << errno << endl;
+ exitcode = 1;
+ continue;
}
const Uint32 bytes = sbuf.st_size;
@@ -183,25 +217,56 @@ NDB_COMMAND(printSchemafile,
FILE * f = fopen(filename, "rb");
if (f == 0) {
- ndbout << "Failed to open file" << endl;
+ ndbout << filename << ": open failed errno=" << errno << endl;
delete [] buf;
- return 1;
+ exitcode = 1;
+ continue;
}
Uint32 sz = fread(buf, 1, bytes, f);
fclose(f);
if (sz != bytes) {
- ndbout << "Failure while reading file" << endl;
+ ndbout << filename << ": read failed errno=" << errno << endl;
+ delete [] buf;
+ exitcode = 1;
+ continue;
+ }
+
+ if (sz < 32) {
+ ndbout << filename << ": too short (no header)" << endl;
delete [] buf;
- return 1;
+ exitcode = 1;
+ continue;
}
SchemaFile* sf = (SchemaFile *)&buf[0];
+ int ret;
if (sf->NdbVersion < NDB_SF_VERSION_5_0_6)
- print_old(filename, sf);
+ ret = print_old(filename, sf, sz);
else
- print(filename, sf, sz);
- delete [] buf;
+ ret = print(filename, sf, sz);
+
+ if (ret != 0) {
+ ndbout << filename << ": check failed"
+ << " version=" << version(sf->NdbVersion) << endl;
+ exitcode = 1;
+ } else if (! okquiet) {
+ ndbout << filename << ": ok"
+ << " version=" << version(sf->NdbVersion) << endl;
+ }
+
+ if (equalcontents && prevfilename != 0) {
+ if (prevbytes != bytes || memcmp(prevbuf, buf, bytes) != 0) {
+ ndbout << filename << ": differs from " << prevfilename << endl;
+ exitcode = 1;
+ }
+ }
+
+ prevfilename = filename;
+ delete [] prevbuf;
+ prevbuf = buf;
+ prevbytes = bytes;
}
- return xitcode;
+ delete [] prevbuf;
+ return exitcode;
}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
index 9631a2b2e9b..65a61174596 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
@@ -1004,8 +1004,19 @@ Dbtup::read_pseudo(Uint32 attrId, Uint32* outBuffer){
return 1;
case AttributeHeader::FRAGMENT_MEMORY:
{
- Uint64 tmp= fragptr.p->noOfPages;
- tmp*= 32768;
+ Uint64 tmp = 0;
+ tmp += fragptr.p->noOfPages;
+ {
+ /**
+ * Each fragment is split into 2...get #pages from other as well
+ */
+ Uint32 twin = fragptr.p->fragmentId ^ 1;
+ FragrecordPtr twinPtr;
+ getFragmentrec(twinPtr, twin, tabptr.p);
+ ndbrequire(twinPtr.p != 0);
+ tmp += twinPtr.p->noOfPages;
+ }
+ tmp *= 32768;
memcpy(outBuffer,&tmp,8);
}
return 2;
diff --git a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
index a943ea3c3c9..f4b0a7774d8 100644
--- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
+++ b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
@@ -1975,6 +1975,11 @@ Ndbcntr::execRESUME_REQ(Signal* signal){
//ResumeRef * const ref = (ResumeRef *)&signal->theData[0];
jamEntry();
+
+ signal->theData[0] = NDB_LE_SingleUser;
+ signal->theData[1] = 2;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
+
//Uint32 senderData = req->senderData;
//BlockReference senderRef = req->senderRef;
NodeState newState(NodeState::SL_STARTED);
@@ -2013,12 +2018,11 @@ Ndbcntr::execSTOP_REQ(Signal* signal){
return;
}
- if(c_stopRec.stopReq.senderRef != 0 && !singleuser){
- jam();
+ if(c_stopRec.stopReq.senderRef != 0){
/**
* Requested a system shutdown
*/
- if(StopReq::getSystemStop(req->requestInfo)){
+ if(!singleuser && StopReq::getSystemStop(req->requestInfo)){
jam();
sendSignalWithDelay(reference(), GSN_STOP_REQ, signal, 100,
StopReq::SignalLength);
@@ -2040,23 +2044,28 @@ Ndbcntr::execSTOP_REQ(Signal* signal){
c_stopRec.stopReq = * req;
c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
- if(StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) && !singleuser) {
- jam();
- if(StopReq::getPerformRestart(c_stopRec.stopReq.requestInfo)){
- ((Configuration&)theConfiguration).stopOnError(false);
- }
- }
if(!singleuser) {
+ if(StopReq::getSystemStop(c_stopRec.stopReq.requestInfo)) {
+ jam();
+ if(StopReq::getPerformRestart(c_stopRec.stopReq.requestInfo)){
+ ((Configuration&)theConfiguration).stopOnError(false);
+ }
+ }
if(!c_stopRec.checkNodeFail(signal)){
jam();
return;
}
+ signal->theData[0] = NDB_LE_NDBStopStarted;
+ signal->theData[1] = StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) ? 1 : 0;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
}
-
- signal->theData[0] = NDB_LE_NDBStopStarted;
- signal->theData[1] = StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) ? 1 : 0;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
+ else
+ {
+ signal->theData[0] = NDB_LE_SingleUser;
+ signal->theData[1] = 0;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
+ }
+
NodeState newState(NodeState::SL_STOPPING_1,
StopReq::getSystemStop(c_stopRec.stopReq.requestInfo));
@@ -2138,9 +2147,11 @@ Ndbcntr::StopRecord::checkNodeFail(Signal* signal){
stopReq.senderRef = 0;
- NodeState newState(NodeState::SL_STARTED);
-
- cntr.updateNodeState(signal, newState);
+ if (cntr.getNodeState().startLevel != NodeState::SL_SINGLEUSER)
+ {
+ NodeState newState(NodeState::SL_STARTED);
+ cntr.updateNodeState(signal, newState);
+ }
signal->theData[0] = NDB_LE_NDBStopAborted;
cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
@@ -2236,12 +2247,24 @@ void Ndbcntr::execABORT_ALL_CONF(Signal* signal){
jamEntry();
if(c_stopRec.stopReq.singleuser) {
jam();
+
NodeState newState(NodeState::SL_SINGLEUSER);
newState.setSingleUser(true);
newState.setSingleUserApi(c_stopRec.stopReq.singleUserApi);
updateNodeState(signal, newState);
c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
+ StopConf * const stopConf = (StopConf *)&signal->theData[0];
+ stopConf->senderData = c_stopRec.stopReq.senderData;
+ stopConf->nodeState = (Uint32) NodeState::SL_SINGLEUSER;
+ sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_CONF, signal, StopConf::SignalLength, JBB);
+
+ c_stopRec.stopReq.senderRef = 0; // the command is done
+
+ signal->theData[0] = NDB_LE_SingleUser;
+ signal->theData[1] = 1;
+ signal->theData[2] = c_stopRec.stopReq.singleUserApi;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
}
else
{
@@ -2259,7 +2282,13 @@ void Ndbcntr::execABORT_ALL_CONF(Signal* signal){
void Ndbcntr::execABORT_ALL_REF(Signal* signal){
jamEntry();
- ndbrequire(false);
+ AbortAllRef *abortAllRef = (AbortAllRef *)&signal->theData[0];
+ AbortAllRef::ErrorCode errorCode = (AbortAllRef::ErrorCode) abortAllRef->errorCode;
+
+ StopRef * const stopRef = (StopRef *)&signal->theData[0];
+ stopRef->senderData = c_stopRec.stopReq.senderData;
+ stopRef->errorCode = StopRef::TransactionAbortFailed;
+ sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
}
void
diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
index 75cb92b98c1..4d7ed288592 100644
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
@@ -2016,6 +2016,8 @@ Qmgr::execAPI_VERSION_REQ(Signal * signal) {
else
conf->version = 0;
conf->nodeId = nodeId;
+ struct in_addr in= globalTransporterRegistry.get_connect_address(nodeId);
+ conf->inet_addr= in.s_addr;
sendSignal(senderRef,
GSN_API_VERSION_CONF,
diff --git a/storage/ndb/src/mgmapi/ndb_logevent.cpp b/storage/ndb/src/mgmapi/ndb_logevent.cpp
index a5ffb302c22..5fb83e58c6c 100644
--- a/storage/ndb/src/mgmapi/ndb_logevent.cpp
+++ b/storage/ndb/src/mgmapi/ndb_logevent.cpp
@@ -297,6 +297,8 @@ struct Ndb_logevent_body_row ndb_logevent_body[]= {
ROW( BackupAborted, "backup_id", 2, backup_id),
ROW( BackupAborted, "error", 3, error),
+ ROW( SingleUser, "type", 1, type),
+ ROW( SingleUser, "node_id", 2, node_id),
{ NDB_LE_ILLEGAL_TYPE, 0, 0, 0, 0, 0}
};
diff --git a/storage/ndb/src/mgmclient/CommandInterpreter.cpp b/storage/ndb/src/mgmclient/CommandInterpreter.cpp
index 0a9b4e4a956..1e32ba65c6b 100644
--- a/storage/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/storage/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -1369,9 +1369,8 @@ CommandInterpreter::executeEnterSingleUser(char* parameters)
ndbout_c("Entering single user mode for node %d failed", nodeId);
printError();
} else {
- ndbout_c("Entering single user mode");
- ndbout_c("Access will be granted for API node %d only.", nodeId);
- ndbout_c("Use ALL STATUS to see when single user mode has been entered.");
+ ndbout_c("Single user mode entered");
+ ndbout_c("Access is granted for API node %d only.", nodeId);
}
}
@@ -1384,7 +1383,7 @@ CommandInterpreter::executeExitSingleUser(char* parameters)
printError();
} else {
ndbout_c("Exiting single user mode in progress.");
- ndbout_c("Use ALL STATUS to see when single user mode has been exited.");
+ ndbout_c("Use ALL STATUS or SHOW to see when single user mode has been exited.");
}
}
diff --git a/storage/ndb/src/mgmsrv/Config.cpp b/storage/ndb/src/mgmsrv/Config.cpp
index 5ff9cbe04ad..6ff5fb789f0 100644
--- a/storage/ndb/src/mgmsrv/Config.cpp
+++ b/storage/ndb/src/mgmsrv/Config.cpp
@@ -179,90 +179,3 @@ void Config::printConfigFile(NdbOut &out) const {
}
#endif
}
-
-Uint32
-Config::getGenerationNumber() const {
-#if 0
- Uint32 ret;
- const Properties *prop = NULL;
-
- get("SYSTEM", &prop);
-
- if(prop != NULL)
- if(prop->get("ConfigGenerationNumber", &ret))
- return ret;
-
- return 0;
-#else
- return 0;
-#endif
-}
-
-int
-Config::setGenerationNumber(Uint32 gen) {
-#if 0
- Properties *prop = NULL;
-
- getCopy("SYSTEM", &prop);
-
- if(prop != NULL) {
- MGM_REQUIRE(prop->put("ConfigGenerationNumber", gen, true));
- MGM_REQUIRE(put("SYSTEM", prop, true));
- return 0;
- }
- return -1;
-#else
- return -1;
-#endif
-}
-
-bool
-Config::change(const BaseString &section,
- const BaseString &param,
- const BaseString &value) {
-#if 0
- const char *name;
- Properties::Iterator it(this);
-
- for(name = it.first(); name != NULL; name = it.next()) {
- Properties *prop = NULL;
- if(strcasecmp(section.c_str(), name) == 0) {
- getCopy(name, &prop);
- if(prop == NULL) /* doesn't exist */
- return false;
- if(value == "") {
- prop->remove(param.c_str());
- put(section.c_str(), prop, true);
- } else {
- PropertiesType t;
- if(!prop->getTypeOf(param.c_str(), &t)) /* doesn't exist */
- return false;
- switch(t) {
- case PropertiesType_Uint32:
- long val;
- char *ep;
- errno = 0;
- val = strtol(value.c_str(), &ep, 0);
- if(value.length() == 0 || *ep != '\0') /* not a number */
- return false;
- if(errno == ERANGE)
- return false;
- prop->put(param.c_str(), (unsigned int)val, true);
- put(section.c_str(), prop, true);
- break;
- case PropertiesType_char:
- prop->put(param.c_str(), value.c_str(), true);
- put(section.c_str(), prop, true);
- break;
- default:
- return false;
- }
- }
- break;
- }
- }
- return true;
-#else
- return false;
-#endif
-}
diff --git a/storage/ndb/src/mgmsrv/Config.hpp b/storage/ndb/src/mgmsrv/Config.hpp
index b5e1e17b027..8e16ddf1810 100644
--- a/storage/ndb/src/mgmsrv/Config.hpp
+++ b/storage/ndb/src/mgmsrv/Config.hpp
@@ -60,16 +60,6 @@ public:
printConfigFile(ndb);
}
- Uint32 getGenerationNumber() const;
- int setGenerationNumber(Uint32);
-
- /** Change configuration
- */
- bool change(const BaseString &section,
- const BaseString &param,
- const BaseString &value);
-
-
/**
* Info
*/
diff --git a/storage/ndb/src/mgmsrv/ConfigInfo.cpp b/storage/ndb/src/mgmsrv/ConfigInfo.cpp
index 4e96047e54d..a870c395bd2 100644
--- a/storage/ndb/src/mgmsrv/ConfigInfo.cpp
+++ b/storage/ndb/src/mgmsrv/ConfigInfo.cpp
@@ -241,6 +241,9 @@ struct DepricationTransform {
static
const DepricationTransform f_deprication[] = {
{ DB_TOKEN, "Discless", "Diskless", 0, 1 },
+ { DB_TOKEN, "Id", "nodeid", 0, 1 },
+ { API_TOKEN, "Id", "nodeid", 0, 1 },
+ { MGM_TOKEN, "Id", "nodeid", 0, 1 },
{ 0, 0, 0, 0, 0}
};
@@ -405,9 +408,21 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
0, 0 },
{
- CFG_NODE_ID,
+ KEY_INTERNAL,
"Id",
DB_TOKEN,
+ "",
+ ConfigInfo::CI_DEPRICATED,
+ false,
+ ConfigInfo::CI_INT,
+ MANDATORY,
+ "1",
+ STR_VALUE(MAX_NODES) },
+
+ {
+ CFG_NODE_ID,
+ "nodeid",
+ DB_TOKEN,
"Number identifying the database node ("DB_TOKEN_PRINT")",
ConfigInfo::CI_USED,
false,
@@ -1244,9 +1259,21 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
0, 0 },
{
- CFG_NODE_ID,
+ KEY_INTERNAL,
"Id",
API_TOKEN,
+ "",
+ ConfigInfo::CI_DEPRICATED,
+ false,
+ ConfigInfo::CI_INT,
+ MANDATORY,
+ "1",
+ STR_VALUE(MAX_NODES) },
+
+ {
+ CFG_NODE_ID,
+ "nodeid",
+ API_TOKEN,
"Number identifying application node ("API_TOKEN_PRINT")",
ConfigInfo::CI_USED,
false,
@@ -1375,9 +1402,21 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
0, 0 },
{
- CFG_NODE_ID,
+ KEY_INTERNAL,
"Id",
MGM_TOKEN,
+ "",
+ ConfigInfo::CI_DEPRICATED,
+ false,
+ ConfigInfo::CI_INT,
+ MANDATORY,
+ "1",
+ STR_VALUE(MAX_NODES) },
+
+ {
+ CFG_NODE_ID,
+ "nodeid",
+ MGM_TOKEN,
"Number identifying the management server node ("MGM_TOKEN_PRINT")",
ConfigInfo::CI_USED,
false,
@@ -2516,14 +2555,14 @@ bool
transformNode(InitConfigFileParser::Context & ctx, const char * data){
Uint32 id;
- if(!ctx.m_currentSection->get("Id", &id)){
+ if(!ctx.m_currentSection->get("nodeid", &id) && !ctx.m_currentSection->get("Id", &id)){
Uint32 nextNodeId= 1;
ctx.m_userProperties.get("NextNodeId", &nextNodeId);
id= nextNodeId;
while (ctx.m_userProperties.get("AllocatedNodeId_", id, &id))
id++;
ctx.m_userProperties.put("NextNodeId", id+1, true);
- ctx.m_currentSection->put("Id", id);
+ ctx.m_currentSection->put("nodeid", id);
#if 0
ctx.reportError("Mandatory parameter Id missing from section "
"[%s] starting at line: %d",
@@ -2531,7 +2570,7 @@ transformNode(InitConfigFileParser::Context & ctx, const char * data){
return false;
#endif
} else if(ctx.m_userProperties.get("AllocatedNodeId_", id, &id)) {
- ctx.reportError("Duplicate Id in section "
+ ctx.reportError("Duplicate nodeid in section "
"[%s] starting at line: %d",
ctx.fname, ctx.m_sectionLineno);
return false;
@@ -3356,6 +3395,7 @@ transform(InitConfigFileParser::Context & ctx,
PropertiesType oldType;
require(ctx.m_currentSection->getTypeOf(oldName, &oldType));
ConfigInfo::Type newType = ctx.m_info->getType(ctx.m_currentInfo, newName);
+
if(!((oldType == PropertiesType_Uint32 || oldType == PropertiesType_Uint64)
&& (newType == ConfigInfo::CI_INT || newType == ConfigInfo::CI_INT64 || newType == ConfigInfo::CI_BOOL))){
ndbout << "oldType: " << (int)oldType << ", newType: " << (int)newType << endl;
diff --git a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp b/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp
index 822e10c89aa..94f07ab0ca1 100644
--- a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp
+++ b/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp
@@ -31,8 +31,10 @@ static void require(bool v) { if(!v) abort();}
//****************************************************************************
// Ctor / Dtor
//****************************************************************************
-InitConfigFileParser::InitConfigFileParser(){
+InitConfigFileParser::InitConfigFileParser(FILE * out)
+{
m_info = new ConfigInfo();
+ m_errstream = out ? out : stdout;
}
InitConfigFileParser::~InitConfigFileParser() {
@@ -42,11 +44,12 @@ InitConfigFileParser::~InitConfigFileParser() {
//****************************************************************************
// Read Config File
//****************************************************************************
-InitConfigFileParser::Context::Context(const ConfigInfo * info)
+InitConfigFileParser::Context::Context(const ConfigInfo * info, FILE * out)
: m_userProperties(true), m_configValues(1000, 20) {
m_config = new Properties(true);
m_defaults = new Properties(true);
+ m_errstream = out;
}
InitConfigFileParser::Context::~Context(){
@@ -61,10 +64,10 @@ Config *
InitConfigFileParser::parseConfig(const char * filename) {
FILE * file = fopen(filename, "r");
if(file == 0){
- ndbout << "Error opening file: " << filename << endl;
+ fprintf(m_errstream, "Error opening file: %s\n", filename);
return 0;
}
-
+
Config * ret = parseConfig(file);
fclose(file);
return ret;
@@ -75,7 +78,7 @@ InitConfigFileParser::parseConfig(FILE * file) {
char line[MAX_LINE_LENGTH];
- Context ctx(m_info);
+ Context ctx(m_info, m_errstream);
ctx.m_lineno = 0;
ctx.m_currentSection = 0;
@@ -160,6 +163,13 @@ InitConfigFileParser::parseConfig(FILE * file) {
ctx.reportError("Could not store section of configuration file.");
return 0;
}
+
+ return run_config_rules(ctx);
+}
+
+Config*
+InitConfigFileParser::run_config_rules(Context& ctx)
+{
for(size_t i = 0; ConfigInfo::m_ConfigRules[i].m_configRule != 0; i++){
ctx.type = InitConfigFileParser::Undefined;
ctx.m_currentSection = 0;
@@ -267,10 +277,10 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line)
}
if (status == ConfigInfo::CI_DEPRICATED) {
const char * desc = m_info->getDescription(ctx.m_currentInfo, fname);
- if(desc){
+ if(desc && desc[0]){
ctx.reportWarning("[%s] %s is depricated, use %s instead",
ctx.fname, fname, desc);
- } else {
+ } else if (desc == 0){
ctx.reportWarning("[%s] %s is depricated", ctx.fname, fname);
}
}
@@ -571,8 +581,9 @@ InitConfigFileParser::Context::reportError(const char * fmt, ...){
va_start(ap, fmt);
if (fmt != 0)
BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap);
- ndbout << "Error line " << m_lineno << ": " << buf << endl;
va_end(ap);
+ fprintf(m_errstream, "Error line %d: %s\n",
+ m_lineno, buf);
//m_currentSection->print();
}
@@ -585,6 +596,354 @@ InitConfigFileParser::Context::reportWarning(const char * fmt, ...){
va_start(ap, fmt);
if (fmt != 0)
BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap);
- ndbout << "Warning line " << m_lineno << ": " << buf << endl;
va_end(ap);
+ fprintf(m_errstream, "Warning line %d: %s\n",
+ m_lineno, buf);
+}
+
+#include <my_sys.h>
+#include <my_getopt.h>
+
+static int order = 1;
+static
+my_bool
+parse_mycnf_opt(int, const struct my_option * opt, char * value)
+{
+ if(opt->comment)
+ ((struct my_option *)opt)->app_type++;
+ else
+ ((struct my_option *)opt)->app_type = order++;
+ return 0;
+}
+
+bool
+InitConfigFileParser::store_in_properties(Vector<struct my_option>& options,
+ InitConfigFileParser::Context& ctx,
+ const char * name)
+{
+ for(unsigned i = 0; i<options.size(); i++)
+ {
+ if(options[i].comment &&
+ options[i].app_type &&
+ strcmp(options[i].comment, name) == 0)
+ {
+ Uint64 value_int;
+ switch(options[i].var_type){
+ case GET_INT:
+ value_int = *(Uint32*)options[i].value;
+ break;
+ case GET_LL:
+ value_int = *(Uint64*)options[i].value;
+ break;
+ case GET_STR:
+ ctx.m_currentSection->put(options[i].name, (char*)options[i].value);
+ continue;
+ default:
+ abort();
+ }
+
+ const char * fname = options[i].name;
+ if (!m_info->verify(ctx.m_currentInfo, fname, value_int)) {
+ ctx.reportError("Illegal value %lld for parameter %s.\n"
+ "Legal values are between %Lu and %Lu",
+ value_int, fname,
+ m_info->getMin(ctx.m_currentInfo, fname),
+ m_info->getMax(ctx.m_currentInfo, fname));
+ return false;
+ }
+ if (options[i].var_type == GET_INT)
+ ctx.m_currentSection->put(options[i].name, (Uint32)value_int);
+ else
+ ctx.m_currentSection->put(options[i].name, value_int);
+ }
+ }
+ return true;
}
+
+bool
+InitConfigFileParser::handle_mycnf_defaults(Vector<struct my_option>& options,
+ InitConfigFileParser::Context& ctx,
+ const char * name)
+{
+ strcpy(ctx.fname, name);
+ ctx.type = InitConfigFileParser::DefaultSection;
+ ctx.m_currentSection = new Properties(true);
+ ctx.m_userDefaults = NULL;
+ require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0);
+ require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0);
+ if(store_in_properties(options, ctx, name))
+ return storeSection(ctx);
+ return false;
+}
+
+static
+int
+load_defaults(Vector<struct my_option>& options, const char* groups[])
+{
+ int argc = 1;
+ const char * argv[] = { "ndb_mgmd", 0, 0, 0, 0 };
+ BaseString file;
+ BaseString extra_file;
+ BaseString group_suffix;
+
+ const char *save_file = defaults_file;
+ char *save_extra_file = defaults_extra_file;
+ const char *save_group_suffix = defaults_group_suffix;
+
+ if (defaults_file)
+ {
+ file.assfmt("--defaults-file=%s", defaults_file);
+ argv[argc++] = file.c_str();
+ }
+
+ if (defaults_extra_file)
+ {
+ extra_file.assfmt("--defaults-extra-file=%s", defaults_extra_file);
+ argv[argc++] = extra_file.c_str();
+ }
+
+ if (defaults_group_suffix)
+ {
+ group_suffix.assfmt("--defaults-group-suffix=%s", defaults_group_suffix);
+ argv[argc++] = group_suffix.c_str();
+ }
+
+ char ** tmp = (char**)argv;
+ int ret = load_defaults("my", groups, &argc, &tmp);
+
+ defaults_file = save_file;
+ defaults_extra_file = save_extra_file;
+ defaults_group_suffix = save_group_suffix;
+
+ if (ret == 0)
+ {
+ return handle_options(&argc, &tmp, options.getBase(), parse_mycnf_opt);
+ }
+
+ return ret;
+}
+
+bool
+InitConfigFileParser::load_mycnf_groups(Vector<struct my_option> & options,
+ InitConfigFileParser::Context& ctx,
+ const char * name,
+ const char *groups[])
+{
+ unsigned i;
+ Vector<struct my_option> copy;
+ for(i = 0; i<options.size(); i++)
+ {
+ if(options[i].comment && strcmp(options[i].comment, name) == 0)
+ {
+ options[i].app_type = 0;
+ copy.push_back(options[i]);
+ }
+ }
+
+ struct my_option end;
+ bzero(&end, sizeof(end));
+ copy.push_back(end);
+
+ if (load_defaults(copy, groups))
+ return false;
+
+ return store_in_properties(copy, ctx, name);
+}
+
+Config *
+InitConfigFileParser::parse_mycnf()
+{
+ int i;
+ Config * res = 0;
+ Vector<struct my_option> options;
+ for(i = 0; i<ConfigInfo::m_NoOfParams; i++)
+ {
+ if (strcmp(ConfigInfo::m_ParamInfo[i]._section, "DB") == 0 ||
+ strcmp(ConfigInfo::m_ParamInfo[i]._section, "API") == 0 ||
+ strcmp(ConfigInfo::m_ParamInfo[i]._section, "MGM") == 0)
+ {
+ struct my_option opt;
+ bzero(&opt, sizeof(opt));
+ const ConfigInfo::ParamInfo& param = ConfigInfo::m_ParamInfo[i];
+ switch(param._type){
+ case ConfigInfo::CI_BOOL:
+ opt.value = (gptr*)malloc(sizeof(int));
+ opt.var_type = GET_INT;
+ break;
+ case ConfigInfo::CI_INT:
+ opt.value = (gptr*)malloc(sizeof(int));
+ opt.var_type = GET_INT;
+ break;
+ case ConfigInfo::CI_INT64:
+ opt.value = (gptr*)malloc(sizeof(Int64));
+ opt.var_type = GET_LL;
+ break;
+ case ConfigInfo::CI_STRING:
+ opt.value = (gptr*)malloc(sizeof(char *));
+ opt.var_type = GET_STR;
+ break;
+ default:
+ continue;
+ }
+ opt.name = param._fname;
+ opt.id = 256;
+ opt.app_type = 0;
+ opt.arg_type = REQUIRED_ARG;
+ opt.comment = param._section;
+ options.push_back(opt);
+ }
+ }
+
+ struct my_option *ndbd, *ndb_mgmd, *mysqld, *api;
+
+ /**
+ * Add ndbd, ndb_mgmd, api/mysqld
+ */
+ {
+ struct my_option opt;
+ bzero(&opt, sizeof(opt));
+ opt.name = "ndbd";
+ opt.id = 256;
+ opt.value = (gptr*)malloc(sizeof(char*));
+ opt.var_type = GET_STR;
+ opt.arg_type = REQUIRED_ARG;
+ options.push_back(opt);
+ ndbd = &options.back();
+
+ opt.name = "ndb_mgmd";
+ opt.id = 256;
+ opt.value = (gptr*)malloc(sizeof(char*));
+ opt.var_type = GET_STR;
+ opt.arg_type = REQUIRED_ARG;
+ options.push_back(opt);
+ ndb_mgmd = &options.back();
+
+ opt.name = "mysqld";
+ opt.id = 256;
+ opt.value = (gptr*)malloc(sizeof(char*));
+ opt.var_type = GET_STR;
+ opt.arg_type = REQUIRED_ARG;
+ options.push_back(opt);
+ mysqld = &options.back();
+
+ opt.name = "api";
+ opt.id = 256;
+ opt.value = (gptr*)malloc(sizeof(char*));
+ opt.var_type = GET_STR;
+ opt.arg_type = REQUIRED_ARG;
+ options.push_back(opt);
+ api = &options.back();
+
+ bzero(&opt, sizeof(opt));
+ options.push_back(opt);
+ }
+
+
+ Context ctx(m_info, m_errstream);
+ const char *groups[]= { "cluster_config", 0 };
+ if (load_defaults(options, groups))
+ goto end;
+
+ ctx.m_lineno = 0;
+ if(!handle_mycnf_defaults(options, ctx, "DB"))
+ goto end;
+ if(!handle_mycnf_defaults(options, ctx, "API"))
+ goto end;
+ if(!handle_mycnf_defaults(options, ctx, "MGM"))
+ goto end;
+
+ {
+ struct sect { struct my_option* src; const char * name; } sections[] =
+ {
+ { ndb_mgmd, "MGM" }
+ ,{ ndbd, "DB" }
+ ,{ mysqld, "API" }
+ ,{ api, "API" }
+ ,{ 0, 0 }, { 0, 0 }
+ };
+
+ for(i = 0; sections[i].src; i++)
+ {
+ for(int j = i + 1; sections[j].src; j++)
+ {
+ if (sections[j].src->app_type < sections[i].src->app_type)
+ {
+ sect swap = sections[i];
+ sections[i] = sections[j];
+ sections[j] = swap;
+ }
+ }
+ }
+
+ ctx.type = InitConfigFileParser::Section;
+ ctx.m_sectionLineno = ctx.m_lineno;
+ for(i = 0; sections[i].src; i++)
+ {
+ if (sections[i].src->app_type)
+ {
+ strcpy(ctx.fname, sections[i].name);
+ BaseString str(*(char**)sections[i].src->value);
+ Vector<BaseString> list;
+ str.split(list, ",");
+
+ const char * defaults_groups[] = { 0, 0, 0 };
+ for(unsigned j = 0; j<list.size(); j++)
+ {
+ BaseString group_idx;
+ BaseString group_host;
+ group_idx.assfmt("%s.%s.%d", groups[0],
+ sections[i].src->name, j + 1);
+ group_host.assfmt("%s.%s.%s", groups[0],
+ sections[i].src->name, list[j].c_str());
+ defaults_groups[0] = group_idx.c_str();
+ if(list[j].length())
+ defaults_groups[1] = group_host.c_str();
+ else
+ defaults_groups[1] = 0;
+
+ ctx.m_currentSection = new Properties(true);
+ ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults);
+ require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0);
+ require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname))!= 0);
+ ctx.m_currentSection->put("HostName", list[j].c_str());
+ if(!load_mycnf_groups(options, ctx, sections[i].name,
+ defaults_groups))
+ goto end;
+
+ if(!storeSection(ctx))
+ goto end;
+ }
+ }
+ }
+ }
+
+ res = run_config_rules(ctx);
+
+end:
+ for(i = 0; options[i].name; i++)
+ free(options[i].value);
+
+ return res;
+}
+
+template class Vector<struct my_option>;
+
+#if 0
+struct my_option
+{
+ const char *name; /* Name of the option */
+ int id; /* unique id or short option */
+ const char *comment; /* option comment, for autom. --help */
+ gptr *value; /* The variable value */
+ gptr *u_max_value; /* The user def. max variable value */
+ const char **str_values; /* Pointer to possible values */
+ ulong var_type;
+ enum get_opt_arg_type arg_type;
+ longlong def_value; /* Default value */
+ longlong min_value; /* Min allowed value */
+ longlong max_value; /* Max allowed value */
+ longlong sub_size; /* Subtract this from given value */
+ long block_size; /* Value should be a mult. of this */
+ int app_type; /* To be used by an application */
+};
+#endif
diff --git a/storage/ndb/src/mgmsrv/InitConfigFileParser.hpp b/storage/ndb/src/mgmsrv/InitConfigFileParser.hpp
index 1ea0a094ccd..616fd5a62fb 100644
--- a/storage/ndb/src/mgmsrv/InitConfigFileParser.hpp
+++ b/storage/ndb/src/mgmsrv/InitConfigFileParser.hpp
@@ -34,11 +34,12 @@ class ConfigInfo;
* object if the config file has correct syntax and semantic.
*/
class InitConfigFileParser {
+ FILE * m_errstream;
public:
/**
* Constructor
*/
- InitConfigFileParser();
+ InitConfigFileParser(FILE * errstream = stdout);
~InitConfigFileParser();
/**
@@ -50,6 +51,7 @@ public:
*/
Config * parseConfig(FILE * file);
Config * parseConfig(const char * filename);
+ Config * parse_mycnf();
/**
* Parser context struct
@@ -60,7 +62,7 @@ public:
* Context = Which section in init config file we are currently parsing
*/
struct Context {
- Context(const ConfigInfo *);
+ Context(const ConfigInfo *, FILE * out);
~Context();
ContextSectionType type; ///< Section type (e.g. default section,section)
@@ -82,6 +84,7 @@ public:
ConfigValuesFactory m_configValues; //
public:
+ FILE * m_errstream;
void reportError(const char * msg, ...);
void reportWarning(const char * msg, ...);
};
@@ -122,6 +125,21 @@ private:
* Information about parameters (min, max values etc)
*/
ConfigInfo* m_info;
+
+ bool handle_mycnf_defaults(Vector<struct my_option>& options,
+ InitConfigFileParser::Context& ctx,
+ const char * name);
+
+ bool load_mycnf_groups(Vector<struct my_option> & options,
+ InitConfigFileParser::Context& ctx,
+ const char * name,
+ const char *groups[]);
+
+ bool store_in_properties(Vector<struct my_option>& options,
+ InitConfigFileParser::Context& ctx,
+ const char * name);
+
+ Config* run_config_rules(Context& ctx);
};
#endif // InitConfigFileParser_H
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
index 82e1d24d045..fedaea6a06c 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -66,6 +66,16 @@
#define DEBUG(x)
#endif
+#define INIT_SIGNAL_SENDER(ss,nodeId) \
+ SignalSender ss(theFacade); \
+ ss.lock(); /* lock will be released on exit */ \
+ {\
+ int result = okToSendTo(nodeId, true);\
+ if (result != 0) {\
+ return result;\
+ }\
+ }
+
extern int global_flag_send_heartbeat_now;
extern int g_no_nodeid_checks;
extern my_bool opt_core;
@@ -89,55 +99,6 @@ MgmtSrvr::logLevelThread_C(void* m)
return 0;
}
-void *
-MgmtSrvr::signalRecvThread_C(void *m)
-{
- MgmtSrvr *mgm = (MgmtSrvr*)m;
- mgm->signalRecvThreadRun();
- return 0;
-}
-
-class SigMatch
-{
-public:
- int gsn;
- void (MgmtSrvr::* function)(NdbApiSignal *signal);
-
- SigMatch() { gsn = 0; function = NULL; };
-
- SigMatch(int _gsn,
- void (MgmtSrvr::* _function)(NdbApiSignal *signal)) {
- gsn = _gsn;
- function = _function;
- };
-
- bool check(NdbApiSignal *signal) {
- if(signal->readSignalNumber() == gsn)
- return true;
- return false;
- };
-
-};
-
-void
-MgmtSrvr::signalRecvThreadRun()
-{
- Vector<SigMatch> siglist;
- siglist.push_back(SigMatch(GSN_MGM_LOCK_CONFIG_REQ,
- &MgmtSrvr::handle_MGM_LOCK_CONFIG_REQ));
- siglist.push_back(SigMatch(GSN_MGM_UNLOCK_CONFIG_REQ,
- &MgmtSrvr::handle_MGM_UNLOCK_CONFIG_REQ));
-
- while(!_isStopThread) {
- SigMatch *handler = NULL;
- NdbApiSignal *signal = NULL;
- if(m_signalRecvQueue.waitFor(siglist, &handler, &signal, DEFAULT_TIMEOUT)) {
- if(handler->function != 0)
- (this->*handler->function)(signal);
- }
- }
-}
-
extern EventLogger g_eventLogger;
static NdbOut&
@@ -425,15 +386,12 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
_isStopThread = false;
_logLevelThread = NULL;
_logLevelThreadSleep = 500;
- m_signalRecvThread = NULL;
theFacade = 0;
m_newConfig = NULL;
if (config_filename)
m_configFilename.assign(config_filename);
- else
- m_configFilename.assign("config.ini");
m_nextConfigGenerationNumber = 0;
@@ -468,7 +426,7 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
_config= readConfig();
if (_config == 0) {
ndbout << "Unable to read config file" << endl;
- require(false);
+ exit(-1);
}
}
@@ -649,12 +607,6 @@ MgmtSrvr::start(BaseString &error_string)
"MgmtSrvr_Loglevel",
NDB_THREAD_PRIO_LOW);
- m_signalRecvThread = NdbThread_Create(signalRecvThread_C,
- (void **)this,
- 32768,
- "MgmtSrvr_Service",
- NDB_THREAD_PRIO_LOW);
-
DBUG_RETURN(true);
}
@@ -663,10 +615,6 @@ MgmtSrvr::start(BaseString &error_string)
//****************************************************************************
MgmtSrvr::~MgmtSrvr()
{
- while (theSignalIdleList != NULL) {
- freeSignal();
- }
-
if(theFacade != 0){
theFacade->stop_instance();
delete theFacade;
@@ -694,10 +642,6 @@ MgmtSrvr::~MgmtSrvr()
NdbThread_Destroy(&_logLevelThread);
}
- if (m_signalRecvThread != NULL) {
- NdbThread_WaitFor(m_signalRecvThread, &res);
- NdbThread_Destroy(&m_signalRecvThread);
- }
if (m_config_retriever)
delete m_config_retriever;
}
@@ -705,21 +649,21 @@ MgmtSrvr::~MgmtSrvr()
//****************************************************************************
//****************************************************************************
-int MgmtSrvr::okToSendTo(NodeId processId, bool unCond)
+int MgmtSrvr::okToSendTo(NodeId nodeId, bool unCond)
{
- if(processId == 0)
+ if(nodeId == 0)
return 0;
- if (getNodeType(processId) != NDB_MGM_NODE_TYPE_NDB)
+ if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB)
return WRONG_PROCESS_TYPE;
// Check if we have contact with it
if(unCond){
- if(theFacade->theClusterMgr->getNodeInfo(processId).connected)
+ if(theFacade->theClusterMgr->getNodeInfo(nodeId).connected)
return 0;
return NO_CONTACT_WITH_PROCESS;
}
- if (theFacade->get_node_alive(processId) == 0) {
+ if (theFacade->get_node_alive(nodeId) == 0) {
return NO_CONTACT_WITH_PROCESS;
} else {
return 0;
@@ -740,241 +684,454 @@ void report_unknown_signal(SimpleSignal *signal)
****************************************************************************/
int
-MgmtSrvr::start(int processId)
+MgmtSrvr::start(int nodeId)
{
- int result;
-
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StartOrd* const startOrd = CAST_PTR(StartOrd, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength);
+ INIT_SIGNAL_SENDER(ss,nodeId);
+ SimpleSignal ssig;
+ StartOrd* const startOrd = CAST_PTR(StartOrd, ssig.getDataPtrSend());
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength);
startOrd->restartInfo = 0;
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
+}
+
+/*****************************************************************************
+ * Version handling
+ *****************************************************************************/
+
+int
+MgmtSrvr::versionNode(int nodeId, Uint32 &version, const char **address)
+{
+ version= 0;
+ if (getOwnNodeId() == nodeId)
+ {
+ /**
+ * If we're inquiring about our own node id,
+ * We know what version we are (version implies connected for mgm)
+ * but would like to find out from elsewhere what address they're using
+ * to connect to us. This means that secondary mgm servers
+ * can list ip addresses for mgm servers.
+ *
+ * If we don't get an address (i.e. no db nodes),
+ * we get the address from the configuration.
+ */
+ sendVersionReq(nodeId, version, address);
+ version= NDB_VERSION;
+ if(!*address)
+ {
+ ndb_mgm_configuration_iterator
+ iter(*_config->m_configValues, CFG_SECTION_NODE);
+ unsigned tmp= 0;
+ for(iter.first();iter.valid();iter.next())
+ {
+ if(iter.get(CFG_NODE_ID, &tmp)) require(false);
+ if((unsigned)nodeId!=tmp)
+ continue;
+ if(iter.get(CFG_NODE_HOST, address)) require(false);
+ break;
+ }
+ }
}
-
+ else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB)
+ {
+ ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(nodeId);
+ if(node.connected)
+ version= node.m_info.m_version;
+ *address= get_connect_address(nodeId);
+ }
+ else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
+ getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM)
+ {
+ return sendVersionReq(nodeId, version, address);
+ }
+
+ return 0;
+}
+
+int
+MgmtSrvr::sendVersionReq(int v_nodeId, Uint32 &version, const char **address)
+{
+ SignalSender ss(theFacade);
+ ss.lock();
+
+ SimpleSignal ssig;
+ ApiVersionReq* req = CAST_PTR(ApiVersionReq, ssig.getDataPtrSend());
+ req->senderRef = ss.getOwnRef();
+ req->nodeId = v_nodeId;
+ ssig.set(ss, TestOrd::TraceAPI, QMGR, GSN_API_VERSION_REQ,
+ ApiVersionReq::SignalLength);
+
+ int do_send = 1;
+ NodeId nodeId;
+
+ while (1)
+ {
+ if (do_send)
+ {
+ bool next;
+ nodeId = 0;
+
+ while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
+ okToSendTo(nodeId, true) != 0);
+
+ const ClusterMgr::Node &node=
+ theFacade->theClusterMgr->getNodeInfo(nodeId);
+ if(next && node.m_state.startLevel != NodeState::SL_STARTED)
+ {
+ NodeId tmp=nodeId;
+ while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
+ okToSendTo(nodeId, true) != 0);
+ if(!next)
+ nodeId= tmp;
+ }
+
+ if(!next) return NO_CONTACT_WITH_DB_NODES;
+
+ if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ do_send = 0;
+ }
+
+ SimpleSignal *signal = ss.waitFor();
+
+ int gsn = signal->readSignalNumber();
+ switch (gsn) {
+ case GSN_API_VERSION_CONF: {
+ const ApiVersionConf * const conf =
+ CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr());
+ assert(conf->nodeId == v_nodeId);
+ version = conf->version;
+ struct in_addr in;
+ in.s_addr= conf->inet_addr;
+ *address= inet_ntoa(in);
+ return 0;
+ }
+ case GSN_NF_COMPLETEREP:{
+ const NFCompleteRep * const rep =
+ CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
+ if (rep->failedNodeId == nodeId)
+ do_send = 1; // retry with other node
+ continue;
+ }
+ case GSN_NODE_FAILREP:{
+ const NodeFailRep * const rep =
+ CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
+ if (NodeBitmask::get(rep->theNodes,nodeId))
+ do_send = 1; // retry with other node
+ continue;
+ }
+ default:
+ report_unknown_signal(signal);
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ break;
+ } // while(1)
+
return 0;
}
-/**
- * Restart one database node
+/*
+ * Common method for handeling all STOP_REQ signalling that
+ * is used by Stopping, Restarting and Single user commands
*/
-int
-MgmtSrvr::restartNode(int processId, bool nostart,
- bool initalStart, bool abort,
- StopCallback callback, void * anyData)
+
+int MgmtSrvr::sendSTOP_REQ(NodeId nodeId,
+ NodeBitmask &stoppedNodes,
+ Uint32 singleUserNodeId,
+ bool abort,
+ bool stop,
+ bool restart,
+ bool nostart,
+ bool initialStart)
{
- int result;
+ stoppedNodes.clear();
- if(m_stopRec.singleUserMode)
- return 5060;
+ SignalSender ss(theFacade);
+ ss.lock(); // lock will be released on exit
- if(m_stopRec.inUse){
- return 5029;
- }
-
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
+ SimpleSignal ssig;
+ StopReq* const stopReq = CAST_PTR(StopReq, ssig.getDataPtrSend());
+ ssig.set(ss, TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
-
stopReq->requestInfo = 0;
- StopReq::setSystemStop(stopReq->requestInfo, false);
- StopReq::setPerformRestart(stopReq->requestInfo, true);
- StopReq::setNoStart(stopReq->requestInfo, nostart);
- StopReq::setInitialStart(stopReq->requestInfo, initalStart);
- StopReq::setStopAbort(stopReq->requestInfo, abort);
- stopReq->singleuser = 0;
stopReq->apiTimeout = 5000;
stopReq->transactionTimeout = 1000;
stopReq->readOperationTimeout = 1000;
stopReq->operationTimeout = 1000;
stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
-
- m_stopRec.singleUserMode = false;
- m_stopRec.sentCount = 1;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = processId;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- if(callback == NULL){
- Uint32 timeOut = 0;
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
- result = sendRecSignal(processId, WAIT_STOP, signal, true, timeOut);
- } else {
- result = sendSignal(processId, NO_WAIT, signal, true);
+ stopReq->senderRef = ss.getOwnRef();
+ if (singleUserNodeId)
+ {
+ stopReq->singleuser = 1;
+ stopReq->singleUserApi = singleUserNodeId;
+ StopReq::setSystemStop(stopReq->requestInfo, false);
+ StopReq::setPerformRestart(stopReq->requestInfo, false);
+ StopReq::setStopAbort(stopReq->requestInfo, false);
}
-
- if (result == -1 && theWaitState != WAIT_NODEFAILURE) {
- m_stopRec.inUse = false;
- return SEND_OR_RECEIVE_FAILED;
+ else
+ {
+ stopReq->singleuser = 0;
+ StopReq::setSystemStop(stopReq->requestInfo, stop);
+ StopReq::setPerformRestart(stopReq->requestInfo, restart);
+ StopReq::setStopAbort(stopReq->requestInfo, abort);
+ StopReq::setNoStart(stopReq->requestInfo, nostart);
+ StopReq::setInitialStart(stopReq->requestInfo, initialStart);
}
- if(callback == 0){
- m_stopRec.inUse = false;
- return m_stopRec.reply;
- } else {
- return 0;
+ // send the signals
+ NodeBitmask nodes;
+ if (nodeId)
+ {
+ {
+ int r;
+ if((r = okToSendTo(nodeId, true)) != 0)
+ return r;
+ }
+ {
+ if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ nodes.set(nodeId);
}
+ else
+ while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
+ {
+ if(okToSendTo(nodeId, true) == 0)
+ {
+ SendStatus result = ss.sendSignal(nodeId, &ssig);
+ if (result == SEND_OK)
+ nodes.set(nodeId);
+ }
+ }
+
+ // now wait for the replies
+ int error = 0;
+ while (!nodes.isclear())
+ {
+ SimpleSignal *signal = ss.waitFor();
+ int gsn = signal->readSignalNumber();
+ switch (gsn) {
+ case GSN_STOP_REF:{
+ const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr());
+ const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
+#ifdef VM_TRACE
+ ndbout_c("Node %d refused stop", nodeId);
+#endif
+ assert(nodes.get(nodeId));
+ nodes.clear(nodeId);
+ error = translateStopRef(ref->errorCode);
+ break;
+ }
+ case GSN_STOP_CONF:{
+ const StopConf * const ref = CAST_CONSTPTR(StopConf, signal->getDataPtr());
+ const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
+#ifdef VM_TRACE
+ ndbout_c("Node %d single user mode", nodeId);
+#endif
+ assert(nodes.get(nodeId));
+ assert(singleUserNodeId != 0);
+ nodes.clear(nodeId);
+ stoppedNodes.set(nodeId);
+ break;
+ }
+ case GSN_NF_COMPLETEREP:{
+ const NFCompleteRep * const rep =
+ CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
+#ifdef VM_TRACE
+ ndbout_c("Node %d fail completed", rep->failedNodeId);
+#endif
+ break;
+ }
+ case GSN_NODE_FAILREP:{
+ const NodeFailRep * const rep =
+ CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
+ NodeBitmask failedNodes;
+ failedNodes.assign(NodeBitmask::Size, rep->theNodes);
+#ifdef VM_TRACE
+ {
+ ndbout << "Failed nodes:";
+ for (unsigned i = 0; i < 32*NodeBitmask::Size; i++)
+ if(failedNodes.get(i))
+ ndbout << " " << i;
+ ndbout << endl;
+ }
+#endif
+ failedNodes.bitAND(nodes);
+ if (!failedNodes.isclear())
+ {
+ nodes.bitANDC(failedNodes); // clear the failed nodes
+ if (singleUserNodeId == 0)
+ stoppedNodes.bitOR(failedNodes);
+ }
+ break;
+ }
+ default:
+ report_unknown_signal(signal);
+#ifdef VM_TRACE
+ ndbout_c("Unknown signal %d", gsn);
+#endif
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ }
+ return error;
}
-/**
- * Restart all database nodes
+/*
+ * Stop one node
*/
-int
-MgmtSrvr::restart(bool nostart, bool initalStart, bool abort,
- int * stopCount, StopCallback callback, void * anyData)
+
+int MgmtSrvr::stopNode(int nodeId, bool abort)
{
- if(m_stopRec.singleUserMode)
- return 5060;
+ NodeBitmask nodes;
+ return sendSTOP_REQ(nodeId,
+ nodes,
+ 0,
+ abort,
+ false,
+ false,
+ false,
+ false);
+}
+
+/*
+ * Perform system shutdown
+ */
- if(m_stopRec.inUse){
- return 5029;
- }
-
- m_stopRec.singleUserMode = false;
- m_stopRec.sentCount = 0;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = 0;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- /**
- * Restart all database nodes into idle ("no-started") state
- */
- Uint32 timeOut = 0;
- NodeId nodeId = 0;
+int MgmtSrvr::stop(int * stopCount, bool abort)
+{
NodeBitmask nodes;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
- if(okToSendTo(nodeId, true) == 0){
+ int ret = sendSTOP_REQ(0,
+ nodes,
+ 0,
+ abort,
+ true,
+ false,
+ false,
+ false);
+ if (stopCount)
+ *stopCount = nodes.count();
+ return ret;
+}
+
+/*
+ * Enter single user mode on all live nodes
+ */
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ,
- StopReq::SignalLength);
-
- stopReq->requestInfo = 0;
- stopReq->singleuser = 0;
- StopReq::setSystemStop(stopReq->requestInfo, true);
- StopReq::setPerformRestart(stopReq->requestInfo, true);
- if (callback == 0) {
- // Start node in idle ("no-started") state
- StopReq::setNoStart(stopReq->requestInfo, 1);
- } else {
- StopReq::setNoStart(stopReq->requestInfo, nostart);
- }
- StopReq::setInitialStart(stopReq->requestInfo, initalStart);
- StopReq::setStopAbort(stopReq->requestInfo, abort);
-
- stopReq->apiTimeout = 5000;
- stopReq->transactionTimeout = 1000;
- stopReq->readOperationTimeout = 1000;
- stopReq->operationTimeout = 1000;
- stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
-
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
-
- m_stopRec.sentCount++;
- int res;
- if(callback == 0){
- res = sendSignal(nodeId, WAIT_STOP, signal, true);
- } else {
- res = sendSignal(nodeId, NO_WAIT, signal, true);
- }
-
- if(res != -1){
- nodes.set(nodeId);
- }
- }
- }
-
- if(stopCount != 0){
- * stopCount = m_stopRec.sentCount;
+int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId)
+{
+ if (getNodeType(singleUserNodeId) != NDB_MGM_NODE_TYPE_API)
+ return 5062;
+ NodeId nodeId = 0;
+ ClusterMgr::Node node;
+ while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
+ {
+ node = theFacade->theClusterMgr->getNodeInfo(nodeId);
+ if((node.m_state.startLevel != NodeState::SL_STARTED) &&
+ (node.m_state.startLevel != NodeState::SL_NOTHING))
+ return 5063;
}
+ NodeBitmask nodes;
+ int ret = sendSTOP_REQ(0,
+ nodes,
+ singleUserNodeId,
+ false,
+ false,
+ false,
+ false,
+ false);
+ if (stopCount)
+ *stopCount = nodes.count();
+ return ret;
+}
+
+/*
+ * Perform node restart
+ */
- if(m_stopRec.sentCount == 0){
- m_stopRec.inUse = false;
- return 0;
- }
-
- if(callback != 0){
- return 0;
- }
-
- theFacade->lock_mutex();
- int waitTime = timeOut/m_stopRec.sentCount;
- if (receiveOptimisedResponse(waitTime) != 0) {
- m_stopRec.inUse = false;
- return -1;
- }
-
+int MgmtSrvr::restartNode(int nodeId, bool nostart, bool initialStart,
+ bool abort)
+{
+ NodeBitmask nodes;
+ return sendSTOP_REQ(nodeId,
+ nodes,
+ 0,
+ abort,
+ false,
+ true,
+ nostart,
+ initialStart);
+}
+
+/*
+ * Perform system restart
+ */
+
+int MgmtSrvr::restart(bool nostart, bool initialStart,
+ bool abort, int * stopCount )
+{
+ NodeBitmask nodes;
+ int ret = sendSTOP_REQ(0,
+ nodes,
+ 0,
+ abort,
+ true,
+ true,
+ true,
+ initialStart);
+
+ if (ret)
+ return ret;
+
+ if (stopCount)
+ *stopCount = nodes.count();
+
+#ifdef VM_TRACE
+ ndbout_c("Stopped %d nodes", nodes.count());
+#endif
/**
* Here all nodes were correctly stopped,
* so we wait for all nodes to be contactable
*/
- nodeId = 0;
+ int waitTime = 12000;
+ NodeId nodeId = 0;
NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB) && nodes.get(nodeId)) {
+
+ ndbout_c(" %d", nodes.get(1));
+ ndbout_c(" %d", nodes.get(2));
+
+ while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
+ if (!nodes.get(nodeId))
+ continue;
enum ndb_mgm_node_status s;
s = NDB_MGM_NODE_STATUS_NO_CONTACT;
+#ifdef VM_TRACE
+ ndbout_c("Waiting for %d not started", nodeId);
+#endif
while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0) {
Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0;
Uint32 connectCount = 0;
bool system;
+ const char *address;
status(nodeId, &s, &version, &startPhase,
- &system, &dynamicId, &nodeGroup, &connectCount);
+ &system, &dynamicId, &nodeGroup, &connectCount, &address);
NdbSleep_MilliSleep(100);
waitTime = (maxTime - NdbTick_CurrentMillisecond());
}
}
- if(nostart){
- m_stopRec.inUse = false;
+ if(nostart)
return 0;
- }
/**
* Now we start all database nodes (i.e. we make them non-idle)
* We ignore the result we get from the start command.
*/
nodeId = 0;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB) && nodes.get(nodeId)) {
+ while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
+ if (!nodes.get(nodeId))
+ continue;
int result;
result = start(nodeId);
DEBUG("Starting node " << nodeId << " with result " << result);
@@ -983,455 +1140,43 @@ MgmtSrvr::restart(bool nostart, bool initalStart, bool abort,
* Maybe the user only wanted to restart a subset of the nodes.
* It is also easy for the user to check which nodes have
* started and which nodes have not.
- *
- * if (result != 0) {
- * m_stopRec.inUse = false;
- * return result;
- * }
*/
}
- m_stopRec.inUse = false;
return 0;
}
-/*****************************************************************************
- * Version handling
- *****************************************************************************/
-
-int
-MgmtSrvr::versionNode(int processId, bool abort,
- VersionCallback callback, void * anyData)
-{
- int version;
-
- if(m_versionRec.inUse)
- return OPERATION_IN_PROGRESS;
-
- m_versionRec.callback = callback;
- m_versionRec.inUse = true ;
-
- if (getOwnNodeId() == processId)
- {
- version= NDB_VERSION;
- }
- else if (getNodeType(processId) == NDB_MGM_NODE_TYPE_NDB)
- {
- ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(processId);
- if(node.connected)
- version= node.m_info.m_version;
- else
- version= 0;
- }
- else if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API ||
- getNodeType(processId) == NDB_MGM_NODE_TYPE_MGM)
- {
- return sendVersionReq(processId);
- }
- else
- version= 0;
-
- if(m_versionRec.callback != 0)
- m_versionRec.callback(processId, version, this,0);
- m_versionRec.inUse = false ;
-
- m_versionRec.version[processId]= version;
-
- return 0;
-}
-
-int
-MgmtSrvr::sendVersionReq(int processId)
-{
- Uint32 ndbnode=0;
- int result;
- for(Uint32 i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
- if(okToSendTo(i, true) == 0)
- {
- ndbnode = i;
- break;
- }
- }
- }
-
- if (ndbnode == 0) {
- m_versionRec.inUse = false;
- if(m_versionRec.callback != 0)
- m_versionRec.callback(processId, 0, this,0);
- return NO_CONTACT_WITH_CLUSTER;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- m_versionRec.inUse = false;
- if(m_versionRec.callback != 0)
- m_versionRec.callback(processId, 0, this,0);
- return COULD_NOT_ALLOCATE_MEMORY;
- }
- ApiVersionReq* req = CAST_PTR(ApiVersionReq, signal->getDataPtrSend());
- req->senderRef = _ownReference;
- req->nodeId = processId;
-
- signal->set(TestOrd::TraceAPI, QMGR, GSN_API_VERSION_REQ,
- ApiVersionReq::SignalLength);
-
-
- // if(m_versionRec.callback == 0){
- Uint32 timeOut = 0;
- timeOut = 10000;
- result = sendRecSignal(ndbnode, WAIT_VERSION, signal, true, timeOut);
- //} else {
- //result = sendSignal(processId, NO_WAIT, signal, true);
- // }
-
- if (result == -1) {
- m_versionRec.inUse = false;
- if(m_versionRec.callback != 0)
- m_versionRec.callback(processId, 0, this,0);
- m_versionRec.version[processId] = 0;
- return SEND_OR_RECEIVE_FAILED;
- }
-
- m_versionRec.inUse = false;
- return 0;
-}
-
-int
-MgmtSrvr::version(int * stopCount, bool abort,
- VersionCallback callback, void * anyData)
-{
- ClusterMgr::Node node;
- int version;
-
- if(m_versionRec.inUse)
- return 1;
-
- m_versionRec.callback = callback;
- m_versionRec.inUse = true ;
- Uint32 i;
- for(i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_MGM) {
- m_versionRec.callback(i, NDB_VERSION, this,0);
- }
- }
- for(i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
- node = theFacade->theClusterMgr->getNodeInfo(i);
- version = node.m_info.m_version;
- if(theFacade->theClusterMgr->getNodeInfo(i).connected)
- m_versionRec.callback(i, version, this,0);
- else
- m_versionRec.callback(i, 0, this,0);
-
- }
- }
- for(i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_API) {
- return sendVersionReq(i);
- }
- }
-
- return 0;
-}
-
-int
-MgmtSrvr::stopNode(int processId, bool abort, StopCallback callback,
- void * anyData)
-
-{
- if(m_stopRec.singleUserMode)
- return 5060;
-
- if(m_stopRec.inUse)
- return 5029;
-
- int result;
-
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
-
- stopReq->requestInfo = 0;
- stopReq->singleuser = 0;
- StopReq::setPerformRestart(stopReq->requestInfo, false);
- StopReq::setSystemStop(stopReq->requestInfo, false);
- StopReq::setStopAbort(stopReq->requestInfo, abort);
-
- stopReq->apiTimeout = 5000;
- stopReq->transactionTimeout = 1000;
- stopReq->readOperationTimeout = 1000;
- stopReq->operationTimeout = 1000;
- stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
-
- m_stopRec.sentCount = 1;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = processId;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- if(callback == NULL){
- Uint32 timeOut = 0;
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
- result = sendRecSignal(processId, WAIT_STOP, signal, true, timeOut);
- } else {
- result = sendSignal(processId, NO_WAIT, signal, true);
- }
-
- if (result == -1) {
- m_stopRec.inUse = false;
- return SEND_OR_RECEIVE_FAILED;
- }
-
- if(callback == 0){
- m_stopRec.inUse = false;
- return m_stopRec.reply;
- } else {
- return 0;
- }
-}
-
int
-MgmtSrvr::stop(int * stopCount, bool abort, StopCallback callback,
- void * anyData)
+MgmtSrvr::exitSingleUser(int * stopCount, bool abort)
{
- if(m_stopRec.singleUserMode)
- return 5060;
-
- if(m_stopRec.inUse){
- return 5029;
- }
-
- m_stopRec.singleUserMode = false;
- m_stopRec.sentCount = 0;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = 0;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
NodeId nodeId = 0;
- Uint32 timeOut = 0;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
- if(okToSendTo(nodeId, true) == 0){
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ,
- StopReq::SignalLength);
-
- stopReq->requestInfo = 0;
- stopReq->singleuser = 0;
- StopReq::setSystemStop(stopReq->requestInfo, true);
- StopReq::setPerformRestart(stopReq->requestInfo, false);
- StopReq::setStopAbort(stopReq->requestInfo, abort);
-
- stopReq->apiTimeout = 5000;
- stopReq->transactionTimeout = 1000;
- stopReq->readOperationTimeout = 1000;
- stopReq->operationTimeout = 1000;
- stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
-
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
-
- m_stopRec.sentCount++;
- if(callback == 0)
- sendSignal(nodeId, WAIT_STOP, signal, true);
- else
- sendSignal(nodeId, NO_WAIT, signal, true);
- }
- }
-
- if(stopCount != 0)
- * stopCount = m_stopRec.sentCount;
-
- if(m_stopRec.sentCount > 0){
- if(callback == 0){
- theFacade->lock_mutex();
- receiveOptimisedResponse(timeOut / m_stopRec.sentCount);
- } else {
- return 0;
- }
- }
-
- m_stopRec.inUse = false;
- return m_stopRec.reply;
-}
-
-/*****************************************************************************
- * Single user mode
- ****************************************************************************/
-
-int
-MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId,
- EnterSingleCallback callback, void * anyData)
-{
- if(m_stopRec.singleUserMode) {
- return 5060;
- }
-
- if (getNodeType(singleUserNodeId) != NDB_MGM_NODE_TYPE_API) {
- return 5062;
- }
- ClusterMgr::Node node;
-
- for(Uint32 i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
- node = theFacade->theClusterMgr->getNodeInfo(i);
- if((node.m_state.startLevel != NodeState::SL_STARTED) &&
- (node.m_state.startLevel != NodeState::SL_NOTHING)) {
- return 5063;
- }
- }
- }
-
- if(m_stopRec.inUse){
- return 5029;
- }
-
- if(singleUserNodeId == 0)
- return 1;
- m_stopRec.singleUserMode = true;
- m_stopRec.sentCount = 0;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = 0;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- NodeId nodeId = 0;
- Uint32 timeOut = 0;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
- if(okToSendTo(nodeId, true) == 0){
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ,
- StopReq::SignalLength);
-
- stopReq->requestInfo = 0;
- stopReq->singleuser = 1;
- stopReq->singleUserApi = singleUserNodeId;
- StopReq::setSystemStop(stopReq->requestInfo, false);
- StopReq::setPerformRestart(stopReq->requestInfo, false);
- StopReq::setStopAbort(stopReq->requestInfo, false);
-
- stopReq->apiTimeout = 5000;
- stopReq->transactionTimeout = 1000;
- stopReq->readOperationTimeout = 1000;
- stopReq->operationTimeout = 1000;
- stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
-
- m_stopRec.sentCount++;
- if(callback == 0)
- sendSignal(nodeId, WAIT_STOP, signal, true);
- else
- sendSignal(nodeId, NO_WAIT, signal, true);
- }
- }
-
- if(stopCount != 0)
- * stopCount = m_stopRec.sentCount;
+ int count = 0;
- if(callback == 0){
- m_stopRec.inUse = false;
- return 0;
- // return m_stopRec.reply;
- } else {
- return 0;
- }
+ SignalSender ss(theFacade);
+ ss.lock(); // lock will be released on exit
- m_stopRec.inUse = false;
- return m_stopRec.reply;
-}
+ SimpleSignal ssig;
+ ResumeReq* const resumeReq =
+ CAST_PTR(ResumeReq, ssig.getDataPtrSend());
+ ssig.set(ss,TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ,
+ ResumeReq::SignalLength);
+ resumeReq->senderData = 12;
+ resumeReq->senderRef = ss.getOwnRef();
-int
-MgmtSrvr::exitSingleUser(int * stopCount, bool abort,
- ExitSingleCallback callback, void * anyData)
-{
- m_stopRec.sentCount = 0;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = 0;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- NodeId nodeId = 0;
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
if(okToSendTo(nodeId, true) == 0){
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- ResumeReq* const resumeReq =
- CAST_PTR(ResumeReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ,
- StopReq::SignalLength);
- resumeReq->senderData = 12;
- resumeReq->senderRef = _ownReference;
-
- m_stopRec.sentCount++;
- if(callback == 0)
- sendSignal(nodeId, WAIT_STOP, signal, true);
- else
- sendSignal(nodeId, NO_WAIT, signal, true);
+ SendStatus result = ss.sendSignal(nodeId, &ssig);
+ if (result == SEND_OK)
+ count++;
}
}
- m_stopRec.singleUserMode = false;
-
if(stopCount != 0)
- * stopCount = m_stopRec.sentCount;
-
+ * stopCount = count;
- if(callback == 0){
- m_stopRec.inUse = false;
- return m_stopRec.reply;
- } else {
- return 0;
- }
-
- m_stopRec.inUse = false;
- return m_stopRec.reply;
+ return 0;
}
-
/*****************************************************************************
* Status
****************************************************************************/
@@ -1439,32 +1184,32 @@ MgmtSrvr::exitSingleUser(int * stopCount, bool abort,
#include <ClusterMgr.hpp>
int
-MgmtSrvr::status(int processId,
+MgmtSrvr::status(int nodeId,
ndb_mgm_node_status * _status,
Uint32 * version,
Uint32 * _phase,
bool * _system,
Uint32 * dynamic,
Uint32 * nodegroup,
- Uint32 * connectCount)
+ Uint32 * connectCount,
+ const char **address)
{
- if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API ||
- getNodeType(processId) == NDB_MGM_NODE_TYPE_MGM) {
- if(versionNode(processId, false,0,0) ==0)
- * version = m_versionRec.version[processId];
- else
- * version = 0;
+ if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
+ getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) {
+ versionNode(nodeId, *version, address);
+ } else {
+ *address= get_connect_address(nodeId);
}
const ClusterMgr::Node node =
- theFacade->theClusterMgr->getNodeInfo(processId);
+ theFacade->theClusterMgr->getNodeInfo(nodeId);
if(!node.connected){
* _status = NDB_MGM_NODE_STATUS_NO_CONTACT;
return 0;
}
- if (getNodeType(processId) == NDB_MGM_NODE_TYPE_NDB) {
+ if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) {
* version = node.m_info.m_version;
}
@@ -1527,67 +1272,81 @@ MgmtSrvr::status(int processId,
}
int
-MgmtSrvr::setEventReportingLevelImpl(int processId,
+MgmtSrvr::setEventReportingLevelImpl(int nodeId,
const EventSubscribeReq& ll)
{
-
- int result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal signal(_ownReference);
+ INIT_SIGNAL_SENDER(ss,nodeId);
+ SimpleSignal ssig;
EventSubscribeReq * dst =
- CAST_PTR(EventSubscribeReq, signal.getDataPtrSend());
-
- * dst = ll;
-
- signal.set(TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
- EventSubscribeReq::SignalLength);
-
- theFacade->lock_mutex();
- send(&signal, processId, NODE_TYPE_DB);
- theFacade->unlock_mutex();
-
+ CAST_PTR(EventSubscribeReq, ssig.getDataPtrSend());
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
+ EventSubscribeReq::SignalLength);
+ *dst = ll;
+
+ send(ss,ssig,nodeId,NODE_TYPE_DB);
+
+#if 0
+ while (1)
+ {
+ SimpleSignal *signal = ss.waitFor();
+ int gsn = signal->readSignalNumber();
+ switch (gsn) {
+ case GSN_EVENT_SUBSCRIBE_CONF:{
+ break;
+ }
+ case GSN_EVENT_SUBSCRIBE_REF:{
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ case GSN_NF_COMPLETEREP:{
+ const NFCompleteRep * const rep =
+ CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
+ if (rep->failedNodeId == nodeId)
+ return SEND_OR_RECEIVE_FAILED;
+ break;
+ }
+ case GSN_NODE_FAILREP:{
+ const NodeFailRep * const rep =
+ CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
+ if (NodeBitmask::get(rep->theNodes,nodeId))
+ return SEND_OR_RECEIVE_FAILED;
+ break;
+ }
+ default:
+ report_unknown_signal(signal);
+ return SEND_OR_RECEIVE_FAILED;
+ }
+
+ }
+#endif
return 0;
}
//****************************************************************************
//****************************************************************************
int
-MgmtSrvr::setNodeLogLevelImpl(int processId, const SetLogLevelOrd & ll)
+MgmtSrvr::setNodeLogLevelImpl(int nodeId, const SetLogLevelOrd & ll)
{
- int result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
- NdbApiSignal signal(_ownReference);
-
- SetLogLevelOrd * dst = CAST_PTR(SetLogLevelOrd, signal.getDataPtrSend());
-
- * dst = ll;
-
- signal.set(TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD,
- SetLogLevelOrd::SignalLength);
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD,
+ SetLogLevelOrd::SignalLength);
+ SetLogLevelOrd* const dst = CAST_PTR(SetLogLevelOrd, ssig.getDataPtrSend());
+ *dst = ll;
- theFacade->lock_mutex();
- theFacade->sendSignalUnCond(&signal, processId);
- theFacade->unlock_mutex();
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
int
-MgmtSrvr::send(NdbApiSignal* signal, Uint32 node, Uint32 node_type){
+MgmtSrvr::send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type){
Uint32 max = (node == 0) ? MAX_NODES : node + 1;
for(; node < max; node++){
while(nodeTypes[node] != (int)node_type && node < max) node++;
if(nodeTypes[node] != (int)node_type)
break;
- theFacade->sendSignalUnCond(signal, node);
+ ss.sendSignal(node, &ssig);
}
return 0;
}
@@ -1596,34 +1355,21 @@ MgmtSrvr::send(NdbApiSignal* signal, Uint32 node, Uint32 node_type){
//****************************************************************************
int
-MgmtSrvr::insertError(int processId, int errorNo)
+MgmtSrvr::insertError(int nodeId, int errorNo)
{
if (errorNo < 0) {
return INVALID_ERROR_NUMBER;
}
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, signal->getDataPtrSend());
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TAMPER_ORD,
+ TamperOrd::SignalLength);
+ TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, ssig.getDataPtrSend());
tamperOrd->errorNo = errorNo;
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TAMPER_ORD,
- TamperOrd::SignalLength);
-
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
@@ -1632,37 +1378,23 @@ MgmtSrvr::insertError(int processId, int errorNo)
//****************************************************************************
int
-MgmtSrvr::setTraceNo(int processId, int traceNo)
+MgmtSrvr::setTraceNo(int nodeId, int traceNo)
{
if (traceNo < 0) {
return INVALID_TRACE_NUMBER;
}
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend());
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
+ TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear();
-
// Assume TRACE command causes toggling. Not really defined... ? TODO
testOrd->setTraceCommand(TestOrd::Toggle,
(TestOrd::TraceSpecification)traceNo);
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
//****************************************************************************
@@ -1681,14 +1413,10 @@ MgmtSrvr::getBlockNumber(const BaseString &blockName)
//****************************************************************************
int
-MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode,
+MgmtSrvr::setSignalLoggingMode(int nodeId, LogMode mode,
const Vector<BaseString>& blocks)
{
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
// Convert from MgmtSrvr format...
@@ -1723,12 +1451,10 @@ MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode,
return -1;
}
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend());
+ TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear();
if (blocks.size() == 0 || blocks[0] == "ALL") {
@@ -1738,78 +1464,44 @@ MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode,
for(unsigned i = 0; i < blocks.size(); i++){
int blockNumber = getBlockNumber(blocks[i]);
if (blockNumber == -1) {
- releaseSignal(signal);
return INVALID_BLOCK_NAME;
}
testOrd->addSignalLoggerCommand(blockNumber, command, logSpec);
} // for
} // else
-
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
-
/*****************************************************************************
* Signal tracing
*****************************************************************************/
-int MgmtSrvr::startSignalTracing(int processId)
+int MgmtSrvr::startSignalTracing(int nodeId)
{
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
+ INIT_SIGNAL_SENDER(ss,nodeId);
- TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend());
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
+
+ TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear();
testOrd->setTestCommand(TestOrd::On);
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
int
-MgmtSrvr::stopSignalTracing(int processId)
+MgmtSrvr::stopSignalTracing(int nodeId)
{
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend());
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
+ TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear();
testOrd->setTestCommand(TestOrd::Off);
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
@@ -1818,7 +1510,7 @@ MgmtSrvr::stopSignalTracing(int processId)
*****************************************************************************/
int
-MgmtSrvr::dumpState(int processId, const char* args)
+MgmtSrvr::dumpState(int nodeId, const char* args)
{
// Convert the space separeted args
// string to an int array
@@ -1840,29 +1532,20 @@ MgmtSrvr::dumpState(int processId, const char* args)
}
}
- return dumpState(processId, args_array, numArgs);
+ return dumpState(nodeId, args_array, numArgs);
}
int
-MgmtSrvr::dumpState(int processId, const Uint32 args[], Uint32 no)
+MgmtSrvr::dumpState(int nodeId, const Uint32 args[], Uint32 no)
{
- int result;
-
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
const Uint32 len = no > 25 ? 25 : no;
+ SimpleSignal ssig;
DumpStateOrd * const dumpOrd =
- CAST_PTR(DumpStateOrd, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len);
+ CAST_PTR(DumpStateOrd, ssig.getDataPtrSend());
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len);
for(Uint32 i = 0; i<25; i++){
if (i < len)
dumpOrd->args[i] = args[i];
@@ -1870,12 +1553,7 @@ MgmtSrvr::dumpState(int processId, const Uint32 args[], Uint32 no)
dumpOrd->args[i] = 0;
}
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
@@ -1906,42 +1584,18 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
int gsn = signal->readSignalNumber();
switch (gsn) {
- case GSN_API_VERSION_CONF: {
- if (theWaitState == WAIT_VERSION) {
- const ApiVersionConf * const conf =
- CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr());
- if(m_versionRec.callback != 0)
- m_versionRec.callback(conf->nodeId, conf->version, this, 0);
- else {
- m_versionRec.version[conf->nodeId]=conf->version;
- }
- } else return;
- theWaitState = NO_WAIT;
- }
- break;
-
case GSN_EVENT_SUBSCRIBE_CONF:
break;
-
+ case GSN_EVENT_SUBSCRIBE_REF:
+ break;
case GSN_EVENT_REP:
eventReport(signal->getDataPtr());
break;
- case GSN_STOP_REF:{
- const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr());
- const NodeId nodeId = refToNode(signal->theSendersBlockRef);
- handleStopReply(nodeId, ref->errorCode);
- return;
- }
+ case GSN_NF_COMPLETEREP:
break;
-
- case GSN_MGM_LOCK_CONFIG_REP:
- case GSN_MGM_LOCK_CONFIG_REQ:
- case GSN_MGM_UNLOCK_CONFIG_REP:
- case GSN_MGM_UNLOCK_CONFIG_REQ: {
- m_signalRecvQueue.receive(new NdbApiSignal(*signal));
+ case GSN_NODE_FAILREP:
break;
- }
default:
g_eventLogger.error("Unknown signal received. SignalNumber: "
@@ -1956,75 +1610,6 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
}
}
-/**
- * A database node was either stopped or there was some error
- */
-void
-MgmtSrvr::handleStopReply(NodeId nodeId, Uint32 errCode)
-{
- /**
- * If we are in single user mode and get a stop reply from a
- * DB node, then we have had a node crash.
- * If all DB nodes are gone, and we are still in single user mode,
- * the set m_stopRec.singleUserMode = false;
- */
- if(m_stopRec.singleUserMode) {
- ClusterMgr::Node node;
- bool failure = true;
- for(Uint32 i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
- node = theFacade->theClusterMgr->getNodeInfo(i);
- if((node.m_state.startLevel == NodeState::SL_NOTHING))
- failure = true;
- else
- failure = false;
- }
- }
- if(failure) {
- m_stopRec.singleUserMode = false;
- }
- }
- if(m_stopRec.inUse == false)
- return;
-
- if(!(m_stopRec.nodeId == 0 || m_stopRec.nodeId == nodeId))
- goto error;
-
- if(m_stopRec.sentCount <= 0)
- goto error;
-
- if(!(theWaitState == WAIT_STOP || m_stopRec.callback != 0))
- goto error;
-
- if(errCode != 0)
- m_stopRec.reply = translateStopRef(errCode);
-
- m_stopRec.sentCount --;
- if(m_stopRec.sentCount == 0){
- if(theWaitState == WAIT_STOP){
- theWaitState = NO_WAIT;
- NdbCondition_Signal(theMgmtWaitForResponseCondPtr);
- return;
- }
- if(m_stopRec.callback != 0){
- m_stopRec.inUse = false;
- StopCallback callback = m_stopRec.callback;
- m_stopRec.callback = NULL;
- (* callback)(m_stopRec.nodeId,
- m_stopRec.anyData,
- m_stopRec.reply);
- return;
- }
- }
- return;
-
- error:
- if(errCode != 0){
- g_eventLogger.error("Unexpected signal received. SignalNumber: %i from %d",
- GSN_STOP_REF, nodeId);
- }
-}
-
void
MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
{
@@ -2040,16 +1625,8 @@ MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
rep->setEventType(NDB_LE_Connected);
if(nfComplete)
{
- handleStopReply(nodeId, 0);
DBUG_VOID_RETURN;
}
-
- if(theWaitNode == nodeId &&
- theWaitState != NO_WAIT && theWaitState != WAIT_STOP)
- {
- theWaitState = WAIT_NODEFAILURE;
- NdbCondition_Signal(theMgmtWaitForResponseCondPtr);
- }
}
rep->setNodeId(_ownNodeId);
@@ -2401,6 +1978,7 @@ MgmtSrvr::eventReport(const Uint32 * theData)
/***************************************************************************
* Backup
***************************************************************************/
+
int
MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
{
@@ -2415,7 +1993,6 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
if(!next) return NO_CONTACT_WITH_DB_NODES;
SimpleSignal ssig;
-
BackupReq* req = CAST_PTR(BackupReq, ssig.getDataPtrSend());
ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_BACKUP_REQ,
BackupReq::SignalLength);
@@ -2430,8 +2007,7 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
while (1) {
if (do_send)
{
- SendStatus result = ss.sendSignal(nodeId, &ssig);
- if (result != SEND_OK) {
+ if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
return SEND_OR_RECEIVE_FAILED;
}
if (waitCompleted == 0)
@@ -2533,13 +2109,13 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
return SEND_OR_RECEIVE_FAILED;
}
}
-
- return 0;
}
int
MgmtSrvr::abortBackup(Uint32 backupId)
{
+ SignalSender ss(theFacade);
+
bool next;
NodeId nodeId = 0;
while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
@@ -2549,44 +2125,17 @@ MgmtSrvr::abortBackup(Uint32 backupId)
return NO_CONTACT_WITH_DB_NODES;
}
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
+ SimpleSignal ssig;
- AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, BACKUP, GSN_ABORT_BACKUP_ORD,
- AbortBackupOrd::SignalLength);
+ AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, ssig.getDataPtrSend());
+ ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_ABORT_BACKUP_ORD,
+ AbortBackupOrd::SignalLength);
ord->requestType = AbortBackupOrd::ClientAbort;
ord->senderData = 19;
ord->backupId = backupId;
- int result = sendSignal(nodeId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
-}
-
-
-NodeId
-MgmtSrvr::getPrimaryNode() const {
-#if 0
- Uint32 tmp;
- const Properties *prop = NULL;
-
- getConfig()->get("SYSTEM", &prop);
- if(prop == NULL)
- return 0;
-
- prop->get("PrimaryMGMNode", &tmp);
-
- return tmp;
-#else
- return 0;
-#endif
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
@@ -2739,7 +2288,6 @@ MgmtSrvr::setDbParameter(int node, int param, const char * value,
NdbMutex_Unlock(m_configMutex);
return 0;
}
-
int
MgmtSrvr::setConnectionDbParameter(int node1,
int node2,
@@ -2874,10 +2422,6 @@ int MgmtSrvr::set_connect_string(const char *str)
}
-template class Vector<SigMatch>;
-#if __SUNPRO_CC != 0x560
-template bool SignalQueue::waitFor<SigMatch>(Vector<SigMatch>&, SigMatch**, NdbApiSignal**, unsigned);
-#endif
template class MutexVector<unsigned short>;
template class MutexVector<Ndb_mgmd_event_service::Event_listener>;
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
index e43a0ff4149..d61c0ce8db7 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
@@ -22,15 +22,17 @@
#include <NdbCondition.h>
#include <mgmapi.h>
-
+#include <NdbTCP.h>
+#include <ConfigRetriever.hpp>
#include <Vector.hpp>
#include <NodeBitmask.hpp>
#include <signaldata/ManagementServer.hpp>
-#include "SignalQueue.hpp"
#include <ndb_version.h>
#include <EventLogger.hpp>
#include <signaldata/EventSubscribeReq.hpp>
+#include <SignalSender.hpp>
+
/**
* @desc Block number for Management server.
* @todo This should probably be somewhere else. I don't know where atm.
@@ -200,51 +202,26 @@ public:
~MgmtSrvr();
- int status(int processId,
- ndb_mgm_node_status * status,
+ /**
+ * Get status on a node.
+ * address may point to a common area (e.g. from inet_addr)
+ * There is no gaurentee that it is preserved across calls.
+ * Copy the string if you are not going to use it immediately.
+ */
+ int status(int nodeId,
+ ndb_mgm_node_status * status,
Uint32 * version,
Uint32 * phase,
bool * systemShutdown,
Uint32 * dynamicId,
Uint32 * nodeGroup,
- Uint32 * connectCount);
+ Uint32 * connectCount,
+ const char **address);
// All the functions below may return any of this error codes:
// NO_CONTACT_WITH_PROCESS, PROCESS_NOT_CONFIGURED, WRONG_PROCESS_TYPE,
// COULD_NOT_ALLOCATE_MEMORY, SEND_OR_RECEIVE_FAILED
-
- typedef void (* StopCallback)(int nodeId, void * anyData, int errorCode);
-
- typedef void (* VersionCallback)(int nodeId, int version,
- void * anyData, int errorCode);
-
-
- typedef void (* EnterSingleCallback)(int nodeId, void * anyData,
- int errorCode);
- typedef void (* ExitSingleCallback)(int nodeId, void * anyData,
- int errorCode);
-
- /**
- * Lock configuration
- */
- int lockConf();
-
- /**
- * Unlock configuration, and commit it if commit is true
- */
- int unlockConf(bool commit);
-
- /**
- * Commit new configuration
- */
- int commitConfig();
-
- /**
- * Rollback configuration
- */
- int rollbackConfig();
-
/**
* Save a configuration to permanent storage
*/
@@ -273,12 +250,12 @@ public:
* @param processId: Id of the DB process to stop
* @return 0 if succeeded, otherwise: as stated above, plus:
*/
- int stopNode(int nodeId, bool abort = false, StopCallback = 0, void *any= 0);
+ int stopNode(int nodeId, bool abort = false);
/**
* Stop the system
*/
- int stop(int * cnt = 0, bool abort = false, StopCallback = 0, void *any = 0);
+ int stop(int * cnt = 0, bool abort = false);
/**
* print version info about a node
@@ -286,27 +263,18 @@ public:
* @param processId: Id of the DB process to stop
* @return 0 if succeeded, otherwise: as stated above, plus:
*/
- int versionNode(int nodeId, bool abort = false,
- VersionCallback = 0, void *any= 0);
+ int versionNode(int nodeId, Uint32 &version, const char **address);
/**
- * print version info about all node in the system
- */
- int version(int * cnt = 0, bool abort = false,
- VersionCallback = 0, void *any = 0);
-
- /**
* Maintenance on the system
*/
- int enterSingleUser(int * cnt = 0, Uint32 singleuserNodeId = 0,
- EnterSingleCallback = 0, void *any = 0);
+ int enterSingleUser(int * cnt = 0, Uint32 singleuserNodeId = 0);
/**
* Resume from maintenance on the system
*/
- int exitSingleUser(int * cnt = 0, bool abort = false,
- ExitSingleCallback = 0, void *any = 0);
+ int exitSingleUser(int * cnt = 0, bool abort = false);
/**
* Start DB process.
@@ -320,15 +288,14 @@ public:
* @param processId: Id of the DB process to start
*/
int restartNode(int processId, bool nostart, bool initialStart,
- bool abort = false,
- StopCallback = 0, void * anyData = 0);
+ bool abort = false);
/**
* Restart the system
*/
int restart(bool nostart, bool initialStart,
bool abort = false,
- int * stopCount = 0, StopCallback = 0, void * anyData = 0);
+ int * stopCount = 0);
struct BackupEvent {
enum Event {
@@ -478,13 +445,6 @@ public:
const Config * getConfig() const;
/**
- * Change configuration paramter
- */
- bool changeConfig(const BaseString &section,
- const BaseString &param,
- const BaseString &value);
-
- /**
* Returns the node count for the specified node type.
*
* @param type The node type.
@@ -493,11 +453,6 @@ public:
int getNodeCount(enum ndb_mgm_node_type type) const;
/**
- * Returns the nodeId of the management master
- */
- NodeId getPrimaryNode() const;
-
- /**
* Returns the port number.
* @return port number.
*/
@@ -523,8 +478,17 @@ public:
private:
//**************************************************************************
- int setEventReportingLevel(int processId, LogLevel::EventCategory, Uint32);
-
+ int send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type);
+
+ int sendSTOP_REQ(NodeId nodeId,
+ NodeBitmask &stoppedNodes,
+ Uint32 singleUserNodeId,
+ bool abort,
+ bool stop,
+ bool restart,
+ bool nostart,
+ bool initialStart);
+
/**
* Check if it is possible to send a signal to a (DB) process
*
@@ -588,9 +552,6 @@ private:
// Returns: -
//**************************************************************************
- void handle_MGM_LOCK_CONFIG_REQ(NdbApiSignal *signal);
- void handle_MGM_UNLOCK_CONFIG_REQ(NdbApiSignal *signal);
-
//**************************************************************************
// Specific signal handling data
//**************************************************************************
@@ -614,59 +575,8 @@ private:
enum WaitSignalType {
NO_WAIT, // We don't expect to receive any signal
WAIT_SET_VAR, // Accept SET_VAR_CONF and SET_VAR_REF
- WAIT_SUBSCRIBE_CONF, // Accept event subscription confirmation
- WAIT_STOP,
- WAIT_BACKUP_STARTED,
- WAIT_BACKUP_COMPLETED,
- WAIT_VERSION,
- WAIT_NODEFAILURE
+ WAIT_SUBSCRIBE_CONF // Accept event subscription confirmation
};
-
- /**
- * Get an unused signal
- * @return A signal if succeeded, NULL otherwise
- */
- NdbApiSignal* getSignal();
-
- /**
- * Add a signal to the list of unused signals
- * @param signal: The signal to add
- */
- void releaseSignal(NdbApiSignal* signal);
-
- /**
- * Remove a signal from the list of unused signals and delete
- * the memory for it.
- */
- void freeSignal();
-
- /**
- * Send a signal
- * @param processId: Id of the receiver process
- * @param waitState: State denoting a set of signals we accept to receive
- * @param signal: The signal to send
- * @return 0 if succeeded, -1 otherwise
- */
- int sendSignal(Uint16 processId, WaitSignalType waitState,
- NdbApiSignal* signal, bool force = false);
-
- /**
- * Send a signal and wait for an answer signal
- * @param processId: Id of the receiver process
- * @param waitState: State denoting a set of signals we accept to receive.
- * @param signal: The signal to send
- * @return 0 if succeeded, -1 otherwise (for example failed to send or
- * failed to receive expected signal).
- */
- int sendRecSignal(Uint16 processId, WaitSignalType waitState,
- NdbApiSignal* signal, bool force = false,
- int waitTime = WAIT_FOR_RESPONSE_TIMEOUT);
-
- /**
- * Wait for a signal to arrive.
- * @return 0 if signal arrived, -1 otherwise
- */
- int receiveOptimisedResponse(int waitTime);
/**
* This function is called from "outside" of MgmtSrvr
@@ -677,7 +587,7 @@ private:
static void signalReceivedNotification(void* mgmtSrvr,
NdbApiSignal* signal,
struct LinearSectionPtr ptr[3]);
-
+
/**
* Called from "outside" of MgmtSrvr when a DB process has died.
* @param mgmtSrvr: The MgmtSrvr object wreceiveOptimisedResponsehich
@@ -714,31 +624,7 @@ private:
class TransporterFacade * theFacade;
- class SignalQueue m_signalRecvQueue;
-
- struct StopRecord {
- StopRecord(){ inUse = false; callback = 0; singleUserMode = false;}
- bool inUse;
- bool singleUserMode;
- int sentCount;
- int reply;
- int nodeId;
- void * anyData;
- StopCallback callback;
- };
- StopRecord m_stopRec;
-
- struct VersionRecord {
- VersionRecord(){ inUse = false; callback = 0;}
- bool inUse;
- Uint32 version[MAX_NODES];
- VersionCallback callback;
- };
- VersionRecord m_versionRec;
- int sendVersionReq( int processId);
-
-
- void handleStopReply(NodeId nodeId, Uint32 errCode);
+ int sendVersionReq( int processId, Uint32 &version, const char **address);
int translateStopRef(Uint32 errCode);
bool _isStopThread;
@@ -759,14 +645,8 @@ private:
static void *logLevelThread_C(void *);
void logLevelThreadRun();
- struct NdbThread *m_signalRecvThread;
- static void *signalRecvThread_C(void *);
- void signalRecvThreadRun();
-
Config *_props;
- int send(class NdbApiSignal* signal, Uint32 node, Uint32 node_type);
-
ConfigRetriever *m_config_retriever;
};
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp b/storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp
index 6c4b4e9ae3c..e56643a3d7e 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp
@@ -23,228 +23,6 @@
#include <ConfigRetriever.hpp>
#include <ndb_version.h>
-void
-MgmtSrvr::handle_MGM_LOCK_CONFIG_REQ(NdbApiSignal *signal) {
- NodeId sender = refToNode(signal->theSendersBlockRef);
- const MgmLockConfigReq * const req = CAST_CONSTPTR(MgmLockConfigReq, signal->getDataPtr());
-
- NdbApiSignal *reply = getSignal();
- if(signal == NULL)
- return; /** @todo handle allocation failure */
-
- reply->set(TestOrd::TraceAPI,
- MGMSRV,
- GSN_MGM_LOCK_CONFIG_REP,
- MgmLockConfigRep::SignalLength);
-
- MgmLockConfigRep *lockRep = CAST_PTR(MgmLockConfigRep, reply->getDataPtrSend());
-
- lockRep->errorCode = MgmLockConfigRep::UNKNOWN_ERROR;
-
- if(req->newConfigGeneration < m_nextConfigGenerationNumber) {
- lockRep->errorCode = MgmLockConfigRep::GENERATION_MISMATCH;
- goto done;
- }
- NdbMutex_Lock(m_configMutex);
-
- m_nextConfigGenerationNumber = req->newConfigGeneration+1;
-
- lockRep->errorCode = MgmLockConfigRep::OK;
-
- done:
- sendSignal(sender, NO_WAIT, reply, true);
- NdbMutex_Unlock(m_configMutex);
- return;
-}
-
-void
-MgmtSrvr::handle_MGM_UNLOCK_CONFIG_REQ(NdbApiSignal *signal) {
- NodeId sender = refToNode(signal->theSendersBlockRef);
- const MgmUnlockConfigReq * const req = CAST_CONSTPTR(MgmUnlockConfigReq, signal->getDataPtr());
- MgmUnlockConfigRep *unlockRep;
-
- NdbApiSignal *reply = getSignal();
- if(signal == NULL)
- goto error; /** @todo handle allocation failure */
-
- reply->set(TestOrd::TraceAPI,
- MGMSRV,
- GSN_MGM_UNLOCK_CONFIG_REP,
- MgmUnlockConfigRep::SignalLength);
-
- unlockRep = CAST_PTR(MgmUnlockConfigRep, reply->getDataPtrSend());
-
- unlockRep->errorCode = MgmUnlockConfigRep::UNKNOWN_ERROR;
-
-
- NdbMutex_Lock(m_configMutex);
-
- if(req->commitConfig == 1) {
- m_newConfig = fetchConfig();
- commitConfig();
- } else
- rollbackConfig();
-
- unlockRep->errorCode = MgmUnlockConfigRep::OK;
-
- sendSignal(sender, NO_WAIT, reply, true);
- error:
- NdbMutex_Unlock(m_configMutex);
- return;
-}
-
-
-/**
- * Prepare all MGM nodes for configuration changes
- *
- * @returns 0 on success, or -1 on failure
- */
-int
-MgmtSrvr::lockConf() {
- int result = -1;
- MgmLockConfigReq* lockReq;
- NodeId node = 0;
-
- /* Check if this is the master node */
- if(getPrimaryNode() != _ownNodeId)
- goto done;
-
- if(NdbMutex_Trylock(m_configMutex) != 0)
- return -1;
-
- m_newConfig = new Config(*_config); /* copy the existing config */
- _config = m_newConfig;
-
- m_newConfig = new Config(*_config);
-
- m_nextConfigGenerationNumber++;
-
- /* Make sure the new configuration _always_ is at least one step older */
- if(m_nextConfigGenerationNumber < m_newConfig->getGenerationNumber()+1)
- m_nextConfigGenerationNumber = _config->getGenerationNumber()+1;
-
- m_newConfig->setGenerationNumber(m_nextConfigGenerationNumber);
-
- node = 0;
- while(getNextNodeId(&node, NDB_MGM_NODE_TYPE_MGM)) {
- if(node != _ownNodeId) {
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- result = COULD_NOT_ALLOCATE_MEMORY;
- goto done;
- }
-
- lockReq = CAST_PTR(MgmLockConfigReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI,
- MGMSRV,
- GSN_MGM_LOCK_CONFIG_REQ,
- MgmLockConfigReq::SignalLength);
-
- lockReq->newConfigGeneration = m_nextConfigGenerationNumber;
-
- result = sendSignal(node, NO_WAIT, signal, true);
-
- NdbApiSignal *reply =
- m_signalRecvQueue.waitFor(GSN_MGM_LOCK_CONFIG_REP, 0);
-
- if(reply == NULL) {
- /** @todo handle timeout/error */
- ndbout << __FILE__ << ":" << __LINE__ << endl;
- result = -1;
- goto done;
- }
-
- }
- }
-
- done:
- NdbMutex_Unlock(m_configMutex);
- return result;
-}
-
-/**
- * Unlocks configuration
- *
- * @returns 0 on success, ! 0 on error
- */
-int
-MgmtSrvr::unlockConf(bool commit) {
- int result = -1;
- MgmUnlockConfigReq* unlockReq;
- NodeId node = 0;
-
- /* Check if this is the master node */
- if(getPrimaryNode() != _ownNodeId)
- goto done;
-
- errno = 0;
- if(NdbMutex_Lock(m_configMutex) != 0)
- return -1;
-
- if(commit)
- commitConfig();
- else
- rollbackConfig();
-
- node = 0;
- while(getNextNodeId(&node, NDB_MGM_NODE_TYPE_MGM)) {
- if(node != _ownNodeId) {
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- result = COULD_NOT_ALLOCATE_MEMORY;
- goto done;
- }
-
- unlockReq = CAST_PTR(MgmUnlockConfigReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI,
- MGMSRV,
- GSN_MGM_UNLOCK_CONFIG_REQ,
- MgmUnlockConfigReq::SignalLength);
- unlockReq->commitConfig = commit;
-
- result = sendSignal(node, NO_WAIT, signal, true);
-
- NdbApiSignal *reply =
- m_signalRecvQueue.waitFor(GSN_MGM_UNLOCK_CONFIG_REP, 0);
-
- if(reply == NULL) {
- /** @todo handle timeout/error */
- result = -1;
- goto done;
- }
-
- }
- }
-
- done:
- NdbMutex_Unlock(m_configMutex);
- return result;
-}
-
-/**
- * Commit the new configuration
- */
-int
-MgmtSrvr::commitConfig() {
- int ret = saveConfig(m_newConfig);
- delete _config;
- _config = m_newConfig;
- m_newConfig = NULL;
- ndbout << "commit " << ret << endl;
- return ret;
-}
-
-/**
- * Rollback to the old configuration
- */
-int
-MgmtSrvr::rollbackConfig() {
- delete m_newConfig;
- m_newConfig = NULL;
- ndbout << "rollback" << endl;
- return saveConfig(_config);
-}
-
/**
* Save a configuration to the running configuration file
*/
@@ -274,7 +52,15 @@ Config *
MgmtSrvr::readConfig() {
Config *conf;
InitConfigFileParser parser;
- conf = parser.parseConfig(m_configFilename.c_str());
+ if (m_configFilename.length())
+ {
+ conf = parser.parseConfig(m_configFilename.c_str());
+ }
+ else
+ {
+ ndbout_c("Reading cluster configuration using my.cnf");
+ conf = parser.parse_mycnf();
+ }
return conf;
}
@@ -288,12 +74,3 @@ MgmtSrvr::fetchConfig() {
}
return 0;
}
-
-bool
-MgmtSrvr::changeConfig(const BaseString &section,
- const BaseString &param,
- const BaseString &value) {
- if(m_newConfig == NULL)
- return false;
- return m_newConfig->change(section, param, value);
-}
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp b/storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp
index f93948abc75..c99936e1861 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp
@@ -20,123 +20,3 @@
// Some kind of reuse should be preferred.
//******************************************************************************
-#include "MgmtSrvr.hpp"
-#include <NdbApiSignal.hpp>
-#include <NdbTick.h>
-
-
-NdbApiSignal*
-MgmtSrvr::getSignal()
-{
- NdbApiSignal* tSignal;
- tSignal = theSignalIdleList;
- if (tSignal != NULL){
- NdbApiSignal* tSignalNext = tSignal->next();
- tSignal->next(NULL);
- theSignalIdleList = tSignalNext;
- return tSignal;
- } else
- {
- tSignal = new NdbApiSignal(_ownReference);
- if (tSignal != NULL)
- tSignal->next(NULL);
- }
- return tSignal;
-}
-
-
-void
-MgmtSrvr::releaseSignal(NdbApiSignal* aSignal)
-{
- aSignal->next(theSignalIdleList);
- theSignalIdleList = aSignal;
-}
-
-
-void
-MgmtSrvr::freeSignal()
-{
- NdbApiSignal* tSignal = theSignalIdleList;
- theSignalIdleList = tSignal->next();
- delete tSignal;
-}
-
-
-int
-MgmtSrvr::sendSignal(Uint16 aNodeId,
- WaitSignalType aWaitState,
- NdbApiSignal* aSignal,
- bool force)
-{
- int tReturnCode;
- theFacade->lock_mutex();
- if(force){
- tReturnCode = theFacade->sendSignalUnCond(aSignal,
- aNodeId);
- } else {
- tReturnCode = theFacade->sendSignal(aSignal,
- aNodeId);
- }
- releaseSignal(aSignal);
- if (tReturnCode == -1) {
- theFacade->unlock_mutex();
- return -1;
- }
- theWaitState = aWaitState;
- theFacade->unlock_mutex();
- return 0;
-}
-
-
-int
-MgmtSrvr::sendRecSignal(Uint16 aNodeId,
- WaitSignalType aWaitState,
- NdbApiSignal* aSignal,
- bool force,
- int waitTime)
-{
- int tReturnCode;
- theFacade->lock_mutex();
- if(force){
- tReturnCode = theFacade->sendSignalUnCond(aSignal, aNodeId);
- } else {
- tReturnCode = theFacade->sendSignalUnCond(aSignal, aNodeId);
- }
- releaseSignal(aSignal);
- if (tReturnCode == -1) {
- theFacade->unlock_mutex();
- return -1;
- }
- theWaitState = aWaitState;
- theWaitNode = aNodeId;
- return receiveOptimisedResponse(waitTime);
-}
-
-
-int
-MgmtSrvr::receiveOptimisedResponse(int waitTime)
-{
- int tResultCode;
- theFacade->checkForceSend(_blockNumber);
- NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
-
- while (theWaitState != NO_WAIT && theWaitState != WAIT_NODEFAILURE
- && waitTime > 0) {
- NdbCondition_WaitTimeout(theMgmtWaitForResponseCondPtr,
- theFacade->theMutexPtr,
- waitTime);
- if(theWaitState == NO_WAIT || theWaitState == WAIT_NODEFAILURE)
- break;
- waitTime = (maxTime - NdbTick_CurrentMillisecond());
- }//while
-
- if(theWaitState == NO_WAIT) {
- tResultCode = 0;
- } else {
- tResultCode = -1;
- }
- theFacade->unlock_mutex();
- return tResultCode;
-}
-
-
diff --git a/storage/ndb/src/mgmsrv/Services.cpp b/storage/ndb/src/mgmsrv/Services.cpp
index 3992796e304..e2a7c3d0c29 100644
--- a/storage/ndb/src/mgmsrv/Services.cpp
+++ b/storage/ndb/src/mgmsrv/Services.cpp
@@ -216,21 +216,6 @@ ParserRow<MgmApiSession> commands[] = {
MGM_ARG("level", Int, Mandatory, "Severety level"),
MGM_ARG("enable", Int, Mandatory, "1=disable, 0=enable, -1=toggle"),
- MGM_CMD("config lock", &MgmApiSession::configLock, ""),
-
- MGM_CMD("config unlock", &MgmApiSession::configUnlock, ""),
- MGM_ARG("commit", Int, Mandatory, "Commit changes"),
-
- MGM_CMD("config change", &MgmApiSession::configChange, ""),
- MGM_ARG("section", String, Mandatory, "Section"),
- MGM_ARG("parameter", String, Mandatory, "Parameter"),
- MGM_ARG("value", String, Mandatory, "Value"),
-
- MGM_CMD("config lock", &MgmApiSession::configLock, ""),
-
- MGM_CMD("config unlock", &MgmApiSession::configUnlock, ""),
- MGM_ARG("commit", Int, Mandatory, "Commit changes"),
-
MGM_CMD("set parameter", &MgmApiSession::setParameter, ""),
MGM_ARG("node", String, Mandatory, "Node"),
MGM_ARG("parameter", String, Mandatory, "Parameter"),
@@ -910,8 +895,10 @@ printNodeStatus(OutputStream *output,
nodeGroup = 0,
connectCount = 0;
bool system;
- mgmsrv.status(nodeId, &status, &version, &startPhase,
- &system, &dynamicId, &nodeGroup, &connectCount);
+ const char *address= NULL;
+ mgmsrv.status(nodeId, &status, &version, &startPhase,
+ &system, &dynamicId, &nodeGroup, &connectCount,
+ &address);
output->println("node.%d.type: %s",
nodeId,
ndb_mgm_get_node_type_string(type));
@@ -923,7 +910,7 @@ printNodeStatus(OutputStream *output,
output->println("node.%d.dynamic_id: %d", nodeId, dynamicId);
output->println("node.%d.node_group: %d", nodeId, nodeGroup);
output->println("node.%d.connect_count: %d", nodeId, connectCount);
- output->println("node.%d.address: %s", nodeId, mgmsrv.get_connect_address(nodeId));
+ output->println("node.%d.address: %s", nodeId, address ? address : "");
}
}
@@ -1192,42 +1179,6 @@ MgmApiSession::setLogFilter(Parser_t::Context &ctx,
m_output->println("");
}
-void
-MgmApiSession::configLock(Parser_t::Context &,
- Properties const &) {
- int ret = m_mgmsrv.lockConf();
- m_output->println("config lock reply");
- m_output->println("result: %d", ret);
- m_output->println("");
-}
-
-void
-MgmApiSession::configUnlock(Parser_t::Context &,
- Properties const &args) {
- Uint32 commit;
- args.get("commit", &commit);
- int ret = m_mgmsrv.unlockConf(commit == 1);
- m_output->println("config unlock reply");
- m_output->println("result: %d", ret);
- m_output->println("");
-}
-
-void
-MgmApiSession::configChange(Parser_t::Context &,
- Properties const &args) {
- BaseString section, param, value;
- args.get("section", section);
- args.get("parameter", param);
- args.get("value", value);
-
- int ret = m_mgmsrv.changeConfig(section.c_str(),
- param.c_str(),
- value.c_str());
- m_output->println("config change reply");
- m_output->println("result: %d", ret);
- m_output->println("");
-}
-
static NdbOut&
operator<<(NdbOut& out, const LogLevel & ll)
{
diff --git a/storage/ndb/src/mgmsrv/Services.hpp b/storage/ndb/src/mgmsrv/Services.hpp
index 7d5d8cb9c8c..8672010d66c 100644
--- a/storage/ndb/src/mgmsrv/Services.hpp
+++ b/storage/ndb/src/mgmsrv/Services.hpp
@@ -83,9 +83,6 @@ public:
void setClusterLogLevel(Parser_t::Context &ctx,
const class Properties &args);
void setLogFilter(Parser_t::Context &ctx, const class Properties &args);
- void configLock(Parser_t::Context &ctx, const class Properties &args);
- void configUnlock(Parser_t::Context &ctx, const class Properties &args);
- void configChange(Parser_t::Context &ctx, const class Properties &args);
void setParameter(Parser_t::Context &ctx, const class Properties &args);
void setConnectionParameter(Parser_t::Context &ctx,
diff --git a/storage/ndb/src/mgmsrv/main.cpp b/storage/ndb/src/mgmsrv/main.cpp
index ec20101493e..f0c2ac298a5 100644
--- a/storage/ndb/src/mgmsrv/main.cpp
+++ b/storage/ndb/src/mgmsrv/main.cpp
@@ -102,6 +102,7 @@ static int opt_daemon; // NOT bool, bool need not be int
static int opt_non_interactive;
static int opt_interactive;
static const char * opt_config_filename= 0;
+static int opt_mycnf = 0;
struct MgmGlobals {
MgmGlobals();
@@ -166,6 +167,10 @@ static struct my_option my_long_options[] =
"Don't run as daemon, but don't read from stdin",
(gptr*) &opt_non_interactive, (gptr*) &opt_non_interactive, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "mycnf", 256,
+ "Read cluster config from my.cnf",
+ (gptr*) &opt_mycnf, (gptr*) &opt_mycnf, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -199,7 +204,7 @@ int main(int argc, char** argv)
#endif
global_mgmt_server_check = 1;
-
+
const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 };
load_defaults("my",load_default_groups,&argc,&argv);
@@ -217,13 +222,26 @@ int main(int argc, char** argv)
opt_daemon= 0;
}
+ if (opt_mycnf && opt_config_filename)
+ {
+ ndbout_c("Both --mycnf and -f is not supported");
+ return 0;
+ }
+
+ if (opt_mycnf == 0 && opt_config_filename == 0)
+ {
+ struct stat buf;
+ if (stat("config.ini", &buf) != -1)
+ opt_config_filename = "config.ini";
+ }
+
glob->socketServer = new SocketServer();
MgmApiService * mapi = new MgmApiService();
glob->mgmObject = new MgmtSrvr(glob->socketServer,
- opt_config_filename,
- opt_connect_str);
+ opt_config_filename,
+ opt_connect_str);
if (g_print_full_config)
goto the_end;
diff --git a/storage/ndb/src/ndbapi/NdbApiSignal.cpp b/storage/ndb/src/ndbapi/NdbApiSignal.cpp
index b1671e593e1..94695185224 100644
--- a/storage/ndb/src/ndbapi/NdbApiSignal.cpp
+++ b/storage/ndb/src/ndbapi/NdbApiSignal.cpp
@@ -62,6 +62,25 @@ NdbApiSignal::NdbApiSignal(BlockReference ref)
theNextSignal = 0;
}
+NdbApiSignal::NdbApiSignal(Ndb* ndb)
+{
+ BlockReference ref = ndb->theMyRef;
+ theVerId_signalNumber = 0; // 4 bit ver id - 16 bit gsn
+ theReceiversBlockNumber = 0; // Only 16 bit blocknum
+ theSendersBlockRef = refToBlock(ref);
+ theLength = 0;
+ theSendersSignalId = 0;
+ theSignalId = 0;
+ theTrace = 0;
+ m_noOfSections = 0;
+ m_fragmentInfo = 0;
+ for (int i = 0; i < 25; i++)
+ theData[i] = 0x13579753;
+
+ setDataPtr(&theData[0]);
+ theNextSignal = 0;
+}
+
/**
* Copy constructor
*/
diff --git a/storage/ndb/src/ndbapi/NdbApiSignal.hpp b/storage/ndb/src/ndbapi/NdbApiSignal.hpp
index 353c575d420..9d04a8594a8 100644
--- a/storage/ndb/src/ndbapi/NdbApiSignal.hpp
+++ b/storage/ndb/src/ndbapi/NdbApiSignal.hpp
@@ -46,7 +46,8 @@
class NdbApiSignal : public SignalHeader
{
public:
- NdbApiSignal(BlockReference myRef);
+ NdbApiSignal(Ndb* ndb);
+ NdbApiSignal(BlockReference ref);
NdbApiSignal(const NdbApiSignal &);
NdbApiSignal(const SignalHeader &header)
: SignalHeader(header), theNextSignal(0), theRealData(0) {};
diff --git a/storage/ndb/src/ndbapi/NdbBlob.cpp b/storage/ndb/src/ndbapi/NdbBlob.cpp
index 77ab87ce5c1..28d657f3fe9 100644
--- a/storage/ndb/src/ndbapi/NdbBlob.cpp
+++ b/storage/ndb/src/ndbapi/NdbBlob.cpp
@@ -141,7 +141,7 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm
// initialization
-NdbBlob::NdbBlob()
+NdbBlob::NdbBlob(Ndb*)
{
init();
}
diff --git a/storage/ndb/src/ndbapi/NdbImpl.hpp b/storage/ndb/src/ndbapi/NdbImpl.hpp
index 5e630b54d68..30e0d28a765 100644
--- a/storage/ndb/src/ndbapi/NdbImpl.hpp
+++ b/storage/ndb/src/ndbapi/NdbImpl.hpp
@@ -32,6 +32,21 @@
#include "NdbDictionaryImpl.hpp"
#include "ObjectMap.hpp"
+template <class T>
+struct Ndb_free_list_t
+{
+ Ndb_free_list_t();
+ ~Ndb_free_list_t();
+
+ void fill(Ndb*, Uint32 cnt);
+ T* seize(Ndb*);
+ void release(T*);
+ void clear();
+ Uint32 get_sizeof() const { return sizeof(T); }
+ T * m_free_list;
+ Uint32 m_alloc_cnt, m_free_cnt;
+};
+
/**
* Private parts of the Ndb object (corresponding to Ndb.hpp in public API)
*/
@@ -66,7 +81,6 @@ public:
int m_optimized_node_selection;
-
BaseString m_dbname; // Database name
BaseString m_schemaname; // Schema name
@@ -78,6 +92,22 @@ public:
m_schemaname.c_str(), table_name_separator);
}
+ /**
+ * NOTE free lists must be _after_ theNdbObjectIdMap take
+ * assure that destructors are run in correct order
+ */
+ Ndb_free_list_t<NdbTransaction> theConIdleList;
+ Ndb_free_list_t<NdbOperation> theOpIdleList;
+ Ndb_free_list_t<NdbIndexScanOperation> theScanOpIdleList;
+ Ndb_free_list_t<NdbIndexOperation> theIndexOpIdleList;
+ Ndb_free_list_t<NdbRecAttr> theRecAttrIdleList;
+ Ndb_free_list_t<NdbApiSignal> theSignalIdleList;
+ Ndb_free_list_t<NdbLabel> theLabelList;
+ Ndb_free_list_t<NdbBranch> theBranchList;
+ Ndb_free_list_t<NdbSubroutine> theSubroutineList;
+ Ndb_free_list_t<NdbCall> theCallList;
+ Ndb_free_list_t<NdbBlob> theNdbBlobIdleList;
+ Ndb_free_list_t<NdbReceiver> theScanList;
};
#ifdef VM_TRACE
@@ -152,4 +182,91 @@ enum LockMode {
Delete
};
+template<class T>
+inline
+Ndb_free_list_t<T>::Ndb_free_list_t()
+{
+ m_free_list= 0;
+ m_alloc_cnt= m_free_cnt= 0;
+}
+
+template<class T>
+inline
+Ndb_free_list_t<T>::~Ndb_free_list_t()
+{
+ clear();
+}
+
+template<class T>
+inline
+void
+Ndb_free_list_t<T>::fill(Ndb* ndb, Uint32 cnt)
+{
+ if (m_free_list == 0)
+ {
+ m_free_cnt++;
+ m_alloc_cnt++;
+ m_free_list = new T(ndb);
+ }
+ while(m_alloc_cnt < cnt)
+ {
+ T* obj= new T(ndb);
+ if(obj == 0)
+ return;
+
+ obj->next(m_free_list);
+ m_free_cnt++;
+ m_alloc_cnt++;
+ m_free_list = obj;
+ }
+}
+
+template<class T>
+inline
+T*
+Ndb_free_list_t<T>::seize(Ndb* ndb)
+{
+ T* tmp = m_free_list;
+ if (tmp)
+ {
+ m_free_list = (T*)tmp->next();
+ tmp->next(NULL);
+ m_free_cnt--;
+ return tmp;
+ }
+
+ if((tmp = new T(ndb)))
+ {
+ m_alloc_cnt++;
+ }
+
+ return tmp;
+}
+
+template<class T>
+inline
+void
+Ndb_free_list_t<T>::release(T* obj)
+{
+ obj->next(m_free_list);
+ m_free_list = obj;
+ m_free_cnt++;
+}
+
+
+template<class T>
+inline
+void
+Ndb_free_list_t<T>::clear()
+{
+ T* obj = m_free_list;
+ while(obj)
+ {
+ T* curr = obj;
+ obj = (T*)obj->next();
+ delete curr;
+ m_alloc_cnt--;
+ }
+}
+
#endif
diff --git a/storage/ndb/src/ndbapi/NdbRecAttr.cpp b/storage/ndb/src/ndbapi/NdbRecAttr.cpp
index 5e5306fc33a..5201c6c9c04 100644
--- a/storage/ndb/src/ndbapi/NdbRecAttr.cpp
+++ b/storage/ndb/src/ndbapi/NdbRecAttr.cpp
@@ -22,7 +22,7 @@
#include "NdbDictionaryImpl.hpp"
#include <NdbTCP.h>
-NdbRecAttr::NdbRecAttr()
+NdbRecAttr::NdbRecAttr(Ndb*)
{
init();
}
@@ -98,7 +98,7 @@ NdbRecAttr::copyout()
NdbRecAttr *
NdbRecAttr::clone() const {
- NdbRecAttr * ret = new NdbRecAttr();
+ NdbRecAttr * ret = new NdbRecAttr(0);
ret->theAttrId = theAttrId;
ret->theNULLind = theNULLind;
diff --git a/storage/ndb/src/ndbapi/NdbUtil.cpp b/storage/ndb/src/ndbapi/NdbUtil.cpp
index 5c74d251ff9..6019ea675a1 100644
--- a/storage/ndb/src/ndbapi/NdbUtil.cpp
+++ b/storage/ndb/src/ndbapi/NdbUtil.cpp
@@ -30,8 +30,7 @@ Comment:
#include "NdbUtil.hpp"
-NdbLabel::NdbLabel() :
- theNext(NULL)
+NdbLabel::NdbLabel(Ndb*)
{
}
@@ -39,8 +38,7 @@ NdbLabel::~NdbLabel()
{
}
-NdbSubroutine::NdbSubroutine() :
- theNext(NULL)
+NdbSubroutine::NdbSubroutine(Ndb*)
{
}
@@ -48,9 +46,8 @@ NdbSubroutine::~NdbSubroutine()
{
}
-NdbBranch::NdbBranch() :
- theSignal(NULL),
- theNext(NULL)
+NdbBranch::NdbBranch(Ndb*) :
+ theSignal(NULL)
{
}
@@ -58,9 +55,8 @@ NdbBranch::~NdbBranch()
{
}
-NdbCall::NdbCall() :
- theSignal(NULL),
- theNext(NULL)
+NdbCall::NdbCall(Ndb*) :
+ theSignal(NULL)
{
}
diff --git a/storage/ndb/src/ndbapi/NdbUtil.hpp b/storage/ndb/src/ndbapi/NdbUtil.hpp
index 80fc15ddd8c..268f6c69e6f 100644
--- a/storage/ndb/src/ndbapi/NdbUtil.hpp
+++ b/storage/ndb/src/ndbapi/NdbUtil.hpp
@@ -31,44 +31,53 @@ Comment:
#include <ndb_global.h>
+class Ndb;
class NdbApiSignal;
class NdbOperation;
-class NdbLabel
+template<class T>
+struct Free_list_element
+{
+ Free_list_element() { theNext = 0;}
+ void next(T* obj) { theNext = obj;}
+ T* next() { return theNext;}
+
+ T* theNext;
+};
+
+class NdbLabel : public Free_list_element<NdbLabel>
{
friend class NdbOperation;
friend class Ndb;
-
-private:
- NdbLabel();
+public:
+ NdbLabel(Ndb*);
~NdbLabel();
- NdbLabel* theNext;
+private:
Uint32 theSubroutine[16];
Uint32 theLabelAddress[16];
Uint32 theLabelNo[16];
};
-class NdbSubroutine
+class NdbSubroutine : public Free_list_element<NdbSubroutine>
{
friend class NdbOperation;
friend class Ndb;
-private:
- NdbSubroutine();
+public:
+ NdbSubroutine(Ndb*);
~NdbSubroutine();
- NdbSubroutine* theNext;
Uint32 theSubroutineAddress[16];
};
-class NdbBranch
+class NdbBranch : public Free_list_element<NdbBranch>
{
friend class NdbOperation;
friend class Ndb;
-private:
- NdbBranch();
+public:
+ NdbBranch(Ndb*);
~NdbBranch();
NdbApiSignal* theSignal;
@@ -76,22 +85,20 @@ private:
Uint32 theBranchAddress;
Uint32 theBranchLabel;
Uint32 theSubroutine;
- NdbBranch* theNext;
};
-class NdbCall
+class NdbCall : public Free_list_element<NdbCall>
{
friend class NdbOperation;
friend class Ndb;
-private:
- NdbCall();
+public:
+ NdbCall(Ndb*);
~NdbCall();
NdbApiSignal* theSignal;
Uint32 theSignalAddress;
Uint32 theSubroutine;
- NdbCall* theNext;
};
#endif
diff --git a/storage/ndb/src/ndbapi/Ndbif.cpp b/storage/ndb/src/ndbapi/Ndbif.cpp
index 48608345acd..d68248e6981 100644
--- a/storage/ndb/src/ndbapi/Ndbif.cpp
+++ b/storage/ndb/src/ndbapi/Ndbif.cpp
@@ -146,15 +146,6 @@ Ndb::init(int aMaxNoOfTransactions)
error_handler:
ndbout << "error_handler" << endl;
releaseTransactionArrays();
- while ( theConIdleList != NULL )
- freeNdbCon();
- while ( theSignalIdleList != NULL )
- freeSignal();
- while (theRecAttrIdleList != NULL)
- freeRecAttr();
- while (theOpIdleList != NULL)
- freeOperation();
-
delete theDictionary;
TransporterFacade::instance()->close(theNdbBlockNumber, 0);
DBUG_RETURN(-1);
diff --git a/storage/ndb/src/ndbapi/Ndbinit.cpp b/storage/ndb/src/ndbapi/Ndbinit.cpp
index a742f571a81..bb77a69937b 100644
--- a/storage/ndb/src/ndbapi/Ndbinit.cpp
+++ b/storage/ndb/src/ndbapi/Ndbinit.cpp
@@ -29,6 +29,10 @@
#include <NdbOut.hpp>
#include <NdbSleep.h>
#include "ObjectMap.hpp"
+#include <NdbIndexScanOperation.hpp>
+#include <NdbIndexOperation.hpp>
+#include "NdbUtil.hpp"
+#include <NdbBlob.hpp>
#include "NdbEventOperationImpl.hpp"
#include <EventLogger.hpp>
@@ -62,20 +66,8 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection,
theRemainingStartTransactions= 0;
theMaxNoOfTransactions= 0;
theMinNoOfEventsToWakeUp= 0;
- theConIdleList= NULL;
- theOpIdleList= NULL;
- theScanOpIdleList= NULL;
- theIndexOpIdleList= NULL;
theTransactionList= NULL;
theConnectionArray= NULL;
- theRecAttrIdleList= NULL;
- theSignalIdleList= NULL;
- theLabelList= NULL;
- theBranchList= NULL;
- theSubroutineList= NULL;
- theCallList= NULL;
- theScanList= NULL;
- theNdbBlobIdleList= NULL;
the_last_check_time= 0;
theFirstTransId= 0;
theRestartGCI= 0;
@@ -160,33 +152,6 @@ Ndb::~Ndb()
TransporterFacade::instance()->close(theNdbBlockNumber, theFirstTransId);
}
-// if (theSchemaConToNdbList != NULL)
-// closeSchemaTransaction(theSchemaConToNdbList);
- while ( theConIdleList != NULL )
- freeNdbCon();
- while (theOpIdleList != NULL)
- freeOperation();
- while (theScanOpIdleList != NULL)
- freeScanOperation();
- while (theIndexOpIdleList != NULL)
- freeIndexOperation();
- while (theLabelList != NULL)
- freeNdbLabel();
- while (theBranchList != NULL)
- freeNdbBranch();
- while (theSubroutineList != NULL)
- freeNdbSubroutine();
- while (theCallList != NULL)
- freeNdbCall();
- while (theScanList != NULL)
- freeNdbScanRec();
- while (theNdbBlobIdleList != NULL)
- freeNdbBlob();
- while (theRecAttrIdleList != NULL)
- freeRecAttr();
- while ( theSignalIdleList != NULL )
- freeSignal();
-
releaseTransactionArrays();
delete []theConnectionArray;
@@ -242,7 +207,8 @@ NdbImpl::NdbImpl(Ndb_cluster_connection *ndb_cluster_connection,
m_ndb_cluster_connection(ndb_cluster_connection->m_impl),
m_dictionary(ndb),
theCurrentConnectIndex(0),
- theNdbObjectIdMap(1024,1024),
+ theNdbObjectIdMap(ndb_cluster_connection->m_impl.m_transporter_facade->theMutexPtr,
+ 1024,1024),
theNoOfDBnodes(0),
m_ev_op(0)
{
diff --git a/storage/ndb/src/ndbapi/Ndblist.cpp b/storage/ndb/src/ndbapi/Ndblist.cpp
index 96d0f4d7de5..f82348fc91d 100644
--- a/storage/ndb/src/ndbapi/Ndblist.cpp
+++ b/storage/ndb/src/ndbapi/Ndblist.cpp
@@ -75,24 +75,7 @@ Ndb::checkFailedNode()
int
Ndb::createConIdleList(int aNrOfCon)
{
- for (int i = 0; i < aNrOfCon; i++)
- {
- NdbTransaction* tNdbCon = new NdbTransaction(this);
- if (tNdbCon == NULL)
- {
- return -1;
- }
- if (theConIdleList == NULL)
- {
- theConIdleList = tNdbCon;
- theConIdleList->next(NULL);
- } else
- {
- tNdbCon->next(theConIdleList);
- theConIdleList = tNdbCon;
- }
- tNdbCon->Status(NdbTransaction::NotConnected);
- }
+ theImpl->theConIdleList.fill(this, aNrOfCon);
return aNrOfCon;
}
@@ -108,19 +91,7 @@ Ndb::createConIdleList(int aNrOfCon)
int
Ndb::createOpIdleList(int aNrOfOp)
{
- for (int i = 0; i < aNrOfOp; i++){
- NdbOperation* tOp = new NdbOperation(this);
- if ( tOp == NULL ){
- return -1;
- }
- if (theOpIdleList == NULL){
- theOpIdleList = tOp;
- theOpIdleList->next(NULL);
- } else{
- tOp->next(theOpIdleList);
- theOpIdleList = tOp;
- }
- }
+ theImpl->theOpIdleList.fill(this, aNrOfOp);
return aNrOfOp;
}
@@ -134,22 +105,7 @@ Ndb::createOpIdleList(int aNrOfOp)
NdbBranch*
Ndb::getNdbBranch()
{
- NdbBranch* tNdbBranch;
- if ( theBranchList == NULL )
- {
- tNdbBranch = new NdbBranch;
- if (tNdbBranch == NULL)
- {
- return NULL;
- }
- tNdbBranch->theNext = NULL;
- } else
- {
- tNdbBranch = theBranchList;
- theBranchList = tNdbBranch->theNext;
- tNdbBranch->theNext = NULL;
- }
- return tNdbBranch;
+ return theImpl->theBranchList.seize(this);
}
/***************************************************************************
@@ -162,22 +118,7 @@ Ndb::getNdbBranch()
NdbCall*
Ndb::getNdbCall()
{
- NdbCall* tNdbCall;
- if ( theCallList == NULL )
- {
- tNdbCall = new NdbCall;
- if (tNdbCall == NULL)
- {
- return NULL;
- }
- tNdbCall->theNext = NULL;
- } else
- {
- tNdbCall = theCallList;
- theCallList = tNdbCall->theNext;
- tNdbCall->theNext = NULL;
- }
- return tNdbCall;
+ return theImpl->theCallList.seize(this);
}
/***************************************************************************
@@ -190,19 +131,7 @@ Ndb::getNdbCall()
NdbTransaction*
Ndb::getNdbCon()
{
- NdbTransaction* tNdbCon;
- if ( theConIdleList == NULL ) {
- tNdbCon = new NdbTransaction(this);
- if (tNdbCon == NULL) {
- return NULL;
- }//if
- tNdbCon->next(NULL);
- } else
- {
- tNdbCon = theConIdleList;
- theConIdleList = tNdbCon->next();
- tNdbCon->next(NULL);
- }
+ NdbTransaction* tNdbCon = theImpl->theConIdleList.seize(this);
tNdbCon->theMagicNumber = 0x37412619;
return tNdbCon;
}
@@ -217,22 +146,7 @@ Ndb::getNdbCon()
NdbLabel*
Ndb::getNdbLabel()
{
- NdbLabel* tNdbLabel;
- if ( theLabelList == NULL )
- {
- tNdbLabel = new NdbLabel;
- if (tNdbLabel == NULL)
- {
- return NULL;
- }
- tNdbLabel->theNext = NULL;
- } else
- {
- tNdbLabel = theLabelList;
- theLabelList = tNdbLabel->theNext;
- tNdbLabel->theNext = NULL;
- }
- return tNdbLabel;
+ return theImpl->theLabelList.seize(this);
}
/***************************************************************************
@@ -246,23 +160,7 @@ Ndb::getNdbLabel()
NdbReceiver*
Ndb::getNdbScanRec()
{
- NdbReceiver* tNdbScanRec;
- if ( theScanList == NULL )
- {
- tNdbScanRec = new NdbReceiver(this);
- if (tNdbScanRec == NULL)
- {
- return NULL;
- }
- tNdbScanRec->next(NULL);
- } else
- {
- tNdbScanRec = theScanList;
- theScanList = tNdbScanRec->next();
- tNdbScanRec->next(NULL);
- }
-
- return tNdbScanRec;
+ return theImpl->theScanList.seize(this);
}
/***************************************************************************
@@ -275,22 +173,7 @@ Ndb::getNdbScanRec()
NdbSubroutine*
Ndb::getNdbSubroutine()
{
- NdbSubroutine* tNdbSubroutine;
- if ( theSubroutineList == NULL )
- {
- tNdbSubroutine = new NdbSubroutine;
- if (tNdbSubroutine == NULL)
- {
- return NULL;
- }
- tNdbSubroutine->theNext = NULL;
- } else
- {
- tNdbSubroutine = theSubroutineList;
- theSubroutineList = tNdbSubroutine->theNext;
- tNdbSubroutine->theNext = NULL;
- }
- return tNdbSubroutine;
+ return theImpl->theSubroutineList.seize(this);
}
/***************************************************************************
@@ -303,18 +186,7 @@ Remark: Get an operation from theOpIdleList and return the object .
NdbOperation*
Ndb::getOperation()
{
- NdbOperation* tOp = theOpIdleList;
- if (tOp != NULL ) {
- NdbOperation* tOpNext = tOp->next();
- tOp->next(NULL);
- theOpIdleList = tOpNext;
- return tOp;
- } else {
- tOp = new NdbOperation(this);
- if (tOp != NULL)
- tOp->next(NULL);
- }
- return tOp;
+ return theImpl->theOpIdleList.seize(this);
}
/***************************************************************************
@@ -327,18 +199,7 @@ Remark: Get an operation from theScanOpIdleList and return the object .
NdbIndexScanOperation*
Ndb::getScanOperation()
{
- NdbIndexScanOperation* tOp = theScanOpIdleList;
- if (tOp != NULL ) {
- NdbIndexScanOperation* tOpNext = (NdbIndexScanOperation*)tOp->next();
- tOp->next(NULL);
- theScanOpIdleList = tOpNext;
- return tOp;
- } else {
- tOp = new NdbIndexScanOperation(this);
- if (tOp != NULL)
- tOp->next(NULL);
- }
- return tOp;
+ return theImpl->theScanOpIdleList.seize(this);
}
/***************************************************************************
@@ -351,18 +212,7 @@ Remark: Get an operation from theIndexOpIdleList and return the object .
NdbIndexOperation*
Ndb::getIndexOperation()
{
- NdbIndexOperation* tOp = theIndexOpIdleList;
- if (tOp != NULL ) {
- NdbIndexOperation* tOpNext = (NdbIndexOperation*) tOp->next();
- tOp->next(NULL);
- theIndexOpIdleList = tOpNext;
- return tOp;
- } else {
- tOp = new NdbIndexOperation(this);
- if (tOp != NULL)
- tOp->next(NULL);
- }
- return tOp;
+ return theImpl->theIndexOpIdleList.seize(this);
}
/***************************************************************************
@@ -374,21 +224,14 @@ Return Value: Return a reference to a receive attribute object.
NdbRecAttr*
Ndb::getRecAttr()
{
- NdbRecAttr* tRecAttr;
- tRecAttr = theRecAttrIdleList;
- if (tRecAttr != NULL) {
- NdbRecAttr* tRecAttrNext = tRecAttr->next();
+ NdbRecAttr* tRecAttr = theImpl->theRecAttrIdleList.seize(this);
+ if (tRecAttr != NULL)
+ {
tRecAttr->init();
- theRecAttrIdleList = tRecAttrNext;
return tRecAttr;
- } else {
- tRecAttr = new NdbRecAttr;
- if (tRecAttr == NULL)
- return NULL;
- tRecAttr->next(NULL);
- }//if
- tRecAttr->init();
- return tRecAttr;
+ }
+
+ return NULL;
}
/***************************************************************************
@@ -400,34 +243,16 @@ Return Value: Return a reference to a signal object.
NdbApiSignal*
Ndb::getSignal()
{
- NdbApiSignal* tSignal = theSignalIdleList;
- if (tSignal != NULL){
- NdbApiSignal* tSignalNext = tSignal->next();
- tSignal->next(NULL);
- theSignalIdleList = tSignalNext;
- } else {
- tSignal = new NdbApiSignal(theMyRef);
-#ifdef POORMANSPURIFY
- cnewSignals++;
-#endif
- if (tSignal != NULL)
- tSignal->next(NULL);
- }
-#ifdef POORMANSPURIFY
- cgetSignals++;
-#endif
- return tSignal;
+ return theImpl->theSignalIdleList.seize(this);
}
NdbBlob*
Ndb::getNdbBlob()
{
- NdbBlob* tBlob = theNdbBlobIdleList;
- if (tBlob != NULL) {
- theNdbBlobIdleList = tBlob->theNext;
+ NdbBlob* tBlob = theImpl->theNdbBlobIdleList.seize(this);
+ if(tBlob)
+ {
tBlob->init();
- } else {
- tBlob = new NdbBlob;
}
return tBlob;
}
@@ -441,8 +266,7 @@ Remark: Add a NdbBranch object into the Branch idlelist.
void
Ndb::releaseNdbBranch(NdbBranch* aNdbBranch)
{
- aNdbBranch->theNext = theBranchList;
- theBranchList = aNdbBranch;
+ theImpl->theBranchList.release(aNdbBranch);
}
/***************************************************************************
@@ -454,8 +278,7 @@ Remark: Add a NdbBranch object into the Branch idlelist.
void
Ndb::releaseNdbCall(NdbCall* aNdbCall)
{
- aNdbCall->theNext = theCallList;
- theCallList = aNdbCall;
+ theImpl->theCallList.release(aNdbCall);
}
/***************************************************************************
@@ -467,9 +290,8 @@ Remark: Add a Connection object into the signal idlelist.
void
Ndb::releaseNdbCon(NdbTransaction* aNdbCon)
{
- aNdbCon->next(theConIdleList);
aNdbCon->theMagicNumber = 0xFE11DD;
- theConIdleList = aNdbCon;
+ theImpl->theConIdleList.release(aNdbCon);
}
/***************************************************************************
@@ -481,8 +303,7 @@ Remark: Add a NdbLabel object into the Label idlelist.
void
Ndb::releaseNdbLabel(NdbLabel* aNdbLabel)
{
- aNdbLabel->theNext = theLabelList;
- theLabelList = aNdbLabel;
+ theImpl->theLabelList.release(aNdbLabel);
}
/***************************************************************************
@@ -494,8 +315,7 @@ Remark: Add a NdbScanReceiver object into the Scan idlelist.
void
Ndb::releaseNdbScanRec(NdbReceiver* aNdbScanRec)
{
- aNdbScanRec->next(theScanList);
- theScanList = aNdbScanRec;
+ theImpl->theScanList.release(aNdbScanRec);
}
/***************************************************************************
@@ -507,8 +327,7 @@ Remark: Add a NdbSubroutine object into theSubroutine idlelist.
void
Ndb::releaseNdbSubroutine(NdbSubroutine* aNdbSubroutine)
{
- aNdbSubroutine->theNext = theSubroutineList;
- theSubroutineList = aNdbSubroutine;
+ theImpl->theSubroutineList.release(aNdbSubroutine);
}
/***************************************************************************
@@ -521,16 +340,14 @@ void
Ndb::releaseOperation(NdbOperation* anOperation)
{
if(anOperation->m_tcReqGSN == GSN_TCKEYREQ){
- anOperation->next(theOpIdleList);
anOperation->theNdbCon = NULL;
anOperation->theMagicNumber = 0xFE11D0;
- theOpIdleList = anOperation;
+ theImpl->theOpIdleList.release(anOperation);
} else {
assert(anOperation->m_tcReqGSN == GSN_TCINDXREQ);
- anOperation->next(theIndexOpIdleList);
anOperation->theNdbCon = NULL;
anOperation->theMagicNumber = 0xFE11D1;
- theIndexOpIdleList = (NdbIndexOperation*)anOperation;
+ theImpl->theIndexOpIdleList.release((NdbIndexOperation*)anOperation);
}
}
@@ -553,10 +370,9 @@ Ndb::releaseScanOperation(NdbIndexScanOperation* aScanOperation)
}
}
#endif
- aScanOperation->next(theScanOpIdleList);
aScanOperation->theNdbCon = NULL;
aScanOperation->theMagicNumber = 0xFE11D2;
- theScanOpIdleList = aScanOperation;
+ theImpl->theScanOpIdleList.release(aScanOperation);
DBUG_VOID_RETURN;
}
@@ -570,8 +386,7 @@ void
Ndb::releaseRecAttr(NdbRecAttr* aRecAttr)
{
aRecAttr->release();
- aRecAttr->next(theRecAttrIdleList);
- theRecAttrIdleList = aRecAttr;
+ theImpl->theRecAttrIdleList.release(aRecAttr);
}
/***************************************************************************
@@ -598,8 +413,7 @@ Ndb::releaseSignal(NdbApiSignal* aSignal)
#ifdef POORMANSPURIFY
creleaseSignals++;
#endif
- aSignal->next(theSignalIdleList);
- theSignalIdleList = aSignal;
+ theImpl->theSignalIdleList.release(aSignal);
}
void
@@ -616,162 +430,7 @@ void
Ndb::releaseNdbBlob(NdbBlob* aBlob)
{
aBlob->release();
- aBlob->theNext = theNdbBlobIdleList;
- theNdbBlobIdleList = aBlob;
-}
-
-/***************************************************************************
-void freeOperation();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeOperation()
-{
- NdbOperation* tOp = theOpIdleList;
- theOpIdleList = theOpIdleList->next();
- delete tOp;
-}
-
-/***************************************************************************
-void freeScanOperation();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeScanOperation()
-{
- NdbIndexScanOperation* tOp = theScanOpIdleList;
- theScanOpIdleList = (NdbIndexScanOperation *)tOp->next();
- delete tOp;
-}
-
-/***************************************************************************
-void freeIndexOperation();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeIndexOperation()
-{
- NdbIndexOperation* tOp = theIndexOpIdleList;
- theIndexOpIdleList = (NdbIndexOperation *) theIndexOpIdleList->next();
- delete tOp;
-}
-
-/***************************************************************************
-void freeNdbBranch();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbBranch()
-{
- NdbBranch* tNdbBranch = theBranchList;
- theBranchList = theBranchList->theNext;
- delete tNdbBranch;
-}
-
-/***************************************************************************
-void freeNdbCall();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbCall()
-{
- NdbCall* tNdbCall = theCallList;
- theCallList = theCallList->theNext;
- delete tNdbCall;
-}
-
-/***************************************************************************
-void freeNdbScanRec();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbScanRec()
-{
- NdbReceiver* tNdbScanRec = theScanList;
- theScanList = theScanList->next();
- delete tNdbScanRec;
-}
-
-/***************************************************************************
-void freeNdbCon();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbCon()
-{
- NdbTransaction* tNdbCon = theConIdleList;
- theConIdleList = theConIdleList->next();
- delete tNdbCon;
-}
-
-/***************************************************************************
-void freeNdbLabel();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbLabel()
-{
- NdbLabel* tNdbLabel = theLabelList;
- theLabelList = theLabelList->theNext;
- delete tNdbLabel;
-}
-
-/***************************************************************************
-void freeNdbSubroutine();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbSubroutine()
-{
- NdbSubroutine* tNdbSubroutine = theSubroutineList;
- theSubroutineList = theSubroutineList->theNext;
- delete tNdbSubroutine;
-}
-
-/***************************************************************************
-void freeRecAttr();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeRecAttr()
-{
- NdbRecAttr* tRecAttr = theRecAttrIdleList;
- theRecAttrIdleList = theRecAttrIdleList->next();
- delete tRecAttr;
-}
-
-/***************************************************************************
-void freeSignal();
-
-Remark: Delete a signal object from the signal idlelist.
-***************************************************************************/
-void
-Ndb::freeSignal()
-{
- NdbApiSignal* tSignal = theSignalIdleList;
- theSignalIdleList = tSignal->next();
- delete tSignal;
-#ifdef POORMANSPURIFY
- cfreeSignals++;
-#endif
-}
-
-void
-Ndb::freeNdbBlob()
-{
- NdbBlob* tBlob = theNdbBlobIdleList;
- theNdbBlobIdleList = tBlob->theNext;
- delete tBlob;
+ theImpl->theNdbBlobIdleList.release(aBlob);
}
/****************************************************************************
@@ -826,3 +485,102 @@ Ndb::releaseConnectToNdb(NdbTransaction* a_con)
DBUG_VOID_RETURN;
}
+template<class T>
+static
+Ndb::Free_list_usage*
+update(Ndb::Free_list_usage* curr,
+ Ndb_free_list_t<T> & list,
+ const char * name)
+{
+ curr->m_name = name;
+ curr->m_created = list.m_alloc_cnt;
+ curr->m_free = list.m_free_cnt;
+ curr->m_sizeof = sizeof(T);
+ return curr;
+}
+
+Ndb::Free_list_usage*
+Ndb::get_free_list_usage(Ndb::Free_list_usage* curr)
+{
+ if (curr == 0)
+ {
+ return 0;
+ }
+
+ if(curr->m_name == 0)
+ {
+ update(curr, theImpl->theConIdleList, "NdbTransaction");
+ }
+ else if(!strcmp(curr->m_name, "NdbTransaction"))
+ {
+ update(curr, theImpl->theOpIdleList, "NdbOperation");
+ }
+ else if(!strcmp(curr->m_name, "NdbOperation"))
+ {
+ update(curr, theImpl->theScanOpIdleList, "NdbIndexScanOperation");
+ }
+ else if(!strcmp(curr->m_name, "NdbIndexScanOperation"))
+ {
+ update(curr, theImpl->theIndexOpIdleList, "NdbIndexOperation");
+ }
+ else if(!strcmp(curr->m_name, "NdbIndexOperation"))
+ {
+ update(curr, theImpl->theRecAttrIdleList, "NdbRecAttr");
+ }
+ else if(!strcmp(curr->m_name, "NdbRecAttr"))
+ {
+ update(curr, theImpl->theSignalIdleList, "NdbApiSignal");
+ }
+ else if(!strcmp(curr->m_name, "NdbApiSignal"))
+ {
+ update(curr, theImpl->theLabelList, "NdbLabel");
+ }
+ else if(!strcmp(curr->m_name, "NdbLabel"))
+ {
+ update(curr, theImpl->theBranchList, "NdbBranch");
+ }
+ else if(!strcmp(curr->m_name, "NdbBranch"))
+ {
+ update(curr, theImpl->theSubroutineList, "NdbSubroutine");
+ }
+ else if(!strcmp(curr->m_name, "NdbSubroutine"))
+ {
+ update(curr, theImpl->theCallList, "NdbCall");
+ }
+ else if(!strcmp(curr->m_name, "NdbCall"))
+ {
+ update(curr, theImpl->theNdbBlobIdleList, "NdbBlob");
+ }
+ else if(!strcmp(curr->m_name, "NdbBlob"))
+ {
+ update(curr, theImpl->theScanList, "NdbReceiver");
+ }
+ else if(!strcmp(curr->m_name, "NdbReceiver"))
+ {
+ return 0;
+ }
+ else
+ {
+ update(curr, theImpl->theConIdleList, "NdbTransaction");
+ }
+
+ return curr;
+}
+
+#define TI(T) \
+ template Ndb::Free_list_usage* \
+ update(Ndb::Free_list_usage*, Ndb_free_list_t<T> &, const char * name);\
+ template struct Ndb_free_list_t<T>
+
+TI(NdbBlob);
+TI(NdbCall);
+TI(NdbLabel);
+TI(NdbBranch);
+TI(NdbSubroutine);
+TI(NdbApiSignal);
+TI(NdbRecAttr);
+TI(NdbOperation);
+TI(NdbReceiver);
+TI(NdbConnection);
+TI(NdbIndexOperation);
+TI(NdbIndexScanOperation);
diff --git a/storage/ndb/src/ndbapi/ObjectMap.hpp b/storage/ndb/src/ndbapi/ObjectMap.hpp
index dc2a5046f77..e3db479f677 100644
--- a/storage/ndb/src/ndbapi/ObjectMap.hpp
+++ b/storage/ndb/src/ndbapi/ObjectMap.hpp
@@ -30,7 +30,7 @@ class NdbObjectIdMap //: NdbLockable
{
public:
STATIC_CONST( InvalidId = ~(Uint32)0 );
- NdbObjectIdMap(Uint32 initalSize = 128, Uint32 expandSize = 10);
+ NdbObjectIdMap(NdbMutex*, Uint32 initalSize = 128, Uint32 expandSize = 10);
~NdbObjectIdMap();
Uint32 map(void * object);
@@ -46,14 +46,16 @@ private:
void * m_obj;
} * m_map;
+ NdbMutex * m_mutex;
void expand(Uint32 newSize);
};
inline
-NdbObjectIdMap::NdbObjectIdMap(Uint32 sz, Uint32 eSz) {
+NdbObjectIdMap::NdbObjectIdMap(NdbMutex* mutex, Uint32 sz, Uint32 eSz) {
m_size = 0;
m_firstFree = InvalidId;
m_map = 0;
+ m_mutex = mutex;
m_expandSize = eSz;
expand(sz);
#ifdef DEBUG_OBJECTMAP
@@ -126,21 +128,26 @@ NdbObjectIdMap::getObject(Uint32 id){
inline void
NdbObjectIdMap::expand(Uint32 incSize){
+ NdbMutex_Lock(m_mutex);
Uint32 newSize = m_size + incSize;
- MapEntry * tmp = (MapEntry*)malloc(newSize * sizeof(MapEntry));
+ MapEntry * tmp = (MapEntry*)realloc(m_map, newSize * sizeof(MapEntry));
- if (m_map) {
- memcpy(tmp, m_map, m_size * sizeof(MapEntry));
- free((void*)m_map);
+ if (likely(tmp != 0))
+ {
+ m_map = tmp;
+
+ for(Uint32 i = m_size; i<newSize; i++){
+ m_map[i].m_next = i + 1;
+ }
+ m_firstFree = m_size;
+ m_map[newSize-1].m_next = InvalidId;
+ m_size = newSize;
}
- m_map = tmp;
-
- for(Uint32 i = m_size; i<newSize; i++){
- m_map[i].m_next = i + 1;
+ else
+ {
+ ndbout_c("NdbObjectIdMap::expand unable to expand!!");
}
- m_firstFree = m_size;
- m_map[newSize-1].m_next = InvalidId;
- m_size = newSize;
+ NdbMutex_Unlock(m_mutex);
}
#endif
diff --git a/storage/ndb/tools/ndb_condig.cpp b/storage/ndb/tools/ndb_condig.cpp
index 725249a5af5..1b9a771f243 100644
--- a/storage/ndb/tools/ndb_condig.cpp
+++ b/storage/ndb/tools/ndb_condig.cpp
@@ -23,6 +23,8 @@
#include <my_getopt.h>
#include <mysql_version.h>
+#include <netdb.h>
+
#include <NdbOut.hpp>
#include <mgmapi.h>
#include <mgmapi_configuration.hpp>
@@ -40,6 +42,8 @@ static const char * g_type = 0;
static const char * g_host = 0;
static const char * g_field_delimiter=",";
static const char * g_row_delimiter=" ";
+static const char * g_config_file = 0;
+static int g_mycnf = 0;
int g_print_full_config, opt_ndb_shm;
my_bool opt_core;
@@ -90,6 +94,12 @@ static struct my_option my_long_options[] =
{ "rows", 'r', "Row separator",
(gptr*) &g_row_delimiter, (gptr*) &g_row_delimiter,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ { "config-file", 256, "Path to config.ini",
+ (gptr*) &g_config_file, (gptr*) &g_config_file,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ { "mycnf", 256, "Read config from my.cnf",
+ (gptr*) &g_mycnf, (gptr*) &g_mycnf,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -124,6 +134,11 @@ struct Match
{
int m_key;
BaseString m_value;
+ virtual int eval(const Iter&);
+};
+
+struct HostMatch : public Match
+{
virtual int eval(NdbMgmHandle, const Iter&);
};
@@ -132,18 +147,21 @@ struct Apply
Apply() {}
Apply(int val) { m_key = val;}
int m_key;
- virtual int apply(NdbMgmHandle, const Iter&);
+ virtual int apply(const Iter&);
};
struct NodeTypeApply : public Apply
{
- virtual int apply(NdbMgmHandle, const Iter&);
+ virtual int apply(const Iter&);
};
static int parse_query(Vector<Apply*>&, int &argc, char**& argv);
static int parse_where(Vector<Match*>&, int &argc, char**& argv);
-static int eval(NdbMgmHandle, const Iter&, const Vector<Match*>&);
-static int apply(NdbMgmHandle, const Iter&, const Vector<Apply*>&);
+static int eval(const Iter&, const Vector<Match*>&);
+static int apply(const Iter&, const Vector<Apply*>&);
+static ndb_mgm_configuration* fetch_configuration();
+static ndb_mgm_configuration* load_configuration();
+
int
main(int argc, char** argv){
NDB_INIT(argv[0]);
@@ -154,51 +172,16 @@ main(int argc, char** argv){
ndb_std_get_one_option)))
return -1;
- NdbMgmHandle mgm = ndb_mgm_create_handle();
- if(mgm == NULL) {
- fprintf(stderr, "Cannot create handle to management server.\n");
- exit(-1);
- }
+ ndb_mgm_configuration * conf = 0;
- ndb_mgm_set_error_stream(mgm, stderr);
-
- if (ndb_mgm_set_connectstring(mgm, g_connectstring))
- {
- fprintf(stderr, "* %5d: %s\n",
- ndb_mgm_get_latest_error(mgm),
- ndb_mgm_get_latest_error_msg(mgm));
- fprintf(stderr,
- "* %s", ndb_mgm_get_latest_error_desc(mgm));
- exit(-1);
- }
+ if (g_config_file || g_mycnf)
+ conf = load_configuration();
+ else
+ conf = fetch_configuration();
- if(ndb_mgm_connect(mgm, try_reconnect-1, 5, 1))
+ if (conf == 0)
{
- fprintf(stderr, "Connect failed");
- fprintf(stderr, " code: %d, msg: %s\n",
- ndb_mgm_get_latest_error(mgm),
- ndb_mgm_get_latest_error_msg(mgm));
- exit(-1);
- }
- else if(g_verbose)
- {
- fprintf(stderr, "Connected to %s:%d\n",
- ndb_mgm_get_connected_host(mgm),
- ndb_mgm_get_connected_port(mgm));
- }
-
- ndb_mgm_configuration * conf = ndb_mgm_get_configuration(mgm, 0);
- if(conf == 0)
- {
- fprintf(stderr, "Could not get configuration");
- fprintf(stderr, "code: %d, msg: %s\n",
- ndb_mgm_get_latest_error(mgm),
- ndb_mgm_get_latest_error_msg(mgm));
- exit(-1);
- }
- else if(g_verbose)
- {
- fprintf(stderr, "Fetched configuration\n");
+ return -1;
}
Vector<Apply*> select_list;
@@ -224,12 +207,12 @@ main(int argc, char** argv){
iter.first();
for(iter.first(); iter.valid(); iter.next())
{
- if(eval(mgm, iter, where_clause))
+ if(eval(iter, where_clause))
{
if(prev)
printf("%s", g_row_delimiter);
prev= true;
- apply(mgm, iter, select_list);
+ apply(iter, select_list);
}
}
printf("\n");
@@ -297,9 +280,10 @@ parse_where(Vector<Match*>& where, int &argc, char**& argv)
Match m;
if(g_host)
{
- m.m_key = CFG_NODE_HOST;
- m.m_value.assfmt("%s", g_host);
- where.push_back(new Match(m));
+ HostMatch *m = new HostMatch;
+ m->m_key = CFG_NODE_HOST;
+ m->m_value.assfmt("%s", g_host);
+ where.push_back(m);
}
if(g_type)
@@ -323,11 +307,11 @@ template class Vector<Match*>;
static
int
-eval(NdbMgmHandle mgm, const Iter& iter, const Vector<Match*>& where)
+eval(const Iter& iter, const Vector<Match*>& where)
{
for(unsigned i = 0; i<where.size(); i++)
{
- if(where[i]->eval(mgm, iter) == 0)
+ if(where[i]->eval(iter) == 0)
return 0;
}
@@ -336,11 +320,11 @@ eval(NdbMgmHandle mgm, const Iter& iter, const Vector<Match*>& where)
static
int
-apply(NdbMgmHandle mgm, const Iter& iter, const Vector<Apply*>& list)
+apply(const Iter& iter, const Vector<Apply*>& list)
{
for(unsigned i = 0; i<list.size(); i++)
{
- list[i]->apply(mgm, iter);
+ list[i]->apply(iter);
if(i + 1 != list.size())
printf("%s", g_field_delimiter);
}
@@ -348,19 +332,19 @@ apply(NdbMgmHandle mgm, const Iter& iter, const Vector<Apply*>& list)
}
int
-Match::eval(NdbMgmHandle h, const Iter& iter)
+Match::eval(const Iter& iter)
{
Uint32 val32;
Uint64 val64;
const char* valc;
if (iter.get(m_key, &val32) == 0)
{
- if(atoi(m_value.c_str()) != val32)
+ if(atoi(m_value.c_str()) != (int)val32)
return 0;
}
else if(iter.get(m_key, &val64) == 0)
{
- if(strtoll(m_value.c_str(), (char **)NULL, 10) != val64)
+ if(strtoll(m_value.c_str(), (char **)NULL, 10) != (long long)val64)
return 0;
}
else if(iter.get(m_key, &valc) == 0)
@@ -376,7 +360,41 @@ Match::eval(NdbMgmHandle h, const Iter& iter)
}
int
-Apply::apply(NdbMgmHandle h, const Iter& iter)
+HostMatch::eval(NdbMgmHandle h, const Iter& iter)
+{
+ const char* valc;
+
+ if(iter.get(m_key, &valc) == 0)
+ {
+ struct hostent *h1, *h2;
+
+ h1 = gethostbyname(m_value.c_str());
+ if (h1 == NULL) {
+ return 0;
+ }
+
+ h2 = gethostbyname(valc);
+ if (h2 == NULL) {
+ return 0;
+ }
+
+ if (h1->h_addrtype != h2->h_addrtype) {
+ return 0;
+ }
+
+ if (h1->h_length != h2->h_length)
+ {
+ return 0;
+ }
+
+ return 0 == memcmp(h1->h_addr, h2->h_addr, h1->h_length);
+ }
+
+ return 0;
+}
+
+int
+Apply::apply(const Iter& iter)
{
Uint32 val32;
Uint64 val64;
@@ -397,7 +415,7 @@ Apply::apply(NdbMgmHandle h, const Iter& iter)
}
int
-NodeTypeApply::apply(NdbMgmHandle h, const Iter& iter)
+NodeTypeApply::apply(const Iter& iter)
{
Uint32 val32;
if (iter.get(CFG_TYPE_OF_SECTION, &val32) == 0)
@@ -406,3 +424,86 @@ NodeTypeApply::apply(NdbMgmHandle h, const Iter& iter)
}
return 0;
}
+
+ndb_mgm_configuration*
+fetch_configuration()
+{
+ ndb_mgm_configuration* conf = 0;
+ NdbMgmHandle mgm = ndb_mgm_create_handle();
+ if(mgm == NULL) {
+ fprintf(stderr, "Cannot create handle to management server.\n");
+ return 0;
+ }
+
+ ndb_mgm_set_error_stream(mgm, stderr);
+
+ if (ndb_mgm_set_connectstring(mgm, g_connectstring))
+ {
+ fprintf(stderr, "* %5d: %s\n",
+ ndb_mgm_get_latest_error(mgm),
+ ndb_mgm_get_latest_error_msg(mgm));
+ fprintf(stderr,
+ "* %s", ndb_mgm_get_latest_error_desc(mgm));
+ goto noconnect;
+ }
+
+ if(ndb_mgm_connect(mgm, try_reconnect-1, 5, 1))
+ {
+ fprintf(stderr, "Connect failed");
+ fprintf(stderr, " code: %d, msg: %s\n",
+ ndb_mgm_get_latest_error(mgm),
+ ndb_mgm_get_latest_error_msg(mgm));
+ goto noconnect;
+ }
+ else if(g_verbose)
+ {
+ fprintf(stderr, "Connected to %s:%d\n",
+ ndb_mgm_get_connected_host(mgm),
+ ndb_mgm_get_connected_port(mgm));
+ }
+
+ conf = ndb_mgm_get_configuration(mgm, 0);
+ if(conf == 0)
+ {
+ fprintf(stderr, "Could not get configuration");
+ fprintf(stderr, "code: %d, msg: %s\n",
+ ndb_mgm_get_latest_error(mgm),
+ ndb_mgm_get_latest_error_msg(mgm));
+ }
+ else if(g_verbose)
+ {
+ fprintf(stderr, "Fetched configuration\n");
+ }
+
+ ndb_mgm_disconnect(mgm);
+noconnect:
+ ndb_mgm_destroy_handle(&mgm);
+
+ return conf;
+}
+
+#include <Config.hpp>
+
+ndb_mgm_configuration*
+load_configuration()
+{
+ InitConfigFileParser parser(stderr);
+ if (g_config_file)
+ {
+ if (g_verbose)
+ fprintf(stderr, "Using config.ini : %s", g_config_file);
+
+ Config* conf = parser.parseConfig(g_config_file);
+ if (conf)
+ return conf->m_configValues;
+ }
+
+ if (g_verbose)
+ fprintf(stderr, "Using my.cnf");
+
+ Config* conf = parser.parse_mycnf();
+ if (conf)
+ return conf->m_configValues;
+
+ return 0;
+}
diff --git a/storage/ndb/tools/restore/Restore.cpp b/storage/ndb/tools/restore/Restore.cpp
index 6c01b753b43..9efafd19468 100644
--- a/storage/ndb/tools/restore/Restore.cpp
+++ b/storage/ndb/tools/restore/Restore.cpp
@@ -870,7 +870,7 @@ operator<<(NdbOut& ndbout, const AttributeS& attr){
return ndbout;
}
- NdbRecAttr tmprec;
+ NdbRecAttr tmprec(0);
tmprec.setup(desc.m_column, (char *)data.void_value);
ndbout << tmprec;
diff --git a/storage/ndb/tools/restore/consumer_restore.cpp b/storage/ndb/tools/restore/consumer_restore.cpp
index 5786bdac697..552246a4f9e 100644
--- a/storage/ndb/tools/restore/consumer_restore.cpp
+++ b/storage/ndb/tools/restore/consumer_restore.cpp
@@ -38,7 +38,7 @@ BackupRestore::init()
m_cluster_connection = new Ndb_cluster_connection(g_connect_string);
if(m_cluster_connection->connect(12, 5, 1) != 0)
{
- return -1;
+ return false;
}
m_ndb = new Ndb(m_cluster_connection);
diff --git a/strings/decimal.c b/strings/decimal.c
index 7816f340eef..ce00b9770b3 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1033,7 +1033,7 @@ int decimal2ulonglong(decimal_t *from, ulonglong *to)
{
ulonglong y=x;
x=x*DIG_BASE + *buf++;
- if (unlikely(y > (ULONGLONG_MAX/DIG_BASE) || x < y))
+ if (unlikely(y > ((ulonglong) ULONGLONG_MAX/DIG_BASE) || x < y))
{
*to=y;
return E_DEC_OVERFLOW;
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index ac19819f9af..80218dce3b3 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -504,7 +504,7 @@ fi
# Clean up the BuildRoot
%clean
-[ "$RBR" != "/" ] && [ -d $RBR ] && rm -rf $RBR;
+[ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT;
%files server
%defattr(-,root,root,0755)
@@ -667,6 +667,11 @@ fi
# itself - note that they must be ordered by date (important when
# merging BK trees)
%changelog
+* Thu Sep 29 2005 Lenz Grimmer <lenz@mysql.com>
+
+- fixed the removing of the RPM_BUILD_ROOT in the %clean section (the
+ $RBR variable did not get expanded, thus leaving old build roots behind)
+
* Thu Aug 04 2005 Lenz Grimmer <lenz@mysql.com>
- Fixed the creation of the mysql user group account in the postinstall
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 84a32b52284..65a4617445c 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -13828,8 +13828,11 @@ static void test_bug10760()
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
rc= mysql_query(mysql, "update t1 set id=id+100");
- DIE_UNLESS(rc);
- if (!opt_silent)
+ /*
+ If cursors are not materialized, the update will return an error;
+ we mainly test that it won't deadlock.
+ */
+ if (rc && !opt_silent)
printf("Got error (as expected): %s\n", mysql_error(mysql));
/*
2: check that MyISAM tables used in cursors survive
diff --git a/zlib/ChangeLog b/zlib/ChangeLog
index 1af7633d668..7f6869d3235 100644
--- a/zlib/ChangeLog
+++ b/zlib/ChangeLog
@@ -1,10 +1,96 @@
ChangeLog file for zlib
-Changes in port for MySQL (19 July 2004)
-- removed contrib, nt, os2, amiga, directories and some other files not used
-in MySQL distribution. If you are working on porting MySQL to one of rare
-platforms, you might find worth looking at the original zlib distribution
-and using appropriate Makefiles/project files from it.
+
+Changes in 1.2.3 (18 July 2005)
+- Apply security vulnerability fixes to contrib/infback9 as well
+- Clean up some text files (carriage returns, trailing space)
+- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant]
+
+Changes in 1.2.2.4 (11 July 2005)
+- Add inflatePrime() function for starting inflation at bit boundary
+- Avoid some Visual C warnings in deflate.c
+- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit
+ compile
+- Fix some spelling errors in comments [Betts]
+- Correct inflateInit2() error return documentation in zlib.h
+- Added zran.c example of compressed data random access to examples
+ directory, shows use of inflatePrime()
+- Fix cast for assignments to strm->state in inflate.c and infback.c
+- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
+- Move declarations of gf2 functions to right place in crc32.c [Oberhumer]
+- Add cast in trees.c t avoid a warning [Oberhumer]
+- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer]
+- Update make_vms.com [Zinser]
+- Initialize state->write in inflateReset() since copied in inflate_fast()
+- Be more strict on incomplete code sets in inflate_table() and increase
+ ENOUGH and MAXD -- this repairs a possible security vulnerability for
+ invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for
+ discovering the vulnerability and providing test cases.
+- Add ia64 support to configure for HP-UX [Smith]
+- Add error return to gzread() for format or i/o error [Levin]
+- Use malloc.h for OS/2 [Necasek]
+
+Changes in 1.2.2.3 (27 May 2005)
+- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile
+- Typecast fread() return values in gzio.c [Vollant]
+- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)
+- Fix crc check bug in gzread() after gzungetc() [Heiner]
+- Add the deflateTune() function to adjust internal compression parameters
+- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)
+- Remove an incorrect assertion in examples/zpipe.c
+- Add C++ wrapper in infback9.h [Donais]
+- Fix bug in inflateCopy() when decoding fixed codes
+- Note in zlib.h how much deflateSetDictionary() actually uses
+- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)
+- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]
+- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]
+- Add gzdirect() function to indicate transparent reads
+- Update contrib/minizip [Vollant]
+- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]
+- Add casts in crc32.c to avoid warnings [Oberhumer]
+- Add contrib/masmx64 [Vollant]
+- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]
+
+Changes in 1.2.2.2 (30 December 2004)
+- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
+ avoid implicit memcpy calls (portability for no-library compilation)
+- Increase sprintf() buffer size in gzdopen() to allow for large numbers
+- Add INFLATE_STRICT to check distances against zlib header
+- Improve WinCE errno handling and comments [Chang]
+- Remove comment about no gzip header processing in FAQ
+- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
+- Add updated make_vms.com [Coghlan], update README
+- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
+ fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
+- Add FAQ entry and comments in deflate.c on uninitialized memory access
+- Add Solaris 9 make options in configure [Gilbert]
+- Allow strerror() usage in gzio.c for STDC
+- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
+- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
+- Use z_off_t for adler32_combine() and crc32_combine() lengths
+- Make adler32() much faster for small len
+- Use OS_CODE in deflate() default gzip header
+
+Changes in 1.2.2.1 (31 October 2004)
+- Allow inflateSetDictionary() call for raw inflate
+- Fix inflate header crc check bug for file names and comments
+- Add deflateSetHeader() and gz_header structure for custom gzip headers
+- Add inflateGetheader() to retrieve gzip headers
+- Add crc32_combine() and adler32_combine() functions
+- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
+- Use zstreamp consistently in zlib.h (inflate_back functions)
+- Remove GUNZIP condition from definition of inflate_mode in inflate.h
+ and in contrib/inflate86/inffast.S [Truta, Anderson]
+- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
+- Update projects/README.projects and projects/visualc6 [Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
+- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
+- Use a new algorithm for setting strm->data_type in trees.c [Truta]
+- Do not define an exit() prototype in zutil.c unless DEBUG defined
+- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
+- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
+- Fix Darwin build version identification [Peterson]
Changes in 1.2.2 (3 October 2004)
- Update zlib.h comments on gzip in-memory processing
@@ -454,7 +540,7 @@ Changes in 1.0.7 (20 Jan 1998)
Changes in 1.0.6 (19 Jan 1998)
- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
-- Fix a deflate bug occuring only with compression level 0 (thanks to
+- Fix a deflate bug occurring only with compression level 0 (thanks to
Andy Buckler for finding this one).
- In minigzip, pass transparently also the first byte for .Z files.
- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
diff --git a/zlib/FAQ b/zlib/FAQ
index 4f61f1094e6..441d910daa1 100644
--- a/zlib/FAQ
+++ b/zlib/FAQ
@@ -148,13 +148,6 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
format using deflateInit2(). You can also request that inflate decode
the gzip format using inflateInit2(). Read zlib.h for more details.
- Note that you cannot specify special gzip header contents (e.g. a file
- name or modification date), nor will inflate tell you what was in the
- gzip header. If you need to customize the header or see what's in it,
- you can use the raw deflate and inflate operations and the crc32()
- function and roll your own gzip encoding and decoding. Read the gzip
- RFC 1952 for details of the header and trailer format.
-
21. Is zlib thread-safe?
Yes. However any library routines that zlib uses and any application-
@@ -295,20 +288,29 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
were downright silly. So now, we simply make sure that the code always
works.
-36. Will zlib read the (insert any ancient or arcane format here) compressed
+36. Valgrind (or some similar memory access checker) says that deflate is
+ performing a conditional jump that depends on an uninitialized value.
+ Isn't that a bug?
+
+ No. That is intentional for performance reasons, and the output of
+ deflate is not affected. This only started showing up recently since
+ zlib 1.2.x uses malloc() by default for allocations, whereas earlier
+ versions used calloc(), which zeros out the allocated memory.
+
+37. Will zlib read the (insert any ancient or arcane format here) compressed
data format?
Probably not. Look in the comp.compression FAQ for pointers to various
formats and associated software.
-37. How can I encrypt/decrypt zip files with zlib?
+38. How can I encrypt/decrypt zip files with zlib?
zlib doesn't support encryption. The original PKZIP encryption is very weak
and can be broken with freely available programs. To get strong encryption,
use GnuPG, http://www.gnupg.org/ , which already includes zlib compression.
For PKZIP compatible "encryption", look at http://www.info-zip.org/
-38. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
+39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
"gzip" is the gzip format, and "deflate" is the zlib format. They should
probably have called the second one "zlib" instead to avoid confusion
@@ -324,14 +326,14 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
Bottom line: use the gzip format for HTTP 1.1 encoding.
-39. Does zlib support the new "Deflate64" format introduced by PKWare?
+40. Does zlib support the new "Deflate64" format introduced by PKWare?
No. PKWare has apparently decided to keep that format proprietary, since
they have not documented it as they have previous compression formats.
In any case, the compression improvements are so modest compared to other
more modern approaches, that it's not worth the effort to implement.
-40. Can you please sign these lengthy legal documents and fax them back to us
+41. Can you please sign these lengthy legal documents and fax them back to us
so that we can use your software in our product?
No. Go away. Shoo.
diff --git a/zlib/README b/zlib/README
index df95ae13f54..758cc50020d 100644
--- a/zlib/README
+++ b/zlib/README
@@ -1,6 +1,6 @@
ZLIB DATA COMPRESSION LIBRARY
-zlib 1.2.2 is a general purpose data compression library. All the code is
+zlib 1.2.3 is a general purpose data compression library. All the code is
thread safe. The data format used by the zlib library is described by RFCs
(Request for Comments) 1950 to 1952 in the files
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
@@ -16,9 +16,8 @@ minigzip.c.
To compile all files and run the test program, follow the instructions given at
the top of Makefile. In short "make test; make install" should work for most
-machines. For Unix: "./configure; make test; make install" For MSDOS, use one
-of the special makefiles such as Makefile.msc. For VMS, use Make_vms.com or
-descrip.mms.
+machines. For Unix: "./configure; make test; make install". For MSDOS, use one
+of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
<info@winimage.com> for the Windows DLL version. The zlib home page is
@@ -34,7 +33,7 @@ Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
issue of Dr. Dobb's Journal; a copy of the article is available in
http://dogma.net/markn/articles/zlibtool/zlibtool.htm
-The changes made in version 1.2.2 are documented in the file ChangeLog.
+The changes made in version 1.2.3 are documented in the file ChangeLog.
Unsupported third party contributions are provided in directory "contrib".
diff --git a/zlib/README.MySQL b/zlib/README.MySQL
new file mode 100644
index 00000000000..355dfb62d71
--- /dev/null
+++ b/zlib/README.MySQL
@@ -0,0 +1,7 @@
+This an incomplete version of the zlib library -- it excludes some of the
+platform-specific project files, contributed code, and examples from the
+original zlib distribution. You can find the original distribution at
+
+ http://www.gzip.org/zlib/
+ or
+ http://www.zlib.net/
diff --git a/zlib/adler32.c b/zlib/adler32.c
index 624a1696eb0..007ba26277c 100644
--- a/zlib/adler32.c
+++ b/zlib/adler32.c
@@ -1,5 +1,5 @@
/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -12,12 +12,13 @@
#define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
+#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8);
+/* use NO_DIVIDE if your processor does not do division in hardware */
#ifdef NO_DIVIDE
# define MOD(a) \
do { \
@@ -39,8 +40,17 @@
if (a >= (BASE << 1)) a -= (BASE << 1); \
if (a >= BASE) a -= BASE; \
} while (0)
+# define MOD4(a) \
+ do { \
+ if (a >= (BASE << 4)) a -= (BASE << 4); \
+ if (a >= (BASE << 3)) a -= (BASE << 3); \
+ if (a >= (BASE << 2)) a -= (BASE << 2); \
+ if (a >= (BASE << 1)) a -= (BASE << 1); \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
#else
# define MOD(a) a %= BASE
+# define MOD4(a) a %= BASE
#endif
/* ========================================================================= */
@@ -49,26 +59,91 @@ uLong ZEXPORT adler32(adler, buf, len)
const Bytef *buf;
uInt len;
{
- unsigned long s1 = adler & 0xffff;
- unsigned long s2 = (adler >> 16) & 0xffff;
- int k;
+ unsigned long sum2;
+ unsigned n;
+
+ /* split Adler-32 into component sums */
+ sum2 = (adler >> 16) & 0xffff;
+ adler &= 0xffff;
+
+ /* in case user likes doing a byte at a time, keep it fast */
+ if (len == 1) {
+ adler += buf[0];
+ if (adler >= BASE)
+ adler -= BASE;
+ sum2 += adler;
+ if (sum2 >= BASE)
+ sum2 -= BASE;
+ return adler | (sum2 << 16);
+ }
- if (buf == Z_NULL) return 1L;
+ /* initial Adler-32 value (deferred check for len == 1 speed) */
+ if (buf == Z_NULL)
+ return 1L;
- while (len > 0) {
- k = len < NMAX ? (int)len : NMAX;
- len -= k;
- while (k >= 16) {
+ /* in case short lengths are provided, keep it somewhat fast */
+ if (len < 16) {
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ if (adler >= BASE)
+ adler -= BASE;
+ MOD4(sum2); /* only added so many BASE's */
+ return adler | (sum2 << 16);
+ }
+
+ /* do length NMAX blocks -- requires just one modulo operation */
+ while (len >= NMAX) {
+ len -= NMAX;
+ n = NMAX / 16; /* NMAX is divisible by 16 */
+ do {
+ DO16(buf); /* 16 sums unrolled */
+ buf += 16;
+ } while (--n);
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* do remaining bytes (less than NMAX, still just one modulo) */
+ if (len) { /* avoid modulos if none remaining */
+ while (len >= 16) {
+ len -= 16;
DO16(buf);
buf += 16;
- k -= 16;
}
- if (k != 0) do {
- s1 += *buf++;
- s2 += s1;
- } while (--k);
- MOD(s1);
- MOD(s2);
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ MOD(adler);
+ MOD(sum2);
}
- return (s2 << 16) | s1;
+
+ /* return recombined sums */
+ return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off_t len2;
+{
+ unsigned long sum1;
+ unsigned long sum2;
+ unsigned rem;
+
+ /* the derivation of this formula is left as an exercise for the reader */
+ rem = (unsigned)(len2 % BASE);
+ sum1 = adler1 & 0xffff;
+ sum2 = rem * sum1;
+ MOD(sum2);
+ sum1 += (adler2 & 0xffff) + BASE - 1;
+ sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+ if (sum1 > BASE) sum1 -= BASE;
+ if (sum1 > BASE) sum1 -= BASE;
+ if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
+ if (sum2 > BASE) sum2 -= BASE;
+ return sum1 | (sum2 << 16);
}
diff --git a/zlib/compress.c b/zlib/compress.c
index 24ef0291911..df04f0148e6 100644
--- a/zlib/compress.c
+++ b/zlib/compress.c
@@ -1,5 +1,5 @@
/* compress.c -- compress a memory buffer
- * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
diff --git a/zlib/crc32.c b/zlib/crc32.c
index b39c7e1253e..f658a9ef55e 100644
--- a/zlib/crc32.c
+++ b/zlib/crc32.c
@@ -1,12 +1,12 @@
/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
* CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
* tables for updating the shift register in one step with three exclusive-ors
- * instead of four steps with four exclusive-ors. This results about a factor
- * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ * instead of four steps with four exclusive-ors. This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
*/
/* @(#) $Id$ */
@@ -64,6 +64,11 @@
# define TBLS 1
#endif /* BYFOUR */
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+ unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+
#ifdef DYNAMIC_CRC_TABLE
local volatile int crc_table_empty = 1;
@@ -72,7 +77,6 @@ local void make_crc_table OF((void));
#ifdef MAKECRCH
local void write_table OF((FILE *, const unsigned long FAR *));
#endif /* MAKECRCH */
-
/*
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
@@ -270,7 +274,7 @@ local unsigned long crc32_little(crc, buf, len)
len--;
}
- buf4 = (const u4 FAR *)buf;
+ buf4 = (const u4 FAR *)(const void FAR *)buf;
while (len >= 32) {
DOLIT32;
len -= 32;
@@ -310,7 +314,7 @@ local unsigned long crc32_big(crc, buf, len)
len--;
}
- buf4 = (const u4 FAR *)buf;
+ buf4 = (const u4 FAR *)(const void FAR *)buf;
buf4--;
while (len >= 32) {
DOBIG32;
@@ -331,3 +335,89 @@ local unsigned long crc32_big(crc, buf, len)
}
#endif /* BYFOUR */
+
+#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+ unsigned long *mat;
+ unsigned long vec;
+{
+ unsigned long sum;
+
+ sum = 0;
+ while (vec) {
+ if (vec & 1)
+ sum ^= *mat;
+ vec >>= 1;
+ mat++;
+ }
+ return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+ unsigned long *square;
+ unsigned long *mat;
+{
+ int n;
+
+ for (n = 0; n < GF2_DIM; n++)
+ square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off_t len2;
+{
+ int n;
+ unsigned long row;
+ unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
+ unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
+
+ /* degenerate case */
+ if (len2 == 0)
+ return crc1;
+
+ /* put operator for one zero bit in odd */
+ odd[0] = 0xedb88320L; /* CRC-32 polynomial */
+ row = 1;
+ for (n = 1; n < GF2_DIM; n++) {
+ odd[n] = row;
+ row <<= 1;
+ }
+
+ /* put operator for two zero bits in even */
+ gf2_matrix_square(even, odd);
+
+ /* put operator for four zero bits in odd */
+ gf2_matrix_square(odd, even);
+
+ /* apply len2 zeros to crc1 (first square will put the operator for one
+ zero byte, eight zero bits, in even) */
+ do {
+ /* apply zeros operator for this bit of len2 */
+ gf2_matrix_square(even, odd);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(even, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ if (len2 == 0)
+ break;
+
+ /* another iteration of the loop with odd and even swapped */
+ gf2_matrix_square(odd, even);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(odd, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ } while (len2 != 0);
+
+ /* return combined crc */
+ crc1 ^= crc2;
+ return crc1;
+}
diff --git a/zlib/deflate.c b/zlib/deflate.c
index 0fc53bc1e82..29ce1f64a57 100644
--- a/zlib/deflate.c
+++ b/zlib/deflate.c
@@ -1,5 +1,5 @@
/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -52,7 +52,7 @@
#include "deflate.h"
const char deflate_copyright[] =
- " deflate 1.2.2 Copyright 1995-2004 Jean-loup Gailly ";
+ " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
@@ -264,7 +264,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
#endif
if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
- strategy < 0 || strategy > Z_RLE) {
+ strategy < 0 || strategy > Z_FIXED) {
return Z_STREAM_ERROR;
}
if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
@@ -274,6 +274,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
s->strm = strm;
s->wrap = wrap;
+ s->gzhead = Z_NULL;
s->w_bits = windowBits;
s->w_size = 1 << s->w_bits;
s->w_mask = s->w_size - 1;
@@ -333,9 +334,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
if (length < MIN_MATCH) return Z_OK;
if (length > MAX_DIST(s)) {
length = MAX_DIST(s);
-#ifndef USE_DICT_HEAD
dictionary += dictLength - length; /* use the tail of the dictionary */
-#endif
}
zmemcpy(s->window, dictionary, length);
s->strstart = length;
@@ -391,6 +390,17 @@ int ZEXPORT deflateReset (strm)
}
/* ========================================================================= */
+int ZEXPORT deflateSetHeader (strm, head)
+ z_streamp strm;
+ gz_headerp head;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (strm->state->wrap != 2) return Z_STREAM_ERROR;
+ strm->state->gzhead = head;
+ return Z_OK;
+}
+
+/* ========================================================================= */
int ZEXPORT deflatePrime (strm, bits, value)
z_streamp strm;
int bits;
@@ -420,7 +430,7 @@ int ZEXPORT deflateParams(strm, level, strategy)
#else
if (level == Z_DEFAULT_COMPRESSION) level = 6;
#endif
- if (level < 0 || level > 9 || strategy < 0 || strategy > Z_RLE) {
+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
return Z_STREAM_ERROR;
}
func = configuration_table[s->level].func;
@@ -440,6 +450,25 @@ int ZEXPORT deflateParams(strm, level, strategy)
return err;
}
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+ z_streamp strm;
+ int good_length;
+ int max_lazy;
+ int nice_length;
+ int max_chain;
+{
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+ s->good_match = good_length;
+ s->max_lazy_match = max_lazy;
+ s->nice_match = nice_length;
+ s->max_chain_length = max_chain;
+ return Z_OK;
+}
+
/* =========================================================================
* For the default windowBits of 15 and memLevel of 8, this function returns
* a close to exact, as well as small, upper bound on the compressed size.
@@ -548,20 +577,47 @@ int ZEXPORT deflate (strm, flush)
if (s->status == INIT_STATE) {
#ifdef GZIP
if (s->wrap == 2) {
+ strm->adler = crc32(0L, Z_NULL, 0);
put_byte(s, 31);
put_byte(s, 139);
put_byte(s, 8);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, 255);
- s->status = BUSY_STATE;
- strm->adler = crc32(0L, Z_NULL, 0);
+ if (s->gzhead == NULL) {
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, OS_CODE);
+ s->status = BUSY_STATE;
+ }
+ else {
+ put_byte(s, (s->gzhead->text ? 1 : 0) +
+ (s->gzhead->hcrc ? 2 : 0) +
+ (s->gzhead->extra == Z_NULL ? 0 : 4) +
+ (s->gzhead->name == Z_NULL ? 0 : 8) +
+ (s->gzhead->comment == Z_NULL ? 0 : 16)
+ );
+ put_byte(s, (Byte)(s->gzhead->time & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, s->gzhead->os & 0xff);
+ if (s->gzhead->extra != NULL) {
+ put_byte(s, s->gzhead->extra_len & 0xff);
+ put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+ }
+ if (s->gzhead->hcrc)
+ strm->adler = crc32(strm->adler, s->pending_buf,
+ s->pending);
+ s->gzindex = 0;
+ s->status = EXTRA_STATE;
+ }
}
else
#endif
@@ -592,6 +648,110 @@ int ZEXPORT deflate (strm, flush)
strm->adler = adler32(0L, Z_NULL, 0);
}
}
+#ifdef GZIP
+ if (s->status == EXTRA_STATE) {
+ if (s->gzhead->extra != NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+
+ while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size)
+ break;
+ }
+ put_byte(s, s->gzhead->extra[s->gzindex]);
+ s->gzindex++;
+ }
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (s->gzindex == s->gzhead->extra_len) {
+ s->gzindex = 0;
+ s->status = NAME_STATE;
+ }
+ }
+ else
+ s->status = NAME_STATE;
+ }
+ if (s->status == NAME_STATE) {
+ if (s->gzhead->name != NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+ int val;
+
+ do {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size) {
+ val = 1;
+ break;
+ }
+ }
+ val = s->gzhead->name[s->gzindex++];
+ put_byte(s, val);
+ } while (val != 0);
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (val == 0) {
+ s->gzindex = 0;
+ s->status = COMMENT_STATE;
+ }
+ }
+ else
+ s->status = COMMENT_STATE;
+ }
+ if (s->status == COMMENT_STATE) {
+ if (s->gzhead->comment != NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+ int val;
+
+ do {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size) {
+ val = 1;
+ break;
+ }
+ }
+ val = s->gzhead->comment[s->gzindex++];
+ put_byte(s, val);
+ } while (val != 0);
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (val == 0)
+ s->status = HCRC_STATE;
+ }
+ else
+ s->status = HCRC_STATE;
+ }
+ if (s->status == HCRC_STATE) {
+ if (s->gzhead->hcrc) {
+ if (s->pending + 2 > s->pending_buf_size)
+ flush_pending(strm);
+ if (s->pending + 2 <= s->pending_buf_size) {
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ strm->adler = crc32(0L, Z_NULL, 0);
+ s->status = BUSY_STATE;
+ }
+ }
+ else
+ s->status = BUSY_STATE;
+ }
+#endif
/* Flush as much pending output as possible */
if (s->pending != 0) {
@@ -704,7 +864,12 @@ int ZEXPORT deflateEnd (strm)
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
status = strm->state->status;
- if (status != INIT_STATE && status != BUSY_STATE &&
+ if (status != INIT_STATE &&
+ status != EXTRA_STATE &&
+ status != NAME_STATE &&
+ status != COMMENT_STATE &&
+ status != HCRC_STATE &&
+ status != BUSY_STATE &&
status != FINISH_STATE) {
return Z_STREAM_ERROR;
}
@@ -744,12 +909,12 @@ int ZEXPORT deflateCopy (dest, source)
ss = source->state;
- *dest = *source;
+ zmemcpy(dest, source, sizeof(z_stream));
ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
if (ds == Z_NULL) return Z_MEM_ERROR;
dest->state = (struct internal_state FAR *) ds;
- *ds = *ss;
+ zmemcpy(ds, ss, sizeof(deflate_state));
ds->strm = dest;
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
@@ -838,9 +1003,11 @@ local void lm_init (s)
s->match_length = s->prev_length = MIN_MATCH-1;
s->match_available = 0;
s->ins_h = 0;
+#ifndef FASTEST
#ifdef ASMV
match_init(); /* initialize the asm code */
#endif
+#endif
}
#ifndef FASTEST
@@ -909,7 +1076,12 @@ local uInt longest_match(s, cur_match)
match = s->window + cur_match;
/* Skip to next match if the match length cannot increase
- * or if the match length is less than 2:
+ * or if the match length is less than 2. Note that the checks below
+ * for insufficient lookahead only occur occasionally for performance
+ * reasons. Therefore uninitialized memory will be accessed, and
+ * conditional jumps will be made that depend on those values.
+ * However the length of the match is limited to the lookahead, so
+ * the output of deflate is not affected by the uninitialized values.
*/
#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
/* This code assumes sizeof(unsigned short) == 2. Do not use
@@ -1131,6 +1303,7 @@ local void fill_window(s)
later. (Using level 0 permanently is not an optimal usage of
zlib, so we don't care about this pathological case.)
*/
+ /* %%% avoid this when Z_RLE */
n = s->hash_size;
p = &s->head[n];
do {
@@ -1309,12 +1482,12 @@ local block_state deflate_fast(s, flush)
* of the string with itself at the start of the input file).
*/
#ifdef FASTEST
- if ((s->strategy < Z_HUFFMAN_ONLY) ||
+ if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
(s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
s->match_length = longest_match_fast (s, hash_head);
}
#else
- if (s->strategy < Z_HUFFMAN_ONLY) {
+ if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
s->match_length = longest_match (s, hash_head);
} else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
s->match_length = longest_match_fast (s, hash_head);
@@ -1418,7 +1591,7 @@ local block_state deflate_slow(s, flush)
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
- if (s->strategy < Z_HUFFMAN_ONLY) {
+ if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
s->match_length = longest_match (s, hash_head);
} else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
s->match_length = longest_match_fast (s, hash_head);
@@ -1500,3 +1673,64 @@ local block_state deflate_slow(s, flush)
return flush == Z_FINISH ? finish_done : block_done;
}
#endif /* FASTEST */
+
+#if 0
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one. Do not maintain a hash table. (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ int bflush; /* set if current block must be flushed */
+ uInt run; /* length of run */
+ uInt max; /* maximum length of run */
+ uInt prev; /* byte at distance one to match */
+ Bytef *scan; /* scan for end of run */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the longest encodable run.
+ */
+ if (s->lookahead < MAX_MATCH) {
+ fill_window(s);
+ if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* See how many times the previous byte repeats */
+ run = 0;
+ if (s->strstart > 0) { /* if there is a previous byte, that is */
+ max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
+ scan = s->window + s->strstart - 1;
+ prev = *scan++;
+ do {
+ if (*scan++ != prev)
+ break;
+ } while (++run < max);
+ }
+
+ /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+ if (run >= MIN_MATCH) {
+ check_match(s, s->strstart, s->strstart - 1, run);
+ _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
+ s->lookahead -= run;
+ s->strstart += run;
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif
diff --git a/zlib/deflate.h b/zlib/deflate.h
index 410681d18a4..05a5ab3a2c1 100644
--- a/zlib/deflate.h
+++ b/zlib/deflate.h
@@ -1,5 +1,5 @@
/* deflate.h -- internal compression state
- * Copyright (C) 1995-2002 Jean-loup Gailly
+ * Copyright (C) 1995-2004 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -49,6 +49,10 @@
/* All codes must not exceed MAX_BITS bits */
#define INIT_STATE 42
+#define EXTRA_STATE 69
+#define NAME_STATE 73
+#define COMMENT_STATE 91
+#define HCRC_STATE 103
#define BUSY_STATE 113
#define FINISH_STATE 666
/* Stream status */
@@ -93,8 +97,10 @@ typedef struct internal_state {
Bytef *pending_buf; /* output still pending */
ulg pending_buf_size; /* size of pending_buf */
Bytef *pending_out; /* next pending byte to output to the stream */
- int pending; /* nb of bytes in the pending buffer */
+ uInt pending; /* nb of bytes in the pending buffer */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ gz_headerp gzhead; /* gzip header information to write */
+ uInt gzindex; /* where in extra, name, or comment */
Byte method; /* STORED (for zip only) or DEFLATED */
int last_flush; /* value of flush param for previous deflate call */
diff --git a/zlib/gzio.c b/zlib/gzio.c
index 5e71b0ab3ae..7e90f4928fc 100644
--- a/zlib/gzio.c
+++ b/zlib/gzio.c
@@ -1,5 +1,5 @@
/* gzio.c -- IO on .gz files
- * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*
* Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
@@ -11,7 +11,7 @@
#include "zutil.h"
-#ifdef NO_DEFLATE /* for compatiblity with old definition */
+#ifdef NO_DEFLATE /* for compatibility with old definition */
# define NO_GZCOMPRESS
#endif
@@ -220,7 +220,7 @@ gzFile ZEXPORT gzdopen (fd, mode)
int fd;
const char *mode;
{
- char name[20];
+ char name[46]; /* allow for up to 128-bit integers */
if (fd < 0) return (gzFile)Z_NULL;
sprintf(name, "<fd:%d>", fd); /* for debugging */
@@ -264,7 +264,7 @@ local int get_byte(s)
if (s->z_eof) return EOF;
if (s->stream.avail_in == 0) {
errno = 0;
- s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+ s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) {
s->z_eof = 1;
if (ferror(s->file)) s->z_err = Z_ERRNO;
@@ -300,7 +300,7 @@ local void check_header(s)
if (len < 2) {
if (len) s->inbuf[0] = s->stream.next_in[0];
errno = 0;
- len = fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
+ len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
s->stream.avail_in += len;
s->stream.next_in = s->inbuf;
@@ -415,6 +415,7 @@ int ZEXPORT gzread (file, buf, len)
s->stream.avail_out--;
s->back = EOF;
s->out++;
+ start++;
if (s->last) {
s->z_err = Z_STREAM_END;
return 1;
@@ -436,8 +437,8 @@ int ZEXPORT gzread (file, buf, len)
s->stream.avail_in -= n;
}
if (s->stream.avail_out > 0) {
- s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
- s->file);
+ s->stream.avail_out -=
+ (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
}
len -= s->stream.avail_out;
s->in += len;
@@ -448,17 +449,13 @@ int ZEXPORT gzread (file, buf, len)
if (s->stream.avail_in == 0 && !s->z_eof) {
errno = 0;
- s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+ s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) {
s->z_eof = 1;
if (ferror(s->file)) {
s->z_err = Z_ERRNO;
break;
}
- if (feof(s->file)) { /* avoid error for empty file */
- s->z_err = Z_STREAM_END;
- break;
- }
}
s->stream.next_in = s->inbuf;
}
@@ -492,6 +489,9 @@ int ZEXPORT gzread (file, buf, len)
}
s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+ if (len == s->stream.avail_out &&
+ (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
+ return -1;
return (int)(len - s->stream.avail_out);
}
@@ -903,6 +903,18 @@ int ZEXPORT gzeof (file)
}
/* ===========================================================================
+ Returns 1 if reading and doing so transparently, otherwise zero.
+*/
+int ZEXPORT gzdirect (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'r') return 0;
+ return s->transparent;
+}
+
+/* ===========================================================================
Outputs a long in LSB order to the given file
*/
local void putLong (file, x)
@@ -941,7 +953,6 @@ local uLong getLong (s)
int ZEXPORT gzclose (file)
gzFile file;
{
- int err;
gz_stream *s = (gz_stream*)file;
if (s == NULL) return Z_STREAM_ERROR;
@@ -950,8 +961,8 @@ int ZEXPORT gzclose (file)
#ifdef NO_GZCOMPRESS
return Z_STREAM_ERROR;
#else
- err = do_flush (file, Z_FINISH);
- if (err != Z_OK) return destroy((gz_stream*)file);
+ if (do_flush (file, Z_FINISH) != Z_OK)
+ return destroy((gz_stream*)file);
putLong (s->file, s->crc);
putLong (s->file, (uLong)(s->in & 0xffffffff));
@@ -960,10 +971,16 @@ int ZEXPORT gzclose (file)
return destroy((gz_stream*)file);
}
+#ifdef STDC
+# define zstrerror(errnum) strerror(errnum)
+#else
+# define zstrerror(errnum) ""
+#endif
+
/* ===========================================================================
- Returns the error message for the last error which occured on the
+ Returns the error message for the last error which occurred on the
given compressed file. errnum is set to zlib error number. If an
- error occured in the file system and not in the compression library,
+ error occurred in the file system and not in the compression library,
errnum is set to Z_ERRNO and the application may consult errno
to get the exact error code.
*/
diff --git a/zlib/infback.c b/zlib/infback.c
index 262f97c73ac..455dbc9ee84 100644
--- a/zlib/infback.c
+++ b/zlib/infback.c
@@ -1,5 +1,5 @@
/* infback.c -- inflate using a call-back interface
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -26,7 +26,7 @@ local void fixedtables OF((struct inflate_state FAR *state));
window and output buffer that is 2**windowBits bytes.
*/
int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
-z_stream FAR *strm;
+z_streamp strm;
int windowBits;
unsigned char FAR *window;
const char *version;
@@ -50,7 +50,8 @@ int stream_size;
sizeof(struct inflate_state));
if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n"));
- strm->state = (voidpf)state;
+ strm->state = (struct internal_state FAR *)state;
+ state->dmax = 32768U;
state->wbits = windowBits;
state->wsize = 1U << windowBits;
state->window = window;
@@ -238,7 +239,7 @@ struct inflate_state FAR *state;
are not correct, i.e. strm is Z_NULL or the state was not initialized.
*/
int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
-z_stream FAR *strm;
+z_streamp strm;
in_func in;
void FAR *in_desc;
out_func out;
@@ -611,7 +612,7 @@ void FAR *out_desc;
}
int ZEXPORT inflateBackEnd(strm)
-z_stream FAR *strm;
+z_streamp strm;
{
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
return Z_STREAM_ERROR;
diff --git a/zlib/inffast.c b/zlib/inffast.c
index 8c02a178d04..bbee92ed1e6 100644
--- a/zlib/inffast.c
+++ b/zlib/inffast.c
@@ -74,6 +74,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
unsigned char FAR *out; /* local strm->next_out */
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
unsigned char FAR *end; /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+ unsigned dmax; /* maximum distance from zlib header */
+#endif
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned write; /* window write index */
@@ -98,6 +101,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
out = strm->next_out - OFF;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+ dmax = state->dmax;
+#endif
wsize = state->wsize;
whave = state->whave;
write = state->write;
@@ -167,6 +173,13 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
}
}
dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+ if (dist > dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
hold >>= op;
bits -= op;
Tracevv((stderr, "inflate: distance %u\n", dist));
diff --git a/zlib/inflate.c b/zlib/inflate.c
index c6d38266d07..792fdee8e9c 100644
--- a/zlib/inflate.c
+++ b/zlib/inflate.c
@@ -1,5 +1,5 @@
/* inflate.c -- zlib decompression
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -113,8 +113,11 @@ z_streamp strm;
state->mode = HEAD;
state->last = 0;
state->havedict = 0;
+ state->dmax = 32768U;
+ state->head = Z_NULL;
state->wsize = 0;
state->whave = 0;
+ state->write = 0;
state->hold = 0;
state->bits = 0;
state->lencode = state->distcode = state->next = state->codes;
@@ -122,6 +125,22 @@ z_streamp strm;
return Z_OK;
}
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
+ value &= (1L << bits) - 1;
+ state->hold += value << state->bits;
+ state->bits += bits;
+ return Z_OK;
+}
+
int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
z_streamp strm;
int windowBits;
@@ -144,7 +163,7 @@ int stream_size;
ZALLOC(strm, 1, sizeof(struct inflate_state));
if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n"));
- strm->state = (voidpf)state;
+ strm->state = (struct internal_state FAR *)state;
if (windowBits < 0) {
state->wrap = 0;
windowBits = -windowBits;
@@ -582,6 +601,8 @@ int flush;
break;
}
state->flags = 0; /* expect zlib header */
+ if (state->head != Z_NULL)
+ state->head->done = -1;
if (!(state->wrap & 1) || /* check if zlib header allowed */
#else
if (
@@ -597,11 +618,13 @@ int flush;
break;
}
DROPBITS(4);
- if (BITS(4) + 8 > state->wbits) {
+ len = BITS(4) + 8;
+ if (len > state->wbits) {
strm->msg = (char *)"invalid window size";
state->mode = BAD;
break;
}
+ state->dmax = 1U << len;
Tracev((stderr, "inflate: zlib header ok\n"));
strm->adler = state->check = adler32(0L, Z_NULL, 0);
state->mode = hold & 0x200 ? DICTID : TYPE;
@@ -621,16 +644,24 @@ int flush;
state->mode = BAD;
break;
}
+ if (state->head != Z_NULL)
+ state->head->text = (int)((hold >> 8) & 1);
if (state->flags & 0x0200) CRC2(state->check, hold);
INITBITS();
state->mode = TIME;
case TIME:
NEEDBITS(32);
+ if (state->head != Z_NULL)
+ state->head->time = hold;
if (state->flags & 0x0200) CRC4(state->check, hold);
INITBITS();
state->mode = OS;
case OS:
NEEDBITS(16);
+ if (state->head != Z_NULL) {
+ state->head->xflags = (int)(hold & 0xff);
+ state->head->os = (int)(hold >> 8);
+ }
if (state->flags & 0x0200) CRC2(state->check, hold);
INITBITS();
state->mode = EXLEN;
@@ -638,15 +669,26 @@ int flush;
if (state->flags & 0x0400) {
NEEDBITS(16);
state->length = (unsigned)(hold);
+ if (state->head != Z_NULL)
+ state->head->extra_len = (unsigned)hold;
if (state->flags & 0x0200) CRC2(state->check, hold);
INITBITS();
}
+ else if (state->head != Z_NULL)
+ state->head->extra = Z_NULL;
state->mode = EXTRA;
case EXTRA:
if (state->flags & 0x0400) {
copy = state->length;
if (copy > have) copy = have;
if (copy) {
+ if (state->head != Z_NULL &&
+ state->head->extra != Z_NULL) {
+ len = state->head->extra_len - state->length;
+ zmemcpy(state->head->extra + len, next,
+ len + copy > state->head->extra_max ?
+ state->head->extra_max - len : copy);
+ }
if (state->flags & 0x0200)
state->check = crc32(state->check, next, copy);
have -= copy;
@@ -655,6 +697,7 @@ int flush;
}
if (state->length) goto inf_leave;
}
+ state->length = 0;
state->mode = NAME;
case NAME:
if (state->flags & 0x0800) {
@@ -662,13 +705,20 @@ int flush;
copy = 0;
do {
len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->name != Z_NULL &&
+ state->length < state->head->name_max)
+ state->head->name[state->length++] = len;
} while (len && copy < have);
- if (state->flags & 0x02000)
+ if (state->flags & 0x0200)
state->check = crc32(state->check, next, copy);
have -= copy;
next += copy;
if (len) goto inf_leave;
}
+ else if (state->head != Z_NULL)
+ state->head->name = Z_NULL;
+ state->length = 0;
state->mode = COMMENT;
case COMMENT:
if (state->flags & 0x1000) {
@@ -676,13 +726,19 @@ int flush;
copy = 0;
do {
len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->comment != Z_NULL &&
+ state->length < state->head->comm_max)
+ state->head->comment[state->length++] = len;
} while (len && copy < have);
- if (state->flags & 0x02000)
+ if (state->flags & 0x0200)
state->check = crc32(state->check, next, copy);
have -= copy;
next += copy;
if (len) goto inf_leave;
}
+ else if (state->head != Z_NULL)
+ state->head->comment = Z_NULL;
state->mode = HCRC;
case HCRC:
if (state->flags & 0x0200) {
@@ -694,6 +750,10 @@ int flush;
}
INITBITS();
}
+ if (state->head != Z_NULL) {
+ state->head->hcrc = (int)((state->flags >> 9) & 1);
+ state->head->done = 1;
+ }
strm->adler = state->check = crc32(0L, Z_NULL, 0);
state->mode = TYPE;
break;
@@ -969,6 +1029,13 @@ int flush;
state->offset += BITS(state->extra);
DROPBITS(state->extra);
}
+#ifdef INFLATE_STRICT
+ if (state->offset > state->dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
if (state->offset > state->whave + out - left) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
@@ -1110,12 +1177,16 @@ uInt dictLength;
/* check state */
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
- if (state->mode != DICT) return Z_STREAM_ERROR;
+ if (state->wrap != 0 && state->mode != DICT)
+ return Z_STREAM_ERROR;
/* check for correct dictionary id */
- id = adler32(0L, Z_NULL, 0);
- id = adler32(id, dictionary, dictLength);
- if (id != state->check) return Z_DATA_ERROR;
+ if (state->mode == DICT) {
+ id = adler32(0L, Z_NULL, 0);
+ id = adler32(id, dictionary, dictLength);
+ if (id != state->check)
+ return Z_DATA_ERROR;
+ }
/* copy dictionary to window */
if (updatewindow(strm, strm->avail_out)) {
@@ -1137,6 +1208,23 @@ uInt dictLength;
return Z_OK;
}
+int ZEXPORT inflateGetHeader(strm, head)
+z_streamp strm;
+gz_headerp head;
+{
+ struct inflate_state FAR *state;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+ /* save header structure */
+ state->head = head;
+ head->done = 0;
+ return Z_OK;
+}
+
/*
Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
or when out of input. When called, *have is the number of pattern bytes
@@ -1239,6 +1327,7 @@ z_streamp source;
struct inflate_state FAR *state;
struct inflate_state FAR *copy;
unsigned char FAR *window;
+ unsigned wsize;
/* check input */
if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
@@ -1261,14 +1350,19 @@ z_streamp source;
}
/* copy state */
- *dest = *source;
- *copy = *state;
- copy->lencode = copy->codes + (state->lencode - state->codes);
- copy->distcode = copy->codes + (state->distcode - state->codes);
+ zmemcpy(dest, source, sizeof(z_stream));
+ zmemcpy(copy, state, sizeof(struct inflate_state));
+ if (state->lencode >= state->codes &&
+ state->lencode <= state->codes + ENOUGH - 1) {
+ copy->lencode = copy->codes + (state->lencode - state->codes);
+ copy->distcode = copy->codes + (state->distcode - state->codes);
+ }
copy->next = copy->codes + (state->next - state->codes);
- if (window != Z_NULL)
- zmemcpy(window, state->window, 1U << state->wbits);
+ if (window != Z_NULL) {
+ wsize = 1U << state->wbits;
+ zmemcpy(window, state->window, wsize);
+ }
copy->window = window;
- dest->state = (voidpf)copy;
+ dest->state = (struct internal_state FAR *)copy;
return Z_OK;
}
diff --git a/zlib/inflate.h b/zlib/inflate.h
index 9a12c8fd296..07bd3e78a7c 100644
--- a/zlib/inflate.h
+++ b/zlib/inflate.h
@@ -1,5 +1,5 @@
/* inflate.h -- internal inflate state definition
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -19,7 +19,6 @@
/* Possible inflate modes between inflate() calls */
typedef enum {
HEAD, /* i: waiting for magic header */
-#ifdef GUNZIP
FLAGS, /* i: waiting for method and flags (gzip) */
TIME, /* i: waiting for modification time (gzip) */
OS, /* i: waiting for extra flags and operating system (gzip) */
@@ -28,7 +27,6 @@ typedef enum {
NAME, /* i: waiting for end of file name (gzip) */
COMMENT, /* i: waiting for end of comment (gzip) */
HCRC, /* i: waiting for header crc (gzip) */
-#endif
DICTID, /* i: waiting for dictionary check value */
DICT, /* waiting for inflateSetDictionary() call */
TYPE, /* i: waiting for type bits, including last-flag bit */
@@ -45,9 +43,7 @@ typedef enum {
MATCH, /* o: waiting for output space to copy string */
LIT, /* o: waiting for output space to write literal */
CHECK, /* i: waiting for 32-bit check value */
-#ifdef GUNZIP
LENGTH, /* i: waiting for 32-bit length (gzip) */
-#endif
DONE, /* finished check, done -- remain here until reset */
BAD, /* got a data error -- remain here until reset */
MEM, /* got an inflate() memory error -- remain here until reset */
@@ -84,8 +80,10 @@ struct inflate_state {
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
int havedict; /* true if dictionary provided */
int flags; /* gzip header method and flags (0 if zlib) */
+ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
unsigned long check; /* protected copy of check value */
unsigned long total; /* protected copy of output count */
+ gz_headerp head; /* where to save gzip header information */
/* sliding window */
unsigned wbits; /* log base 2 of requested window size */
unsigned wsize; /* window size or zero if not using window */
diff --git a/zlib/inftrees.c b/zlib/inftrees.c
index 509461d9273..8a9c13ff03d 100644
--- a/zlib/inftrees.c
+++ b/zlib/inftrees.c
@@ -1,5 +1,5 @@
/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2004 Mark Adler
+ * Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -9,7 +9,7 @@
#define MAXBITS 15
const char inflate_copyright[] =
- " inflate 1.2.2 Copyright 1995-2004 Mark Adler ";
+ " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
@@ -62,7 +62,7 @@ unsigned short FAR *work;
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
- 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 198};
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
@@ -232,6 +232,7 @@ unsigned short FAR *work;
/* replicate for those indices with low len bits equal to huff */
incr = 1U << (len - drop);
fill = 1U << curr;
+ min = fill; /* save offset to next table */
do {
fill -= incr;
next[(huff >> drop) + fill] = this;
@@ -262,7 +263,7 @@ unsigned short FAR *work;
drop = root;
/* increment past last table */
- next += 1U << curr;
+ next += min; /* here min is 1 << curr */
/* determine length of next table */
curr = len - drop;
diff --git a/zlib/trees.c b/zlib/trees.c
index 52c820fa2e9..395e4e16814 100644
--- a/zlib/trees.c
+++ b/zlib/trees.c
@@ -1,5 +1,5 @@
/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2003 Jean-loup Gailly
+ * Copyright (C) 1995-2005 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -555,7 +555,7 @@ local void gen_bitlen(s, desc)
while (n != 0) {
m = s->heap[--h];
if (m > max_code) continue;
- if (tree[m].Len != (unsigned) bits) {
+ if ((unsigned) tree[m].Len != (unsigned) bits) {
Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
s->opt_len += ((long)bits - (long)tree[m].Len)
*(long)tree[m].Freq;
@@ -930,8 +930,9 @@ void _tr_flush_block(s, buf, stored_len, eof)
/* Build the Huffman trees unless a stored block is forced */
if (s->level > 0) {
- /* Check if the file is ascii or binary */
- if (s->strm->data_type == Z_UNKNOWN) set_data_type(s);
+ /* Check if the file is binary or text */
+ if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
+ set_data_type(s);
/* Construct the literal and distance trees */
build_tree(s, (tree_desc *)(&(s->l_desc)));
@@ -982,7 +983,7 @@ void _tr_flush_block(s, buf, stored_len, eof)
#ifdef FORCE_STATIC
} else if (static_lenb >= 0) { /* force static trees */
#else
- } else if (static_lenb == opt_lenb) {
+ } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
#endif
send_bits(s, (STATIC_TREES<<1)+eof, 3);
compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
@@ -1117,21 +1118,24 @@ local void compress_block(s, ltree, dtree)
}
/* ===========================================================================
- * Set the data type to ASCII or BINARY, using a crude approximation:
- * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
- * IN assertion: the fields freq of dyn_ltree are set and the total of all
- * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
+ * Set the data type to BINARY or TEXT, using a crude approximation:
+ * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
+ * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
+ * IN assertion: the fields Freq of dyn_ltree are set.
*/
local void set_data_type(s)
deflate_state *s;
{
- int n = 0;
- unsigned ascii_freq = 0;
- unsigned bin_freq = 0;
- while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
- while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
- while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
- s->strm->data_type = bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII;
+ int n;
+
+ for (n = 0; n < 9; n++)
+ if (s->dyn_ltree[n].Freq != 0)
+ break;
+ if (n == 9)
+ for (n = 14; n < 32; n++)
+ if (s->dyn_ltree[n].Freq != 0)
+ break;
+ s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
}
/* ===========================================================================
diff --git a/zlib/zconf.h b/zlib/zconf.h
index 3c21403fce6..03a9431c8be 100644
--- a/zlib/zconf.h
+++ b/zlib/zconf.h
@@ -1,5 +1,5 @@
/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -43,6 +43,10 @@
# define get_crc_table z_get_crc_table
# define zError z_zError
+# define alloc_func z_alloc_func
+# define free_func z_free_func
+# define in_func z_in_func
+# define out_func z_out_func
# define Byte z_Byte
# define uInt z_uInt
# define uLong z_uLong
@@ -64,8 +68,10 @@
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-# define WIN32
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
diff --git a/zlib/zlib.3 b/zlib/zlib.3
index 3139e2467f2..90b8162870f 100644
--- a/zlib/zlib.3
+++ b/zlib/zlib.3
@@ -1,4 +1,4 @@
-.TH ZLIB 3 "3 October 2004"
+.TH ZLIB 3 "18 July 2005"
.SH NAME
zlib \- compression/decompression library
.SH SYNOPSIS
@@ -133,8 +133,8 @@ before asking for help.
Send questions and/or comments to zlib@gzip.org,
or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
.SH AUTHORS
-Version 1.2.2
-Copyright (C) 1995-2004 Jean-loup Gailly (jloup@gzip.org)
+Version 1.2.3
+Copyright (C) 1995-2005 Jean-loup Gailly (jloup@gzip.org)
and Mark Adler (madler@alumni.caltech.edu).
.LP
This software is provided "as-is,"
diff --git a/zlib/zlib.h b/zlib/zlib.h
index b4ddd34395c..022817927ce 100644
--- a/zlib/zlib.h
+++ b/zlib/zlib.h
@@ -1,7 +1,7 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.2.2, October 3rd, 2004
+ version 1.2.3, July 18th, 2005
- Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
+ Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -37,8 +37,8 @@
extern "C" {
#endif
-#define ZLIB_VERSION "1.2.2"
-#define ZLIB_VERNUM 0x1220
+#define ZLIB_VERSION "1.2.3"
+#define ZLIB_VERNUM 0x1230
/*
The 'zlib' compression library provides in-memory compression and
@@ -95,7 +95,7 @@ typedef struct z_stream_s {
free_func zfree; /* used to free the internal state */
voidpf opaque; /* private data object passed to zalloc and zfree */
- int data_type; /* best guess about the data type: ascii or binary */
+ int data_type; /* best guess about the data type: binary or text */
uLong adler; /* adler32 value of the uncompressed data */
uLong reserved; /* reserved for future use */
} z_stream;
@@ -103,6 +103,29 @@ typedef struct z_stream_s {
typedef z_stream FAR *z_streamp;
/*
+ gzip header information passed to and from zlib routines. See RFC 1952
+ for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+ int text; /* true if compressed data believed to be text */
+ uLong time; /* modification time */
+ int xflags; /* extra flags (not used when writing a gzip file) */
+ int os; /* operating system */
+ Bytef *extra; /* pointer to extra field or Z_NULL if none */
+ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
+ uInt extra_max; /* space at extra (only when reading header) */
+ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
+ uInt name_max; /* space at name (only when reading header) */
+ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
+ uInt comm_max; /* space at comment (only when reading header) */
+ int hcrc; /* true if there was or will be a header crc */
+ int done; /* true when done reading gzip header (not used
+ when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
The application must update next_in and avail_in when avail_in has
dropped to zero. It must update next_out and avail_out when avail_out
has dropped to zero. The application must initialize zalloc, zfree and
@@ -166,11 +189,13 @@ typedef z_stream FAR *z_streamp;
#define Z_FILTERED 1
#define Z_HUFFMAN_ONLY 2
#define Z_RLE 3
+#define Z_FIXED 4
#define Z_DEFAULT_STRATEGY 0
/* compression strategy; see deflateInit2() below for details */
#define Z_BINARY 0
-#define Z_ASCII 1
+#define Z_TEXT 1
+#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
#define Z_UNKNOWN 2
/* Possible values of the data_type field (though see inflate()) */
@@ -244,6 +269,10 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
and with zero avail_out, it must be called again after making room in the
output buffer because there might be more output pending.
+ Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+ decide how much data to accumualte before producing output, in order to
+ maximize compression.
+
If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
flushed to the output buffer and the output is aligned on a byte boundary, so
that the decompressor can get all input data available so far. (In particular
@@ -255,7 +284,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
Z_SYNC_FLUSH, and the compression state is reset so that decompression can
restart from this point if previous compressed data has been damaged or if
random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
- the compression.
+ compression.
If deflate returns with avail_out == 0, this function must be called again
with the same value of the flush parameter and more output space (updated
@@ -280,8 +309,8 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
deflate() sets strm->adler to the adler32 checksum of all input read
so far (that is, total_in bytes).
- deflate() may update data_type if it can make a good guess about
- the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+ deflate() may update strm->data_type if it can make a good guess about
+ the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
binary. This field is only for information purposes and does not affect
the compression algorithm in any manner.
@@ -363,11 +392,11 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
output as possible to the output buffer. Z_BLOCK requests that inflate() stop
- if and when it get to the next deflate block boundary. When decoding the zlib
- or gzip format, this will cause inflate() to return immediately after the
- header and before the first block. When doing a raw inflate, inflate() will
- go ahead and process the first block, and will return when it gets to the end
- of that block, or when it runs out of data.
+ if and when it gets to the next deflate block boundary. When decoding the
+ zlib or gzip format, this will cause inflate() to return immediately after
+ the header and before the first block. When doing a raw inflate, inflate()
+ will go ahead and process the first block, and will return when it gets to
+ the end of that block, or when it runs out of data.
The Z_BLOCK option assists in appending to or combining deflate streams.
Also to assist in this, on return inflate() will set strm->data_type to the
@@ -496,7 +525,9 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
parameter only affects the compression ratio but not the correctness of the
- compressed output even if it is not set appropriately.
+ compressed output even if it is not set appropriately. Z_FIXED prevents the
+ use of dynamic Huffman codes, allowing for a simpler decoder for special
+ applications.
deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
@@ -525,7 +556,9 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
deflateInit or deflateInit2, a part of the dictionary may in effect be
discarded, for example if the dictionary is larger than the window size in
deflate or deflate2. Thus the strings most likely to be useful should be
- put at the end of the dictionary, not at the front.
+ put at the end of the dictionary, not at the front. In addition, the
+ current implementation of deflate will use at most the window size minus
+ 262 bytes of the provided dictionary.
Upon return of this function, strm->adler is set to the adler32 value
of the dictionary; the decompressor may later use this value to determine
@@ -591,6 +624,23 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
if strm->avail_out was zero.
*/
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+ int good_length,
+ int max_lazy,
+ int nice_length,
+ int max_chain));
+/*
+ Fine tune deflate's internal compression parameters. This should only be
+ used by someone who understands the algorithm used by zlib's deflate for
+ searching for the best matching string, and even then only by the most
+ fanatic optimizer trying to squeeze out the last compressed bit for their
+ specific input data. Read the deflate.c source code for the meaning of the
+ max_lazy, good_length, nice_length, and max_chain parameters.
+
+ deflateTune() can be called after deflateInit() or deflateInit2(), and
+ returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
uLong sourceLen));
/*
@@ -616,6 +666,30 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
stream state was inconsistent.
*/
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ deflateSetHeader() provides gzip header information for when a gzip
+ stream is requested by deflateInit2(). deflateSetHeader() may be called
+ after deflateInit2() or deflateReset() and before the first call of
+ deflate(). The text, time, os, extra field, name, and comment information
+ in the provided gz_header structure are written to the gzip header (xflag is
+ ignored -- the extra flags are set according to the compression level). The
+ caller must assure that, if not Z_NULL, name and comment are terminated with
+ a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+ available there. If hcrc is true, a gzip header crc is included. Note that
+ the current versions of the command-line version of gzip (up through version
+ 1.3.x) do not support header crc's, and will report that it is a "multi-part
+ gzip file" and give up.
+
+ If deflateSetHeader is not used, the default gzip header has text false,
+ the time set to zero, and os set to 255, with no extra, name, or comment
+ fields. The gzip header is returned to the default state by deflateReset().
+
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
/*
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
int windowBits));
@@ -648,15 +722,15 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
windowBits can also be greater than 15 for optional gzip decoding. Add
32 to windowBits to enable zlib and gzip decoding with automatic header
detection, or add 16 to decode only the gzip format (the zlib format will
- return a Z_DATA_ERROR. If a gzip stream is being decoded, strm->adler is
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
a crc32 instead of an adler32.
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
- memLevel). msg is set to null if there is no error message. inflateInit2
- does not perform any decompression apart from reading the zlib header if
- present: this will be done by inflate(). (So next_in and avail_in may be
- modified, but next_out and avail_out are unchanged.)
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
+ is set to null if there is no error message. inflateInit2 does not perform
+ any decompression apart from reading the zlib header if present: this will
+ be done by inflate(). (So next_in and avail_in may be modified, but next_out
+ and avail_out are unchanged.)
*/
ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
@@ -664,11 +738,14 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
uInt dictLength));
/*
Initializes the decompression dictionary from the given uncompressed byte
- sequence. This function must be called immediately after a call of inflate
- if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
- can be determined from the adler32 value returned by this call of
- inflate. The compressor and decompressor must use exactly the same
- dictionary (see deflateSetDictionary).
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the adler32 value returned by that call of inflate.
+ The compressor and decompressor must use exactly the same dictionary (see
+ deflateSetDictionary). For raw inflate, this function can be called
+ immediately after inflateInit2() or inflateReset() and before any call of
+ inflate() to set the dictionary. The application must insure that the
+ dictionary that was used for compression is provided.
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
parameter is invalid (such as NULL dictionary) or the stream state is
@@ -719,8 +796,64 @@ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
stream state was inconsistent (such as zalloc or state being NULL).
*/
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ This function inserts bits in the inflate input stream. The intent is
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ inflateGetHeader() requests that gzip header information be stored in the
+ provided gz_header structure. inflateGetHeader() may be called after
+ inflateInit2() or inflateReset(), and before the first call of inflate().
+ As inflate() processes the gzip stream, head->done is zero until the header
+ is completed, at which time head->done is set to one. If a zlib stream is
+ being decoded, then head->done is set to -1 to indicate that there will be
+ no gzip header information forthcoming. Note that Z_BLOCK can be used to
+ force inflate() to return immediately after header processing is complete
+ and before any actual data is decompressed.
+
+ The text, time, xflags, and os fields are filled in with the gzip header
+ contents. hcrc is set to true if there is a header CRC. (The header CRC
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ contains the maximum number of bytes to write to extra. Once done is true,
+ extra_len contains the actual extra field length, and extra contains the
+ extra field, or that field truncated if extra_max is less than extra_len.
+ If name is not Z_NULL, then up to name_max characters are written there,
+ terminated with a zero unless the length is greater than name_max. If
+ comment is not Z_NULL, then up to comm_max characters are written there,
+ terminated with a zero unless the length is greater than comm_max. When
+ any of extra, name, or comment are not Z_NULL and the respective field is
+ not present in the header, then that field is set to Z_NULL to signal its
+ absence. This allows the use of deflateSetHeader() with the returned
+ structure to duplicate the header. However if those fields are set to
+ allocated memory, then the application will need to save those pointers
+ elsewhere so that they can be eventually freed.
+
+ If inflateGetHeader is not used, then the header information is simply
+ discarded. The header is always checked for validity, including the header
+ CRC if present. inflateReset() will reset the process to discard the header
+ information. The application would need to call inflateGetHeader() again to
+ retrieve the header from the next gzip stream.
+
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
/*
-ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits,
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
unsigned char FAR *window));
Initialize the internal stream state for decompression using inflateBack()
@@ -744,7 +877,7 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits,
typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
-ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm,
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
in_func in, void FAR *in_desc,
out_func out, void FAR *out_desc));
/*
@@ -813,7 +946,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm,
that inflateBack() cannot return Z_OK.
*/
-ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm));
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
/*
All memory allocated by inflateBackInit() is freed.
@@ -1087,6 +1220,12 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
input stream, otherwise zero.
*/
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+ Returns 1 if file is being read directly without decompression, otherwise
+ zero.
+*/
+
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
/*
Flushes all pending output if necessary, closes the compressed file
@@ -1119,7 +1258,6 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
*/
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-
/*
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
return the updated checksum. If buf is NULL, this function returns
@@ -1135,12 +1273,21 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
if (adler != original_adler) error();
*/
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+ z_off_t len2));
+/*
+ Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
+ and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+ each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+*/
+
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
/*
- Update a running crc with the bytes buf[0..len-1] and return the updated
- crc. If buf is NULL, this function returns the required initial value
- for the crc. Pre- and post-conditioning (one's complement) is performed
- within this function so it shouldn't be done by the application.
+ Update a running CRC-32 with the bytes buf[0..len-1] and return the
+ updated CRC-32. If buf is NULL, this function returns the required initial
+ value for the for the crc. Pre- and post-conditioning (one's complement) is
+ performed within this function so it shouldn't be done by the application.
Usage example:
uLong crc = crc32(0L, Z_NULL, 0);
@@ -1151,6 +1298,16 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
if (crc != original_crc) error();
*/
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+/*
+ Combine two CRC-32 check values into one. For two sequences of bytes,
+ seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+ calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
+ check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+ len2.
+*/
+
/* various hacks, don't look :) */
@@ -1167,7 +1324,7 @@ ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
int stream_size));
ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits,
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
unsigned char FAR *window,
const char *version,
int stream_size));
diff --git a/zlib/zutil.c b/zlib/zutil.c
index 0ef4f99f57e..d55f5948a37 100644
--- a/zlib/zutil.c
+++ b/zlib/zutil.c
@@ -1,5 +1,5 @@
/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -11,10 +11,6 @@
struct internal_state {int dummy;}; /* for buggy compilers */
#endif
-#ifndef STDC
-extern void exit OF((int));
-#endif
-
const char * const z_errmsg[10] = {
"need dictionary", /* Z_NEED_DICT 2 */
"stream end", /* Z_STREAM_END 1 */
@@ -78,38 +74,38 @@ uLong ZEXPORT zlibCompileFlags()
flags += 1 << 13;
#endif
#ifdef NO_GZCOMPRESS
- flags += 1 << 16;
+ flags += 1L << 16;
#endif
#ifdef NO_GZIP
- flags += 1 << 17;
+ flags += 1L << 17;
#endif
#ifdef PKZIP_BUG_WORKAROUND
- flags += 1 << 20;
+ flags += 1L << 20;
#endif
#ifdef FASTEST
- flags += 1 << 21;
+ flags += 1L << 21;
#endif
#ifdef STDC
# ifdef NO_vsnprintf
- flags += 1 << 25;
+ flags += 1L << 25;
# ifdef HAS_vsprintf_void
- flags += 1 << 26;
+ flags += 1L << 26;
# endif
# else
# ifdef HAS_vsnprintf_void
- flags += 1 << 26;
+ flags += 1L << 26;
# endif
# endif
#else
- flags += 1 << 24;
+ flags += 1L << 24;
# ifdef NO_snprintf
- flags += 1 << 25;
+ flags += 1L << 25;
# ifdef HAS_sprintf_void
- flags += 1 << 26;
+ flags += 1L << 26;
# endif
# else
# ifdef HAS_snprintf_void
- flags += 1 << 26;
+ flags += 1L << 26;
# endif
# endif
#endif
@@ -141,7 +137,10 @@ const char * ZEXPORT zError(err)
}
#if defined(_WIN32_WCE)
- /* does not exist on WCE */
+ /* The Microsoft C Run-Time Library for Windows CE doesn't have
+ * errno. We define it as a global variable to simplify porting.
+ * Its value is always 0 and should not be used.
+ */
int errno = 0;
#endif
diff --git a/zlib/zutil.h b/zlib/zutil.h
index 7b42edcaa98..b7d5eff81b6 100644
--- a/zlib/zutil.h
+++ b/zlib/zutil.h
@@ -1,5 +1,5 @@
/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -17,14 +17,26 @@
#include "zlib.h"
#ifdef STDC
-# include <stddef.h>
+# ifndef _WIN32_WCE
+# include <stddef.h>
+# endif
# include <string.h>
# include <stdlib.h>
#endif
#ifdef NO_ERRNO_H
+# ifdef _WIN32_WCE
+ /* The Microsoft C Run-Time Library for Windows CE doesn't have
+ * errno. We define it as a global variable to simplify porting.
+ * Its value is always 0 and should not be used. We rename it to
+ * avoid conflict with other libraries that use the same workaround.
+ */
+# define errno z_errno
+# endif
extern int errno;
#else
-# include <errno.h>
+# ifndef _WIN32_WCE
+# include <errno.h>
+# endif
#endif
#ifndef local
@@ -105,6 +117,9 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#ifdef OS2
# define OS_CODE 0x06
+# ifdef M_I86
+ #include <malloc.h>
+# endif
#endif
#if defined(MACOS) || defined(TARGET_OS_MAC)
@@ -193,15 +208,6 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# define NO_vsnprintf
#endif
-#ifdef HAVE_STRERROR
-# ifndef VMS
- extern char *strerror OF((int));
-# endif
-# define zstrerror(errnum) strerror(errnum)
-#else
-# define zstrerror(errnum) ""
-#endif
-
#if defined(pyr)
# define NO_MEMCPY
#endif